Skip to content

Latest commit

 

History

History
60 lines (38 loc) · 2.75 KB

header-parameters.md

File metadata and controls

60 lines (38 loc) · 2.75 KB

Header parameters

Most servers never need this.

A gateway or load balancer in front of your server can only route on what it can read without parsing the body. Mark a tool argument with x-mcp-header, and clients on the 2026-07-28 protocol version send its value as an HTTP header as well.

Mark an argument

The mark is one extra key in the argument's JSON Schema. On MCPServer, Field puts it there:

--8<-- "docs_src/header_parameters/tutorial001.py"
  • Over Streamable HTTP on 2026-07-28, a client sends Mcp-Param-Region alongside the body, and the server rejects a call where the two disagree.
  • A client that hasn't listed the tool has never seen the mark: it sends no header, and the call is rejected. This SDK's Client then lists the tools and resends the call once, so listing first only saves a round trip.
  • Every other connection ignores the annotation.

Your function doesn't change: region still arrives as an argument.

What can be marked

str, int and bool arguments. Anything else is refused when the tool is registered, with InvalidSignature.

That includes str | None, which has no single type. An optional argument needs its schema spelled out, with pydantic's WithJsonSchema:

region: Annotated[str | None, WithJsonSchema({"type": "string", "x-mcp-header": "Region"})] = None

On the low-level Server

There you write input_schema by hand, so the key goes straight in:

--8<-- "docs_src/header_parameters/tutorial002.py"
  • Nothing checks the annotation for you: an invalid one is served, and 2026-07-28 clients leave the tool out of their listing.

Schemas by name

To check the header, the SDK needs the tool's input schema before it dispatches the call. Without get_tool_input_schema it gets it by running your on_list_tools handler on every call that carries arguments, whether or not any tool is marked.

--8<-- "docs_src/header_parameters/tutorial003.py"
  • Pass the function to answer from what you already have.
  • Return None for a tool with nothing to check.

Recap

  • x-mcp-header on a tool argument makes 2026-07-28 clients repeat it as an Mcp-Param-* HTTP header.
  • The server rejects a call whose header and body disagree.
  • Only str, int and bool arguments can be marked. MCPServer raises InvalidSignature for anything else.
  • The low-level Server checks nothing, and clients drop a tool whose annotation is invalid.
  • get_tool_input_schema keeps the low-level Server from running on_list_tools on every call.

The rest of the hand-written Server API is The low-level Server.