Module 2: MCP Architecture Overview
Understanding the Building Blocks
Before you can configure or build MCP integrations, you need to understand how the pieces fit together. This module gives you that architectural foundation. We'll cover the core components, how they communicate, and how data flows through the system.
By the end of this module, when you see an MCP configuration file or encounter an error, you'll understand what's actually happening under the hood.
The Client-Server Model
MCP follows a client-server architecture, but it might not work exactly how you expect:
MCP Client (Host)
- The application that talks to the AI model
- Examples: Claude Desktop, Claude Code, custom AI applications
- Initiates connections to MCP servers
- Decides when to use available tools and resources
- Presents capabilities to the AI model
MCP Server
- Exposes specific capabilities (tools, resources, prompts)
- Runs as a separate process
- Can be local or remote
- Stateless between requests (usually)
- Examples: filesystem server, GitHub server, database server
Key insight: The AI model doesn't directly talk to MCP servers. The client application mediates all communication. When Claude uses a tool, here's what actually happens:
User → Claude (AI) → Claude Desktop (Client) → MCP Server → External System
↓
User ← Claude (AI) ← Claude Desktop (Client) ← Response
The client handles connection management, security, and translation between the AI's tool calls and MCP protocol messages.
The Three Primitives
MCP organizes capabilities into three types:
1. Resources
Resources represent data that the AI can read. They're identified by URIs and can be:
- Files:
file:///path/to/document.md - Database records:
postgres://database/table/123 - API responses:
api://service/endpoint - Any custom scheme you define
Resources are read-only by design. They represent the current state of something. When the AI needs to read a file, it requests the resource. When it needs to modify something, it uses a tool.
// Example resource definition
{
uri: "file:///project/README.md",
name: "Project README",
mimeType: "text/markdown",
description: "Main project documentation"
}
2. Tools
Tools are functions that the AI can execute. They take parameters and return results. Unlike resources, tools can have side effects - they can modify data, send messages, or trigger actions.
// Example tool definition
{
name: "create_file",
description: "Create a new file with the specified content",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "File path" },
content: { type: "string", description: "File content" }
},
required: ["path", "content"]
}
}
The AI model sees the tool name, description, and input schema. When it decides to use a tool, the client validates the parameters against the schema and sends the request to the server.
3. Prompts
Prompts are pre-built templates that guide AI behavior. They're less commonly used than resources and tools but valuable for standardizing common operations.
// Example prompt definition
{
name: "code_review",
description: "Review code for bugs and improvements",
arguments: [
{ name: "language", description: "Programming language", required: true },
{ name: "code", description: "Code to review", required: true }
]
}
Prompts can include system messages, examples, and structured formats that help the AI perform specific tasks consistently.
Transport Layers
MCP needs a way to send messages between clients and servers. The protocol supports multiple transports:
Standard Input/Output (stdio)
The most common transport for local servers. The client launches the server as a subprocess and communicates through stdin/stdout pipes.
Claude Desktop → [launches process] → MCP Server
stdin → messages → stdout
Advantages:
- Simple to implement
- Works on all platforms
- No network configuration needed
- Secure by default (local only)
Server-Sent Events (SSE)
For remote servers, SSE provides a web-based transport:
Client → HTTP POST → Server (for requests)
Client ← SSE stream ← Server (for responses)
Advantages:
- Works over HTTP/HTTPS
- Can run on remote hosts
- Firewall friendly
- Good for hosted MCP services
Streamable HTTP
A newer transport option that uses standard HTTP with streaming support. Both request and response can be streamed, making it suitable for long-running operations.
The Message Protocol
MCP uses JSON-RPC 2.0 for message formatting. Every message follows this structure:
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": {
"path": "/path/to/file.txt"
}
}
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "File contents here..."
}
]
}
}
Notification (no response expected):
{
"jsonrpc": "2.0",
"method": "notifications/progress",
"params": {
"progressToken": "abc123",
"progress": 50,
"total": 100
}
}
Understanding this format helps when debugging. If something isn't working, you can often inspect the raw messages to see what's being sent and received.
Connection Lifecycle
When a client connects to a server, they go through a handshake:
1. Initialize
Client → initialize request (protocol version, capabilities)
Server → initialize response (server info, capabilities)
Client → initialized notification
2. Capability Discovery
Client → list resources/tools/prompts requests
Server → lists of available capabilities
3. Normal Operation
Client → tool calls, resource reads, etc.
Server → responses
4. Shutdown
Client → close connection
Server → cleanup and exit
The initialize phase is crucial. It establishes what protocol version both sides speak and what capabilities are available. If initialization fails, no communication happens.
Capability Negotiation
During initialization, both client and server declare their capabilities:
Client Capabilities:
roots: Can handle root directoriessampling: Can request AI completions from the serverexperimental: Support for experimental features
Server Capabilities:
resources: Server provides resources (and whether they support subscriptions)tools: Server provides toolsprompts: Server provides promptslogging: Server supports logging
This negotiation ensures both sides know what to expect. A client won't try to list resources if the server didn't declare resource capability.
Data Flow Example
Let's trace a complete interaction:
User asks: "What's in my README file?"
-
Claude (AI model) decides it needs to read a file and requests the
read_filetool -
Claude Desktop (client) receives the tool request:
- Validates the request against the tool schema
- Formats a JSON-RPC message
- Sends to the filesystem MCP server via stdin
-
Filesystem Server receives the request:
- Parses the JSON-RPC message
- Validates the file path is within allowed directories
- Reads the actual file from disk
- Formats the content as a response
- Sends response via stdout
-
Claude Desktop receives the response:
- Parses the JSON-RPC response
- Extracts the file content
- Returns it to Claude as tool result
-
Claude (AI model) receives the file content and formulates a response for the user
This all happens in milliseconds. The user just sees Claude answering their question.
Architecture Diagram
┌─────────────────────────────────────────────────────────┐
│ User Interface │
│ (Chat Interface) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Claude (AI Model) │
│ Reasoning, tool decisions, responses │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ MCP Client (Host) │
│ Claude Desktop / Claude Code / Custom Application │
│ - Manages server connections │
│ - Validates tool calls │
│ - Handles security/permissions │
└─────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ MCP Server 1 │ │ MCP Server 2 │ │ MCP Server 3 │
│ (Filesystem) │ │ (GitHub) │ │ (Database) │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
▼ ▼ ▼
Local Files GitHub API PostgreSQL
Security Boundaries
MCP has important security implications. The architecture enforces several boundaries:
Client Controls Access The client decides which servers to connect to and which capabilities to expose to the AI. Users configure this, not the AI.
Servers Run with Limited Scope Each server only has access to what it's specifically configured for. A filesystem server might only access specific directories. A database server only connects to specified databases.
Tools Require Explicit Invocation The AI can't secretly call tools. Every tool call goes through the client, which can log, audit, or require approval.
No Server-to-Server Communication MCP servers don't talk to each other directly. All coordination happens through the client. This prevents unexpected interactions.
Understanding Error Handling
When things go wrong, MCP provides structured error responses:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32602,
"message": "File not found",
"data": {
"path": "/nonexistent/file.txt"
}
}
}
Common error codes:
-32700: Parse error (invalid JSON)-32600: Invalid request-32601: Method not found-32602: Invalid params-32603: Internal error
The AI receives these errors and can respond appropriately, often explaining the issue to the user or trying an alternative approach.
Statefulness
MCP connections are inherently stateful. Once initialized, the connection persists until explicitly closed. This enables:
Session Context Servers can maintain context across multiple requests. A database server might keep a connection pool. A browser automation server might maintain browser state.
Subscriptions Clients can subscribe to resource changes. When a file changes, the server can notify the client without being polled.
Progress Reporting Long-running operations can send progress updates through the persistent connection.
However, servers should be designed to handle disconnections gracefully. If a client crashes, the server should clean up and be ready for reconnection.
Key Takeaways
-
Client-Server Architecture - The client (Claude Desktop, Claude Code) mediates between the AI and MCP servers
-
Three Primitives - Resources (read data), Tools (take actions), Prompts (templates)
-
Transport Options - stdio for local, SSE or HTTP for remote
-
JSON-RPC Messages - Standard format for all communication
-
Capability Negotiation - Client and server agree on what's supported
-
Security by Design - Multiple boundaries limit what AI can access
-
Stateful Connections - Enable subscriptions, progress, and session context
Looking Ahead
Now that you understand how MCP works architecturally, it's time to get practical. In the next module, we'll set up real MCP servers. You'll configure Claude Desktop and Claude Code to connect to servers and experience MCP in action.
Next up: Module 3 - Setting Up MCP Servers

