Skip to content

refactor(#2796): shared JsonRpc helper for MCP — wire constants, erro…#82

Merged
Skobeltsyn merged 1 commit into
mainfrom
refactor/2796-jsonrpc-helper
May 30, 2026
Merged

refactor(#2796): shared JsonRpc helper for MCP — wire constants, erro…#82
Skobeltsyn merged 1 commit into
mainfrom
refactor/2796-jsonrpc-helper

Conversation

@Skobeltsyn
Copy link
Copy Markdown
Contributor

…r codes, McpException hierarchy

New agents_engine.mcp.JsonRpc consolidates the JSON-RPC 2.0 envelope shape that was hand-rolled separately on both sides:

JsonRpc helper

  • encodeRequest(id, method, params) — builds request/notification envelopes; passing null for id signals a notification.
  • encodeResult(id, result) / encodeError(id, code, message) — response envelope builders the server now uses.
  • parseEnvelope(payload) — single Map lookup point.
  • isNotification(envelope) — the duplicated !containsKey("id") || method.startsWith("notifications/") predicate, in one place.

Wire constants + error codes

  • JsonRpcWire centralises the literal "2.0", the key names (jsonrpc/method/params/id/result/error/code/message), and the notification prefix.
  • JsonRpcErrorCode names the standard JSON-RPC error codes (-32700/-32600/-32601/-32602/-32603) as PARSE_ERROR / INVALID_REQUEST / METHOD_NOT_FOUND / INVALID_PARAMS / INTERNAL_ERROR. Every bare literal in McpServer.kt replaced.

McpException hierarchy

  • sealed class McpException : IllegalStateException (extends ISE so existing catch (e: IllegalStateException) test sites keep working — no breaking change for downstream consumers).
  • Three subclasses: Transport (network / stdio EOF), Protocol (JSON-RPC error response or malformed envelope), ToolFailure (tool ran but signalled error). McpClient.post now throws McpException.Protocol instead of bare error(), and the helper's parseResponse does the same.

Side effect (small)

  • McpClient's handshake() notifications/initialized raw-string emission now flows through JsonRpc.encodeRequest so the wire is identical to every other notification.

Full ./gradlew test green; 254+ TEST-*.xml files, zero failures/errors.

…r codes, McpException hierarchy

New `agents_engine.mcp.JsonRpc` consolidates the JSON-RPC 2.0 envelope
shape that was hand-rolled separately on both sides:

JsonRpc helper
- `encodeRequest(id, method, params)` — builds request/notification
  envelopes; passing null for id signals a notification.
- `encodeResult(id, result)` / `encodeError(id, code, message)` —
  response envelope builders the server now uses.
- `parseEnvelope(payload)` — single Map lookup point.
- `isNotification(envelope)` — the duplicated
  `!containsKey("id") || method.startsWith("notifications/")`
  predicate, in one place.

Wire constants + error codes
- `JsonRpcWire` centralises the literal `"2.0"`, the key names
  (`jsonrpc/method/params/id/result/error/code/message`), and the
  notification prefix.
- `JsonRpcErrorCode` names the standard JSON-RPC error codes
  (`-32700/-32600/-32601/-32602/-32603`) as `PARSE_ERROR` /
  `INVALID_REQUEST` / `METHOD_NOT_FOUND` / `INVALID_PARAMS` /
  `INTERNAL_ERROR`. Every bare literal in McpServer.kt replaced.

McpException hierarchy
- `sealed class McpException : IllegalStateException` (extends ISE so
  existing `catch (e: IllegalStateException)` test sites keep
  working — no breaking change for downstream consumers).
- Three subclasses: `Transport` (network / stdio EOF), `Protocol`
  (JSON-RPC error response or malformed envelope), `ToolFailure`
  (tool ran but signalled error). `McpClient.post` now throws
  `McpException.Protocol` instead of bare `error()`, and the
  helper's `parseResponse` does the same.

Side effect (small)
- McpClient's `handshake()` `notifications/initialized` raw-string
  emission now flows through `JsonRpc.encodeRequest` so the wire is
  identical to every other notification.

Full ./gradlew test green; 254+ TEST-*.xml files, zero failures/errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Skobeltsyn Skobeltsyn merged commit 0bcb1e7 into main May 30, 2026
2 of 3 checks passed
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.

1 participant