HTTP request-metadata header codec for the MCP 2026-07-28 Streamable HTTP transport.
The transport mirrors selected JSON-RPC body fields into HTTP headers so intermediaries can route requests without parsing the body:
Mcp-Method— the requestmethod, on every request.Mcp-Name—params.namefortools/callandprompts/get,params.uriforresources/read, andparams.taskIdfor the tasks extension'stasks/get,tasks/updateandtasks/cancel(ext-tasks routing headers).Mcp-Param-{Name}— tool arguments whoseinputSchemaproperty carries an"x-mcp-header": "{Name}"annotation.
This module is pure: it builds those headers for a client, validates
x-mcp-header annotations, and lets a server decode header values and
compare them to body values. Header names it returns are lowercase, matching
how Plug normalizes request header names.
Value encoding
Strings are sent as-is, integers as decimal, booleans as true/false.
A string that is not plain header-safe ASCII — it contains a byte outside
0x20..0x7E (non-ASCII, control characters including tab and DEL), has a
leading or trailing space, or starts with =? and ends with ?= (so it
could be mistaken for the sentinel) — is sent as
=?base64?{standard padded Base64 of its UTF-8 bytes}?=.
Integer comparison is numeric and strict: a header matches an integer body
value only when it is a canonical decimal integer (optional -, no leading
zeros other than "0" itself, no "-0") within the JavaScript safe range
-(2^53 - 1)..(2^53 - 1). Body values 42 and 42.0 both match "42".
Summary
Types
An x-mcp-header annotation reachable from the schema root.
Functions
Decodes a received header value.
Encodes a string, integer, or boolean as a header value.
Lists the x-mcp-header annotations reachable from the root of an
inputSchema through chains of properties keys only.
Returns the Mcp-Method header for a request method.
Returns the Mcp-Name header for a request, or nil when none applies.
Returns whether requests with method must carry an Mcp-Name header.
The params key Mcp-Name mirrors for method ("name", "uri" or
"taskId"), or nil when the method carries no Mcp-Name.
Builds the Mcp-Param-{Name} headers for a tool call.
Validates every x-mcp-header annotation in an inputSchema.
Compares a decoded header value to the corresponding body value.
Types
Functions
Decodes a received header value.
A value that starts with =?base64? and ends with ?= must carry valid,
padded standard Base64 of valid UTF-8 and decodes to that string; anything
else in that shape returns :error. Every other value is returned unchanged.
Encodes a string, integer, or boolean as a header value.
Strings that are not plain header-safe ASCII are wrapped in the
=?base64?...?= sentinel; see the module documentation.
@spec header_params(map()) :: [header_param()]
Lists the x-mcp-header annotations reachable from the root of an
inputSchema through chains of properties keys only.
Each entry has the declared header Name as written, the property-key
path from the root, and the property's declared type. Annotations whose
Name or type is not a string are left out; validate_x_mcp_header/1
reports those. Entries are ordered by path.
Returns the Mcp-Method header for a request method.
Returns the Mcp-Name header for a request, or nil when none applies.
Only tools/call and prompts/get (from params["name"]),
resources/read (from params["uri"]) and the tasks extension's
tasks/get|update|cancel (from params["taskId"]) carry the header, and
only when that param is a string. The value is encoded with
encode_value/1.
Returns whether requests with method must carry an Mcp-Name header.
The params key Mcp-Name mirrors for method ("name", "uri" or
"taskId"), or nil when the method carries no Mcp-Name.
Builds the Mcp-Param-{Name} headers for a tool call.
tool_or_schema is a tool definition (with "inputSchema") or an
inputSchema itself; args are the string-keyed call arguments. A header
is produced for each annotation from header_params/1 whose argument value
at path is a string, integer, boolean, or integral float (42.0 encodes
as "42"). Absent and nil values, and values of any other type, produce
no header. Header names are "mcp-param-" followed by the lowercased Name.
Validates every x-mcp-header annotation in an inputSchema.
The whole schema is searched, including items, composition keywords and
$defs. Each annotation must:
- sit on a property reachable from the root through
propertieskeys only; - be on a property whose
"type"is"string","integer"or"boolean"; - be a non-empty RFC 9110 token (which excludes CR and LF);
- be unique, compared case-insensitively, within the schema.
Errors name the annotation and its JSON Pointer location, never argument values.
Compares a decoded header value to the corresponding body value.
Strings compare exactly and booleans against "true"/"false". Integers
and floats compare numerically against a canonical decimal integer header
within the JavaScript safe range ("42" matches 42 and 42.0; "042",
"-0", "+1" and "42.0" match nothing). Any other body value, including
nil, never matches.