Chapter 3: MCP Protocol Specification Explained

Haiyue
10min

Chapter 3: MCP Protocol Specification Explained

Learning Objectives

  1. Deep understanding of MCP protocol message formats
  2. Master request-response pattern and event flow
  3. Learn protocol version control and compatibility
  4. Understand error handling and exceptional situations
  5. Master protocol extension mechanisms

3.1 MCP Protocol Basics

Protocol Architecture Overview

// MCP protocol is based on JSON-RPC 2.0 with the following features:
interface MCPProtocolFeatures {
  // Transport layer support
  transport: {
    stdio: 'Standard input/output';
    websocket: 'WebSocket connection';
    http: 'HTTP long polling';
  };

  // Message format
  messageFormat: 'JSON-RPC 2.0';

  // Bidirectional communication
  bidirectional: true;

  // Streaming support
  streaming: boolean;

  // Protocol version
  version: '2024-11-05';
}

// Protocol version definition
const MCP_PROTOCOL_VERSION = '2024-11-05';

// Supported transport methods
enum TransportType {
  STDIO = 'stdio',
  WEBSOCKET = 'websocket',
  HTTP = 'http'
}

JSON-RPC 2.0 Basics

// JSON-RPC 2.0 basic message structure
interface JSONRPCMessage {
  jsonrpc: '2.0';  // Protocol version, must be '2.0'
  id?: string | number | null;  // Message ID, can be omitted for notifications
}

// Request message
interface JSONRPCRequest extends JSONRPCMessage {
  method: string;     // Method name
  params?: any;       // Parameters, can be object or array
  id: string | number; // Request ID, must exist
}

// Response message
interface JSONRPCResponse extends JSONRPCMessage {
  id: string | number | null; // Corresponding request ID
  result?: any;       // Success result
  error?: {           // Error information
    code: number;
    message: string;
    data?: any;
  };
}

// Notification message
interface JSONRPCNotification extends JSONRPCMessage {
  method: string;     // Method name
  params?: any;       // Parameters
  // Note: Notification messages don't have id field
}

3.2 MCP Message Types and Formats

Initialization Flow

The initialization process establishes the connection between client and server, negotiating capabilities and protocol versions.

// Initialize request/response interfaces
interface InitializeRequest {
  jsonrpc: '2.0';
  id: string | number;
  method: 'initialize';
  params: {
    protocolVersion: string;
    capabilities: ClientCapabilities;
    clientInfo: {
      name: string;
      version: string;
    };
  };
}

interface InitializeResponse {
  jsonrpc: '2.0';
  id: string | number;
  result: {
    protocolVersion: string;
    capabilities: ServerCapabilities;
    serverInfo: {
      name: string;
      version: string;
    };
    instructions?: string;
  };
}

Tools are the primary way for MCP to provide functionality. The protocol defines standard messages for listing and calling tools.

// List tools request/response
interface ListToolsRequest {
  jsonrpc: '2.0';
  id: string | number;
  method: 'tools/list';
  params?: {
    cursor?: string;
  };
}

interface ListToolsResponse {
  jsonrpc: '2.0';
  id: string | number;
  result: {
    tools: Array<{
      name: string;
      description?: string;
      inputSchema: JSONSchema;
    }>;
    nextCursor?: string;
  };
}

// Call tool request/response
interface CallToolRequest {
  jsonrpc: '2.0';
  id: string | number;
  method: 'tools/call';
  params: {
    name: string;
    arguments?: Record<string, any>;
  };
}

interface CallToolResponse {
  jsonrpc: '2.0';
  id: string | number;
  result: {
    content: Array<ContentItem>;
    isError?: boolean;
  };
}

Resources represent data that can be accessed by the AI model, such as files, database records, or API responses.

// List resources request/response
interface ListResourcesRequest {
  jsonrpc: '2.0';
  id: string | number;
  method: 'resources/list';
  params?: {
    cursor?: string;
  };
}

interface ListResourcesResponse {
  jsonrpc: '2.0';
  id: string | number;
  result: {
    resources: Array<{
      uri: string;
      name: string;
      description?: string;
      mimeType?: string;
    }>;
    nextCursor?: string;
  };
}

// Read resource request/response
interface ReadResourceRequest {
  jsonrpc: '2.0';
  id: string | number;
  method: 'resources/read';
  params: {
    uri: string;
  };
}

interface ReadResourceResponse {
  jsonrpc: '2.0';
  id: string | number;
  result: {
    contents: Array<{
      uri: string;
      mimeType?: string;
      text?: string;
      blob?: string;
    }>;
  };
}

3.3 Error Handling and Status Codes

MCP Error Codes

The protocol defines standard error codes for common error scenarios:

enum MCPErrorCode {
  // JSON-RPC standard errors
  PARSE_ERROR = -32700,
  INVALID_REQUEST = -32600,
  METHOD_NOT_FOUND = -32601,
  INVALID_PARAMS = -32602,
  INTERNAL_ERROR = -32603,

  // MCP-specific errors
  INVALID_TOOL = -32000,
  TOOL_EXECUTION_ERROR = -32001,
  RESOURCE_NOT_FOUND = -32002,
  RESOURCE_ACCESS_DENIED = -32003,
  PROMPT_NOT_FOUND = -32004,
  INVALID_PROMPT_ARGS = -32005
}

// Error response format
interface MCPErrorResponse {
  jsonrpc: '2.0';
  id: string | number | null;
  error: {
    code: MCPErrorCode;
    message: string;
    data?: {
      type?: string;
      description?: string;
      details?: any;
    };
  };
}

3.4 Protocol Version Control and Compatibility

Version Negotiation

The MCP protocol supports version negotiation during initialization to ensure client-server compatibility:

class MCPVersionManager {
  private readonly supportedVersions = ['2024-11-05', '2024-10-07'];
  private readonly currentVersion = '2024-11-05';

  isVersionSupported(clientVersion: string): boolean {
    return this.supportedVersions.includes(clientVersion);
  }

  getNegotiatedVersion(clientVersion: string): string | null {
    if (this.isVersionSupported(clientVersion)) {
      return clientVersion;
    }
    return this.supportedVersions[0]; // Return highest supported version
  }

  hasFeature(version: string, feature: string): boolean {
    const features = {
      '2024-11-05': ['streaming', 'subscriptions', 'list_changes'],
      '2024-10-07': ['basic_tools', 'basic_resources', 'basic_prompts']
    };
    return features[version]?.includes(feature) || false;
  }
}

3.5 Streaming and Batch Operations

Streaming Support

For long-running operations, MCP supports streaming responses to provide incremental updates:

// Streaming response
interface StreamingResponse {
  jsonrpc: '2.0';
  id: string | number;
  result: {
    stream: true;
    streamId: string;
  };
}

// Stream chunk notification
interface StreamChunk {
  jsonrpc: '2.0';
  method: 'notifications/stream/chunk';
  params: {
    streamId: string;
    chunk: {
      type: 'text' | 'image' | 'data';
      content: any;
      final?: boolean;
    };
  };
}

Batch Operations

The protocol supports batching multiple requests for efficiency:

// Batch request
interface BatchRequest {
  jsonrpc: '2.0';
  id: string | number;
  method: 'batch';
  params: {
    requests: Array<{
      method: string;
      params?: any;
      id: string | number;
    }>;
  };
}

// Batch response
interface BatchResponse {
  jsonrpc: '2.0';
  id: string | number;
  result: {
    responses: Array<{
      id: string | number;
      result?: any;
      error?: any;
    }>;
  };
}

3.6 Protocol Extension Mechanism

Experimental Features

MCP supports experimental features through the capabilities system:

interface ExperimentalFeatures {
  streaming?: {
    supported: boolean;
    maxStreams?: number;
  };

  batch?: {
    supported: boolean;
    maxBatchSize?: number;
  };

  customTransports?: {
    supported: boolean;
    transports: string[];
  };
}

class MCPExtensionManager {
  negotiateExtensions(clientCapabilities: any): ExperimentalFeatures {
    const experimental: ExperimentalFeatures = {};

    if (clientCapabilities.experimental?.streaming) {
      experimental.streaming = {
        supported: true,
        maxStreams: 10
      };
    }

    if (clientCapabilities.experimental?.batch) {
      experimental.batch = {
        supported: true,
        maxBatchSize: 100
      };
    }

    return experimental;
  }
}

Summary

Through this chapter, we have gained deep understanding of MCP protocol technical specifications:

  1. Protocol Basics: Bidirectional communication protocol based on JSON-RPC 2.0
  2. Message Types: Message formats for initialization, tools, resources, prompt templates
  3. Error Handling: Standardized error codes and handling mechanisms
  4. Version Control: Version negotiation and backward compatibility
  5. Advanced Features: Streaming, batch operations, protocol extensions

These specifications lay a solid foundation for developing robust and reliable MCP Servers. Next, we will learn how to develop specific tool functionality.

Extended Reading