From d816a201fa08f20459e083680326a3fc5e266545 Mon Sep 17 00:00:00 2001 From: Den Delimarsky Date: Sun, 29 Mar 2026 07:42:45 +0000 Subject: [PATCH 1/2] feat: add extensions field to client and server capabilities (backport #1630) Backport of #1630 to v1.x branch. Adds the `extensions` field to `ClientCapabilities` and `ServerCapabilities` to allow servers and clients to advertise extension support in the capability object, per SEP-2133. Adapted from the main branch implementation to use v1.x types: - Uses `object` type in spec.types.ts (matching existing `experimental` field) - Uses `AssertObjectSchema` in Zod schemas instead of `JSONObjectSchema` :house: Remote-Dev: homespace --- src/spec.types.ts | 8 ++++++ src/types.ts | 12 +++++++-- test/server/mcp.test.ts | 54 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/spec.types.ts b/src/spec.types.ts index 07a1cceff..2640152a2 100644 --- a/src/spec.types.ts +++ b/src/spec.types.ts @@ -383,6 +383,10 @@ export interface ClientCapabilities { }; }; }; + /** + * Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name). + */ + extensions?: { [key: string]: object }; } /** @@ -461,6 +465,10 @@ export interface ServerCapabilities { }; }; }; + /** + * Extensions that the server supports. Keys are extension identifiers (vendor-prefix/extension-name). + */ + extensions?: { [key: string]: object }; } /** diff --git a/src/types.ts b/src/types.ts index 87899a38f..835eac89f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -511,7 +511,11 @@ export const ClientCapabilitiesSchema = z.object({ /** * Present if the client supports task creation. */ - tasks: ClientTasksCapabilitySchema.optional() + tasks: ClientTasksCapabilitySchema.optional(), + /** + * Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name). + */ + extensions: z.record(z.string(), AssertObjectSchema).optional() }); export const InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({ @@ -589,7 +593,11 @@ export const ServerCapabilitiesSchema = z.object({ /** * Present if the server supports task creation. */ - tasks: ServerTasksCapabilitySchema.optional() + tasks: ServerTasksCapabilitySchema.optional(), + /** + * Extensions that the server supports. Keys are extension identifiers (vendor-prefix/extension-name). + */ + extensions: z.record(z.string(), AssertObjectSchema).optional() }); /** diff --git a/test/server/mcp.test.ts b/test/server/mcp.test.ts index 961af234a..575d6a300 100644 --- a/test/server/mcp.test.ts +++ b/test/server/mcp.test.ts @@ -198,6 +198,60 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => { message: 'Completed step 3 of 3' }); }); + + /*** + * Test: Extensions capability registration + */ + test('should register and advertise server extensions capability', async () => { + const mcpServer = new McpServer({ + name: 'test server', + version: '1.0' + }); + const client = new Client({ + name: 'test client', + version: '1.0' + }); + + mcpServer.server.registerCapabilities({ + extensions: { + 'io.modelcontextprotocol/test-extension': { listChanged: true } + } + }); + + const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); + await Promise.all([client.connect(clientTransport), mcpServer.connect(serverTransport)]); + + const capabilities = client.getServerCapabilities(); + expect(capabilities?.extensions).toBeDefined(); + expect(capabilities?.extensions?.['io.modelcontextprotocol/test-extension']).toEqual({ listChanged: true }); + }); + + test('should advertise client extensions capability to server', async () => { + const mcpServer = new McpServer({ + name: 'test server', + version: '1.0' + }); + const client = new Client( + { + name: 'test client', + version: '1.0' + }, + { + capabilities: { + extensions: { + 'io.modelcontextprotocol/test-extension': { streaming: true } + } + } + } + ); + + const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); + await Promise.all([client.connect(clientTransport), mcpServer.connect(serverTransport)]); + + const capabilities = mcpServer.server.getClientCapabilities(); + expect(capabilities?.extensions).toBeDefined(); + expect(capabilities?.extensions?.['io.modelcontextprotocol/test-extension']).toEqual({ streaming: true }); + }); }); describe('ResourceTemplate', () => { From 2225fd1124249a09507b758ce332354960f30c05 Mon Sep 17 00:00:00 2001 From: Den Delimarsky Date: Sun, 29 Mar 2026 07:44:00 +0000 Subject: [PATCH 2/2] chore: add changeset for extensions capability :house: Remote-Dev: homespace --- .changeset/add-extensions-capability.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/add-extensions-capability.md diff --git a/.changeset/add-extensions-capability.md b/.changeset/add-extensions-capability.md new file mode 100644 index 000000000..c5d4d200f --- /dev/null +++ b/.changeset/add-extensions-capability.md @@ -0,0 +1,5 @@ +--- +'@modelcontextprotocol/sdk': minor +--- + +Add `extensions` field to `ClientCapabilities` and `ServerCapabilities` to allow servers and clients to advertise extension support per SEP-2133