Theory: MCP Concepts & Protocol
Understanding the Model Context Protocol — the open standard for connecting LLMs to external data and tools.
What is MCP
The Model Context Protocol (MCP) is an open protocol that standardises how LLM applications communicate with external data sources and tools. Released by Anthropic in late 2024, it addresses a fundamental problem in the LLM ecosystem: the N×M integration problem.
Before MCP, every LLM application that wanted to connect to external services had to write custom integration code for each one. A code editor might need a GitHub connector, a database connector, a Slack connector, and so on. Each connector was built differently, with its own authentication flow, data format, and error handling. Multiply this by the number of LLM applications, and you get an explosion of bespoke integrations.
MCP turns this N×M problem into an N+M problem. Application developers implement the MCP client protocol once. Tool/data providers implement the MCP server protocol once. Any client can then connect to any server. The protocol handles discovery, schema negotiation, and message exchange in a standardised way.
The closest analogy is USB for hardware peripherals, or LSP (Language Server Protocol) for code editors. LSP solved the same N×M problem for programming language support: instead of every editor building its own Python support, Go support, and so on, editors implement LSP once and language servers implement LSP once. MCP does the same for LLM-to-tool connectivity.
Protocol Architecture
MCP defines three distinct roles in the architecture:
Host
The host is the LLM application that the user interacts with directly. Claude Desktop, Claude Code, and various IDE integrations are examples of hosts. The host is responsible for: managing the LLM conversation, rendering the UI, and coordinating multiple MCP client connections. A host contains one or more MCP clients.
Client
An MCP client is a protocol endpoint that lives inside the host process. Each client maintains a stateful, 1:1 session with exactly one MCP server. The client handles protocol negotiation, capability discovery, and message serialisation. A host typically creates one client per server connection.
Server
An MCP server is a lightweight process or service that exposes specific capabilities — tools, resources, and prompts — through the MCP protocol. Servers are designed to be focused: a filesystem server handles file operations, a GitHub server handles repository operations, a database server handles queries. This separation of concerns keeps servers simple and composable.
Security model: MCP servers run with limited permissions. The host controls which servers are connected, and users must approve tool calls before execution. This follows the principle of least privilege: each server only has access to the capabilities it needs.
JSON-RPC
All MCP messages are encoded as JSON-RPC 2.0. This is a lightweight remote procedure call protocol that uses JSON for serialisation. Each message is one of three types:
- Request: A message with an
id, amethodname, and optionalparams. The sender expects a response. - Response: A message with the same
idas the request, and either aresultor anerror. - Notification: A message with a
methodandparamsbut noid. Fire-and-forget; no response expected.
// Request: client asks server to call a tool
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": {"path": "/tmp/example.txt"}
}
}
// Response: server returns the result
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [{"type": "text", "text": "File contents here..."}]
}
}
The choice of JSON-RPC is deliberate: it is simple, widely supported, language-agnostic, and easy to debug by inspecting the raw messages.
Tools vs Resources vs Prompts
MCP servers expose three types of primitives, each controlled by a different actor:
Tools
Tools are functions that the LLM can invoke to perform actions or retrieve computed data. The model decides when and how to call tools based on the conversation context. Tools have input schemas (JSON Schema) that define their parameters. Examples: create_issue, run_sql_query, send_message.
Resources
Resources are data that the application (host) can load into the LLM's context. Unlike tools, resources are not called by the model — they are included by the host based on relevance. Resources have URIs that follow a scheme like file://, db://, or custom schemes. Examples: file:///config.json, git://repo/README.md.
Prompts
Prompts are reusable templates that users can select from a menu. They provide structured ways to start common workflows. A prompt might include pre-filled instructions, required context, and suggested tool usage. Examples: "Summarise this PR", "Debug this error", "Review this code".
Design heuristic: If it performs an action or computation, make it a Tool. If it provides static or semi-static data, make it a Resource. If it structures a user's intent into a reusable workflow, make it a Prompt.
Capability Negotiation
When a client connects to a server, they perform a capability negotiation handshake. The client sends an initialize request declaring its supported protocol version and capabilities. The server responds with its own capabilities: which primitives it supports (tools, resources, prompts), any optional features, and server metadata.
// Client -> Server
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {"name": "my-app", "version": "1.0.0"}
}}
// Server -> Client
{"jsonrpc": "2.0", "id": 1, "result": {
"protocolVersion": "2025-03-26",
"capabilities": {"tools": {}, "resources": {}},
"serverInfo": {"name": "my-server", "version": "1.0.0"}
}}
After initialisation, the client can query available tools (tools/list), resources (resources/list), and prompts (prompts/list). This dynamic discovery means the host does not need to know in advance what a server offers — it learns at connection time.
Existing Servers
The MCP ecosystem already includes servers for many common integrations. Some notable categories:
- Filesystem: Read, write, and search files on the local machine. The reference filesystem server restricts access to specified directories.
- GitHub: Create issues, read PRs, search repositories, manage branches. Authenticates via personal access token.
- Databases: PostgreSQL, SQLite, and other database servers expose query tools and schema resources.
- Communication: Slack, email, and messaging servers let agents read and send messages.
- Web: Fetch URLs, search the web (Brave Search), take screenshots (Puppeteer).
Community-built servers extend the ecosystem further. The official MCP servers repository is the canonical starting point, and registries like Smithery aggregate community contributions.