Skip to main content

Module 2: Anatomy of MCP

Duration: ~20 minutes | Level: Beginner | Prerequisites: Module 1: Why MCP Exists


Four Actors, One Protocol

An MCP interaction involves four distinct roles. Getting these straight prevents endless confusion later, especially when terms like "client" and "server" appear in multiple layers.

1. The AI Model

The model, Claude Sonnet 4.6, GPT-5, Gemini, or any other LLM, is the reasoning engine. It doesn't know about MCP directly. What it knows is that certain tools are available, described in its context window. When the model decides a tool should be called, it produces a structured tool-call output. The host then handles the actual MCP communication.

The model is the consumer of capabilities. It reasons about which tool to call, constructs the arguments, and incorporates the returned results.

2. The Host

The host is the application the user interacts with: Claude Desktop, Cursor, a custom agent you built, or any other AI-enabled application. The host is responsible for:

  • Managing the conversation context
  • Feeding tool definitions into the model
  • Passing the model's tool calls to its MCP clients, which deliver them to the server that actually executes them
  • Managing user permissions for sensitive operations

The host contains an embedded MCP client (or multiple clients) that handle the protocol communication. Users typically interact with the host, not with MCP directly.

3. The MCP Client

The client is the MCP-protocol component embedded inside the host. It:

  • Establishes and maintains a connection to an MCP server
  • Establishes what the server supports: through revision 2025-11-25 with an initialize handshake at startup, and from 2026-07-28 by carrying its capabilities on every request (see below)
  • Sends tool calls, resource reads, and prompt requests to its server
  • Returns results to the host (which passes them to the model)

One host can contain multiple MCP clients. Each client maintains a connection to one MCP server. This is how Claude Desktop can simultaneously use a filesystem server, a GitHub server, and a database server.

4. The MCP Server

The server is what you build. It's a process that:

  • Runs your business logic (querying a DB, calling an API, reading files)
  • Exposes that logic as structured MCP primitives: Tools, Resources, and Prompts
  • Communicates with the client using the MCP protocol
  • Handles requests and returns results

The server is where you spend your implementation time. The rest, the model, the host, the client, is usually provided by the AI application you're integrating with.


A Concrete Example: Database Query Tool

Let's make this concrete. Suppose you build an MCP server that lets an AI query your PostgreSQL database.

What you build: An MCP server process that:

  1. Connects to PostgreSQL on startup
  2. Exposes a run_query tool with a sql string parameter
  3. On tool call: validates the SQL, executes it, returns the results

What happens at runtime:

  1. The user opens Cursor and says "Show me the top 10 customers by revenue"
  2. Cursor's embedded MCP client connects to your server (if not already connected)
  3. Cursor feeds the run_query tool definition into the model's context
  4. The model produces a tool call: run_query(sql: "SELECT customer_id, SUM(amount) FROM orders GROUP BY 1 ORDER BY 2 DESC LIMIT 10")
  5. The MCP client sends this call to your server over the protocol
  6. Your server executes the SQL against PostgreSQL
  7. The results come back through the protocol to the client, to the model
  8. The model formats a natural-language response for the user

What the user sees: An accurate, data-backed answer without copy-pasting any query results into the chat.


Server Multiplicity: One Host, Many Servers

One of MCP's most powerful features is that a single host can connect to multiple servers simultaneously. Each server is a separate process with its own set of capabilities.

The model sees all the tools from all connected servers as if they were one unified capability set. It doesn't know or care which server handles which tool; that routing is the host's job, which passes each call to the client connected to the server that exposes that tool.

This composability is fundamental to MCP's value proposition: each server is small and focused, doing one thing well. Servers are reusable across different hosts and compositions.


Server Lifecycle

Understanding when MCP processes run clarifies a lot of design questions:

Local stdio servers: Launched as a child process by the host when the user connects, run for the duration of the session, terminated when the user disconnects or closes the host application. They are personal, only the local user's host connects to them.

Remote HTTP servers: Persistent processes that multiple clients can connect to simultaneously. They run as long-lived services (in a container, on a VM, as a serverless function). Multiple users can connect through different host applications.

The lifecycle choice affects everything: connection management, authentication, state management, resource usage. We'll cover this in detail in the transports module.


Statelessness: Why There Is No Session

Revision 2026-07-28 removed something most MCP material still takes for granted: the session.

What the protocol used to do. Through revision 2025-11-25, every connection had three phases. Initialisation: the client sent initialize with its protocol version and capabilities, the server replied with its own, and the client acknowledged with a notifications/initialized notification. Operation: the bulk of the connection, with the negotiated feature set fixed for its lifetime; either party could send notifications, and servers could send requests back to the client. Shutdown: either party closed the transport. The handshake existed to settle two questions once, up front, rather than on every message: which protocol version are we speaking, and which optional features does the other side support.

What it does now. Settling those questions per connection makes the connection stateful, and connection-scoped state is awkward for load balancers, serverless platforms and horizontally scaled deployments, all of which would rather route any request to any instance. So 2026-07-28 deleted the model. The specification's lifecycle page was replaced by one on versioning and compatibility, and the base protocol now opens with this:

The Model Context Protocol (MCP) is a stateless protocol: all the information needed to process a request is contained in the request itself. A server processes each request independently; no state should be inferred from previous requests, even those on the same connection or stream.

Protocol version and client capabilities travel in the _meta field of every request (io.modelcontextprotocol/protocolVersion and io.modelcontextprotocol/clientCapabilities, both required; io.modelcontextprotocol/clientInfo is recommended). A server that does not implement the requested version answers that request with UnsupportedProtocolVersionError (-32022), listing the versions it does support, and the client retries with one of them. Any state that has to outlive a single request must be referenced by an explicit identifier the client passes back each time. The spec is blunt about the consequence: an open connection, a running stdio process included, is not a conversation and not a session.

Servers no longer send requests back to the client either. When a server needs sampling, roots or user input, it returns a result with resultType: "input_required", and the client retries the original request carrying the answers.

Servers MUST implement one new method, server/discover, which reports their supported versions, capabilities, identity and an optional instructions string. Clients MAY call it first to pick a version and to show the user what a server offers, but are free to invoke any request cold and handle the version error if one comes back.

Why you will still meet the handshake

The older revisions have not been switched off. The spec calls them legacy, calls the per-request model modern, and defines how a dual-era implementation serves both. The Java MCP SDK 2.0.0 implements 2025-11-25, which is what the Java code on this site targets. Module 6 walks through the legacy handshake in detail.


Key Takeaways

  • Host = the application users interact with (Claude Desktop, Cursor, your custom agent)
  • Client = the MCP protocol component embedded in the host
  • Server = what you build, your business logic wrapped in MCP
  • Model = the AI reasoning engine, which sees only tool definitions and results
  • One host can connect to multiple servers; each server is a separate process
  • Servers expose three kinds of primitives: Tools, Resources, and Prompts

In the next module, we'll go deep on those three primitives, what each one is for and when to use which.


Further Reading