Align x-mcp-header implementation with SEP-2243 spec clarifications#1619
Open
tarekgh wants to merge 2 commits into
Open
Align x-mcp-header implementation with SEP-2243 spec clarifications#1619tarekgh wants to merge 2 commits into
tarekgh wants to merge 2 commits into
Conversation
- Enforce RFC 9110 tchar validation for header names using SearchValues on .NET 8+ and bitmap lookup on netstandard2.0 - Remove 'number' from allowed x-mcp-header types (only string, integer, boolean are permitted); reject float/double/decimal in [McpHeader] - Add base64 sentinel collision check in McpHeaderEncoder.RequiresBase64Encoding so literal values resembling =?base64?...?= are encoded to avoid confusion - Fix DecodeValue to use case-sensitive prefix matching per spec requirement that sentinel markers must appear exactly as shown (lowercase) - Support nested property traversal for x-mcp-header validation and extraction on both client and server sides - Share tchar validation logic between McpHeaderAttribute and McpHeaderExtractor via internal FindFirstNonTchar method - Add recursive ValidateCustomParamHeadersFromProperties in StreamableHttpHandler for server-side nested property header/body comparison - Add 28 new tests covering tchar validation, sentinel collision encoding, number type rejection, nested property handling, and case-sensitive decoding
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the SDK’s SEP-2243 x-mcp-header handling to match the latest spec clarifications, tightening header-name validation, restricting allowed header types, hardening Base64 sentinel parsing, and extending validation/extraction to nested schema properties.
Changes:
- Enforce RFC 9110
tcharvalidation forx-mcp-header/[McpHeader]names and share that logic across client/server code. - Disallow
"number"/ floating-point header types forx-mcp-header(client-side schema rejection; server-side attribute/type checks). - Make Base64 sentinel decoding case-sensitive and add “sentinel collision” encoding safeguards; add nested-schema traversal for
x-mcp-header.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/ModelContextProtocol.Tests/Server/McpHeaderAttributeTests.cs | Expands test coverage for RFC 9110 tchar header-name validation. |
| tests/ModelContextProtocol.Tests/Client/McpHeaderExtractorValidationTests.cs | Adds integration tests for number rejection, nested properties, and tchar enforcement. |
| tests/ModelContextProtocol.Tests/Client/McpHeaderEncoderTests.cs | Adds sentinel-collision tests and asserts case-sensitive sentinel decoding. |
| src/ModelContextProtocol.Core/Server/McpHeaderAttribute.cs | Switches header-name validation to RFC 9110 tchar via shared helper. |
| src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs | Tightens [McpHeader] supported types to integer/string/boolean (removes float/double/decimal). |
| src/ModelContextProtocol.Core/Protocol/McpHeaderEncoder.cs | Enforces case-sensitive sentinel parsing and prevents sentinel-collision ambiguity. |
| src/ModelContextProtocol.Core/Client/McpHeaderExtractor.cs | Adds nested property traversal and stricter schema validation for x-mcp-header. |
| src/ModelContextProtocol.Core/Client/McpClient.Methods.cs | Updates inline comments around x-mcp-header validation behavior. |
| src/ModelContextProtocol.AspNetCore/StreamableHttpHandler.cs | Adds recursive server-side validation for nested x-mcp-header properties. |
- Reject x-mcp-header parameters whose JSON Schema type is a disallowed or malformed value, including non-string/union types. A union array is accepted only when it contains at least one of string/integer/boolean (with optional "null"); an absent type is still treated as unknown and allowed to avoid excluding valid enum/const/$ref schemas. - Reword the rejection message: "number" is a JSON primitive but is not a permitted header type, so report it as an unsupported type rather than non-primitive. - Clarify the ListToolsAsync comment to note that the client validates x-mcp-header annotations on all transports, while only Streamable HTTP is required to by SEP-2243. - Drop the unused parameter from EncodeValue_NonSentinelPattern_NotBase64Encoded. - Add tests for nullable union, disallowed union, null-only union, and missing-type schemas.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the spec clarifications from modelcontextprotocol/modelcontextprotocol#2772 to ensure the SDK fully complies with SEP-2243.
Changes
RFC 9110 tchar validation for header names
Remove "number" from allowed x-mcp-header types
Base64 sentinel collision check
Nested property support
Tests
28 new tests added:
All existing tests pass across net8.0, net9.0, net10.0, and net472.