You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'd like to work on this once the registration API in #1200 is settled. Is this available for an external contribution? Could you confirm the intended validation hook and failure behavior for invalid tool definitions, and whether the validator should be shared with #1202?
For context on the shared-validator question: #1202 (closes #1199) adds McpParamHeaders, which already parses x-mcp-header declarations from a tool's input schema (name rules, case-insensitive duplicates, allowed primitive types) to validate incoming Mcp-Param-* headers at call time. Invalid declarations are currently skipped with a debug log, which is the gap this issue covers at registration time.
If it helps, I can expose that parsing as a reusable validator in #1202 so the registration-time check here builds on it, or adapt it to whatever hook you settle on in #1200.
Registration time is the right place to enforce this, because the constraint is structural (the value has to survive a trip through an HTTP header) and cannot be checked at call time by the schema validator alone.
A validation pass over the tool input schema should reject at least these:
Placement. x-mcp-header is only meaningful on a top-level property of the input object schema. An occurrence inside a nested properties block or a $defs entry cannot be mirrored to a request-level header, because the header name would not identify which instance to read it from. Reject rather than ignore, so the author finds out at registration.
Type. Only types that serialize to a single header value are legal: string, integer, boolean, and enums of those. Arrays and objects must be rejected. A header cannot carry a JSON body without inventing an encoding, and inventing one here would fork the spec.
Name. Mcp-Param-{Name} requires {Name} to reduce to an RFC 9110 token after whatever casing rule you pick. Reject names containing anything outside the token character set (space, colon, parentheses, non-ASCII), and define the casing normalization explicitly so two tools cannot produce two spellings of the same header.
Collision. Reject any derived name that collides with another annotated property on the same tool, and with protocol-owned headers. Deriving a Mcp--prefixed header from a user-supplied property name without a reserved-prefix check lets an author shadow an existing protocol header.
Required-ness interaction. If the property is also listed in required, a call that omits the header must fail as a tool call params error, not as an input-schema validation error. The value is not in the JSON body by definition, so the schema validator will always see it missing, and reporting that as a schema violation sends the caller looking in the wrong place.
Worth aligning this with #1199 rather than landing it independently: that issue is the server-side read half (Mcp-Param-{Name} lookup), and if registration does not enforce the same rules the read side assumes, a server can be built that validates but never receives the header. Validating at registration is what makes the two halves agree, and it turns the failure into a clear message at build time instead of a missing value at runtime.
Activity
pma1999 commentedon Oct 24, 2026
I'd like to work on this once the registration API in #1200 is settled. Is this available for an external contribution? Could you confirm the intended validation hook and failure behavior for invalid tool definitions, and whether the validator should be shared with #1202?
prathamgoyal787 commentedon Oct 26, 2026
For context on the shared-validator question: #1202 (closes #1199) adds
McpParamHeaders, which already parsesx-mcp-headerdeclarations from a tool's input schema (name rules, case-insensitive duplicates, allowed primitive types) to validate incomingMcp-Param-*headers at call time. Invalid declarations are currently skipped with a debug log, which is the gap this issue covers at registration time.If it helps, I can expose that parsing as a reusable validator in #1202 so the registration-time check here builds on it, or adapt it to whatever hook you settle on in #1200.
media-ctrl commentedon Nov 8, 2026
Registration time is the right place to enforce this, because the constraint is structural (the value has to survive a trip through an HTTP header) and cannot be checked at call time by the schema validator alone.
A validation pass over the tool input schema should reject at least these:
Placement.
x-mcp-headeris only meaningful on a top-level property of the input object schema. An occurrence inside a nestedpropertiesblock or a$defsentry cannot be mirrored to a request-level header, because the header name would not identify which instance to read it from. Reject rather than ignore, so the author finds out at registration.Type. Only types that serialize to a single header value are legal: string, integer, boolean, and enums of those. Arrays and objects must be rejected. A header cannot carry a JSON body without inventing an encoding, and inventing one here would fork the spec.
Name.
Mcp-Param-{Name}requires{Name}to reduce to an RFC 9110 token after whatever casing rule you pick. Reject names containing anything outside the token character set (space, colon, parentheses, non-ASCII), and define the casing normalization explicitly so two tools cannot produce two spellings of the same header.Collision. Reject any derived name that collides with another annotated property on the same tool, and with protocol-owned headers. Deriving a
Mcp--prefixed header from a user-supplied property name without a reserved-prefix check lets an author shadow an existing protocol header.Required-ness interaction. If the property is also listed in
required, a call that omits the header must fail as a tool call params error, not as an input-schema validation error. The value is not in the JSON body by definition, so the schema validator will always see it missing, and reporting that as a schema violation sends the caller looking in the wrong place.Worth aligning this with #1199 rather than landing it independently: that issue is the server-side read half (
Mcp-Param-{Name}lookup), and if registration does not enforce the same rules the read side assumes, a server can be built that validates but never receives the header. Validating at registration is what makes the two halves agree, and it turns the failure into a clear message at build time instead of a missing value at runtime.