Skip to content

Forward Mcp-Name header in McpTransportContext - #1326

Open
neerajbhatt wants to merge 1 commit into
modelcontextprotocol:mainfrom
neerajbhatt:fix/1317-mcp-name-transport-context
Open

neerajbhatt wants to merge 1 commit into
modelcontextprotocol:mainfrom
neerajbhatt:fix/1317-mcp-name-transport-context

Conversation

@neerajbhatt

Copy link
Copy Markdown
Contributor

Fixes #1317

Motivation

Server features (e.g. routing-header checks for methods like tasks/get) need the
decoded Mcp-Name request header, but the modern transport only used it internally
in validateHeaders() and did not expose it through McpTransportContext.

Changes

  • New McpNameHeader value, stored under McpNameHeader.TRANSPORT_CONTEXT_KEY,
    modelled on McpParamHeaders.
  • HTTP: every validated JSON-RPC request carries a value, attached after the
    user's context extractor so it always wins. The value is one of:
    • ABSENT: the header was not sent;
    • MALFORMED: invalid base64, repeated values, or names differing only in case;
    • the decoded value (isPresent(), value()).
  • Stdio: carries the NOT_MIRRORED sentinel, so features can tell "this transport
    has no headers" apart from "the client omitted the header".
  • Decoding reuses McpHeaderDecoder and reads all header names/values via the header
    accessor. toString() never includes the value.

Contract: the transport only decodes and forwards. For methods it doesn't validate
itself, the feature owns the equality check against params and should treat
isMalformed() as a mismatch. Existing validateHeaders() behavior is unchanged.

Tests

  • McpHeaderDecoderTests: plain, base64, malformed, duplicate, mixed-case names.
  • HttpServletMcpTransportIntegrationTests: present / absent / malformed / repeated
    (raw socket for repeated headers), plus regression for existing name/uri validation.
  • StdioMcpTransportTests: NOT_MIRRORED sentinel.

Focused run: 111 passed, 0 failed.

Expose the decoded Mcp-Name request header to server features through a
new McpNameHeader value stored under McpNameHeader.TRANSPORT_CONTEXT_KEY.

- HTTP: every validated JSON-RPC request carries a value, attached after
  the user's context extractor so it always wins. The value is either
  ABSENT, MALFORMED (bad base64, repeated values, or names differing
  only in case), or the decoded value.
- Stdio: carries the NOT_MIRRORED sentinel, so features can tell
  "no headers on this transport" apart from "client omitted the header".
- Decoding reuses McpHeaderDecoder and reads every header name and value
  through the header accessor. toString() never includes the value.

The transport only decodes and forwards. For methods it does not
validate itself, the feature owns the equality check against params
and should treat a malformed value as a mismatch. Existing
validateHeaders() behavior is unchanged.

Fixes modelcontextprotocol#1317

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@Kehrlann Kehrlann self-assigned this Nov 10, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Forward Mcp-Name header in the McpTransportContext for extension validation

2 participants