Skip to main content
Preview. Two kinds of limit apply: how often you may call, and what the transport will accept at all.

Rate limits

Requests are counted against several dimensions at once, and the first one to run out refuses the call. The defaults, per 60-second window:
The ordering is the policy: a single end user may burst, a workspace may burst harder, and a credential that fans a whole customer base into one key hardest. These are the same limits /api/v2/ runs on — an MCP client is not throttled separately, it is throttled by the same counter.
A refusal comes back as a tool error carrying rate_limited and a retry hint. Unlike an empty wallet, retrying does help here — wait out the window. The windows are fixed rather than sliding, so a caller can send up to two windows’ worth across a boundary. That is a known and deliberate trade: a sliding window needs a read-modify-write the cache API cannot make atomic, and the cost of the fixed one is something you notice in a graph rather than an outage.

Transport constraints

These are the ones that look like faults in a test client and are not. Every one of them is what the Streamable HTTP transport permits or requires — the 2025-06-18 spec for a handshake-era client, and 2026-07-28 for a modern one, which turned three of these from a server’s choice into the rule.

Which revisions are accepted

Four, in two eras: the current 2026-07-28, which has no handshake, and the handshake revisions 2025-06-18, 2025-03-26 and 2024-11-05. The list the server actually answers on is mcpserver/protocol.py: SUPPORTED_PROTOCOL_VERSIONS, and server/discover reads it out over the wire so a client never has to trust this page for it. Which era a request is served in is decided by the MCP-Protocol-Version header alone, so a client working today keeps working untouched — an absent header still means 2025-03-26. Protocol revisions is the whole story: what a modern client must send, what server/discover answers, and the three error codes this revision added. A client built for a revision we do not speak is still not locked out. The initialize handshake answers in the newest handshake revision we speak rather than refusing over a string, so such a client negotiates down and carries on — because a handshake that failed on an unrecognised version string would make the client list a whitelist by accident. The 400 is reserved for a client that keeps asserting an unsupported revision in the header after that, and it names what we do speak.
No Mcp-Session-Id is ever issued, in either era. Sessions were a MAY in the handshake era and 2026-07-28 removed them from the protocol altogether, so there was nothing to unwind here: a stateless server removes an entire class of expiry bugs — there is no session to go stale between a tool listing and a tool call. If your client is waiting for one, it will not arrive, and it does not need it.

Response bodies

Requests get Content-Type: application/json and a single JSON object. There is no SSE on this endpoint in Preview: streaming a tool result buys nothing when the result is a JSON object, and it costs every client an extra parsing path.

What is deliberately not here yet

Tools first. The server advertises tools capability and nothing else.
Conformant to omit, and it earns nothing while every result is a JSON object.
See above. Not planned, and 2026-07-28 removed them from the spec.
Deliberately absent from SUPPORTED_PROTOCOL_VERSIONS, and the omission is the decision rather than a gap. Nothing in the installed base speaks it, and it added surface — tasks, URL-mode elicitation — that this server does not implement. Claiming it would be advertising a revision we would then have to refuse features from. A client that asks for it is answered -32022 with the four we do speak, which is one retry rather than a guess. See Protocol revisions.
This server asks nothing of a client. clientCapabilities is required on every modern request and is read only to enforce its presence — which is why -32021 (MissingRequiredClientCapability) is a code this server names and never emits.
Preview means the tool set may change. Names and schemas can move between releases. Call tools/list at connection time rather than hard-coding a tool name in an unattended integration, and expect this page’s guarantees about the transport to be steadier than the ones about the tools.