diff --git a/docs/commands.md b/docs/commands.md index 0e8c6b5f..4f9816ba 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -198,14 +198,14 @@ agentcore add # External MCP server endpoint agentcore add gateway-target \ --name WeatherTools \ - --source existing-endpoint \ + --type mcp-server \ --endpoint https://mcp.example.com/mcp \ --gateway MyGateway # External endpoint with OAuth outbound auth agentcore add gateway-target \ --name SecureTools \ - --source existing-endpoint \ + --type mcp-server \ --endpoint https://api.example.com/mcp \ --gateway MyGateway \ --outbound-auth oauth \ @@ -218,7 +218,7 @@ agentcore add gateway-target \ | -------------------------------- | ----------------------------------------------- | | `--name ` | Target name | | `--description ` | Target description | -| `--source ` | `existing-endpoint` | +| `--type ` | Target type (required): `mcp-server` | | `--endpoint ` | MCP server endpoint URL | | `--gateway ` | Gateway to attach target to | | `--outbound-auth ` | `oauth`, `api-key`, or `none` | @@ -382,7 +382,7 @@ agentcore deploy -y agentcore add gateway --name MyGateway agentcore add gateway-target \ --name WeatherTools \ - --source existing-endpoint \ + --type mcp-server \ --endpoint https://mcp.example.com/mcp \ --gateway MyGateway agentcore deploy -y diff --git a/docs/gateway.md b/docs/gateway.md index 2ddc1c21..4f47e72a 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -18,7 +18,7 @@ agentcore add gateway --name my-gateway # 3. Add a target (external MCP server) agentcore add gateway-target \ - --source existing-endpoint \ + --type mcp-server \ --name weather-tools \ --endpoint https://mcp.example.com/mcp \ --gateway my-gateway @@ -39,7 +39,7 @@ requests to. ```bash agentcore add gateway-target \ - --source existing-endpoint \ + --type mcp-server \ --name my-tools \ --endpoint https://mcp.example.com/mcp \ --gateway my-gateway @@ -87,7 +87,7 @@ Controls how the gateway authenticates with upstream MCP servers. Configured per ```bash agentcore add gateway-target \ - --source existing-endpoint \ + --type mcp-server \ --name secure-tools \ --endpoint https://api.example.com/mcp \ --gateway my-gateway \ @@ -108,7 +108,7 @@ agentcore add identity \ --client-secret my-secret agentcore add gateway-target \ - --source existing-endpoint \ + --type mcp-server \ --name secure-tools \ --endpoint https://api.example.com/mcp \ --gateway my-gateway \ @@ -129,7 +129,7 @@ include gateway client code with the correct authentication for your framework. # 1. Add gateway and targets agentcore add gateway --name my-gateway agentcore add gateway-target \ - --source existing-endpoint \ + --type mcp-server \ --name my-tools \ --endpoint https://mcp.example.com/mcp \ --gateway my-gateway diff --git a/docs/local-development.md b/docs/local-development.md index c9b464eb..284bfd6a 100644 --- a/docs/local-development.md +++ b/docs/local-development.md @@ -142,7 +142,7 @@ populated by `agentcore deploy`. If you haven't deployed yet, no gateway env var ```bash # 1. Add a gateway and target agentcore add gateway --name my-gateway -agentcore add gateway-target --name my-tools --source existing-endpoint \ +agentcore add gateway-target --name my-tools --type mcp-server \ --endpoint https://mcp.example.com/mcp --gateway my-gateway # 2. Deploy to create the gateway diff --git a/integ-tests/add-remove-gateway.test.ts b/integ-tests/add-remove-gateway.test.ts index 88d64cb0..559b5d69 100644 --- a/integ-tests/add-remove-gateway.test.ts +++ b/integ-tests/add-remove-gateway.test.ts @@ -42,6 +42,8 @@ describe('integration: add and remove gateway with external MCP server', () => { 'gateway-target', '--name', targetName, + '--type', + 'mcp-server', '--endpoint', 'https://mcp.exa.ai/mcp', '--gateway', diff --git a/src/cli/commands/add/__tests__/add-gateway-target.test.ts b/src/cli/commands/add/__tests__/add-gateway-target.test.ts index ef8820bb..9bafd869 100644 --- a/src/cli/commands/add/__tests__/add-gateway-target.test.ts +++ b/src/cli/commands/add/__tests__/add-gateway-target.test.ts @@ -44,7 +44,7 @@ describe('add gateway-target command', () => { it('requires endpoint', async () => { const result = await runCLI( - ['add', 'gateway-target', '--name', 'noendpoint', '--gateway', gatewayName, '--json'], + ['add', 'gateway-target', '--name', 'noendpoint', '--type', 'mcp-server', '--gateway', gatewayName, '--json'], projectDir ); expect(result.exitCode).toBe(1); @@ -63,6 +63,8 @@ describe('add gateway-target command', () => { 'gateway-target', '--name', targetName, + '--type', + 'mcp-server', '--endpoint', 'https://mcp.exa.ai/mcp', '--gateway', diff --git a/src/cli/commands/add/__tests__/validate.test.ts b/src/cli/commands/add/__tests__/validate.test.ts index 533d2f1e..4bf5f489 100644 --- a/src/cli/commands/add/__tests__/validate.test.ts +++ b/src/cli/commands/add/__tests__/validate.test.ts @@ -60,7 +60,7 @@ const validGatewayOptionsJwt: AddGatewayOptions = { const validGatewayTargetOptions: AddGatewayTargetOptions = { name: 'test-tool', - source: 'existing-endpoint', + type: 'mcp-server', endpoint: 'https://example.com/mcp', gateway: 'my-gateway', }; @@ -326,7 +326,7 @@ describe('validate', () => { it('returns error when no gateways exist', async () => { mockReadMcpSpec.mockResolvedValue({ agentCoreGateways: [] }); - const result = await validateAddGatewayTargetOptions(validGatewayTargetOptions); + const result = await validateAddGatewayTargetOptions({ ...validGatewayTargetOptions }); expect(result.valid).toBe(false); expect(result.error).toContain('No gateways found'); expect(result.error).toContain('agentcore add gateway'); @@ -334,7 +334,7 @@ describe('validate', () => { it('returns error when specified gateway does not exist', async () => { mockReadMcpSpec.mockResolvedValue({ agentCoreGateways: [{ name: 'other-gateway' }] }); - const result = await validateAddGatewayTargetOptions(validGatewayTargetOptions); + const result = await validateAddGatewayTargetOptions({ ...validGatewayTargetOptions }); expect(result.valid).toBe(false); expect(result.error).toContain('Gateway "my-gateway" not found'); expect(result.error).toContain('other-gateway'); @@ -345,22 +345,21 @@ describe('validate', () => { const result = await validateAddGatewayTargetOptions({ ...validGatewayTargetOptions }); expect(result.valid).toBe(true); }); - // AC20: existing-endpoint source validation - it('rejects create-new source', async () => { + // AC20: type validation + it('returns error when --type is missing', async () => { const options: AddGatewayTargetOptions = { name: 'test-tool', - source: 'create-new' as any, gateway: 'my-gateway', }; const result = await validateAddGatewayTargetOptions(options); expect(result.valid).toBe(false); - expect(result.error).toBe("Only 'existing-endpoint' source is currently supported"); + expect(result.error).toContain('--type is required'); }); - it('passes for valid existing-endpoint with https', async () => { + it('accepts --type mcp-server', async () => { const options: AddGatewayTargetOptions = { name: 'test-tool', - source: 'existing-endpoint', + type: 'mcp-server', endpoint: 'https://example.com/mcp', gateway: 'my-gateway', }; @@ -369,10 +368,32 @@ describe('validate', () => { expect(options.language).toBe('Other'); }); - it('passes for valid existing-endpoint with http', async () => { + it('returns error for invalid --type', async () => { + const options: AddGatewayTargetOptions = { + name: 'test-tool', + type: 'invalid', + gateway: 'my-gateway', + }; + const result = await validateAddGatewayTargetOptions(options); + expect(result.valid).toBe(false); + expect(result.error).toContain('Invalid type'); + }); + + it('passes for mcp-server with https endpoint', async () => { + const options: AddGatewayTargetOptions = { + name: 'test-tool', + type: 'mcp-server', + endpoint: 'https://example.com/mcp', + gateway: 'my-gateway', + }; + const result = await validateAddGatewayTargetOptions(options); + expect(result.valid).toBe(true); + }); + + it('passes for mcp-server with http endpoint', async () => { const options: AddGatewayTargetOptions = { name: 'test-tool', - source: 'existing-endpoint', + type: 'mcp-server', endpoint: 'http://localhost:3000/mcp', gateway: 'my-gateway', }; @@ -380,21 +401,21 @@ describe('validate', () => { expect(result.valid).toBe(true); }); - it('returns error for existing-endpoint without endpoint', async () => { + it('returns error for mcp-server without endpoint', async () => { const options: AddGatewayTargetOptions = { name: 'test-tool', - source: 'existing-endpoint', + type: 'mcp-server', gateway: 'my-gateway', }; const result = await validateAddGatewayTargetOptions(options); expect(result.valid).toBe(false); - expect(result.error).toBe('--endpoint is required when source is existing-endpoint'); + expect(result.error).toContain('--endpoint is required'); }); - it('returns error for existing-endpoint with non-http(s) URL', async () => { + it('returns error for mcp-server with non-http(s) URL', async () => { const options: AddGatewayTargetOptions = { name: 'test-tool', - source: 'existing-endpoint', + type: 'mcp-server', endpoint: 'ftp://example.com/mcp', gateway: 'my-gateway', }; @@ -403,10 +424,10 @@ describe('validate', () => { expect(result.error).toBe('Endpoint must use http:// or https:// protocol'); }); - it('returns error for existing-endpoint with invalid URL', async () => { + it('returns error for mcp-server with invalid URL', async () => { const options: AddGatewayTargetOptions = { name: 'test-tool', - source: 'existing-endpoint', + type: 'mcp-server', endpoint: 'not-a-url', gateway: 'my-gateway', }; @@ -423,6 +444,7 @@ describe('validate', () => { const options: AddGatewayTargetOptions = { name: 'test-tool', + type: 'mcp-server', endpoint: 'https://example.com/mcp', gateway: 'my-gateway', outboundAuthType: 'API_KEY', @@ -440,6 +462,7 @@ describe('validate', () => { const options: AddGatewayTargetOptions = { name: 'test-tool', + type: 'mcp-server', endpoint: 'https://example.com/mcp', gateway: 'my-gateway', outboundAuthType: 'API_KEY', @@ -457,6 +480,7 @@ describe('validate', () => { const options: AddGatewayTargetOptions = { name: 'test-tool', + type: 'mcp-server', endpoint: 'https://example.com/mcp', gateway: 'my-gateway', outboundAuthType: 'API_KEY', @@ -531,17 +555,17 @@ describe('validate', () => { expect(result.error).toBe('--oauth-discovery-url must be a valid URL'); }); - it('rejects --host with existing-endpoint', async () => { + it('rejects --host with mcp-server type', async () => { const options: AddGatewayTargetOptions = { name: 'test-tool', - source: 'existing-endpoint', + type: 'mcp-server', endpoint: 'https://example.com/mcp', host: 'Lambda', gateway: 'my-gateway', }; const result = await validateAddGatewayTargetOptions(options); expect(result.valid).toBe(false); - expect(result.error).toBe('--host is not applicable for existing endpoint targets'); + expect(result.error).toBe('--host is not applicable for MCP server targets'); }); }); diff --git a/src/cli/commands/add/types.ts b/src/cli/commands/add/types.ts index 46757121..595bc10e 100644 --- a/src/cli/commands/add/types.ts +++ b/src/cli/commands/add/types.ts @@ -49,7 +49,6 @@ export interface AddGatewayTargetOptions { name?: string; description?: string; type?: string; - source?: string; endpoint?: string; language?: 'Python' | 'TypeScript' | 'Other'; gateway?: string; diff --git a/src/cli/commands/add/validate.ts b/src/cli/commands/add/validate.ts index d3cbf4f4..3c02f38c 100644 --- a/src/cli/commands/add/validate.ts +++ b/src/cli/commands/add/validate.ts @@ -219,13 +219,16 @@ export async function validateAddGatewayTargetOptions(options: AddGatewayTargetO return { valid: false, error: '--name is required' }; } - if (options.type && options.type !== 'mcpServer' && options.type !== 'lambda') { - return { valid: false, error: 'Invalid type. Valid options: mcpServer, lambda' }; + if (!options.type) { + return { valid: false, error: '--type is required. Valid options: mcp-server' }; } - if (options.source && options.source !== 'existing-endpoint') { - return { valid: false, error: "Only 'existing-endpoint' source is currently supported" }; + const typeMap: Record = { 'mcp-server': 'mcpServer' }; + const mappedType = typeMap[options.type]; + if (!mappedType) { + return { valid: false, error: `Invalid type: ${options.type}. Valid options: mcp-server` }; } + options.type = mappedType; // Gateway is required — a gateway target must be attached to a gateway if (!options.gateway) { @@ -260,10 +263,7 @@ export async function validateAddGatewayTargetOptions(options: AddGatewayTargetO }; } - // Default to existing-endpoint (only supported source for now) - options.source ??= 'existing-endpoint'; - - // Validate outbound auth configuration (applies to all source types) + // Validate outbound auth configuration if (options.outboundAuthType && options.outboundAuthType !== 'NONE') { const hasInlineOAuth = !!(options.oauthClientId ?? options.oauthClientSecret ?? options.oauthDiscoveryUrl); @@ -309,12 +309,12 @@ export async function validateAddGatewayTargetOptions(options: AddGatewayTargetO } } - if (options.source === 'existing-endpoint') { + if (mappedType === 'mcpServer') { if (options.host) { - return { valid: false, error: '--host is not applicable for existing endpoint targets' }; + return { valid: false, error: '--host is not applicable for MCP server targets' }; } if (!options.endpoint) { - return { valid: false, error: '--endpoint is required when source is existing-endpoint' }; + return { valid: false, error: '--endpoint is required for mcp-server type' }; } try { diff --git a/src/cli/commands/remove/__tests__/remove-gateway-target.test.ts b/src/cli/commands/remove/__tests__/remove-gateway-target.test.ts index 67130423..4269de87 100644 --- a/src/cli/commands/remove/__tests__/remove-gateway-target.test.ts +++ b/src/cli/commands/remove/__tests__/remove-gateway-target.test.ts @@ -63,6 +63,8 @@ describe('remove gateway-target command', () => { 'https://example.com/mcp', '--gateway', tempGateway, + '--type', + 'mcp-server', '--json', ], projectDir diff --git a/src/cli/commands/remove/__tests__/remove-gateway.test.ts b/src/cli/commands/remove/__tests__/remove-gateway.test.ts index a2d273e2..b2dfd1f6 100644 --- a/src/cli/commands/remove/__tests__/remove-gateway.test.ts +++ b/src/cli/commands/remove/__tests__/remove-gateway.test.ts @@ -108,6 +108,8 @@ describe('remove gateway command', () => { 'https://example.com/mcp', '--gateway', gatewayName, + '--type', + 'mcp-server', '--json', ], projectDir diff --git a/src/cli/primitives/GatewayTargetPrimitive.ts b/src/cli/primitives/GatewayTargetPrimitive.ts index 292b8dfd..27c432fc 100644 --- a/src/cli/primitives/GatewayTargetPrimitive.ts +++ b/src/cli/primitives/GatewayTargetPrimitive.ts @@ -236,8 +236,7 @@ export class GatewayTargetPrimitive extends BasePrimitive', 'Target name') .option('--description ', 'Target description') - .option('--type ', 'Target type: mcpServer or lambda') - .option('--source ', 'Source: existing-endpoint or create-new') + .option('--type ', 'Target type (required): mcp-server') .option('--endpoint ', 'MCP server endpoint URL') .option('--language ', 'Language: Python, TypeScript, Other') .option('--gateway ', 'Gateway name') @@ -274,14 +273,15 @@ export class GatewayTargetPrimitive extends BasePrimitive { diff --git a/src/cli/tui/screens/mcp/AddGatewayTargetScreen.tsx b/src/cli/tui/screens/mcp/AddGatewayTargetScreen.tsx index 169b9633..7c891e5a 100644 --- a/src/cli/tui/screens/mcp/AddGatewayTargetScreen.tsx +++ b/src/cli/tui/screens/mcp/AddGatewayTargetScreen.tsx @@ -1,3 +1,4 @@ +import type { GatewayTargetType } from '../../../../schema'; import { ToolNameSchema } from '../../../../schema'; import { ConfirmReview, Panel, Screen, StepIndicator, TextInput, WizardSelect } from '../../components'; import type { SelectableItem } from '../../components'; @@ -5,7 +6,7 @@ import { HELP_TEXT } from '../../constants'; import { useListNavigation } from '../../hooks'; import { generateUniqueName } from '../../utils'; import type { AddGatewayTargetConfig } from './types'; -import { MCP_TOOL_STEP_LABELS, OUTBOUND_AUTH_OPTIONS } from './types'; +import { MCP_TOOL_STEP_LABELS, OUTBOUND_AUTH_OPTIONS, TARGET_TYPE_OPTIONS } from './types'; import { useAddGatewayTargetWizard } from './useAddGatewayTargetWizard'; import { Box, Text } from 'ink'; import React, { useMemo, useState } from 'react'; @@ -51,12 +52,25 @@ export function AddGatewayTargetScreen({ return items; }, [existingOAuthCredentialNames]); + const targetTypeItems: SelectableItem[] = useMemo( + () => TARGET_TYPE_OPTIONS.map(o => ({ id: o.id, title: o.title, description: o.description })), + [] + ); + const isGatewayStep = wizard.step === 'gateway'; const isOutboundAuthStep = wizard.step === 'outbound-auth'; + const isTargetTypeStep = wizard.step === 'target-type'; const isTextStep = wizard.step === 'name' || wizard.step === 'endpoint'; const isConfirmStep = wizard.step === 'confirm'; const noGatewaysAvailable = isGatewayStep && existingGateways.length === 0; + const targetTypeNav = useListNavigation({ + items: targetTypeItems, + onSelect: item => wizard.setTargetType(item.id as GatewayTargetType), + onExit: () => wizard.goBack(), + isActive: isTargetTypeStep, + }); + const gatewayNav = useListNavigation({ items: gatewayItems, onSelect: item => wizard.setGateway(item.id), @@ -117,6 +131,15 @@ export function AddGatewayTargetScreen({ return ( + {isTargetTypeStep && ( + + )} + {isGatewayStep && !noGatewaysAvailable && ( o.id === wizard.config.targetType)?.title ?? + wizard.config.targetType ?? + '', + }, ...(wizard.config.endpoint ? [{ label: 'Endpoint', value: wizard.config.endpoint }] : []), { label: 'Gateway', value: wizard.config.gateway ?? '' }, ...(wizard.config.outboundAuth diff --git a/src/cli/tui/screens/mcp/__tests__/types.test.ts b/src/cli/tui/screens/mcp/__tests__/types.test.ts index 31c1e9db..cac8e71f 100644 --- a/src/cli/tui/screens/mcp/__tests__/types.test.ts +++ b/src/cli/tui/screens/mcp/__tests__/types.test.ts @@ -1,4 +1,4 @@ -import { AUTHORIZER_TYPE_OPTIONS, SKIP_FOR_NOW, SOURCE_OPTIONS } from '../types.js'; +import { AUTHORIZER_TYPE_OPTIONS, SKIP_FOR_NOW, TARGET_TYPE_OPTIONS } from '../types.js'; import { describe, expect, it } from 'vitest'; describe('MCP types constants', () => { @@ -10,11 +10,8 @@ describe('MCP types constants', () => { expect(SKIP_FOR_NOW).toBe('skip-for-now'); }); - it('SOURCE_OPTIONS has entries for existing-endpoint and create-new', () => { - const existingEndpoint = SOURCE_OPTIONS.find((opt: { id: string }) => opt.id === 'existing-endpoint'); - const createNew = SOURCE_OPTIONS.find((opt: { id: string }) => opt.id === 'create-new'); - - expect(existingEndpoint).toBeDefined(); - expect(createNew).toBeDefined(); + it('TARGET_TYPE_OPTIONS has mcpServer entry', () => { + const mcpServer = TARGET_TYPE_OPTIONS.find((opt: { id: string }) => opt.id === 'mcpServer'); + expect(mcpServer).toBeDefined(); }); }); diff --git a/src/cli/tui/screens/mcp/types.ts b/src/cli/tui/screens/mcp/types.ts index f24aeed5..2f176b80 100644 --- a/src/cli/tui/screens/mcp/types.ts +++ b/src/cli/tui/screens/mcp/types.ts @@ -1,4 +1,10 @@ -import type { GatewayAuthorizerType, NodeRuntime, PythonRuntime, ToolDefinition } from '../../../../schema'; +import type { + GatewayAuthorizerType, + GatewayTargetType, + NodeRuntime, + PythonRuntime, + ToolDefinition, +} from '../../../../schema'; // ───────────────────────────────────────────────────────────────────────────── // Gateway Flow Types @@ -48,7 +54,7 @@ export type ComputeHost = 'Lambda' | 'AgentCoreRuntime'; */ export type AddGatewayTargetStep = | 'name' - | 'source' + | 'target-type' | 'endpoint' | 'language' | 'gateway' @@ -63,8 +69,8 @@ export interface AddGatewayTargetConfig { description: string; sourcePath: string; language: TargetLanguage; - /** Source type for external endpoints */ - source?: 'existing-endpoint' | 'create-new'; + /** Target type selected by user */ + targetType?: GatewayTargetType; /** External endpoint URL */ endpoint?: string; /** Gateway name */ @@ -83,7 +89,7 @@ export interface AddGatewayTargetConfig { export const MCP_TOOL_STEP_LABELS: Record = { name: 'Name', - source: 'Source', + 'target-type': 'Target Type', endpoint: 'Endpoint', language: 'Language', gateway: 'Gateway', @@ -104,9 +110,8 @@ export const AUTHORIZER_TYPE_OPTIONS = [ export const SKIP_FOR_NOW = 'skip-for-now' as const; -export const SOURCE_OPTIONS = [ - { id: 'existing-endpoint', title: 'Existing endpoint', description: 'Connect to an existing MCP server' }, - { id: 'create-new', title: 'Create new', description: 'Scaffold a new MCP server' }, +export const TARGET_TYPE_OPTIONS = [ + { id: 'mcpServer', title: 'MCP Server endpoint', description: 'Connect to an existing MCP-compatible server' }, ] as const; export const TARGET_LANGUAGE_OPTIONS = [ diff --git a/src/cli/tui/screens/mcp/useAddGatewayTargetWizard.ts b/src/cli/tui/screens/mcp/useAddGatewayTargetWizard.ts index d29daaf6..3295a2b1 100644 --- a/src/cli/tui/screens/mcp/useAddGatewayTargetWizard.ts +++ b/src/cli/tui/screens/mcp/useAddGatewayTargetWizard.ts @@ -1,16 +1,8 @@ import { APP_DIR, MCP_APP_SUBDIR } from '../../../../lib'; -import type { ToolDefinition } from '../../../../schema'; +import type { GatewayTargetType, ToolDefinition } from '../../../../schema'; import type { AddGatewayTargetConfig, AddGatewayTargetStep } from './types'; import { useCallback, useMemo, useState } from 'react'; -/** - * Steps for adding a gateway target (existing endpoint only). - * name → endpoint → gateway → outbound-auth → confirm - */ -function getSteps(): AddGatewayTargetStep[] { - return ['name', 'endpoint', 'gateway', 'outbound-auth', 'confirm']; -} - function deriveToolDefinition(name: string): ToolDefinition { return { name, @@ -24,7 +16,6 @@ function getDefaultConfig(): AddGatewayTargetConfig { name: '', description: '', sourcePath: '', - source: 'existing-endpoint', language: 'Python', host: 'Lambda', toolDefinition: deriveToolDefinition(''), @@ -35,15 +26,27 @@ export function useAddGatewayTargetWizard(existingGateways: string[] = []) { const [config, setConfig] = useState(getDefaultConfig); const [step, setStep] = useState('name'); - const steps = useMemo(() => getSteps(), []); + // Dynamic steps — recomputes when targetType changes + const steps = useMemo(() => { + const baseSteps: AddGatewayTargetStep[] = ['name', 'target-type']; + if (config.targetType) { + switch (config.targetType) { + case 'mcpServer': + default: + baseSteps.push('endpoint', 'gateway', 'outbound-auth'); + break; + } + baseSteps.push('confirm'); + } + return baseSteps; + }, [config.targetType]); + const currentIndex = steps.indexOf(step); const goBack = useCallback(() => { - const currentSteps = getSteps(); - const idx = currentSteps.indexOf(step); - const prevStep = currentSteps[idx - 1]; + const prevStep = steps[currentIndex - 1]; if (prevStep) setStep(prevStep); - }, [step]); + }, [currentIndex, steps]); const setName = useCallback((name: string) => { setConfig(c => ({ @@ -53,6 +56,11 @@ export function useAddGatewayTargetWizard(existingGateways: string[] = []) { sourcePath: `${APP_DIR}/${MCP_APP_SUBDIR}/${name}`, toolDefinition: deriveToolDefinition(name), })); + setStep('target-type'); + }, []); + + const setTargetType = useCallback((targetType: GatewayTargetType) => { + setConfig(c => ({ ...c, targetType })); setStep('endpoint'); }, []); @@ -93,6 +101,7 @@ export function useAddGatewayTargetWizard(existingGateways: string[] = []) { existingGateways, goBack, setName, + setTargetType, setEndpoint, setGateway, setOutboundAuth,