Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

mcpx × revisions, both directions

created:      2026-09-30T08:00:00-05:00
last-updated: 2026-09-30T08:00:00-05:00
increment:    1
status:       standard
tags:         area:compare, area:protocol
description:  what mcpx does for each protocol feature, serving each
              revision and consuming each era, at one named commit, in a
              shape whose status cells can be refreshed row by row.

Status as of 05c78b2 (origin/main, “mcpx: stop leaking daemons, restore the CI cache, and add a Containerfile (#182)”). The protocol work in progress at the time of writing changes several rows. Refresh a row by re-reading the code cited in it and editing its cells, then change the commit above. GET /v1/protocol reports which revision defines which feature and what each upstream negotiated. It does not report whether mcpx implements a feature correctly, and nothing generates that side yet.

Columns. srv→: a host of that revision connected to mcpx. cli→legacy: mcpx connected to an upstream speaking 2025-03-26 to 2025-11-25 (mcpx offers 2025-11-25). cli→modern: mcpx connected to a 2026-07-28 upstream. The register column links the area file holding the individual differences, with value, effort and risk.

Legend: ✓ works as the revision defines · partial (the cell says how) · ✗ missing or broken · n/a not defined for that peer · acc. accepted beyond the revision (accept-liberally, ../protocol.md). Evidence marked W*, M*, S* comes from the wire session described in stateless.md.

#featuresrv→2025-03-26srv→2025-06-18srv→2025-11-25srv→2026-07-28cli→legacycli→moderncode (row)register
1version handshake / negotiation✓ (2024-11-05 & future refused)✓✓partial: _meta honoured; wrong requested, HTTP 200partial: always offers 2025-11-25, accepts anything✗ discover field name; -32022 on init abortsinternal/mcpserver/server.go:844-859; internal/mcpclient/client.go:202-325lifecycle-versioning
2server/discoveracc.acc.acc.partial: protocolVersions, top-level serverInfo, no ttln/a✗internal/mcpserver/server.go:529-538lifecycle-versioning, pagination-caching
3resultType on resultsstripped ✓stripped ✓stripped ✓✓ (task handle wrong)n/a✓ read (input_required detection)internal/mcpserver/server.go:432-436; internal/mcpserver/revisions.go:163-168; internal/mcpclient/client.go:663-665lifecycle-versioning
4result _meta serverInfon/an/an/a✗n/a✗ not readinternal/mcpserver/server.go:432-436lifecycle-versioning
5stdio framing✓✓✓✓✓✓internal/mcpserver/server.go:1000-1073; internal/mcpclient/stdio.go:112-145transports
6stdio concurrencypartial (in-line)partialpartialpartial✓ id-multiplexed✓internal/mcpserver/server.go:1051-1067transports
7batching✗n/an/an/apartial: HTTP split, stdio droppedn/ainternal/mcpserver/server.go:1041-1044; internal/mcpclient/http.go:197-210transports
8HTTP POST JSON/SSE✓✓✓✓✓✓internal/mcpserver/server.go:1118-1193; internal/mcpclient/http.go:97-162—
9HTTP GET stream✓ 405✓ 405✓ 405✓ 405✗ never openedn/ainternal/mcpserver/server.go:1124-1131transports
10Mcp-Session-Idpartial: issued on failed init; no 404partialpartial✗ minted on discoverpartial: no re-init on 404✗ still sentinternal/mcpserver/server.go:1208-1230; internal/mcpclient/http.go:89-93, internal/mcpclient/http.go:126-130transports, lifecycle-versioning
11MCP-Protocol-Version headern/apartial: not validated or usedpartialpartial: mismatch 400 but not -32020✗ fixed 2025-11-25✓ from _metainternal/mcpserver/server.go:1161-1168; internal/mcpclient/http.go:81-85transports, lifecycle-versioning
12Mcp-Method / Mcp-Namen/an/an/a✗ not checkedn/a✗ not sent—transports
13HTTP error statuses (400/404)✓ (200 is legacy-correct)✓✓✗n/apartial: body inspected by substringinternal/mcpserver/server.go:1192; internal/mcpclient/client.go:329-331transports
14Origin validation✗✗✗✗n/an/a—transports
15legacy HTTP+SSE (2024-11-05)n/an/an/an/a✗n/ainternal/pool/pool.go:368-381transports
16capabilities declaredpartial: stdio listChanged never deliveredpartialpartial: + extensions leak, tasks.listpartial: + core tasks leakpartial: sampling always, roots emptypartialinternal/mcpserver/server.go:1389-1420; internal/mcpclient/modern.go:46-58capabilities, lifecycle-versioning
17ping✓✓✓acc.✓ answered✓ answeredinternal/mcpserver/server.go:543; internal/mcpclient/modern.go:110-115lifecycle-versioning
18tools/list✓ (61 tools)✓✓partial: no ttlMs/cacheScope✓ paginated✗ unreachableinternal/mcpserver/server.go:546-556; internal/mcpclient/client.go:731-750tools, pagination-caching, lifecycle-versioning
19tools/call via mcpx_callpartial: isError lost, text onlypartialpartialpartial✓ raw result kept in /v1✗ unreachableinternal/cli/serve.go:103-117; internal/cli/commands.go:385-415tools
20resources/list✓ (namespaced URIs)✓✓partial✓✗internal/mcpserver/server.go:683-699; internal/cli/serve.go:473-497resources, pagination-caching
21resources/templates/list✗ uri not uriTemplate✗✗✗✓ reads uriTemplate✗internal/mcpserver/server.go:574-593resources
22resources/readpartial: -32602 not -32002; blob as textpartialpartialpartial: code ✓, no ttl, internal→-32602✓✗internal/mcpserver/server.go:701-722resources
23resources subscribe / updatedpartial: stdio only, never upstream, wrong URIpartialpartialpartial (via listen)✗ never subscribes✗ no listeninternal/mcpserver/server.go:595-620; internal/mcpclient/client.go:536-543resources, notifications
24prompts/listpartial: title leak✓✓partial✓✗internal/mcpserver/server.go:724-740prompts, pagination-caching
25prompts/getpartial: flattenedpartialpartialpartial✓✗internal/mcpserver/server.go:742-764; internal/cli/serve.go:640-669prompts
26completion/completepartial: ref ignoredpartialpartialpartial✓ Complete if declared✗internal/mcpserver/server.go:1555-1599; internal/pool/request.go:60-70completion
27logging (setLevel, notifications/message)acc. no-op, never emitsacc.acc.acc. (removed); logLevel never readpartial: setLevel info; logs → event bus✗ uses removed methodinternal/mcpserver/server.go:565-572; internal/daemon/hooks.go:29-33logging
28elicitation (server→host)n/a (broker)✓ form, SSE/stdio✓ form+urlpartial: needs session; stateless → -32603n/an/ainternal/mcpserver/ask.go:122-233; internal/mcpserver/conn.go:191-208elicitation
29elicitation (upstream→mcpx)n/a✓ via broker✓ incl. url, complete notifn/a✓ (string ids dropped)✓ input_required (unreachable until )internal/daemon/hooks.go:122-170; internal/mcpclient/modern.go:156-189transports, lifecycle-versioning
30sampling (server→host)partial: no revision or tools gatingpartialpartialpartialn/an/ainternal/mcpserver/conn.go:211; internal/mcpserver/ask.go:256-266sampling
31sampling (upstream→mcpx)n/an/an/an/apartial: always declared, broker onlypartialinternal/daemon/hooks.go:180-232capabilities, sampling
32roots✗ never asks host; notif gets error✗✗✗partial: declared, emptypartialinternal/daemon/server.go:176; internal/mcpclient/modern.go:116-120roots, capabilities
33tasks (server)acc.acc.partial: no taskSupport, cancel-terminal, no binding, no related-task✗ wrong shape, no tasks/updaten/an/ainternal/mcpserver/server.go:474-501; internal/mcpserver/tasks.gocapabilities, tasks
34tasks (client)n/an/an/an/a✗ never task-augments✗ extension not declaredinternal/mcpclient/client.go:845-858tools
35subscriptions/listenacc. (stdio)acc.acc.partial: stdio wrong ack, no subscriptionId; HTTP 202n/a✗ never openedinternal/mcpserver/server.go:622-640notifications, transports
36notifications (list_changed) to host✗ stdio declared, never sent✗✗partial: stdio via listen only——internal/mcpserver/server.go:1389-1402capabilities
37notifications from hostpartial: unknown ones get an error replypartialpartialpartial✓ all known handled✓internal/mcpserver/server.go:766; internal/mcpclient/client.go:473-522notifications
38cancellation (host→mcpx→upstream)partial: recorded only on stdio; HTTP disconnect propagatespartialpartialpartial✓ sends notifications/cancelled (“timeout”)partialinternal/mcpserver/server.go:1521-1538; internal/mcpclient/client.go:709-716progress-cancellation
39progress✗✗✗✗partial: relayed to the host under its token (#212); does not reset mcpx’s own timeoutsameinternal/mcpserver/ask.go:95-108; internal/daemon/hooks.go:34-36progress-cancellation
40_meta passthrough (trace, sessionID)✗✗✗✗✗ never sent✗internal/mcpserver/ask.go:95-108meta
41paginationpartial: bad cursor→0partialpartialpartial✓ ≤100 pages✗internal/mcpserver/server.go:1477-1513pagination-caching
42content downgrade✓ resource_link→resource ( mime)✓ untouched✓✓ untouchedn/an/ainternal/mcpserver/revisions.go:132-289content-types
43auth to upstreamn/an/an/an/apartial: headers only; auth inert; no OAuthsameinternal/pool/pool.go:377-380auth
44auth on /mcp✗✗✗✗n/an/ainternal/cli/root.go:196-204auth

Reading it

  • The legacy server columns are mostly ✓ or partial. The partials are lossy rendering (mcpx_call, prompts/get, resources/read) and declarations with nothing behind them. None of them stops a legacy host from working.
  • The modern server column is partial almost everywhere. mcpx’s own client works against it, but a conformant 2026 client does not: see stateless.md.
  • The modern client column is ✗ almost everywhere. One field name in discovery stops everything behind it. The rows are ✗ because they are unreachable, not because each is broken on its own, and several (MRTR, _meta) are implemented and would work once discovery does.