Vault / raw/2026-05-28-mcp-architecture.md
MCP Architecture (official docs)
Source: https://modelcontextprotocol.io/docs/learn/architecture
Scope
MCP includes:
- MCP Specification — implementation requirements.
- MCP SDKs — per-language implementations.
- MCP Development Tools — including the MCP Inspector.
- MCP Reference Server Implementations.
"MCP focuses solely on the protocol for context exchange — it does not dictate how AI applications use LLMs or manage the provided context."
Participants
- MCP Host — AI application that coordinates one or more MCP clients (e.g., Claude Code, Claude Desktop, VS Code).
- MCP Client — connection-holder; one per server. Lives inside the host.
- MCP Server — program that provides context to clients.
Key nuance: a single host can have multiple connections to the same server (separate client objects). VS Code is the example.
"Local" vs "remote" is determined by transport, not server location:
- stdio → local subprocess.
- Streamable HTTP → remote (e.g., the official Sentry MCP server).
Layers
MCP has two layers:
- Data layer (inner) — JSON-RPC 2.0 protocol for client-server communication. Lifecycle, primitives, notifications.
- Transport layer (outer) — communication mechanism (stdio, Streamable HTTP) with auth.
Data layer details
- Lifecycle management — connection init, capability negotiation, termination.
- Server features: tools, resources, prompts.
- Client features: sampling, elicitation, logging.
- Utility: notifications, progress.
Transport layer details
- stdio — stdin/stdout between local processes. No network overhead.
- Streamable HTTP — HTTP POST + optional SSE for streaming. Supports OAuth, bearer tokens, API keys.
Same JSON-RPC message format across all transports.
Primitives — server-exposed
- Tools — executable functions (model-controlled). Methods:
tools/list,tools/call. - Resources — data sources (application-controlled). Methods:
resources/list,resources/read. - Prompts — reusable templates (user-controlled). Methods:
prompts/list,prompts/get.
Servers declare which primitives they support in capabilities during init.
Primitives — client-exposed (server can use these)
- Sampling — server asks client to run an LLM call (
sampling/createMessage). Server stays model-independent. - Elicitation — server asks user for more info / confirmation (
elicitation/create). - Logging — server sends log messages to client for debugging.
Cross-cutting
- Tasks (experimental) — durable execution wrappers for long-running ops, status tracking, deferred result retrieval.
Lifecycle (initialize → ready → operate → shutdown)
- Client sends
initializewithprotocolVersion,capabilities,clientInfo. - Server responds with its
capabilities,serverInfo. - Client sends
notifications/initialized. - Operations:
tools/list,tools/call, etc. - Notifications flow either direction (e.g.,
notifications/tools/list_changed).
Example messages
Initialize:
{
"jsonrpc": "2.0", "id": 1, "method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {"elicitation": {}},
"clientInfo": {"name": "example-client", "version": "1.0.0"}
}
}
Initialize response:
{
"jsonrpc": "2.0", "id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {"tools": {"listChanged": true}, "resources": {}},
"serverInfo": {"name": "example-server", "version": "1.0.0"}
}
}
Tool call:
{
"jsonrpc": "2.0", "id": 3, "method": "tools/call",
"params": {"name": "weather_current", "arguments": {"location": "SF", "units": "imperial"}}
}
Notification (no id, no response expected):
{"jsonrpc": "2.0", "method": "notifications/tools/list_changed"}
Capability negotiation
- Client capability
"elicitation": {}— client can handle user-info requests. - Server capability
"tools": {"listChanged": true}— supports tools AND emits change notifications. - Server capability
"resources": {}— supports resources primitive.
Server only sends tools/list_changed if it declared listChanged: true at init.
Tool object fields
Each tool in tools/list response has:
name— unique identifier (e.g.,calculator_arithmetic, not justcalculate).title— human-readable display name.description— what it does + when to use it.inputSchema— JSON Schema for params.
Stateless mode
MCP is stateful by default. Subset can be made stateless using Streamable HTTP. Important for horizontally-scaled deployments.
Why this matters for CCA-F
Memorize:
- Host/client/server distinction (host has many clients).
- Three server primitives + three client primitives.
- Lifecycle order (init → ready notification → operate).
- That
listChangedcapability is required for change notifications. - That
samplinglets servers be model-agnostic.