Skip to content

ADR-0028 — Decline SEP-2243 custom parameter headers (x-mcp-header)

  • Status: Accepted
  • Date: 2026-07-28

Context

MCP 2026-07-28 introduces SEP-2243 "custom parameter headers": a tool author may annotate an input-schema property with x-mcp-header, declaring that the argument is carried in a named HTTP request header (Base64-wrapped as =?base64?...?= for non-ASCII) rather than in the JSON-RPC params body. The official conformance suite exercises this via http-custom-header-server-validation (SEP-2243): a server implementing it MUST validate the Base64 encoding, reject invalid padding/characters, treat unwrapped values as literals, and reject a request where the header is omitted but the value appears in the body.

The spec makes this optional — a server MAY designate no header-sourced parameters. mocapi declares none, so the suite reports all five checks as NotTestable. This ADR records why that is a deliberate, principled decline rather than a temporary gap, so it is not re-litigated.

Decision

mocapi does not implement SEP-2243 custom parameter headers, on architectural grounds:

  1. It is an HTTP-transport-only feature. The value source is an HTTP header. The stdio transport has no headers, so the feature cannot exist uniformly across mocapi's transports — it is intrinsically HTTP-shaped.
  2. It violates the transport-agnostic server contract (ADR-0002, the constitution). mocapi's handler/server layer deals in JsonRpcCall / JsonRpcMessage and knows nothing about HTTP. Sourcing a tool argument (a server-layer concern) from an HTTP header (a transport concern) would force the tool-parameter model to reach into transport-specific plumbing — either special-casing HTTP inside the server, or bolting on a per-transport "does this transport have headers?" conditional. Both blur the McpServerMcpTransport boundary this project deliberately keeps clean.
  3. The legitimate use cases are already served idiomatically, without leaking transport into the tool contract: caller identity / tenancy via OAuth2 SecurityContext and the McpPrincipalSource SPI (ADR-0013); distributed tracing via W3C trace-context keys on the _meta envelope (ADR-0017); and request-scoped context via customizers and parameter resolvers.

Consequences

  • A tool cannot declare a header-sourced argument; every tool argument travels in the JSON-RPC params body. This is a narrow, opt-in feature to forgo.
  • The http-custom-header-server-validation scenario is permanently baselined in mocapi-conformance/conformance-expected-failures.yaml (referencing this ADR), distinct from the deprecated-feature declines in ADR-0022.
  • The transport-agnostic invariant (ADR-0002) is preserved: no HTTP concept reaches the handler/tool-parameter layer.
  • Reversal cost: if a future need justifies it, header-sourced parameters would have to be modeled as a transport capability (only HTTP advertises it) with an explicit resolver seam — a larger change than a tool annotation, by design. This ADR would be superseded rather than quietly reversed.