Agent Ready Academy
Module 6: MCP — Model Context Protocol

MCP Architecture

Servers, clients, tools, resources, and the protocol flow

~12 min read

Overview

Understanding how the pieces of MCP fit together is essential before you configure or build servers. This lesson breaks down the architecture: the relationship between hosts, clients, and servers; the lifecycle of an MCP connection; the message format that makes it all work; and the two transport mechanisms that carry messages between components. By the end, you will have a clear mental model of how an agent's request becomes a tool call and how the result flows back.

The Big Picture

An MCP system has three main components that form a clear hierarchy:

MCP architecture hierarchy: the Host Application contains a Language Model and an MCP Client (with Connection Manager). The MCP Client communicates via JSON-RPC over stdio or SSE with multiple MCP Servers (GitHub, Database, Custom).

The host application is the program you interact with -- Claude Code, Cursor, or a custom agent. The host contains the language model and the user interface. It is the outermost boundary.

The MCP client lives inside the host. It manages one or more connections to MCP servers. When the language model decides it needs to call a tool, the client is responsible for routing that call to the correct server, sending the request, and returning the response. A single host can have many clients, each connected to a different server, though in practice most implementations use one client that manages multiple server connections.

The MCP server is a standalone process that wraps an external service and exposes it through the MCP protocol. A GitHub MCP server translates MCP tool calls into GitHub API requests. A database MCP server translates them into SQL queries. The server handles authentication, error handling, and data transformation for its specific domain.

Client-Server Communication

The communication between client and server follows a strict pattern built on JSON-RPC 2.0, a lightweight remote procedure call protocol. Every message is a JSON object that falls into one of three categories:

  • Requests -- messages that expect a response (identified by an id field)
  • Responses -- answers to requests (carrying the same id)
  • Notifications -- one-way messages that do not expect a response

Here is what a typical tool call looks like at the wire level:

Tool call sequence: the agent tells the MCP client to call search_issues. The client sends a JSON-RPC request to the MCP server. The server calls the GitHub API. The API response flows back through the server, client, and to the agent.

The agent never talks directly to GitHub. It talks to the MCP client, which talks to the MCP server, which talks to GitHub. Each layer has a single, well-defined responsibility.

The Connection Lifecycle

An MCP connection goes through four phases: initialization, operation, and shutdown, with an optional capability negotiation step.

MCP connection lifecycle in four phases: Phase 1 Initialize — client and server exchange protocol versions and capabilities. Phase 2 Discovery — client requests tools/list and resources/list, server responds with available tools and their schemas. Phase 3 Operation — client calls tools and reads resources as needed. Phase 4 Shutdown — client closes the connection.

Phase 1 -- Initialize. The client sends an initialize request containing its protocol version, supported capabilities, and identity. The server responds with its own protocol version, capabilities, and identity. The client then sends an initialized notification to confirm the handshake is complete. This is where the two sides agree on what they can do together.

Phase 2 -- Discovery. The client asks the server what it offers by calling tools/list, resources/list, and optionally prompts/list. The server responds with descriptions and schemas for each item. This is how the agent learns what tools are available -- their names, descriptions, and input parameters.

Phase 3 -- Operation. The agent operates normally. When the language model decides to use a tool, the client sends a tools/call request. When it needs data, the client sends a resources/read request. The server processes each request and returns results. This phase can last as long as the session is active.

Phase 4 -- Shutdown. The client closes the connection. For stdio transport, this means terminating the server process. For SSE transport, this means closing the HTTP connection.

Transport Mechanisms

MCP supports two ways to carry messages between client and server: stdio and HTTP with Server-Sent Events.

Stdio Transport

With stdio transport, the MCP server runs as a child process of the host application. The client writes JSON-RPC messages to the server's standard input (stdin) and reads responses from its standard output (stdout). Each message is a single line of JSON terminated by a newline.

Stdio transport: the MCP Client in the host process sends JSON-RPC requests via stdin to the MCP Server running as a child process, and reads JSON-RPC responses from the server's stdout.

Stdio is the most common transport for local development. It is simple, requires no network configuration, and provides natural process lifecycle management -- when the host exits, the child process exits too. Claude Code and most desktop MCP clients use stdio by default.

HTTP with SSE Transport

With SSE transport, the MCP server runs as an HTTP server. The client connects via HTTP, and the server uses Server-Sent Events to push messages back to the client. This transport is designed for remote servers, multi-client scenarios, and production deployments.

SSE transport: the MCP Client on the local machine sends HTTP POST requests to the MCP Server on a remote server, and receives responses back via a Server-Sent Events stream.

SSE transport is appropriate when the server needs to run on a different machine, when multiple clients need to connect to the same server, or when you need to deploy the server behind a load balancer or API gateway.

When to use which: Start with stdio for local development and single-user scenarios. Move to SSE when you need remote access, centralized servers, or multi-tenant deployments.

Capability Negotiation

Not every server supports every feature, and not every client needs every feature. During initialization, both sides advertise their capabilities -- a structured declaration of what they support.

A server might advertise:

  • tools -- it exposes callable tools
  • resources -- it exposes readable resources (with optional subscribe support for real-time updates)
  • prompts -- it exposes prompt templates
  • logging -- it can emit structured log messages

A client might advertise:

  • roots -- it can tell the server about workspace directories
  • sampling -- it can ask the language model to generate text on the server's behalf

This negotiation ensures that both sides have a shared understanding of what is possible. A client will not try to list tools from a server that did not advertise the tools capability. A server will not try to use sampling if the client did not offer it.

How the Agent Sees MCP

From the language model's perspective, MCP tools look identical to any other tools. During the discovery phase, the client collects tool descriptions and input schemas from all connected MCP servers and presents them to the model as available functions. The model does not know or care whether a tool is built into the agent or provided by an MCP server.

The language model's unified view of tools: built-in tools (read_file, search_code) and MCP tools (create_issue from GitHub, run_query from Database, send_message from Slack) appear identically — the model does not distinguish between them.

This transparency is a key design principle. The model reasons about create_issue the same way it reasons about read_file. The fact that one goes through MCP and the other is a native function is invisible at the reasoning layer. This means adding new capabilities via MCP does not require retraining or fine-tuning the model -- you just connect a new server.

The Schema Contract

Every MCP tool declares an input schema using JSON Schema. This schema serves three purposes:

  • For the model -- it describes what arguments the tool accepts, so the model can construct valid calls
  • For the client -- it enables input validation before sending the request to the server
  • For the developer -- it serves as self-documenting API reference

A well-written tool schema includes not just the structure of the input, but descriptions of each parameter, required fields, and constraints. The better the schema, the more accurately the model will use the tool.

Putting It All Together

Here is the complete flow when an agent uses an MCP tool, from human request to final result:

Complete MCP flow: human asks to find open bugs. The agent passes available tools to the language model. The model decides to call search_issues. The MCP client routes the call to the GitHub server, which calls the GitHub API. Results flow back through each layer. The model synthesizes a natural language summary for the human.

The human asks a question. The model decides it needs to search for issues. The MCP client routes the request to the GitHub MCP server. The server calls the GitHub API. The result flows back up through each layer. The model synthesizes a natural language response. The human sees the answer.

Every step in this chain is standardized by MCP, except the external API call (which is the server's responsibility) and the model's reasoning (which is the host's responsibility).

Summary

The MCP architecture is built on a clear separation of concerns: the host manages the user experience and language model, the MCP client manages connections and message routing, and MCP servers wrap external services in a standard interface. Communication uses JSON-RPC 2.0 over either stdio (for local servers) or HTTP with SSE (for remote servers). The connection lifecycle follows four phases -- initialize, discover, operate, and shut down -- with capability negotiation ensuring both sides agree on supported features. From the model's perspective, MCP tools are indistinguishable from built-in tools, making the protocol transparent at the reasoning layer. In the next lesson, we will put this architecture to work by configuring and using existing MCP servers.

Check Your Understanding

Question 1 of 4

What are the two transport mechanisms MCP supports?