What is JSONRPCRequest?
JSONRPCRequest is the foundational message type for all client-to-server (and server-to-client) calls in MCP. It models the JSON-RPC 2.0 request object exactly: a fixed jsonrpc field set to the string "2.0", a caller-chosen id that must be either a string or integer, a method string naming the operation (e.g. "tools/call" or "initialize"), and an optional params object carrying the operation's arguments. Because MCP inherits JSON-RPC 2.0 in full, every guaranteee from that spec applies — the server must reply with a JSONRPCResponse carrying the same id, or a JSONRPCError if something went wrong.\n\nWithin the MCP message flow, JSONRPCRequest sits at the entry point of every RPC exchange. The transport layer (stdio, HTTP+SSE, or WebSocket) delivers the raw JSON frame; the SDK deserializes it into a typed request and routes it to the registered handler for that method. The id field is the correlation key that lets multiplexed sessions match responses to outstanding calls, which is why null ids — permitted by JSON-RPC 2.0 for notifications — are intentionally absent here; MCP separates the two concepts into distinct types (JSONRPCRequest vs JSONRPCNotification).\n\nThe params object may include a reserved _meta key whose progressToken sub-field instructs the server to emit progress notifications during a long-running operation. This design keeps the core request shape minimal and spec-compliant while allowing MCP-specific extensions to live in a single, well-known namespace. No other top-level keys are added by the MCP spec, so any future capabilities are expected to extend params rather than the request envelope itself.
When to use
Whenever you need a response — for fire-and-forget use a notification.
When NOT to use
If the receiver shouldn't reply, send a notification instead.
Notes
id Type Restrictions Matter
JSON-RPC 2.0 technically allows fractional numbers as ids, but MCP explicitly restricts the id to string | integer (no floats). Sending a floating-point id will cause spec-compliant MCP servers to reject or misroute the response. Always use integers or opaque string UUIDs to stay safe across implementations.
Null id Means Notification, Not Request
If you omit or null the id field you are sending a JSONRPCNotification, not a JSONRPCRequest — a different type with a different routing path. The server will not send a response for notifications. Mixing these up is a common source of 'missing response' bugs; keep the types distinct in your own abstractions.
params._meta.progressToken Usage
Setting params._meta.progressToken to any string or integer tells the server it may emit ProgressNotification messages referencing that token before the final response arrives. Clients must register a notifications/progress handler before sending the request, otherwise progress frames will be silently dropped. The token only needs to be unique within a single session.
Method Namespace Collisions
MCP reserves method names that follow the 'namespace/operation' pattern (e.g., 'tools/call', 'resources/read'). Custom extension methods should use a vendor-prefixed namespace (e.g., 'acme/customOp') to avoid collisions with future MCP spec additions. The SDK does not validate method names at the type level, so enforcement is entirely the application's responsibility.
Request Size and params Depth
There is no hard size limit in the JSON-RPC spec or MCP protocol layer, but transport implementations (especially stdio) can be sensitive to large frames. For tool calls with large inputs, prefer passing a resource URI in params and letting the server fetch the content rather than embedding multi-kilobyte payloads inline. Deep nesting in params also slows schema validation in strictly-validating SDKs.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| jsonrpc | '2.0' | yes | Protocol identifier. |
| id | string | number | yes | Correlates the response. |
| method | string | yes | Method to invoke. |
| params | object? | no | Method arguments. |
Examples
A ping request
{ "jsonrpc": "2.0", "id": 1, "method": "ping" }
Common mistakes
❌ Using duplicate IDs across active requests
✅ IDs MUST be unique while the request is outstanding.