Chapter 1: MCP Architecture — Hosts, Clients, and Servers


Before writing a single line of code, it helps to understand what MCP actually is at the protocol level. This chapter covers the three roles in an MCP system, the three primitive types servers can expose, and how messages flow between components.


The Three Roles

Every MCP interaction involves three components:

Host

The Host is the application the user interacts with. Claude Desktop is a host. So is Claude Code, Cursor, and Windsurf. The host is responsible for:

The host owns the overall experience. It decides which MCP servers are available and presents their capabilities to the AI model.

Client

The Client lives inside the Host. It is the component that speaks the MCP protocol on the host’s behalf. Each host maintains one client per server connection.

The client:

In practice, when you configure Claude Desktop with an MCP server, Claude Desktop spawns a client connection to that server automatically. You rarely interact with the client directly.

Server

The Server is what you build. It is a process that:

Your server can be a local Python script, a remote HTTP service, or anything in between. It is isolated from the AI model — it communicates only with the client, never directly with the LLM.


The Communication Flow

Here is what happens when an AI assistant calls a tool on your server:

User ──► Host (e.g. Claude Desktop)
           │
           ▼
         Client ──► Server (your MCP server)
           │              │
           │    request   │
           │ ──────────── ►
           │              │
           │    response  │
           │ ◄────────────
           ▼
         AI Model ◄── Host presents result
  1. The user asks a question or gives an instruction
  2. The AI model (inside the Host) decides to call a tool
  3. The Host/Client sends a tools/call request to your server
  4. Your server executes the tool and returns the result
  5. The result is passed back to the AI model
  6. The model incorporates the result into its response

The Protocol: JSON-RPC 2.0

MCP messages are JSON-RPC 2.0. Every message is a JSON object with:

A tool call looks like this:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": { "city": "Paris" }
  }
}

And the server responds:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      { "type": "text", "text": "Paris: 18°C, partly cloudy" }
    ]
  }
}

You typically never write these JSON messages by hand — the Python SDK handles serialization for you.


The Three Primitives

MCP defines three types of capabilities a server can expose:

Tools

Tools are functions the AI can call. They take structured input and return structured output. Examples:

Tools are the most commonly used primitive. They are how the AI takes action in the world.

Resources

Resources are data the AI can read. They are identified by URIs and can be static or dynamic. Examples:

Resources are analogous to GET endpoints in a REST API. They return data without side effects.

Prompts

Prompts are reusable message templates. They accept arguments and return a sequence of messages the AI can use as context or instructions. Examples:

Prompts are optional but useful for standardizing common workflows.


Capability Negotiation

When a client connects to a server, they perform a handshake:

  1. Client sends initialize with its protocol version and capabilities
  2. Server responds with its protocol version and what it supports
  3. Client sends initialized to confirm
  4. Both sides now know what the other can do

After initialization, the client can call tools/list, resources/list, and prompts/list to discover exactly what the server offers. The AI model uses this information to decide which tools are available in a given conversation.


Server Lifecycle

A typical server lifecycle:

  1. Startup — the host launches your server process (or connects to a running HTTP server)
  2. Initialization — capability handshake
  3. Discovery — client lists tools/resources/prompts
  4. Operation — client makes requests as the AI calls tools or reads data
  5. Shutdown — the host terminates the connection (sends a shutdown notification)

For stdio servers, startup and shutdown are tied to the process lifecycle. For HTTP servers, the connection is managed separately from the process.


Key Takeaways


← Introduction Table of Contents Chapter 2: Your First MCP Server →