AGT-14Required
Reject MCP requests whose headers disagree with the body
Require MCP-Protocol-Version, Mcp-Method and, on tool calls, resource reads and prompt requests, Mcp-Name. Refuse any request whose headers differ from its JSON body.
How to do it
The 2026-07-28 revision copies the method and the tool or resource name into headers, so gateways can route and rate-limit without reading the body. If a gateway allows Mcp-Name: list_slots and the body calls delete_booking, the policy is bypassed. Compare each header with the body after decoding any =?base64?…?= value. Do the same for Mcp-Param-* headers from x-mcp-header fields. Answer a mismatch or a missing header with 400 and JSON-RPC error -32020 (HeaderMismatch). A gateway that enforces policy on these headers refuses requests from protocol versions older than 2026-07-28. Never mark a secret parameter with x-mcp-header, because proxies log headers. Validate arguments as Design tools like a small public API says.
Examples
JavaScript example
const HEADER_MISMATCH = -32020;
const NAMED_METHODS = new Set(['tools/call', 'resources/read', 'prompts/get']);
const decoded = value => value?.startsWith('=?base64?') && value.endsWith('?=') ? Buffer.from(value.slice(9, -2), 'base64').toString('utf8') : value;
export function headerMismatch(req) {
const { method, params = {} } = req.body;
if (req.get('mcp-method') !== method) return { code: HEADER_MISMATCH, message: 'Mcp-Method does not match the body' };
if (NAMED_METHODS.has(method) && decoded(req.get('mcp-name')) !== (params.name ?? params.uri)) return { code: HEADER_MISMATCH, message: 'Mcp-Name does not match the body' };
return null;
}
Python example
import base64
HEADER_MISMATCH = -32020
NAMED_METHODS = {"tools/call", "resources/read", "prompts/get"}
def decoded(value: str | None) -> str | None:
if value and value.startswith("=?base64?") and value.endswith("?="):
return base64.b64decode(value[9:-2]).decode("utf-8")
return value
def header_mismatch(headers, body: dict) -> dict | None:
method, params = body.get("method"), body.get("params") or {}
if headers.get("mcp-method") != method:
return {"code": HEADER_MISMATCH, "message": "Mcp-Method does not match the body"}
if method in NAMED_METHODS and decoded(headers.get("mcp-name")) != (params.get("name") or params.get("uri")):
return {"code": HEADER_MISMATCH, "message": "Mcp-Name does not match the body"}
return None
How to check
Send a tools/call for delete_booking with Mcp-Name: list_slots, and another with no Mcp-Method. Both get 400 with error code -32020, and no booking changes.
Sources
Related rules
- AIF-15 Design tools like a small public API in AI features
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/agents-as-users/mcp-servers/mcp-header-validation">Agent Wranglers agents as users playbook</a>. In code you write, add a comment next to it with the same link.