Your SDK writes the schema. model_json_schema() in Pydantic and
zod-to-json-schema both emit $defs plus $ref for any nested
model, and anyOf for any optional field. An x-mcp-header annotation that
lands inside either one is not statically reachable from the schema root, and the
2026-07-28 constraint list makes that a rejection. The client drops the whole tool and
tells your server nothing. Load the first sample below to see it.
Nothing is uploaded. The parse, the graph traversal and every clause check run in this page.
Everything above is definition validity. It is decided from
inputSchema alone, with no argument values in hand. How a client turns a call
argument into the bytes of an Mcp-Param-{name} field value is a separate, runtime
obligation, and it is normatively defined in Custom Headers from Tool Parameters on
the Streamable HTTP transport page. That page is not part of the offline spec copy this tool
was built against, so this panel computes the encoding arithmetic for you and asserts nothing
about the transport page's table. A non-ASCII default in a schema is
not a definition-validity failure and never changes the verdict above.
Quoted verbatim from the on-disk copy of
Tools, Model Context Protocol specification, page banner "Version 2026-07-28 (latest)".
Superscripts and the U+2212 minus sign are rendered in ASCII as ^ and -;
nothing else is altered.
Properties MAY include an
x-mcp-headerannotation to expose parameter values as HTTP headers
The
x-mcp-headerextension property allows servers to designate specific tool parameters to be mirrored into HTTP headers when using the Streamable HTTP transport. This enables network intermediaries (load balancers, proxies, WAFs) to route and process requests based on parameter values without parsing the request body.The
x-mcp-headerproperty is placed directly within the JSON Schema of the property to be mirrored. Its value specifies the name portion of the resultingMcp-Param-{name}HTTP header.Constraints on
x-mcp-headervalues:
- MUST NOT be empty
- MUST match HTTP field-name token syntax (
1*tchar, RFC 9110 Section 5.1)- MUST NOT contain control characters, including carriage return (CR,
\r) or line feed (LF,\n)- MUST be case-insensitively unique among all
x-mcp-headervalues in theinputSchema- MUST only be applied to parameters with primitive types (integer, string, boolean). Parameters with type
numberare not permitted. Integer values MUST be within the safe range for integers represented using IEEE754 double-precision floating point numbers (-2^53+1 to 2^53-1)- MUST only be applied to properties that are statically reachable from the schema root, as defined in Custom Headers from Tool Parameters, which also defines how header values are extracted from call arguments
Clients using the Streamable HTTP transport MUST reject tool definitions where any
x-mcp-headervalue violates these constraints. Rejection means the client MUST exclude the invalid tool from the result oftools/list. Clients SHOULD log a warning when rejecting a tool definition, including the tool name and the reason for rejection. This ensures that a single malformed tool definition does not prevent other valid tools from being used. Clients using other transports (e.g., stdio) MAY ignorex-mcp-headerannotations entirely.Server developers SHOULD NOT mark sensitive parameters (passwords, API keys, tokens, PII) with
x-mcp-header, as header values are visible to network intermediaries.
Two things in that block do the damage. Rejection is at MUST and it removes the entire tool, not the annotation. The feedback path is at SHOULD and it is a client-side log line, so a server operator can watch a tool vanish from every client with nothing in their own logs to explain it.
inputSchema. The constraint list names inputSchema
and only inputSchema. Annotations found in outputSchema are counted and
reported as out of scope, never as violations, and they do not participate in the uniqueness scan.const,
enum, default, maximum or minimum. Otherwise this
tool prints "not determinable" rather than guessing.properties
keys from the schema root. Every other schema keyword is treated as breaking the chain.$ref. A $ref is
treated as a chain break wherever it points.This is an independent tool by 0xelitesystem. It is not affiliated with, endorsed
by, or connected to the Model Context Protocol project, Pydantic, or the authors of
zod-to-json-schema. Those names appear only because their published output shapes are
what trip the constraint. The spec text quoted above is quoted for identification and commentary;
no code from any of those projects is reproduced here. The checks were implemented from the
normative constraint list, not ported from an implementation.