← Back to Home
πŸ›οΈ

MCP Architecture: Hosts, Clients & Servers

The three roles and the message flow that let a model discover and call your tools.

⏱10 min readπŸ“šDevOps Fundamentals

MCP has a clean architecture built from three roles β€” host, client, and server β€” talking over well-defined transports. Understanding this model makes building and debugging MCP integrations straightforward.


🎯 Learning Objectives


The Three Roles

Role What it is Example
Host The AI application the user interacts with; contains the model An AI IDE, a chat assistant, a desktop app
Client A connector inside the host, one per server, that speaks MCP The host’s MCP client for the GitHub server
Server An external program exposing tools/resources/prompts A GitHub server, a Postgres server

The relationship: one host runs one or more clients, and each client maintains a dedicated 1:1 connection to one server.

text
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Host (AI app) ─────────────────┐
β”‚   Model                                          β”‚
β”‚     β”‚                                            β”‚
β”‚   β”Œβ”€β”΄β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚   β”‚ Client A β”‚   β”‚ Client B β”‚   β”‚ Client C β”‚      β”‚
β”‚   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β–Ό              β–Ό              β–Ό
  GitHub server  Postgres server  Files server

πŸ’‘ Why one client per server?

Each client-server pair is an isolated, stateful session. This keeps servers independent β€” one crashing or misbehaving doesn’t affect the others β€” and lets the host manage permissions per connection.


Transports

MCP messages (JSON-RPC 2.0) travel over one of two main transports:

Transport Use case How
stdio Local server on the same machine Host launches the server as a subprocess; they exchange messages over stdin/stdout
Streamable HTTP (with SSE) Remote server over a network HTTP requests plus server-sent events for streaming responses

Local developer tools usually use stdio (simple, no network); hosted/shared servers use HTTP.


The Connection Lifecycle

A client and server go through a defined handshake before any tools are called:

text
1. initialize      client β–Ά server   "here's my protocol version + capabilities"
2. initialize      server β–Ά client   "here's mine"
3. initialized     client β–Ά server   "ready"
 ── now the session is live ──
4. tools/list      client β–Ά server   "what tools do you have?"
5. tools/call      client β–Ά server   "run create_issue with these args"
6. (result)        server β–Ά client   "here's the result"

Step 4 is capability discovery β€” the client asks the server what it offers, so the model can be told which tools are available without hardcoding anything.


What a Tool Definition Looks Like

When the client calls tools/list, the server returns each tool’s name, description, and an input schema. The description and schema are what the model reads to decide when and how to call it:

json
{
"name": "create_issue",
"description": "Create a new issue in a GitHub repository",
"inputSchema": {
  "type": "object",
  "properties": {
    "repo":  { "type": "string", "description": "owner/name" },
    "title": { "type": "string" },
    "body":  { "type": "string" }
  },
  "required": ["repo", "title"]
}
}

⚠ Descriptions are the model's instructions

The model chooses tools based on their names and descriptions. Vague descriptions lead to misuse; clear, specific ones (β€œCreate a GitHub issue; use only when the user asks to file a bug”) make the model reliable. Treat tool descriptions as prompt engineering.


A Full Message Flow

Putting it together, when a user asks the assistant to β€œfile a bug about the login crash”:

text
User β–Ά Host: "file a bug about the login crash"
Host  β–Ά Model: prompt + available tools (from tools/list)
Model β–Ά Host:  "call create_issue(repo=acme/app, title=Login crash)"
Host  β–Ά Client β–Ά Server: tools/call create_issue {...}
Server β–Ά GitHub API: creates the issue
Server β–Ά Client β–Ά Host: { url: "https://github.com/.../issues/42" }
Host  β–Ά Model β–Ά User: "Done β€” filed issue #42."

The model decides what to do; the host mediates and enforces permissions; the server does the actual work.


πŸ§ͺ Hands-on Lab

πŸ“

Map the Roles

In this setup, name the host, the client(s), and the server(s): β€œAn AI coding assistant connects to a local filesystem server (launched as a subprocess) and a remote Jira server over HTTP.”


🧠 Knowledge Check

Knowledge Check

What is the relationship between MCP clients and servers?

Knowledge Check

What does the tools/list step accomplish?


πŸ’Ό Interview Preparation

Interview Q&A

Explain the MCP architecture and why it separates host, client, and server.


Summary

You now understand MCP’s host-client-server model, its transports, the connection lifecycle, and capability discovery. With the architecture clear, let’s build one: next you’ll create your first MCP server exposing a tool.

Up Next

Building Your First MCP Server

You've mastered this lesson. Continue your journey to becoming a DevOps Engineer.

Start Next Lesson→