Skip to content

Commit dd76258

Browse files
docs(core),test(server): renumber standard-header rung 8→7 ahead of capability gate; align era-gating test title with its initialize body
The standard-header-validation ladder entry is moved to order 7 (ahead of client-capabilities, now 8, and param-header-validation, now 9), and its rationale carries an explicit precedence caveat: serveModern evaluates this rung immediately after the supported-revision gate, so a request that also fails a dispatch rung (method-registry 5, request-params 6) is answered here first — the documented order is not the observed precedence relative to those. The era-gating test's title said it posts a 2025-era tools/list without standard headers, but the body POSTs initialize (the 2025 handshake, which is the right body for era-gating); aligned the title to match.
1 parent ab7e805 commit dd76258

2 files changed

Lines changed: 19 additions & 18 deletions

File tree

packages/core/src/shared/inboundClassification.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ export type InboundValidationRung =
169169
| 'envelope'
170170
| 'method-registry'
171171
| 'request-params'
172-
| 'client-capabilities'
173172
| 'standard-header-validation'
173+
| 'client-capabilities'
174174
| 'param-header-validation';
175175

176176
/** A ladder rejection: the JSON-RPC error to emit and the HTTP status to emit it with. */
@@ -314,9 +314,25 @@ export const INBOUND_VALIDATION_LADDER: readonly InboundValidationRungDescriptor
314314
rationale: 'Per-method params validation; emitted in-band by the dispatch layer (HTTP 200), never via the ladder status table.'
315315
},
316316
{
317-
rung: 'client-capabilities',
317+
rung: 'standard-header-validation',
318318
order: 7,
319319
evaluatedAt: 'pre-dispatch',
320+
codes: [HEADER_MISMATCH_ERROR_CODE],
321+
conformance: ['http-header-validation'],
322+
rationale:
323+
'SEP-2243 standard `Mcp-Method` / `Mcp-Name` headers — presence, sentinel decoding, and `Mcp-Name` ↔ body cross-check ' +
324+
'— are validated by the HTTP entry on a modern-classified request after the supported-revision gate and before ' +
325+
'dispatch. The classifier’s own header-mismatch cells (protocol-version, `Mcp-Method` mismatch) stay on the edge ' +
326+
'`era-classification` rung; this rung carries the entry-layer presence/`Mcp-Name` half. Evaluated before the ' +
327+
'capability gate, the factory call, and the `Mcp-Param-*` rung so a request that fails several rungs is answered by ' +
328+
'the standard-header rung first. The documented order (after method-registry 5 and request-params 6) is NOT the ' +
329+
'observed precedence: serveModern evaluates this rung immediately after the supported-revision gate, so a request ' +
330+
'that also fails a dispatch rung is answered here before the dispatch rungs (5–6) are consulted.'
331+
},
332+
{
333+
rung: 'client-capabilities',
334+
order: 8,
335+
evaluatedAt: 'pre-dispatch',
320336
codes: [ProtocolErrorCode.MissingRequiredClientCapability],
321337
conformance: ['server-stateless'],
322338
rationale:
@@ -327,21 +343,6 @@ export const INBOUND_VALIDATION_LADDER: readonly InboundValidationRungDescriptor
327343
'missing the capability and would also fail a dispatch rung is answered by this gate first, so the entry must ' +
328344
'consult the method registry before the gate if the documented precedence is to stay observable.'
329345
},
330-
{
331-
rung: 'standard-header-validation',
332-
order: 8,
333-
evaluatedAt: 'pre-dispatch',
334-
codes: [HEADER_MISMATCH_ERROR_CODE],
335-
conformance: ['http-header-validation'],
336-
rationale:
337-
'SEP-2243 standard `Mcp-Method` / `Mcp-Name` headers — presence, sentinel decoding, and `Mcp-Name` ↔ body cross-check ' +
338-
'— are validated by the HTTP entry on a modern-classified request after the supported-revision gate and before ' +
339-
'dispatch. The classifier’s own header-mismatch cells (protocol-version, `Mcp-Method` mismatch) stay on the edge ' +
340-
'`era-classification` rung; this rung carries the entry-layer presence/`Mcp-Name` half. The documented order ' +
341-
'(after method resolution, params validation, and the capability gate) is not the observed precedence: serveModern ' +
342-
'evaluates this rung immediately after the supported-revision gate, so a request that fails several rungs is ' +
343-
'answered by this gate before the dispatch rungs (5–6) and the capability gate (7) are consulted.'
344-
},
345346
{
346347
rung: 'param-header-validation',
347348
order: 9,

packages/server/test/server/stdHeaderValidation.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ describe('SEP-2243 standard-header validation (createMcpHandler, modern era)', (
149149
});
150150

151151
describe('SEP-2243 standard-header validation is era-gated', () => {
152-
it('legacy traffic is byte-untouched: a 2025-era tools/list without standard headers still serves', async () => {
152+
it('legacy traffic is byte-untouched: a 2025-era initialize without standard headers still serves', async () => {
153153
const handler = createMcpHandler(makeFactory());
154154
const response = await handler.fetch(
155155
new Request('http://localhost/mcp', {

0 commit comments

Comments
 (0)