From f5d0dc9de6c5075fbe95ea4b169b45f5ad22e972 Mon Sep 17 00:00:00 2001 From: Kiro Agent <244629292+kiro-agent@users.noreply.github.com> Date: Sun, 30 Aug 2026 14:46:23 +0000 Subject: [PATCH 1/3] fix(mcp-auth): negotiate protocol version instead of rejecting Add 2025-06-18 to the default supported protocol versions and negotiate downwards on initialize instead of returning JSON-RPC -32602 for an unsupported version. Per the MCP lifecycle spec the server echoes the requested version when supported, otherwise responds with a version it does support. We pick the highest supported version that is not newer than the requested one, because @modelcontextprotocol/sdk <= 1.16.0 rejects any negotiated version outside its own accepted set. Only when no supported version is old enough do we fall back to -32602. --- src/constructs/mcp-auth.ts | 4 +-- src/constructs/mcp-cognito-auth.ts | 2 +- src/constructs/rest-api.ts | 2 +- src/mcp-auth/mcp/server.ts | 39 ++++++++++++++++++++-- test/mcp-auth/mcp-server.test.ts | 52 ++++++++++++++++++++++++++++-- 5 files changed, 91 insertions(+), 8 deletions(-) diff --git a/src/constructs/mcp-auth.ts b/src/constructs/mcp-auth.ts index a030607e..d1e43e0f 100644 --- a/src/constructs/mcp-auth.ts +++ b/src/constructs/mcp-auth.ts @@ -47,7 +47,7 @@ export interface McpAuthProps { /** * Supported MCP protocol versions (newest first). - * @default ['2025-11-25', '2025-03-26', '2024-11-05'] + * @default ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'] */ readonly protocolVersions?: string[]; @@ -139,7 +139,7 @@ export class McpAuth extends Construct { MCP_CLIENT_ID: props.clientId, MCP_SERVER_NAME: props.serverInfo.name, MCP_SERVER_VERSION: props.serverInfo.version, - MCP_PROTOCOL_VERSIONS: (props.protocolVersions ?? ['2025-11-25', '2025-03-26', '2024-11-05']).join(','), + MCP_PROTOCOL_VERSIONS: (props.protocolVersions ?? ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05']).join(','), MCP_SCOPES: (props.scopes ?? ['openid', 'email', 'profile']).join(','), MCP_ALLOWED_REDIRECT_URIS: props.allowedRedirectUris.join(','), MCP_STRIP_PARAMETERS: (props.stripParameters ?? ['resource']).join(','), diff --git a/src/constructs/mcp-cognito-auth.ts b/src/constructs/mcp-cognito-auth.ts index a17ef3a8..c011c952 100644 --- a/src/constructs/mcp-cognito-auth.ts +++ b/src/constructs/mcp-cognito-auth.ts @@ -42,7 +42,7 @@ export interface McpCognitoAuthProps { /** * Supported MCP protocol versions (newest first). - * @default ['2025-11-25', '2025-03-26', '2024-11-05'] + * @default ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'] */ readonly protocolVersions?: string[]; diff --git a/src/constructs/rest-api.ts b/src/constructs/rest-api.ts index 633dda1f..3863e52b 100644 --- a/src/constructs/rest-api.ts +++ b/src/constructs/rest-api.ts @@ -100,7 +100,7 @@ export interface McpAuthOptions { /** * Supported MCP protocol versions (newest first). - * @default ['2025-11-25', '2025-03-26', '2024-11-05'] + * @default ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'] */ readonly protocolVersions?: string[]; diff --git a/src/mcp-auth/mcp/server.ts b/src/mcp-auth/mcp/server.ts index 605d5253..7ee718ea 100644 --- a/src/mcp-auth/mcp/server.ts +++ b/src/mcp-auth/mcp/server.ts @@ -62,12 +62,24 @@ export function createMcpServer(options: McpServerOptions | undefined)?.protocolVersion as string | undefined; - if (!clientVersion || !options.protocolVersions.includes(clientVersion)) { + if (!clientVersion) { + return jsonResponse(200, jsonRpcError(id, INVALID_PARAMS, `Unsupported protocol version. Supported: ${options.protocolVersions.join(', ')}`)); + } + + // Per the MCP lifecycle spec: echo the requested version when we support it, + // otherwise negotiate to a version we do support. We negotiate *downwards* — + // the highest supported version that is not newer than the one requested — + // because clients (e.g. @modelcontextprotocol/sdk <= 1.16.0) reject any + // negotiated version outside their own accepted set. Answering with a newer + // version than the client asked for would fail the handshake. + const negotiatedVersion = negotiateProtocolVersion(clientVersion, options.protocolVersions); + + if (!negotiatedVersion) { return jsonResponse(200, jsonRpcError(id, INVALID_PARAMS, `Unsupported protocol version. Supported: ${options.protocolVersions.join(', ')}`)); } return jsonResponse(200, jsonRpcSuccess(id, { - protocolVersion: clientVersion, + protocolVersion: negotiatedVersion, capabilities: { tools: {} }, serverInfo: options.serverInfo, })); @@ -120,3 +132,26 @@ export function createMcpServer(options: McpServerOptions v <= requested) + .sort(); + + return candidates.length > 0 ? candidates[candidates.length - 1] : undefined; +} diff --git a/test/mcp-auth/mcp-server.test.ts b/test/mcp-auth/mcp-server.test.ts index f635e10a..e7cc79c1 100644 --- a/test/mcp-auth/mcp-server.test.ts +++ b/test/mcp-auth/mcp-server.test.ts @@ -60,8 +60,56 @@ describe('createMcpServer', () => { expect(body.result.protocolVersion).toBe('2025-03-26'); }); - test('rejects unsupported protocol version', async () => { - const server = makeServer(); + test('echoes back 2025-06-18 when it is supported', async () => { + const server = makeServer({ + protocolVersions: ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'], + }); + const result = await server.handle( + rpcBody('initialize', { protocolVersion: '2025-06-18' }), + {}, + ); + + expect(result.statusCode).toBe(200); + const body = JSON.parse(result.body); + expect(body.error).toBeUndefined(); + expect(body.result.protocolVersion).toBe('2025-06-18'); + }); + + test('negotiates down to the highest supported version not newer than requested', async () => { + // Client asks for a version we do not support; the closest older version + // we share is 2025-03-26 (2025-06-18 would be newer than the request). + const server = makeServer({ + protocolVersions: ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'], + }); + const result = await server.handle( + rpcBody('initialize', { protocolVersion: '2025-05-01' }), + {}, + ); + + expect(result.statusCode).toBe(200); + const body = JSON.parse(result.body); + expect(body.error).toBeUndefined(); + expect(body.result.protocolVersion).toBe('2025-03-26'); + }); + + test('negotiates down for an unknown future version instead of erroring', async () => { + const server = makeServer({ + protocolVersions: ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'], + }); + const result = await server.handle( + rpcBody('initialize', { protocolVersion: '2030-01-01' }), + {}, + ); + + expect(result.statusCode).toBe(200); + const body = JSON.parse(result.body); + expect(body.error).toBeUndefined(); + // Highest supported version, since all supported versions are older. + expect(body.result.protocolVersion).toBe('2025-11-25'); + }); + + test('errors only when no supported version is old enough to downgrade to', async () => { + const server = makeServer({ protocolVersions: ['2025-11-25', '2025-06-18'] }); const result = await server.handle( rpcBody('initialize', { protocolVersion: '1999-01-01' }), {}, From 8bd9d7025809c9290ebfc4d9e656032b42c892f8 Mon Sep 17 00:00:00 2001 From: Kiro Agent <244629292+kiro-agent@users.noreply.github.com> Date: Sun, 30 Aug 2026 14:53:16 +0000 Subject: [PATCH 2/3] fix(mcp-auth): update MCP_PROTOCOL_VERSIONS default assertion The McpAuth construct test asserted the old default env value; update it to include 2025-06-18 to match the new default. --- test/constructs/mcp-auth.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/constructs/mcp-auth.test.ts b/test/constructs/mcp-auth.test.ts index f772b3a1..0679f4f5 100644 --- a/test/constructs/mcp-auth.test.ts +++ b/test/constructs/mcp-auth.test.ts @@ -129,7 +129,7 @@ describe('McpAuth', () => { MCP_CLIENT_ID: 'test-client-id', MCP_SERVER_NAME: 'test-server', MCP_SERVER_VERSION: '1.0.0', - MCP_PROTOCOL_VERSIONS: '2025-11-25,2025-03-26,2024-11-05', + MCP_PROTOCOL_VERSIONS: '2025-11-25,2025-06-18,2025-03-26,2024-11-05', MCP_SCOPES: 'openid,email,profile', MCP_ALLOWED_REDIRECT_URIS: 'https://claude.ai/oauth/callback', MCP_STRIP_PARAMETERS: 'resource', From b87d9ad35be5c7d01236b741dd5949c1fbe7dc2d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 30 Aug 2026 14:55:58 +0000 Subject: [PATCH 3/3] chore: self mutation Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- docs/constructs/interfaces/McpAuthOptions.html | 2 +- docs/constructs/interfaces/McpAuthProps.html | 2 +- docs/constructs/interfaces/McpCognitoAuthProps.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/constructs/interfaces/McpAuthOptions.html b/docs/constructs/interfaces/McpAuthOptions.html index f444c5a6..3090a1b9 100644 --- a/docs/constructs/interfaces/McpAuthOptions.html +++ b/docs/constructs/interfaces/McpAuthOptions.html @@ -18,7 +18,7 @@ Requires explicit endpoint URLs and client ID.

lambdaOptions?: LambdaOptions

Lambda function options for MCP auth handlers.

protocolVersions?: string[]

Supported MCP protocol versions (newest first).

-
['2025-11-25', '2025-03-26', '2024-11-05']
+
['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05']
 
scopes?: string[]

OAuth scopes to advertise in discovery metadata.

diff --git a/docs/constructs/interfaces/McpAuthProps.html b/docs/constructs/interfaces/McpAuthProps.html index d808c7ae..07f92798 100644 --- a/docs/constructs/interfaces/McpAuthProps.html +++ b/docs/constructs/interfaces/McpAuthProps.html @@ -24,7 +24,7 @@
clientId: string

The pre-provisioned OAuth client ID returned by the register endpoint.

lambdaOptions?: LambdaOptions

Lambda function options for MCP auth handlers.

protocolVersions?: string[]

Supported MCP protocol versions (newest first).

-
['2025-11-25', '2025-03-26', '2024-11-05']
+
['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05']
 
scopes?: string[]

OAuth scopes to advertise in discovery metadata.

diff --git a/docs/constructs/interfaces/McpCognitoAuthProps.html b/docs/constructs/interfaces/McpCognitoAuthProps.html index 16502e69..8046ad30 100644 --- a/docs/constructs/interfaces/McpCognitoAuthProps.html +++ b/docs/constructs/interfaces/McpCognitoAuthProps.html @@ -34,7 +34,7 @@
lambdaOptions?: LambdaOptions

Lambda function options for MCP auth handlers.

protocolVersions?: string[]

Supported MCP protocol versions (newest first).

-
['2025-11-25', '2025-03-26', '2024-11-05']
+
['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05']
 
scopes?: string[]

OAuth scopes to advertise in discovery metadata.