createmcps.com

Spec explainer

What is the Mcp-Method header in MCP?

Last verified: 10 August 2026 · spec 2026-07-28 · ruleset 1.4.2

Mcp-Method is an HTTP header required on every MCP Streamable HTTP request. Its value mirrors the JSON-RPC method field in the body, so a gateway or load balancer can route and inspect a request without parsing JSON. If the header and body disagree, the server must reject the request with 400 and -32020 HeaderMismatch.

The short answer

A conforming tools/call request
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call          ← mirrors "method" in the body
Mcp-Name: get_weather           ← mirrors params.name

{
  "jsonrpc": "2.0", "id": 2, "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": { "location": "Seattle, WA" },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}
Mcp-Method | method | All requests. These headers are REQUIRED for compliance.
MCP-HDR-001 MUST · spec 2026-07-28

That last clause — REQUIRED for compliance — is what makes this a migration task rather than an optimisation. A server built against 2025-11-25 does not send or validate these headers at all.

Why the header exists

Everything in MCP's Streamable HTTP transport is a POST to the same URL. Before this revision, an intermediary that wanted to know what a request actually did — to rate-limit tools/call differently from tools/list, to route expensive tools to a bigger pool, to log operations — had to buffer and parse the JSON body. That is expensive, it defeats streaming, and it forces every proxy in the path to understand MCP.

Lifting the method into a header makes the request self-describing at the HTTP layer. An nginx or Envoy config can match on Mcp-Method the way it already matches on any other header, with no body inspection and no MCP awareness.

Our recommendation, not a spec quote: this is also why the matching requirement below is strict rather than advisory. A routing header that is allowed to lie about the body is worse than no header — it turns every intermediary into a place where policy can be bypassed by sending one method in the header and another in the body.

The three required headers

Mcp-Method arrived alongside two others, and they are easy to confuse because they are all required but not all required on the same requests.

HeaderMirrorsRequired on
MCP-Protocol-Version_meta protocolVersionEvery POST
Mcp-MethodmethodEvery request
Mcp-Nameparams.name or params.uritools/call, resources/read, prompts/get
Mcp-Name | params.name or params.uri | tools/call, resources/read, prompts/get requests.
MCP-HDR-002 MUST · spec 2026-07-28
Every POST request to the MCP endpoint MUST include an MCP-Protocol-Version header.
MCP-HDR-004 MUST · spec 2026-07-28

Mismatches, and the -32020 error

The single normative rule that governs all three headers is that they must agree with the body:

Servers that process the request body MUST reject requests where the values specified in the headers do not match the corresponding values in the request body.
MCP-HDR-003 MUST · spec 2026-07-28
The header value MUST match the io.modelcontextprotocol/protocolVersion field carried in the request body's _meta. If the values do not match, the server MUST reject the request with 400 Bad Request and a HeaderMismatch JSON-RPC error.
MCP-HDR-005 MUST · spec 2026-07-28
Wrong — header and body disagree
POST /mcp
Mcp-Method: tools/list        ← says list
{ "method": "tools/call", … } ← does call

// A server that dispatches on the body and ignores
// the header will happily run tools/call here.
// Every gateway in the path believed it was a list.
Correct — 400 + HeaderMismatch
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 2,
  "error": {
    "code": -32020,
    "message": "Header mismatch: Mcp-Method does not match body method"
  }
}

-32020 sits in the -32020-32099 range the specification reserves for itself, added in this revision. It is one of three new codes, next to -32021 MissingRequiredClientCapability and -32022 UnsupportedProtocolVersion.

Our recommendation, not a spec quote: run header validation before method dispatch. A server that returns -32601 Method not found for a mismatched header has validated in the wrong order — the spec states the MUST-reject requirement but does not state the ordering, so this is our inference from it, and it is the one HDR rule with no verbatim sentence behind it (MCP-HDR-010, which we grade as a warning rather than a failure for exactly that reason).

Case-insensitivity is normative, not incidental

Header names (called "field names" in RFC 9110) are case-insensitive. Clients and servers MUST use case-insensitive comparisons for header names.
MCP-HDR-006 MUST · spec 2026-07-28

This one bites in production rather than in testing, because every client in your test suite probably sends the documented casing. The failure appears when a different client, an HTTP/2 stack that lowercases field names, or a proxy that normalises them, sends mcp-method and your exact-match lookup returns undefined — which your code then treats as a missing required header.

Node — the fix is usually one line
// Wrong: works only for one casing
const method = req.headers["Mcp-Method"]

// Right: Node lowercases incoming header names for you,
// but be explicit rather than relying on the runtime
const method = req.headers["mcp-method"]

// In a framework that hands you a raw Headers object:
const method = headers.get("mcp-method")   // Headers.get is case-insensitive

The Base64 sentinel encoding

HTTP header values are constrained to a narrow ASCII set, but tool and prompt names are not. The spec resolves that with a sentinel encoding — a name outside the safe set travels Base64-encoded — and puts the decoding obligation on the server:

For headers that permit the Base64 sentinel encoding (Mcp-Name and Mcp-Param-{Name}), servers MUST decode encoded values before comparing them to the body value.
MCP-HDR-007 MUST · spec 2026-07-28

The failure mode is quiet and complete: a server that compares the raw header against the body name will reject every request for a tool whose name needs encoding, while every ASCII-named tool keeps working. It looks like “that one tool is broken” rather than a header bug.

Mcp-Param-{Name}, for servers that opt in

A tool can promote individual input parameters into headers by marking them x-mcp-header in its inputSchema. That is opt-in — most servers never do it — but a server that declares it takes on two extra obligations:

Any server that processes the message body MUST validate that encoded header values, after decoding if Base64-encoded, match the corresponding values in the request body.
MCP-HDR-008 MUST · spec 2026-07-28
Servers MUST reject requests with a recognized Mcp-Param-{Name} header that contains invalid characters.
MCP-HDR-009 MUST · spec 2026-07-28

Both rules are marked v1: false in our catalogue, meaning we do not yet probe them automatically; they need a server that declares x-mcp-header in a published schema before there is anything to check. The schema-side constraints on those declarations are covered by the seven MCP-SCH-* rules.

The 10 header rules we check

RuleWhat we checkLevelIf it fails
MCP-HDR-001Missing Mcp-Method rejected with 400 + HeaderMismatchMUSTfail
MCP-HDR-002Missing Mcp-Name on tools/call rejected with 400 + HeaderMismatchMUSTfail
MCP-HDR-003Mcp-Name header must match the request bodyMUSTfail
MCP-HDR-004Missing MCP-Protocol-Version rejected (modern-only servers)MUSTfail
MCP-HDR-005MCP-Protocol-Version header must match _meta.protocolVersionMUSTfail
MCP-HDR-006Header names compared case-insensitivelyMUSTfail
MCP-HDR-007Base64 sentinel-encoded header values decoded before comparisonMUSTfail
MCP-HDR-008Mcp-Param-{Name} validated against body when x-mcp-header is declaredMUSTfail
MCP-HDR-009Mcp-Param-{Name} containing invalid characters is rejectedMUSTfail
MCP-HDR-010Header validation runs before method dispatchMAYwarn

Nine of the ten carry a verbatim spec sentence. MCP-HDR-010 (validate before dispatch) is our inference, graded as a warning.

Check your header handling

The validator sends deliberately mismatched and missing headers and reports exactly which of these ten rules your server satisfies — including the ordering check that distinguishes a -32020 from a -32601.

Validate a server →

Frequently asked

What is the Mcp-Method header?

A required HTTP header on every MCP Streamable HTTP request whose value mirrors the JSON-RPC method field in the request body — for example Mcp-Method: tools/call alongside "method": "tools/call". It lets a gateway, proxy or load balancer route and inspect a request without parsing the JSON body.

Is Mcp-Method required?

Yes. The 2026-07-28 specification lists it as REQUIRED for compliance on all requests. A server that processes the request body must reject a request whose header value does not match the body value with HTTP 400 Bad Request and JSON-RPC error code -32020 (HeaderMismatch).

What is the difference between Mcp-Method and Mcp-Name?

Mcp-Method carries the JSON-RPC method and is required on every request. Mcp-Name carries the target of that method — params.name or params.uri — and is required only on tools/call, resources/read and prompts/get. Together they let an intermediary see both what operation is being performed and on which tool or resource.

What is error -32020 HeaderMismatch?

The JSON-RPC error code a server must return, with HTTP 400, when a header value contradicts the corresponding value in the request body. It was added in 2026-07-28 as part of the reserved -32020 to -32099 range. Returning -32601 Method not found instead usually means header validation is running after method dispatch rather than before it.

Are MCP header names case-sensitive?

No. Header field names are case-insensitive under RFC 9110, and the specification requires clients and servers to use case-insensitive comparisons. Mcp-Method, MCP-METHOD and mcp-method are the same header, so matching on an exact-case string is a conformance bug even though it appears to work against clients that happen to use the documented casing.

What is the Base64 sentinel encoding in Mcp-Name?

HTTP header values cannot safely carry arbitrary Unicode, so a tool or prompt name outside the header-safe ASCII set is transmitted Base64-encoded behind a sentinel marker. Servers must decode such values before comparing them to the body value — comparing the encoded form against the raw body name would reject every conformant request using a non-ASCII name.