Every request shape our three MCP endpoints can be sent, what it returns, and why.
Applies identically to /mcp, /mcp/triage, /mcp/doctor
and to their /c/<channel>/ copies. Measured live, not asserted.
| Request | Status | Body |
|---|---|---|
POST JSON-RPC | 200 | The JSON-RPC result. This is the transport; everything else on this page is discovery. |
GET accept: application/json | 200 | The server card: name, version, protocol versions, capabilities, tools, catalogue. |
GET accept: application/json, text/event-stream;q=0.9 | 200 | The same card. JSON is ranked above the stream, so JSON is what you get — RFC 9110 §12.5.1. |
GET no accept header | 200 | The same card. No Accept means anything is acceptable. |
HEAD (any of the above) | mirrors the GET | Nothing. Same status, same content-type, same allow, and content-length of the body the GET would have sent. |
GET or HEAD accept: text/event-stream | 405 | A JSON-RPC error explaining that this revision has no GET stream, and naming POST as the thing to do instead. See below. |
OPTIONS | 204 | CORS preflight; every origin is allowed. |
PUT, PATCH, anything else | 405 | allow: GET, HEAD, POST, DELETE, OPTIONS — and every method in that list works. |
# check any row of that table yourself curl -si https://www.pathwren.workers.dev/mcp/doctor -H 'accept: application/json' | head -1 # 200 curl -sI https://www.pathwren.workers.dev/mcp/doctor # 200, no body curl -si https://www.pathwren.workers.dev/mcp/doctor -H 'accept: text/event-stream' | head -1 # 405, and it says why
This is the one refusal on the page, so it is the one that gets the argument in full.
A GET that ranks text/event-stream at or above everything else is
asking to open a standalone server-to-client SSE stream. We answer
405 Method Not Allowed. Three reasons, in the order they decide it:
200 text/event-stream would trade a refusal a client can act on in one round trip
for a stream it waits on for messages that are never coming. It would make our numbers look
better and our clients wait longer, which is the wrong way round.That last point is not a guess. Every client that has met this 405 here went on to finish its session over POST anyway, seconds later, on the same endpoint — the SDKs treat “no stream” as the ordinary answer it is. The refusal costs nothing, so we kept it and made it legible instead of removing it.
It is a document, not a bare status. application/json, a real JSON-RPC error
(so a client following the backward-compatibility algorithm does not mistake us for a
pre-2025 server and retry against the deprecated HTTP+SSE transport), the reason, the clause,
and the request that works:
curl -s https://www.pathwren.workers.dev/mcp/doctor -H 'accept: text/event-stream' | jq '.error.data | {how_to_call, reason, allow}'
Not “HEAD returns 200” — mirrors. The endpoint builds the real GET response and
removes the body, so HEAD is still correct after whatever GET does next, including the 405
above: HEAD with accept: text/event-stream returns 405 with no body.
RFC 9110 §9.3.2.
Until 2026-09-01 HEAD fell through to the unsupported-method branch and returned 405 on every one of these endpoints, which cost at least one real client three failed probes before anybody owned the row.
A 405 carrying allow: GET, … on a refused GET tells a reader that the header
and the behaviour disagree, and it is the first thing an automated grader checks. So:
PUT and friends — allow is the full set
GET, HEAD, POST, DELETE, OPTIONS, and every method in it works.allow is POST, OPTIONS: what works for a client sending
that Accept header. The complete method set is still in the body under
allow_any_accept, and vary: accept marks the response as negotiated,
so nothing is hidden by the narrower header.These servers accept 2026-07-28, 2025-11-25,
2025-06-18, 2025-03-26 and 2024-11-05 for version
negotiation on POST, and POST answers all of them. The mechanisms the older revisions added
around the POST — the standalone GET stream, Mcp-Session-Id sessions,
Last-Event-ID resumption — are not implemented, and per 2026-07-28 a session id
is ignored rather than minted or echoed. If your client needs the deprecated 2024-11-05
HTTP+SSE transport specifically, it will not work here, and the 405 says so rather than
letting you discover it after a handshake.
The three servers: ai-crawler-index, crawler-log-triage, agent-discovery-doctor. Specification: modelcontextprotocol.io.