> ## Documentation Index
> Fetch the complete documentation index at: https://learn.orbexa.io/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP data layer and JSON-RPC 2.0 messages

> MCP data layer explained — JSON-RPC 2.0 message format, capability negotiation, Server/Client primitives, error handling, and content types

# Data Layer Protocol

## 2.1 JSON-RPC 2.0 Fundamentals

The MCP data layer is built on the [JSON-RPC 2.0](https://www.jsonrpc.org/) specification. All messages are in JSON format and fall into three categories:

### Request

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}
```

* `jsonrpc`: Fixed as `"2.0"`
* `id`: Unique request identifier (string or number), used for matching responses
* `method`: The method name to call
* `params`: Method parameters (optional, Object type)

### Response

Success response:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": { "tools": [] }
}
```

Error response:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": { "code": -32601, "message": "Method not found", "data": {} }
}
```

`result` and `error` are mutually exclusive; a response will contain only one of them.

### Notification

Has no `id` field and expects no response:

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "notifications/tools/list_changed"
}
```

Notifications are unidirectional; the sender does not wait for any reply.

## 2.2 Server-Side Primitives

An MCP Server can expose three core capabilities:

### Tools — Model-Controlled

Executable functions. The AI model autonomously decides when to call them.

| Method                             | Direction        | Purpose                                        |
| ---------------------------------- | ---------------- | ---------------------------------------------- |
| `tools/list`                       | Client -> Server | List all available tools (supports pagination) |
| `tools/call`                       | Client -> Server | Execute a specified tool                       |
| `notifications/tools/list_changed` | Server -> Client | Tool list change notification                  |

**Tool Definition** (protocol version `2025-11-25`):

```json theme={null}
{
  "name": "check_inventory",
  "title": "Inventory Check",
  "description": "Query real-time inventory quantity for a given SKU",
  "inputSchema": {
    "type": "object",
    "properties": {
      "sku": { "type": "string", "description": "Product SKU code" },
      "warehouse": { "type": "string", "description": "Warehouse code (optional)" }
    },
    "required": ["sku"]
  },
  "outputSchema": {
    "type": "object",
    "properties": {
      "sku": { "type": "string" },
      "quantity": { "type": "number" },
      "warehouses": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "code": { "type": "string" },
            "quantity": { "type": "number" }
          }
        }
      }
    }
  }
}
```

**Key field descriptions**:

* `name`: Unique identifier for the tool
* `title`: Human-readable display name
* `description`: Describes the tool's purpose; directly influences the AI model's selection decisions
* `inputSchema`: Input parameter definition in JSON Schema format (required)
* `outputSchema`: Output structure definition in JSON Schema format (optional, added in `2025-11-25`)

**Tool execution result**:

```json theme={null}
{
  "content": [
    { "type": "text", "text": "SKU SHOE-001 inventory: Beijing warehouse 45 units, Shanghai warehouse 23 units" }
  ],
  "structuredContent": {
    "sku": "SHOE-001",
    "quantity": 68,
    "warehouses": [
      { "code": "BJ", "quantity": 45 },
      { "code": "SH", "quantity": 23 }
    ]
  },
  "isError": false
}
```

* `content`: Content array supporting multiple types (text, image, audio, resource\_link, embedded\_resource)
* `structuredContent`: Structured data corresponding to the `outputSchema` (optional, returned alongside `content`, preferred for programmatic processing)
* `isError`: Indicates whether this is a tool-level error (`true` means the tool execution failed but the protocol layer is fine)

**Two types of errors**:

1. **Protocol-level errors**: JSON-RPC error responses, indicating the request itself has issues (method not found, invalid parameters, etc.)
2. **Tool-level errors**: `isError: true`, indicating the tool executed but encountered a business error (product not found, insufficient permissions, etc.)

### Resources — Application-Controlled

Data sources that provide contextual information. The difference from Tools: Tools "do things," Resources "provide information."

| Method                                 | Direction        | Purpose                                            |
| -------------------------------------- | ---------------- | -------------------------------------------------- |
| `resources/list`                       | Client -> Server | List all available resources (supports pagination) |
| `resources/read`                       | Client -> Server | Read a specified resource                          |
| `resources/subscribe`                  | Client -> Server | Subscribe to resource changes                      |
| `resources/unsubscribe`                | Client -> Server | Unsubscribe                                        |
| `notifications/resources/list_changed` | Server -> Client | Resource list change notification                  |
| `notifications/resources/updated`      | Server -> Client | Subscribed resource content change notification    |

**Resource Definition**:

```json theme={null}
{
  "uri": "commerce://catalog/categories",
  "name": "Product Categories",
  "description": "All current product categories and their hierarchy",
  "mimeType": "application/json",
  "annotations": {
    "audience": ["user", "assistant"],
    "priority": 0.8,
    "lastModified": "2026-04-10T08:00:00Z"
  }
}
```

**Annotations field descriptions**:

* `audience`: Target audience; possible values include `"user"` and `"assistant"`
* `priority`: Priority, a float between 0 and 1 (1 is highest priority)
* `lastModified`: Last modified time (ISO 8601 format)

**URI Templates**: Resource URIs support RFC 6570 URI template syntax for defining dynamic resources:

```
commerce://products/{sku}
commerce://orders/{orderId}/items
```

### Prompts (Prompt Templates) — User-Controlled

Reusable interaction templates. Servers can provide predefined prompts that users actively select in the Host application.

| Method                               | Direction        | Purpose                                                   |
| ------------------------------------ | ---------------- | --------------------------------------------------------- |
| `prompts/list`                       | Client -> Server | List all available prompts (supports pagination)          |
| `prompts/get`                        | Client -> Server | Get a specified prompt (supports parameterized arguments) |
| `notifications/prompts/list_changed` | Server -> Client | Prompt list change notification                           |

**Prompt Definition**:

```json theme={null}
{
  "name": "product_recommendation",
  "description": "Recommend products based on user needs",
  "arguments": [
    { "name": "category", "description": "Product category", "required": true },
    { "name": "budget", "description": "Budget range", "required": false }
  ]
}
```

**Getting a Prompt**:

```json theme={null}
// Client -> Server
{
  "method": "prompts/get",
  "params": {
    "name": "product_recommendation",
    "arguments": { "category": "running shoes", "budget": "50-100" }
  }
}

// Server -> Client
{
  "result": {
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "Please recommend running shoes in the $50-100 price range, considering value, comfort, and brand reputation."
        }
      }
    ]
  }
}
```

## 2.3 Client-Side Primitives

MCP Clients can also expose capabilities to Servers (must be declared during initialization):

### Sampling — Server Requests LLM Inference

The Server does not need a built-in AI SDK; it can request the Host's LLM to complete inference.

```json theme={null}
// Server -> Client
{
  "method": "sampling/createMessage",
  "params": {
    "messages": [
      { "role": "user", "content": { "type": "text", "text": "Translate the following text to French: Hello World" } }
    ],
    "maxTokens": 100,
    "modelPreferences": {
      "hints": [{ "name": "claude-sonnet" }],
      "costPriority": 0.3,
      "speedPriority": 0.8,
      "intelligencePriority": 0.5
    }
  }
}
```

**modelPreferences fields**:

* `hints`: Model hint list; the Server suggests which model to use (the Host may ignore this)
* `costPriority`: Cost priority (0-1, higher values favor lower-cost models)
* `speedPriority`: Speed priority (0-1, higher values favor faster models)
* `intelligencePriority`: Intelligence priority (0-1, higher values favor more capable models)

### Elicitation — Server Requests User Input

Used when the Server needs user confirmation or supplementary information.

```json theme={null}
// Server -> Client
{
  "method": "elicitation/request",
  "params": {
    "message": "The following information is required to process the return",
    "requestedSchema": {
      "type": "object",
      "properties": {
        "reason": { "type": "string", "description": "Return reason" },
        "confirm": { "type": "boolean", "description": "Confirm return" }
      },
      "required": ["reason", "confirm"]
    }
  }
}
```

### Roots — Filesystem Boundaries

The Server queries the accessible filesystem scope.

```json theme={null}
// Server -> Client
{ "method": "roots/list" }

// Client -> Server
{
  "result": {
    "roots": [
      { "uri": "file:///home/user/project", "name": "Project directory" }
    ]
  }
}
```

### Logging — Log Messages

The Server sends log messages to the Client for debugging and monitoring.

```json theme={null}
// Server -> Client (notification)
{
  "method": "notifications/message",
  "params": {
    "level": "warning",
    "logger": "inventory-service",
    "data": "SKU SHOE-001 inventory below threshold"
  }
}
```

Log levels: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`.

## 2.4 Capability Negotiation

During initialization, both sides declare their supported capabilities. Only declared capabilities can be used.

**Server capabilities**:

```json theme={null}
{
  "capabilities": {
    "tools": { "listChanged": true },
    "resources": { "subscribe": true, "listChanged": true },
    "prompts": { "listChanged": true },
    "logging": {}
  }
}
```

* `listChanged`: The Server will send notifications when the list changes
* `subscribe`: Supports resource subscription (notifies the Client when content changes)

**Client capabilities**:

```json theme={null}
{
  "capabilities": {
    "sampling": {},
    "elicitation": {},
    "roots": { "listChanged": true }
  }
}
```

* `sampling`: The Client supports Server requests for LLM inference
* `elicitation`: The Client supports Server requests for user input
* `roots.listChanged`: The Client will notify the Server when filesystem boundaries change

## 2.5 Error Handling

MCP uses standard JSON-RPC 2.0 error codes plus MCP-specific extensions:

### Standard JSON-RPC Error Codes

| Error Code | Meaning          |
| ---------- | ---------------- |
| -32700     | Parse error      |
| -32600     | Invalid Request  |
| -32601     | Method not found |
| -32602     | Invalid params   |
| -32603     | Internal error   |

### MCP Custom Error Codes

| Error Code | Meaning            | Description                       |
| ---------- | ------------------ | --------------------------------- |
| -32001     | Request timeout    | Server processing took too long   |
| -32002     | Resource not found | Requested resource URI is invalid |

### Tool-Level Errors

Business errors during tool execution do not use JSON-RPC error; instead, they are conveyed via the `isError` flag in the normal response:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      { "type": "text", "text": "Order ORD-001 does not exist or has been cancelled" }
    ],
    "isError": true
  }
}
```

This design allows the AI model to see the error message and adjust its behavior accordingly (for example, retrying with a different order ID).

***

**Next Chapter**: [Transport Layer](/en/book-5/ch3-transport) — Detailed explanation of stdio and Streamable HTTP transport methods
