Skip to content

Commit 67759c4

Browse files
committed
feat: mcp gateway schema types (auth, outbound auth, OAuth credentials)
1 parent 26c1b5b commit 67759c4

File tree

3 files changed

+94
-9
lines changed

3 files changed

+94
-9
lines changed

src/schema/schemas/__tests__/mcp.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,11 @@ describe('AgentCoreGatewayTargetSchema', () => {
261261
name: 'myTarget',
262262
targetType: 'lambda',
263263
toolDefinitions: [validToolDef],
264+
compute: {
265+
host: 'Lambda',
266+
implementation: { language: 'Python', path: 'tools', handler: 'h' },
267+
pythonVersion: 'PYTHON_3_12',
268+
},
264269
});
265270
expect(result.success).toBe(true);
266271
});
@@ -270,6 +275,11 @@ describe('AgentCoreGatewayTargetSchema', () => {
270275
name: 'myTarget',
271276
targetType: 'lambda',
272277
toolDefinitions: [],
278+
compute: {
279+
host: 'Lambda',
280+
implementation: { language: 'Python', path: 'tools', handler: 'h' },
281+
pythonVersion: 'PYTHON_3_12',
282+
},
273283
});
274284
expect(result.success).toBe(false);
275285
});
@@ -303,6 +313,11 @@ describe('AgentCoreGatewaySchema', () => {
303313
name: 'target1',
304314
targetType: 'lambda',
305315
toolDefinitions: [validToolDef],
316+
compute: {
317+
host: 'Lambda',
318+
implementation: { language: 'Python', path: 'tools', handler: 'h' },
319+
pythonVersion: 'PYTHON_3_12',
320+
},
306321
},
307322
],
308323
};
@@ -387,7 +402,16 @@ describe('AgentCoreMcpSpecSchema', () => {
387402
agentCoreGateways: [
388403
{
389404
name: 'gw1',
390-
targets: [{ name: 't1', targetType: 'lambda', toolDefinitions: [validToolDef] }],
405+
targets: [{
406+
name: 't1',
407+
targetType: 'lambda',
408+
toolDefinitions: [validToolDef],
409+
compute: {
410+
host: 'Lambda',
411+
implementation: { language: 'Python', path: 'tools', handler: 'h' },
412+
pythonVersion: 'PYTHON_3_12',
413+
},
414+
}],
391415
},
392416
],
393417
});

src/schema/schemas/agentcore-project.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@ export type Memory = z.infer<typeof MemorySchema>;
7171
// Credential Schema
7272
// ============================================================================
7373

74-
export const CredentialTypeSchema = z.literal('ApiKeyCredentialProvider');
75-
export type CredentialType = z.infer<typeof CredentialTypeSchema>;
76-
7774
export const CredentialNameSchema = z
7875
.string()
7976
.min(3, 'Credential name must be at least 3 characters')
@@ -83,11 +80,36 @@ export const CredentialNameSchema = z
8380
'Must contain only alphanumeric characters, underscores, dots, and hyphens (3-255 chars)'
8481
);
8582

86-
export const CredentialSchema = z.object({
87-
type: CredentialTypeSchema,
83+
export const CredentialTypeSchema = z.enum(['ApiKeyCredentialProvider', 'OAuthCredentialProvider']);
84+
export type CredentialType = z.infer<typeof CredentialTypeSchema>;
85+
86+
export const ApiKeyCredentialSchema = z.object({
87+
type: z.literal('ApiKeyCredentialProvider'),
88+
name: CredentialNameSchema,
89+
});
90+
91+
export type ApiKeyCredential = z.infer<typeof ApiKeyCredentialSchema>;
92+
93+
export const OAuthCredentialSchema = z.object({
94+
type: z.literal('OAuthCredentialProvider'),
8895
name: CredentialNameSchema,
96+
/** OIDC discovery URL for the OAuth provider */
97+
discoveryUrl: z.string().url(),
98+
/** Scopes this credential provider supports */
99+
scopes: z.array(z.string()).default([]),
100+
/** Credential provider vendor type */
101+
vendor: z.string().default('CustomOauth2'),
102+
/** Whether this credential was auto-created by the CLI (e.g., for CUSTOM_JWT inbound auth) */
103+
managed: z.boolean().optional(),
89104
});
90105

106+
export type OAuthCredential = z.infer<typeof OAuthCredentialSchema>;
107+
108+
export const CredentialSchema = z.discriminatedUnion('type', [
109+
ApiKeyCredentialSchema,
110+
OAuthCredentialSchema,
111+
]);
112+
91113
export type Credential = z.infer<typeof CredentialSchema>;
92114

93115
// ============================================================================

src/schema/schemas/mcp.ts

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export type GatewayTargetType = z.infer<typeof GatewayTargetTypeSchema>;
1515
// Gateway Authorization Schemas
1616
// ============================================================================
1717

18-
export const GatewayAuthorizerTypeSchema = z.enum(['NONE', 'CUSTOM_JWT']);
18+
export const GatewayAuthorizerTypeSchema = z.enum(['NONE', 'AWS_IAM', 'CUSTOM_JWT']);
1919
export type GatewayAuthorizerType = z.infer<typeof GatewayAuthorizerTypeSchema>;
2020

2121
/** OIDC well-known configuration endpoint suffix (per OpenID Connect Discovery 1.0 spec) */
@@ -44,6 +44,7 @@ export const CustomJwtAuthorizerConfigSchema = z.object({
4444
allowedAudience: z.array(z.string().min(1)),
4545
/** List of allowed client IDs */
4646
allowedClients: z.array(z.string().min(1)).min(1),
47+
allowedScopes: z.array(z.string().min(1)).optional(),
4748
});
4849

4950
export type CustomJwtAuthorizerConfig = z.infer<typeof CustomJwtAuthorizerConfigSchema>;
@@ -57,6 +58,17 @@ export const GatewayAuthorizerConfigSchema = z.object({
5758

5859
export type GatewayAuthorizerConfig = z.infer<typeof GatewayAuthorizerConfigSchema>;
5960

61+
export const OutboundAuthTypeSchema = z.enum(['OAUTH', 'API_KEY', 'NONE']);
62+
export type OutboundAuthType = z.infer<typeof OutboundAuthTypeSchema>;
63+
64+
export const OutboundAuthSchema = z.object({
65+
type: OutboundAuthTypeSchema.default('NONE'),
66+
credentialName: z.string().min(1).optional(),
67+
scopes: z.array(z.string()).optional(),
68+
}).strict();
69+
70+
export type OutboundAuth = z.infer<typeof OutboundAuthSchema>;
71+
6072
export const McpImplLanguageSchema = z.enum(['TypeScript', 'Python']);
6173
export type McpImplementationLanguage = z.infer<typeof McpImplLanguageSchema>;
6274

@@ -262,10 +274,37 @@ export const AgentCoreGatewayTargetSchema = z
262274
.object({
263275
name: z.string().min(1),
264276
targetType: GatewayTargetTypeSchema,
265-
toolDefinitions: z.array(ToolDefinitionSchema).min(1),
277+
/** Tool definitions. Required for Lambda targets. Optional for MCP Server (discovered via tools/list). */
278+
toolDefinitions: z.array(ToolDefinitionSchema).optional(),
279+
/** Compute configuration. Required for Lambda/Runtime scaffold targets. */
266280
compute: ToolComputeConfigSchema.optional(),
281+
/** MCP Server endpoint URL. Required for external MCP Server targets. */
282+
endpoint: z.string().url().optional(),
283+
/** Outbound auth configuration for the target. */
284+
outboundAuth: OutboundAuthSchema.optional(),
267285
})
268-
.strict();
286+
.strict()
287+
.refine(
288+
data => {
289+
// External MCP Server: needs endpoint, no compute
290+
if (data.targetType === 'mcpServer' && !data.compute && !data.endpoint) {
291+
return false;
292+
}
293+
// Lambda target: needs compute and tool definitions
294+
if (data.targetType === 'lambda') {
295+
if (!data.compute) return false;
296+
if (!data.toolDefinitions || data.toolDefinitions.length === 0) return false;
297+
}
298+
// Outbound auth with credential needs a credential name
299+
if (data.outboundAuth && data.outboundAuth.type !== 'NONE' && !data.outboundAuth.credentialName) {
300+
return false;
301+
}
302+
return true;
303+
},
304+
{
305+
message: 'Invalid target configuration. MCP Server targets need an endpoint or compute. Lambda targets need compute and tool definitions. OAuth/API_KEY auth needs a credential name.',
306+
}
307+
);
269308

270309
export type AgentCoreGatewayTarget = z.infer<typeof AgentCoreGatewayTargetSchema>;
271310

0 commit comments

Comments
 (0)