Align x-mcp-header implementation with SEP-2243 spec clarifications#1619
Open
tarekgh wants to merge 1 commit into
Open
Align x-mcp-header implementation with SEP-2243 spec clarifications#1619tarekgh wants to merge 1 commit into
tarekgh wants to merge 1 commit 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. |
Comment on lines
189
to
+191
| // Validate x-mcp-header annotations per SEP-2243. | ||
| // Clients MUST exclude tools with invalid annotations and SHOULD log a warning. | ||
| // Streamable HTTP clients MUST exclude tools with invalid annotations; | ||
| // non-HTTP clients MAY also reject them for safety. |
Comment on lines
+183
to
187
| // MUST only be applied to primitive types (integer, string, boolean). | ||
| // Parameters with type "number" are not permitted. | ||
| if (property.Value.TryGetProperty("type", out var typeElement) && | ||
| typeElement.ValueKind == JsonValueKind.String) | ||
| { |
Comment on lines
+185
to
+194
| [Theory] | ||
| [InlineData("=?BASE64?literal?=", false)] // Case-sensitive: uppercase prefix does not match sentinel | ||
| [InlineData("=?base64?start", false)] // Missing suffix: no sentinel match | ||
| [InlineData("end?=", false)] // Missing prefix: no sentinel match | ||
| [InlineData("plain-text", false)] // No sentinel pattern | ||
| public void EncodeValue_NonSentinelPattern_NotBase64Encoded(string input, bool _) | ||
| { | ||
| var result = McpHeaderEncoder.EncodeValue(input); | ||
| Assert.Equal(input, result); | ||
| } |
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.