1- import { APP_DIR , MCP_APP_SUBDIR , requireConfigRoot } from '../../lib' ;
1+ import { APP_DIR , MCP_APP_SUBDIR , findConfigRoot , requireConfigRoot } from '../../lib' ;
22import type {
33 AgentCoreCliMcpDefs ,
44 AgentCoreGatewayTarget ,
@@ -7,13 +7,16 @@ import type {
77 FilePath ,
88} from '../../schema' ;
99import { AgentCoreCliMcpDefsSchema , AgentCoreGatewayTargetSchema , ToolDefinitionSchema } from '../../schema' ;
10+ import type { AddGatewayTargetOptions as CLIAddGatewayTargetOptions } from '../commands/add/types' ;
11+ import { validateAddGatewayTargetOptions } from '../commands/add/validate' ;
1012import { getErrorMessage } from '../errors' ;
1113import type { RemovableGatewayTarget } from '../operations/remove/remove-gateway-target' ;
1214import type { RemovalPreview , RemovalResult , SchemaChange } from '../operations/remove/types' ;
1315import { getTemplateToolDefinitions , renderGatewayTargetTemplate } from '../templates/GatewayTargetRenderer' ;
1416import type { AddGatewayTargetConfig } from '../tui/screens/mcp/types' ;
1517import { DEFAULT_HANDLER , DEFAULT_NODE_VERSION , DEFAULT_PYTHON_VERSION } from '../tui/screens/mcp/types' ;
1618import { BasePrimitive } from './BasePrimitive' ;
19+ import { SOURCE_CODE_NOTE } from './constants' ;
1720import type { AddResult , AddScreenComponent } from './types' ;
1821import type { Command } from '@commander-js/extra-typings' ;
1922import { existsSync } from 'fs' ;
@@ -233,13 +236,107 @@ export class GatewayTargetPrimitive extends BasePrimitive<AddGatewayTargetOption
233236 . description ( 'Add a gateway target to the project' )
234237 . option ( '--name <name>' , 'Target name' )
235238 . option ( '--description <desc>' , 'Target description' )
239+ . option ( '--type <type>' , 'Target type: mcpServer or lambda' )
240+ . option ( '--source <source>' , 'Source: existing-endpoint or create-new' )
241+ . option ( '--endpoint <url>' , 'MCP server endpoint URL' )
236242 . option ( '--language <lang>' , 'Language: Python, TypeScript, Other' )
237243 . option ( '--gateway <name>' , 'Gateway name' )
238- . option ( '--host <host>' , 'Host type: Lambda or AgentCoreRuntime' )
244+ . option ( '--host <host>' , 'Compute host: Lambda or AgentCoreRuntime' )
245+ . option ( '--outbound-auth <type>' , 'Outbound auth type: oauth, api-key, or none' )
246+ . option ( '--credential-name <name>' , 'Existing credential name for outbound auth' )
247+ . option ( '--oauth-client-id <id>' , 'OAuth client ID (creates credential inline)' )
248+ . option ( '--oauth-client-secret <secret>' , 'OAuth client secret (creates credential inline)' )
249+ . option ( '--oauth-discovery-url <url>' , 'OAuth discovery URL (creates credential inline)' )
250+ . option ( '--oauth-scopes <scopes>' , 'OAuth scopes, comma-separated' )
239251 . option ( '--json' , 'Output as JSON' )
240- . action ( ( ) => {
241- console . error ( 'Gateway target integration is coming soon.' ) ;
242- process . exit ( 1 ) ;
252+ . action ( async ( rawOptions : Record < string , string | boolean | undefined > ) => {
253+ const cliOptions = rawOptions as unknown as CLIAddGatewayTargetOptions ;
254+ try {
255+ if ( ! findConfigRoot ( ) ) {
256+ console . error ( 'No agentcore project found. Run `agentcore create` first.' ) ;
257+ process . exit ( 1 ) ;
258+ }
259+
260+ const validation = await validateAddGatewayTargetOptions ( cliOptions ) ;
261+ if ( ! validation . valid ) {
262+ if ( cliOptions . json ) {
263+ console . log ( JSON . stringify ( { success : false , error : validation . error } ) ) ;
264+ } else {
265+ console . error ( validation . error ) ;
266+ }
267+ process . exit ( 1 ) ;
268+ }
269+
270+ // Map CLI flag values to internal types
271+ const outboundAuthMap : Record < string , 'OAUTH' | 'API_KEY' | 'NONE' > = {
272+ oauth : 'OAUTH' ,
273+ 'api-key' : 'API_KEY' ,
274+ none : 'NONE' ,
275+ } ;
276+
277+ // Handle existing-endpoint targets differently (no code generation)
278+ if ( cliOptions . source === 'existing-endpoint' && cliOptions . endpoint ) {
279+ const config : AddGatewayTargetConfig = {
280+ name : cliOptions . name ! ,
281+ description : cliOptions . description ?? `Tool for ${ cliOptions . name ! } ` ,
282+ sourcePath : '' ,
283+ language : cliOptions . language ?? 'Other' ,
284+ host : 'AgentCoreRuntime' ,
285+ toolDefinition : {
286+ name : cliOptions . name ! ,
287+ description : cliOptions . description ?? `Tool for ${ cliOptions . name ! } ` ,
288+ inputSchema : { type : 'object' } ,
289+ } ,
290+ gateway : cliOptions . gateway ,
291+ endpoint : cliOptions . endpoint ,
292+ source : 'existing-endpoint' ,
293+ ...( cliOptions . outboundAuthType
294+ ? {
295+ outboundAuth : {
296+ type : outboundAuthMap [ cliOptions . outboundAuthType . toLowerCase ( ) ] ?? 'NONE' ,
297+ credentialName : cliOptions . credentialName ,
298+ } ,
299+ }
300+ : { } ) ,
301+ } ;
302+ const result = await this . createExternalGatewayTarget ( config ) ;
303+ const output = { success : true , toolName : result . toolName , sourcePath : result . projectPath || undefined } ;
304+ if ( cliOptions . json ) {
305+ console . log ( JSON . stringify ( output ) ) ;
306+ } else {
307+ console . log ( `Added gateway target '${ result . toolName } '` ) ;
308+ }
309+ process . exit ( 0 ) ;
310+ }
311+
312+ const result = await this . add ( {
313+ name : cliOptions . name ! ,
314+ description : cliOptions . description ,
315+ language : cliOptions . language ?? 'Python' ,
316+ gateway : cliOptions . gateway ,
317+ host : cliOptions . host ,
318+ } ) ;
319+
320+ if ( cliOptions . json ) {
321+ console . log ( JSON . stringify ( result ) ) ;
322+ } else if ( result . success ) {
323+ console . log ( `Added gateway target '${ result . toolName } '` ) ;
324+ if ( result . sourcePath ) {
325+ console . log ( `Tool code: ${ result . sourcePath } ` ) ;
326+ }
327+ } else {
328+ console . error ( result . error ) ;
329+ }
330+
331+ process . exit ( result . success ? 0 : 1 ) ;
332+ } catch ( error ) {
333+ if ( cliOptions . json ) {
334+ console . log ( JSON . stringify ( { success : false , error : getErrorMessage ( error ) } ) ) ;
335+ } else {
336+ console . error ( `Error: ${ getErrorMessage ( error ) } ` ) ;
337+ }
338+ process . exit ( 1 ) ;
339+ }
243340 } ) ;
244341
245342 removeCmd
@@ -248,9 +345,59 @@ export class GatewayTargetPrimitive extends BasePrimitive<AddGatewayTargetOption
248345 . option ( '--name <name>' , 'Name of resource to remove' )
249346 . option ( '--force' , 'Skip confirmation prompt' )
250347 . option ( '--json' , 'Output as JSON' )
251- . action ( ( ) => {
252- console . error ( 'Gateway target integration is coming soon.' ) ;
253- process . exit ( 1 ) ;
348+ . action ( async ( cliOptions : { name ?: string ; force ?: boolean ; json ?: boolean } ) => {
349+ try {
350+ if ( ! findConfigRoot ( ) ) {
351+ console . error ( 'No agentcore project found. Run `agentcore create` first.' ) ;
352+ process . exit ( 1 ) ;
353+ }
354+
355+ if ( cliOptions . name || cliOptions . force || cliOptions . json ) {
356+ if ( ! cliOptions . name ) {
357+ console . log ( JSON . stringify ( { success : false , error : '--name is required' } ) ) ;
358+ process . exit ( 1 ) ;
359+ }
360+
361+ const result = await this . remove ( cliOptions . name ) ;
362+ console . log (
363+ JSON . stringify ( {
364+ success : result . success ,
365+ resourceType : this . kind ,
366+ resourceName : cliOptions . name ,
367+ message : result . success ? `Removed gateway target '${ cliOptions . name } '` : undefined ,
368+ note : result . success ? SOURCE_CODE_NOTE : undefined ,
369+ error : ! result . success ? result . error : undefined ,
370+ } )
371+ ) ;
372+ process . exit ( result . success ? 0 : 1 ) ;
373+ } else {
374+ const [ { render } , { default : React } , { RemoveFlow } ] = await Promise . all ( [
375+ import ( 'ink' ) ,
376+ import ( 'react' ) ,
377+ import ( '../tui/screens/remove' ) ,
378+ ] ) ;
379+ const { clear, unmount } = render (
380+ React . createElement ( RemoveFlow , {
381+ isInteractive : false ,
382+ force : cliOptions . force ,
383+ initialResourceType : this . kind ,
384+ initialResourceName : cliOptions . name ,
385+ onExit : ( ) => {
386+ clear ( ) ;
387+ unmount ( ) ;
388+ process . exit ( 0 ) ;
389+ } ,
390+ } )
391+ ) ;
392+ }
393+ } catch ( error ) {
394+ if ( cliOptions . json ) {
395+ console . log ( JSON . stringify ( { success : false , error : getErrorMessage ( error ) } ) ) ;
396+ } else {
397+ console . error ( `Error: ${ getErrorMessage ( error ) } ` ) ;
398+ }
399+ process . exit ( 1 ) ;
400+ }
254401 } ) ;
255402 }
256403
0 commit comments