Skip to main content

MCP Protocol Reference

The Model Context Protocol (MCP) is a JSON-RPC 2.0 based protocol for communication between AI clients and tool servers.

Protocol Overview

MCP uses JSON-RPC 2.0 for all messages:

// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}

// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [...]
}
}

// Error
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32600,
"message": "Invalid request"
}
}

Message Types

Requests

Requests have an id and a method:

{
"jsonrpc": "2.0",
"id": "unique-id",
"method": "method/name",
"params": { ... }
}

Responses

Responses contain either result or error:

// Success
{
"jsonrpc": "2.0",
"id": "unique-id",
"result": { ... }
}

// Error
{
"jsonrpc": "2.0",
"id": "unique-id",
"error": {
"code": -32000,
"message": "Error description",
"data": { ... } // Optional
}
}

Notifications

Notifications have no id (no response expected):

{
"jsonrpc": "2.0",
"method": "notifications/event",
"params": { ... }
}

Standard Methods

Initialize

Initialize the MCP session:

// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "1.0",
"clientInfo": {
"name": "My Client",
"version": "1.0.0"
},
"capabilities": {
"tools": true,
"resources": true
}
}
}

// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "1.0",
"serverInfo": {
"name": "MCP Server",
"version": "1.0.0"
},
"capabilities": {
"tools": { "supported": true },
"resources": { "supported": true }
}
}
}

tools/list

List available tools:

// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}

// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "query",
"description": "Execute a SQL query",
"inputSchema": {
"type": "object",
"properties": {
"sql": {
"type": "string",
"description": "The SQL query to execute"
}
},
"required": ["sql"]
}
}
]
}
}

tools/call

Call a specific tool:

// Request
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "query",
"arguments": {
"sql": "SELECT * FROM users LIMIT 10"
}
}
}

// Response
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "id | name | email\n1 | Alice | alice@example.com\n..."
}
]
}
}

resources/list

List available resources:

// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/list"
}

// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resources": [
{
"uri": "file:///workspace/README.md",
"name": "README.md",
"mimeType": "text/markdown"
}
]
}
}

resources/read

Read a specific resource:

// Request
{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/read",
"params": {
"uri": "file:///workspace/README.md"
}
}

// Response
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"contents": [
{
"uri": "file:///workspace/README.md",
"mimeType": "text/markdown",
"text": "# My Project\n\nThis is the README..."
}
]
}
}

prompts/list

List available prompts:

// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "prompts/list"
}

// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"prompts": [
{
"name": "explain-code",
"description": "Explain a piece of code",
"arguments": [
{
"name": "code",
"description": "The code to explain",
"required": true
}
]
}
]
}
}

prompts/get

Get a specific prompt:

// Request
{
"jsonrpc": "2.0",
"id": 2,
"method": "prompts/get",
"params": {
"name": "explain-code",
"arguments": {
"code": "function foo() { return 42; }"
}
}
}

// Response
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "Please explain this code:\n\n```\nfunction foo() { return 42; }\n```"
}
}
]
}
}

Error Codes

Standard JSON-RPC Errors

CodeMessageDescription
-32700Parse errorInvalid JSON
-32600Invalid requestNot valid JSON-RPC
-32601Method not foundUnknown method
-32602Invalid paramsInvalid parameters
-32603Internal errorInternal server error

MCP-Specific Errors

CodeMessageDescription
-32000Server errorGeneric server error
-32001Resource not foundResource doesn't exist
-32002Tool not foundTool doesn't exist
-32003Permission deniedAccess denied

Gateway-Specific Handling

Request Wrapping

The gateway wraps MCP requests with server routing:

// Client sends to gateway
{
"server_id": "postgres",
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}

// Gateway forwards to server
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}

Response Passthrough

Responses are passed through unchanged:

// Server responds
{
"jsonrpc": "2.0",
"id": 1,
"result": { ... }
}

// Gateway returns same response
{
"jsonrpc": "2.0",
"id": 1,
"result": { ... }
}

Error Handling

The gateway may add its own errors:

// Server not found
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32001,
"message": "Server 'unknown' not found"
}
}

// Connection failed
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32000,
"message": "Failed to connect to server"
}
}

Implementation Notes

Message Parsing

#[derive(Debug, Serialize, Deserialize)]
pub struct McpMessage {
pub jsonrpc: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub method: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub params: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub result: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<McpError>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct McpError {
pub code: i32,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<serde_json::Value>,
}

ID Handling

The id field can be a string, number, or null:

// Handle various ID types
match &message.id {
Some(Value::Number(n)) => println!("Numeric ID: {}", n),
Some(Value::String(s)) => println!("String ID: {}", s),
Some(Value::Null) => println!("Null ID"),
None => println!("No ID (notification)"),
_ => println!("Invalid ID type"),
}

Content Types

MCP supports multiple content types in responses:

{
"content": [
{ "type": "text", "text": "Plain text content" },
{ "type": "image", "data": "base64...", "mimeType": "image/png" },
{ "type": "resource", "uri": "file:///path/to/file" }
]
}

Further Reading