Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/preserve-request-meta-envelope-keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@modelcontextprotocol/core-internal': patch
'@modelcontextprotocol/server': patch
---

Publish `RequestMetaEnvelope` with its wire keys intact, so `ctx.mcpReq.envelope?.[CLIENT_CAPABILITIES_META_KEY]` is typed as `ClientCapabilities | undefined`. The 2.4.0 declaration emit dropped the computed keys and published the type as `{}`.
26 changes: 9 additions & 17 deletions packages/core-internal/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,7 @@

import type * as z from 'zod/v4';

import type {
CLIENT_CAPABILITIES_META_KEY,
CLIENT_INFO_META_KEY,
INTERNAL_ERROR,
INVALID_PARAMS,
INVALID_REQUEST,
LOG_LEVEL_META_KEY,
METHOD_NOT_FOUND,
PARSE_ERROR,
PROTOCOL_VERSION_META_KEY
} from './constants';
import type { INTERNAL_ERROR, INVALID_PARAMS, INVALID_REQUEST, METHOD_NOT_FOUND, PARSE_ERROR } from './constants';
import type {
AnnotationsSchema,
AudioContentSchema,
Expand Down Expand Up @@ -240,20 +230,22 @@ export type NotificationParams = Infer<typeof NotificationsParamsSchema>;
* The per-request `_meta` envelope carried by every request under protocol revision
* 2026-07-28 (protocol version, client info, client capabilities, optional log level).
*
* Neutral hand-written shape keyed by the public meta-key constants — never
* inferred from a wire-module schema (this neutral layer does not import from
* Neutral hand-written shape whose keys are the public meta-key constant
* values, written as string literals so the tsdown declaration bundler
* cannot drop them (it published this type as `{}` in 2.4.0). Never inferred
* from a wire-module schema (this neutral layer does not import from
* `wire/rev*`). A `type` alias rather than an interface so it stays assignable
* to `_meta`'s string-indexed object slot.
*/
export type RequestMetaEnvelope = {
[PROTOCOL_VERSION_META_KEY]: string;
'io.modelcontextprotocol/protocolVersion': string;
/**
* Optional since spec PR #3002: clients SHOULD send it, servers must not
* require it (and should not rely on it for behavior or security).
*/
[CLIENT_INFO_META_KEY]?: Implementation;
[CLIENT_CAPABILITIES_META_KEY]: ClientCapabilities;
[LOG_LEVEL_META_KEY]?: LoggingLevel;
'io.modelcontextprotocol/clientInfo'?: Implementation;
'io.modelcontextprotocol/clientCapabilities': ClientCapabilities;
'io.modelcontextprotocol/logLevel'?: LoggingLevel;
};

/* Empty result */
Expand Down
21 changes: 21 additions & 0 deletions packages/core-internal/test/types/requestMetaEnvelope.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { describe, expectTypeOf, it } from 'vitest';

import {
CLIENT_CAPABILITIES_META_KEY,
CLIENT_INFO_META_KEY,
LOG_LEVEL_META_KEY,
PROTOCOL_VERSION_META_KEY
} from '../../src/types/constants';
import type { ClientCapabilities, Implementation, LoggingLevel, RequestMetaEnvelope } from '../../src/types/types';

describe('RequestMetaEnvelope', () => {
it('is keyed by the public meta-key constants', () => {
expectTypeOf<keyof RequestMetaEnvelope>().toEqualTypeOf<
typeof PROTOCOL_VERSION_META_KEY | typeof CLIENT_INFO_META_KEY | typeof CLIENT_CAPABILITIES_META_KEY | typeof LOG_LEVEL_META_KEY
>();
expectTypeOf<RequestMetaEnvelope[typeof PROTOCOL_VERSION_META_KEY]>().toEqualTypeOf<string>();
expectTypeOf<RequestMetaEnvelope[typeof CLIENT_INFO_META_KEY]>().toEqualTypeOf<Implementation | undefined>();
expectTypeOf<RequestMetaEnvelope[typeof CLIENT_CAPABILITIES_META_KEY]>().toEqualTypeOf<ClientCapabilities>();
expectTypeOf<RequestMetaEnvelope[typeof LOG_LEVEL_META_KEY]>().toEqualTypeOf<LoggingLevel | undefined>();
});
});
12 changes: 10 additions & 2 deletions scripts/smoke-dist-types.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ try {
"import { AjvJsonSchemaValidator } from '@modelcontextprotocol/client/validators/ajv';",
"import { CfWorkerJsonSchemaValidator as ClientCf } from '@modelcontextprotocol/client/validators/cf-worker';",
"import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';",
"import { McpServer } from '@modelcontextprotocol/server';",
"import { CLIENT_CAPABILITIES_META_KEY, McpServer } from '@modelcontextprotocol/server';",
"import type { ClientCapabilities, RequestMetaEnvelope } from '@modelcontextprotocol/server';",
"import { AjvJsonSchemaValidator as ServerAjv } from '@modelcontextprotocol/server/validators/ajv';",
"import { CfWorkerJsonSchemaValidator as ServerCf } from '@modelcontextprotocol/server/validators/cf-worker';",
"import { StdioServerTransport } from '@modelcontextprotocol/server/stdio';",
"export const c = new Client({ name: 'smoke', version: '1.0.0' });",
"export const s = new McpServer({ name: 'smoke', version: '1.0.0' });",
'declare const envelope: Partial<RequestMetaEnvelope> | undefined;',
'const capabilities = envelope?.[CLIENT_CAPABILITIES_META_KEY];',
'export const _caps: ClientCapabilities | undefined = capabilities;',
'export type T = ClientSchema;',
'export { AjvJsonSchemaValidator, ServerAjv, ClientCf, ServerCf, StdioClientTransport, StdioServerTransport };',
''
Expand Down Expand Up @@ -77,10 +81,14 @@ try {
[
"import { Client } from '@modelcontextprotocol/client';",
"import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';",
"import { McpServer } from '@modelcontextprotocol/server';",
"import { CLIENT_CAPABILITIES_META_KEY, McpServer } from '@modelcontextprotocol/server';",
"import type { ClientCapabilities, RequestMetaEnvelope } from '@modelcontextprotocol/server';",
"import { StdioServerTransport } from '@modelcontextprotocol/server/stdio';",
"export const c = new Client({ name: 'smoke', version: '1.0.0' });",
"export const s = new McpServer({ name: 'smoke', version: '1.0.0' });",
'declare const envelope: Partial<RequestMetaEnvelope> | undefined;',
'const capabilities = envelope?.[CLIENT_CAPABILITIES_META_KEY];',
'export const _caps: ClientCapabilities | undefined = capabilities;',
'export { StdioClientTransport, StdioServerTransport };',
''
].join('\n')
Expand Down
Loading