Skip to content

Adopt the JSON-RPC error-code allocation policy (#109) - #125

Merged
TGoodhew merged 1 commit into
mainfrom
issue-109-error-code-policy
Jul 31, 2026
Merged

Adopt the JSON-RPC error-code allocation policy (#109)#125
TGoodhew merged 1 commit into
mainfrom
issue-109-error-code-policy

Conversation

@TGoodhew

Copy link
Copy Markdown
Owner

Closes #109.

2026-07-28 splits the server-error range: -32000-32019 implementation-defined, -32020-32099 reserved for the specification. Nothing we emit collides today — every code is a standard JSON-RPC one — but there was no convention stopping a future custom code from landing in the reserved half, where it would collide with a spec code and mean something else to every client.

Change

  • McpError documents the split and names the three renumbered spec codes with factories that carry useful data: HeaderMismatch (-32020), MissingRequiredClientCapability (-32021), UnsupportedProtocolVersion (-32022).
  • IsImplementationDefined exists so a test can hold us to the rule.
  • HeaderMismatch is there for MCP 2026-07-28: Streamable HTTP - Mcp-Method/Mcp-Name headers and stale session remnants #110; MissingRequiredClientCapability for wherever a capability turns out to be genuinely required.

The judgment call on UnsupportedProtocolVersion

Wired to the one case that is unambiguous today: a request declaring something that is not a revision at all ("latest") cannot be served on any reading, so it gets the spec error carrying the list we do speak.

A dated revision we do not fully implement is still served best-effort and logged. Refusing it would be more literally conformant and worse in practice: we already answer much of 2026-07-28's shape — resultType, per-result serverInfo, server/discover, the cache hints — and 2026-07-28 is not in SupportedProtocolVersions yet, so a blanket refusal would put every one of those features out of reach of the only clients that ask for them. The code says where that changes: when the revision is either finished or ruled out, the best-effort branch becomes a refusal. That is the last step of the epic, not a step inside it.

Verification

  • 7 new tests — the renumbered values; the reserved block is not ours; UnsupportedProtocolVersion data names the supported list; a non-revision is refused; a dated unimplemented revision is served; a notification is never answered with an error whatever it declares (JSON-RPC has nowhere to put one).
  • One test walks every code the server emits and asserts each is standard JSON-RPC or spec-allocated — never invented in the reserved block. That is the guard the issue actually asked for.
  • Full suite green: 385 GpibMcp + 113 Hpgl, 0 failures (Release|x86) — was 378 + 113.

2026-07-28 splits the server-error range: -32000..-32019 is implementation-
defined, -32020..-32099 belongs to the specification. Nothing we emit collides
today - every code is a standard JSON-RPC one - but there was no convention to
stop a future custom code landing in the reserved half, where it would collide
with a spec code and mean something else to every client.

McpError now documents the split, names the three renumbered spec codes
(HeaderMismatch -32020, MissingRequiredClientCapability -32021,
UnsupportedProtocolVersion -32022) with factories that carry useful data, and
exposes IsImplementationDefined so a test can hold us to the rule.
HeaderMismatch is for the transport-header work; MissingRequiredClientCapability
for wherever a capability turns out to be required.

UnsupportedProtocolVersion is wired to the one case that is unambiguous today: a
request declaring something that is not a revision at all ("latest") cannot be
served on any reading, so it gets the specification error carrying the list we
do speak. A DATED revision we do not fully implement is still served,
best-effort, and logged - we already answer much of 2026-07-28s shape, and
refusing it outright would put those features out of reach of the only clients
that ask for them. That branch becomes a refusal when the revision is either
finished or ruled out: the last step of the epic, not a step inside it.

Notifications are never answered with an error whatever they declare - JSON-RPC
has nowhere to put it.

7 tests, including one that walks every code the server emits and asserts each
is standard JSON-RPC or spec-allocated, never invented in the reserved block.
@TGoodhew
TGoodhew merged commit c607832 into main Jul 31, 2026
1 check passed
@TGoodhew
TGoodhew deleted the issue-109-error-code-policy branch July 31, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP 2026-07-28: adopt the JSON-RPC error-code allocation policy

1 participant