Title: Lecture 9 — Inside the Host-Client-Server Model
Course: AIINFRA 300: Agentic AI & the Model Context Protocol (MCP) > Section: Week 09 — MCP Architecture Deep Dive

📖 Lecture — Inside the Host-Client-Server Model

By now you've built REST integrations, containerized services, and cloud deployments, so it's natural to size up MCP as "just another API." Resist that instinct — it's the single most common misconception about this protocol, and it will cause real design mistakes if you carry it into your capstone. This week we open up MCP's architecture so you can see exactly why it behaves differently, and exactly what that buys you. Where the shape comes from. MCP is modeled on the Language Server Protocol (LSP), the protocol that lets an editor like VS Code talk to a Python or Rust language backend without either side knowing the other's internals. LSP proved that a clean, stateful, capability-negotiated protocol between a "frontend" and a "backend" service could scale across dozens of editors and dozens of languages, each pair talking over an isolated connection. MCP applies that same pattern to AI applications that need tools, data, and reusable prompts. The three tiers. A Host is the AI application the user actually opens — Claude Desktop, Cursor, or a custom agent runtime you build for your capstone. The Host doesn't talk to servers directly. Instead, for every MCP server it wants to use, the Host creates a dedicated Client, and each Client maintains exactly one 1:1 connection to exactly one Server. If a Host connects to three servers — say, a filesystem server, a database server, and a Notion server — it instantiates three separate Client objects, each with its own connection state, its own negotiated capabilities, and its own message stream. Nothing is shared between them.

Tier | Role | Example
Host | The AI application the user interacts with; owns the LLM conversation and orchestrates Clients | Claude Desktop, Cursor, a custom agent app
Client | A 1:1 connector living inside the Host, one per Server | The Notion client instance inside Claude Desktop
Server | An independent process exposing Tools, Resources, and Prompts | A local filesystem server, a Notion MCP server

Two layers, cleanly separated. MCP splits concerns into a data layer and a transport layer. The data layer defines the actual protocol: JSON-RPC 2.0 messages that describe the connection lifecycle, the three primitives, and notifications. The transport layer is just how those bytes get from one process to another — stdio for a server running as a local subprocess, or Streamable HTTP (with optional SSE for streaming) for a server running remotely. This is the second misconception worth naming directly: MCP is not tied to one transport, and it is not tied to one model or vendor. The exact same JSON-RPC message — same method names, same shapes — is what flows whether the server sits on your laptop or across the internet. MCP also deliberately says nothing about how the Host uses its LLM; that's the Host's business, not the protocol's. Stateful, not stateless. Unlike a REST call, an MCP connection is not fire-and-forget. Every session opens with an initialize handshake: the Client and Server exchange protocol versions and declare their capabilities (which primitives they support, whether they support things like sampling or elicitation) before a single tool is ever called. Only after this handshake completes — and the client sends an initialized notification — does the session move into normal operation. This is why treating MCP as a "universal API router" is dangerous: a REST call can be retried statelessly from anywhere, but an MCP session carries negotiated state. Routing many unrelated one-off integrations through a single shared MCP layer can quietly turn that layer into a single point of failure, when a plain REST call would have been simpler and more resilient. The three primitives. Once initialized, a Server exposes up to three kinds of primitives, each with a consistent discovery/retrieval pattern:

Primitive | Who controls it | Discovery | Retrieval/Execution
Tools | Model-controlled executable actions | tools/list | tools/call
Resources | Application-driven contextual data | resources/list | resources/read
Prompts | Reusable interaction templates | prompts/list | prompts/get

On the Client side, the Host can expose complementary capabilities back to the Server: Sampling (letting a server request an LLM completion through the Host), Elicitation (letting a server ask the user a clarifying question mid-task), and Logging. Where the spec is headed. The November 2025 MCP spec update pushed beyond simple synchronous tool calls, adding support for secure, long-running, governed, asynchronous workflows — the kind of durable, auditable operations production systems actually need, rather than everything blocking on a single request/response round trip. In practice. You'll build servers with the official MCP Python SDK (1.2.0+), which absorbed FastMCP in 2024. FastMCP's ergonomic decorator style is now estimated to power roughly 70% of all MCP servers across every language, which is why it's the natural entry point for the lab.