Skip to main content

Module dispatch

Module dispatch 

Source
Expand description

Transport-agnostic MCP JSON-RPC dispatch.

Handles initialize, tools/list, tools/call, resources/list, resources/read, and the relevant notifications.

§Code Mode: search + execute

Rather than one MCP tool per registered query/view/report/command (which scales as N_entities × ~8 auto-ops, blowing up the tools/list token footprint the same way a large hand-rolled REST-per-endpoint MCP server does — see Cloudflare’s “Code Mode” writeup), tools/list advertises exactly two operational tools:

  • search — looks up operations in ServerInfo::operation_index by substring/kind, returning compact {id, kind, args, outputType} entries instead of a full per-operation tool + JSON Schema.
  • execute — runs a JS function body (see sandbox) against a generated myko.* API bound to the same Executor methods the old per-operation tools called, so a script can chain several query/command calls in one round trip instead of one MCP call each.

ClientFilters visibility/callability checks move accordingly: they used to gate tools/list/tools/call per operation name; now search filters its index by the same names, and execute’s sandbox re-checks them per myko.* call the script makes (see [sandbox::call_operation] — not public, but that’s where the check lives).

This is a breaking change from the prior one-tool-per-operation wire shape — existing ClientFilters glob configs (query_*, etc.) still work exactly as before since they match against the same {kind}_{id} strings, just from a different call site.

§Resources

Every tool also surfaces a schema resource at myko://schema/<kind>/<id> whose content is the JSON Schema for the tool’s input. This predates (and is orthogonal to) search/execute — it’s not part of the tool-count problem search/execute fixes, since resources aren’t tool definitions loaded into the model’s context by default. Left unchanged:

  • Resources are URI-keyed and can’t carry structured arguments, but every query / view / report registration takes args.
  • Even argument-less reads are backed by reactive cells (the data is live), so pre-loading a snapshot into context at startup would just go stale. On-demand tools/call is the right shape for live reads.

Reactive query subscriptions via resources/subscribe are future work.

Error responses follow the MCP 2025-06-18 error-handling shape:

  • Protocol Error — JSON-RPC error response with code: -32602 and message "Unknown tool: …". Used when a tool is hidden by visibility filtering (indistinguishable on the wire from a tool that does not exist) or when required tools/call params are missing.
  • Tool Execution Error — successful JSON-RPC response with isError: true content carrying a descriptive message. Used when tools/call arguments fail client-supplied argument constraints (the spec’s “Invalid input data” category) or when tool execution raises an error downstream.

Structs§

ServerInfo
Server identity for the initialize response.

Functions§

handle_request
Dispatch one JSON-RPC request. Returns None for notifications that do not produce a response.