Skip to content

[Server] Enforce x-mcp-header where a request uses it (SEP-2243) - #453

Merged
chr-hertel merged 2 commits into
modelcontextprotocol:mainfrom
chr-hertel:pr/2026-header-mirroring
Aug 18, 2026
Merged

[Server] Enforce x-mcp-header where a request uses it (SEP-2243)#453
chr-hertel merged 2 commits into
modelcontextprotocol:mainfrom
chr-hertel:pr/2026-header-mirroring

Conversation

@chr-hertel

Copy link
Copy Markdown
Member

Stacked on #452. The request-side half of x-mcp-header; the definition-side half merged as #441.

StandardHeaderValidator inspected only top-level properties, so an annotation on a nested property was silently unenforced — the Mcp-Param-* header could say anything. The walk now follows a chain of properties keys to any depth and reads the argument at that exact path.

Integer values compare numerically, so a client writing 42.0 for a body value of 42 is no longer rejected.

Part of SEP-2243.


Cross-fork PRs can only target main, so this diff also carries its ancestors until they merge. Only the last commit(s) belong to this PR — GitHub's "Commits" tab separates them.

Only top-level properties were inspected, so an annotation on a nested
property was silently unenforced - the header could say anything. The walk
now follows a chain of properties keys to any depth and reads the argument
at that exact path.

Integer values compare numerically, so a client writing 42.0 for a body
value of 42 is no longer rejected.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the server-side StandardHeaderValidator to correctly enforce x-mcp-header annotations beyond top-level tool input properties, ensuring nested Mcp-Param-* headers are validated against the exact body argument path. It also relaxes numeric comparison so integer header/body values can agree even when serialized differently (e.g., 42 vs 42.0).

Changes:

  • Recursively discover x-mcp-header annotations through nested properties chains and validate headers against the corresponding nested argument path.
  • Add numeric-aware comparison for mirrored params to avoid rejecting equivalent integer values with different decimal renderings.
  • Extend unit tests to cover nested mirroring discovery, unreachable annotations, nested argument validation, and numeric comparison behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/Server/Stateless/StandardHeaderValidator.php Recursively extracts mirrored properties and validates Mcp-Param-* values against nested arguments; adds numeric comparison behavior.
tests/Unit/Server/Stateless/StandardHeaderValidatorTest.php Adds coverage for nested x-mcp-header discovery and nested/header numeric validation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Server/Stateless/StandardHeaderValidator.php
is_numeric() and loose == both treat a string like "042" as equal to
"42", so a string argument could pass header validation against a
header that doesn't match it exactly. Gate the numeric comparison on
the argument's actual type and a decimal-only header instead.
@chr-hertel
chr-hertel merged commit 7e38c94 into modelcontextprotocol:main Aug 18, 2026
25 checks passed
@chr-hertel
chr-hertel deleted the pr/2026-header-mirroring branch August 18, 2026 22:42
@chr-hertel chr-hertel added Server Issues & PRs related to the Server component 2026-07-28 All issues and PRs related to the spec release 2026-07-28 labels Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2026-07-28 All issues and PRs related to the spec release 2026-07-28 Server Issues & PRs related to the Server component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants