[Server][Tests] Validate the standard MCP request headers (SEP-2243) (#445)

The revision puts the method, the subject name and the mirrored arguments in
headers so an intermediary can route and cache without parsing the body. A
header that contradicts the body it travels with therefore has to be
refused, not ignored: StandardHeaderValidator compares each against the
request and answers -32020 on a mismatch.

Set with Builder::setHeaderValidator(); a transport with no header layer is
unaffected.
This commit is contained in:
Christopher Hertel 2026-08-18 22:27:05 +02:00 • committed by GitHub
commit de35ca40bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 478 additions and 14 deletions

View file

@ -13,21 +13,10 @@
# make conformance-draft-server
#
# Absent by design, because they pass in full: server-stateless (the SEP-2575
# lifecycle), caching (SEP-2549 hints), and every wire-schema-valid check bar
# one noted below.
# lifecycle), caching (SEP-2549 hints), both SEP-2243 header-validation
# scenarios, and every wire-schema-valid check bar one noted below.
server:
# --- SEP-2243: standard HTTP headers ---------------------------------------
# Mcp-Method / Mcp-Name validation and the X-MCP-* parameter rules are not
# implemented. Self-contained and the largest remaining block; a good next
# chunk after MRTR.
- http-header-validation:sep-2243-server-reject-invalid-headers
- http-custom-header-server-validation:sep-2243-server-no-xmcp-tool
- http-custom-header-server-validation:sep-2243-server-decode-base64
- http-custom-header-server-validation:sep-2243-server-validate-param-match
- http-custom-header-server-validation:sep-2243-server-reject-invalid-param-chars
- http-custom-header-server-validation:sep-2243-server-reject-param-mismatch
# --- SEP-2322: the MRTR retry half -----------------------------------------
# InputRequiredResult exists and tools/call can answer with one — that is what
# makes server-stateless green. What is missing is the second round trip: the
@ -49,7 +38,6 @@ server:
# keyword), so the run summary counts them as passed — but the baseline
# evaluator still wants them declared, and declaring them is right: each is a
# SHOULD the SDK does not yet honour.
- http-header-validation:sep-2243-server-reject-error-code
- input-required-result-ignore-extra-params:sep-2322-ignore-unexpected-params
- input-required-result-missing-input-response:sep-2322-missing-response-rerequests
- sep-2164-resource-not-found:sep-2164-data-uri

View file

@ -93,6 +93,21 @@ $protocol = Server::builder()
name: 'test_logging_tool',
description: 'Emits a server-side log message while returning normally',
)
// Mirrors its arguments into Mcp-Param-* headers (SEP-2243), so the header/
// body agreement rules have something to be checked against.
->addTool(
static fn (string $region = '', int $retries = 0): string => sprintf('region=%s retries=%d', $region, $retries),
name: 'test_custom_headers',
description: 'Tests custom header mirroring via x-mcp-header',
inputSchema: [
'type' => 'object',
'properties' => [
'region' => ['type' => 'string', 'x-mcp-header' => 'Region'],
'retries' => ['type' => 'integer', 'x-mcp-header' => 'Retries'],
],
'required' => ['region'],
],
)
// Resources
->addResource(static fn () => 'This is the content of the static text resource.', 'test://static-text', 'static-text', 'A static text resource for testing')
->addResource(static fn () => fopen('data://image/png;base64,'.Elements::TEST_IMAGE_BASE64, 'r'), 'test://static-binary', 'static-binary', 'A static binary resource (image) for testing')