📖 MCP Basics

Master the Model Context Protocol from the ground up. Learn the lifecycle, messages, and transport layer.

🔌 What is the Model Context Protocol?

The Model Context Protocol (MCP) is an open standard that provides a unified way for AI models to interact with external tools, data sources, and APIs. Think of it as a universal adapter for AI agents.

🎯 Key Benefits

  • Standardized: Write once, use anywhere
  • Secure: Controlled execution context
  • Composable: Mix and match tools
  • Open: No vendor lock-in

🛠️ Core Components

  • Server: Exposes tools
  • Client: Invokes tools
  • Transport: Communication layer
  • Protocol: JSON-RPC 2.0 messages
💡 Key Insight: MCP is to AI tools what REST is to web APIs - a standard protocol everyone can use.

🔄 The MCP Lifecycle

Every MCP interaction follows a predictable lifecycle. Understanding this is crucial for building reliable agents.

1

Connection Established

Client connects to MCP server via transport (stdio, SSE, WebSocket)

2

Initialize Handshake

Client and server exchange capabilities and protocol versions

3

Tool Discovery

Client requests tools/list to see available tools

4

Tool Invocation

Client sends tools/call with arguments to execute tool

5

Result Returned

Server executes tool and sends result back to client

🤝 1. Initialize

The initialization phase establishes the connection and negotiates capabilities.

Request (from Client)

{
  "jsonrpc": "2.0",
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {}
    },
    "clientInfo": {
      "name": "my-agent",
      "version": "1.0.0"
    }
  },
  "id": 1
}

Response (from Server)

{
  "jsonrpc": "2.0",
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {}
    },
    "serverInfo": {
      "name": "my-mcp-server",
      "version": "1.0.0"
    }
  },
  "id": 1
}
⚠️ Important: Both client and server must agree on a protocol version. Mismatched versions will cause connection failures.

📋 2. Tools/List

After initialization, the client discovers what tools are available by calling tools/list.

Request

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

Response

{
  "jsonrpc": "2.0",
  "result": {
    "tools": [
      {
        "name": "calculate",
        "description": "Perform basic mathematical operations",
        "inputSchema": {
          "type": "object",
          "properties": {
            "operation": {
              "type": "string",
              "enum": ["add", "subtract", "multiply", "divide"],
              "description": "The operation to perform"
            },
            "a": {
              "type": "number",
              "description": "First number"
            },
            "b": {
              "type": "number",
              "description": "Second number"
            }
          },
          "required": ["operation", "a", "b"]
        }
      }
    ]
  },
  "id": 2
}

Tool Schema Explained

  • name: Unique identifier for the tool
  • description: What the tool does (helps AI decide when to use it)
  • inputSchema: JSON Schema defining required/optional parameters

⚡ 3. Tools/Call

When the AI agent decides to use a tool, it sends a tools/call request.

Request

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "calculate",
    "arguments": {
      "operation": "multiply",
      "a": 42,
      "b": 13
    }
  },
  "id": 3
}

Response (Success)

{
  "jsonrpc": "2.0",
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Result: 546"
      }
    ]
  },
  "id": 3
}

Response (Error)

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32602,
    "message": "Invalid params",
    "data": "Parameter 'operation' must be one of: add, subtract, multiply, divide"
  },
  "id": 3
}
💡 Pro Tip: Always return detailed error messages. They help the AI agent understand what went wrong and try again with corrected parameters.

🌊 Streaming Transport

MCP supports multiple transport mechanisms for client-server communication:

📡 Stdio

Standard input/output pipes

Use when: Local process communication

🔄 SSE

Server-Sent Events over HTTP

Use when: Web-based clients, firewalls

⚡ WebSocket

Bidirectional real-time connection

Use when: Two-way streaming needed

Example: SSE Transport Setup

// Server side
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";

app.get("/mcp/sse", async (req, res) => {
  const transport = new SSEServerTransport("/mcp/message", res);
  await server.connect(transport);
});

// Client side
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";

const transport = new SSEClientTransport(
  new URL("http://localhost:3000/mcp/sse")
);
await client.connect(transport);
⚠️ Keep-Alive: For long-running operations, implement keep-alive pings to prevent transport timeouts.

📚 Quick Reference

Method Purpose Required
initialize Establish connection and capabilities ✅ Yes
tools/list Discover available tools ✅ Yes
tools/call Execute a tool ✅ Yes
resources/list List available resources ❌ Optional
prompts/list List available prompts ❌ Optional

Ready to Build? 🚀

Now that you understand MCP, start building your first tool!