Roadmap / Model Context Protocol

✓

MCP Per-Request Metadata

mediummcpprotocols

The problem

Until revision 2025-11-25, an MCP (Model Context Protocol) connection began with a handshake: client and server exchanged protocol versions and capabilities, and the server then remembered them. Since revision 2026-07-28 there is no handshake: the protocol is stateless. Every request carries its protocol version and the client's capabilities in its params._meta field, and the server checks them on every request.

You will write that check, as a function that returns None if the request may proceed, or the JSON-RPC error response to send back.

The keys

In params._meta, all keys start with io.modelcontextprotocol/:

  • protocolVersion (a string, required), for example "2026-07-28";
  • clientCapabilities (an object, required);
  • clientInfo (an object with the client's name and version, recommended).

The constants PROTOCOL_VERSION, CLIENT_CAPABILITIES and CLIENT_INFO in the starter hold the full keys.

The check

check_meta(request, supported): request is a valid JSON-RPC request dict and supported the list of protocol versions the server implements.

  1. params._meta must be an object containing the two required keys, with the right types. If either is missing or of the wrong type, return error -32602 (invalid params) with the message "Missing required _meta field: <key>", with the full key, naming the first problem in the order above (version, then capabilities).
  2. If the protocol version is not in supported, return error -32022 with message "Unsupported protocol version" and data equal to {"supported": supported, "requested": <version>}, so that the client can retry with a version they have in common.

The error response is {"jsonrpc": "2.0", "id": <the request's id>, "error": {"code": ..., "message": ..., "data": ...}}, with "data" only for -32022.

Example. The server supports ["2026-07-28"]. Three requests with id 7:

  • _meta with protocolVersion "2026-07-28" and clientCapabilities {}: None, the request may proceed.
  • _meta with only protocolVersion: an error response with code -32602, and the message "Missing required _meta field: " followed by the full key of clientCapabilities.
  • _meta with protocolVersion "2025-01-01" and capabilities: code -32022, message "Unsupported protocol version", and data with supported ["2026-07-28"] and requested "2025-01-01".

The client's name

client_info(request) returns the clientInfo object from _meta (full key in CLIENT_INFO), or None if it is absent or not an object: it is recommended, not required.

Example. For the first request, with clientInfo {"name": "my-app", "version": "1.0"} in _meta: {"name": "my-app", "version": "1.0"}. Without that key: None.

What to implement

  • check_meta(request, supported) and client_info(request).

Requirements

  • A request without params, or with params but no _meta, is missing its required fields.
solution.py
Python idle

Press Run (⌘/Ctrl + Enter) to test your code.