Lesson 3 - Step 1 of 5

Protocol Overview

Understand JSON-RPC 2.0, the foundation of MCP communication.

What You'll Build

In this lesson, you'll build a reusable jsonrpc.py module from scratch. By the end, you'll have working code that can:

  • Create valid JSON-RPC requests, responses, and notifications
  • Handle errors with proper error codes
  • Route incoming messages to handler functions

Each step builds on the previous one, and your code will be runnable after every step.

What is JSON-RPC?

JSON-RPC is a lightweight remote procedure call (RPC) protocol that uses JSON for data encoding. MCP uses JSON-RPC 2.0 for all communication between clients and servers.

Why JSON-RPC?

JSON-RPC is simple, transport-agnostic, and well-established. It works equally well over HTTP, WebSockets, or stdin/stdout — perfect for MCP's dual transport model.

Message Types

JSON-RPC 2.0 has three message types:

Type Has ID? Expects Response?
Request Yes Yes
Response Yes (matching) No
Notification No No

Request Structure

Every request must have these fields:

json
{
    "jsonrpc": "2.0",        // Required: Must be exactly "2.0"
    "id": 1,                 // Required: Unique identifier (string or int)
    "method": "tools/list",  // Required: Method name to call
    "params": {}             // Optional: Parameters for the method
}

Response Structure

Responses match requests by ID:

json
// Success response
{
    "jsonrpc": "2.0",
    "id": 1,                 // Must match the request ID
    "result": {              // The method's return value
        "tools": []
    }
}

// Error response
{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {               // Error object (instead of result)
        "code": -32601,
        "message": "Method not found"
    }
}

The ID Field

The id field connects requests to responses:

  • Client generates a unique ID for each request
  • Server includes the same ID in the response
  • Client matches responses to pending requests by ID
  • ID can be a string or integer (not null)
text
Client                              Server
  |                                    |
  |--- Request (id: 1) --------------->|
  |--- Request (id: 2) --------------->|
  |                                    |
  |<-------------- Response (id: 2) ---|  (responses can arrive
  |<-------------- Response (id: 1) ---|   out of order)
MCP Convention

MCP typically uses incrementing integers for IDs (1, 2, 3, ...). The ID must be unique within a session but doesn't need to be globally unique.