What is MCP?
Every AI assistant faces the same friction: it lives inside a chat window while your data lives everywhere else — in files, databases, APIs, calendars, code repos. Connecting them has meant writing one-off integrations for every tool and every model.
MCP fixes this with a single universal protocol. Think of it like USB-C for AI — one standard connector that works between any host (Claude, GPT, Gemini) and any service (GitHub, Postgres, Slack, your custom API).
MCP separates the AI model from its context sources. Servers expose capabilities; hosts discover and call them. Neither side needs to know how the other is built.
N×M integration hell
Without MCP, every AI × every tool needs its own adapter. With MCP, it’s one protocol for all combinations.
User-controlled permissions
The host asks the user before connecting to any server. Servers declare exactly what they expose — nothing hidden.
Multiple transports
Local servers use stdio. Remote servers use HTTP with SSE. Same protocol, different wire.
Architecture — hosts, clients, servers
MCP has three roles. Understanding them is the key to understanding the whole system.
Host
The AI application the user runs (Claude Desktop, VS Code, your app). It manages one MCP client per connected server and controls what gets shown to the user.
Client
A protocol handler embedded in the host. One client per server. Handles the JSON-RPC 2.0 session: capability negotiation, tool calls, resource reads, and error handling.
Server
A lightweight process that wraps a service and exposes it via MCP. Can be local (stdio) or remote (HTTP). Declares its tools, resources, and prompts at connection time.
How it works — the full request flow
From a user typing a message to a tool result appearing in the reply, here is every step that happens inside an MCP-powered AI assistant.
The first thing that happens when a host connects to a server is a handshake. The client sends its protocol version; the server replies with what it supports. Both sides now know exactly what the other can do. This happens once per session.
After the handshake, the client asks for a list of available tools, resources, and prompt templates. Each tool comes with a name, description, and JSON schema for its inputs. The host injects these descriptions directly into the LLM’s system prompt — so the model knows what it can call.
When a user message arrives, the LLM decides whether a tool is needed. If so, it emits a structured tool_use block in its response. The MCP client intercepts this, validates the arguments against the tool’s schema, and forwards the call to the right server via JSON-RPC 2.0.
The server executes the tool in its own process — completely isolated from the host. It may call a real API, query a database, read a file, or run any code. The result is serialised and returned to the MCP client as a tool_result block.
The tool result is injected back into the LLM’s context. The model now has real, live data and generates a natural-language response grounded in it. If another tool call is needed (multi-hop), the cycle repeats. The user sees only the final polished answer.
The three primitives
Every MCP server exposes its capabilities through exactly three building blocks. Understanding these tells you everything a server can offer.
| Primitive | Who controls it | Purpose | Example |
|---|---|---|---|
| Tools | Model | Executable actions with side effects | Write a file, send a Slack message, query a DB |
| Resources | Application | Read-only data exposed as URIs | File contents, DB schemas, API responses |
| Prompts | User | Reusable prompt templates with arguments | Code review template, summarise-issue workflow |
Tools can have side effects (write, send, create). Resources are always read-only. If a server needs to modify something, it must be a tool — not a resource. This distinction is enforced by the protocol.
Real-world use cases
MCP is already powering production workflows across engineering, support, and data teams. Here are the most common patterns.
Developer tooling
Connect Claude to GitHub, Jira, and your CI system. Ask it to open PRs, triage issues, or explain build failures — without leaving your editor.
Data exploration
Natural language queries over Postgres, BigQuery, or Snowflake. The LLM writes SQL, runs it via MCP, and explains the results.
Support automation
Agent reads tickets from Zendesk, looks up account data from Salesforce, drafts a reply, and only escalates when confidence is low.
Business intelligence
Connect to your metrics store. Ask questions in plain English, get charts, and drill down — all driven by MCP tool calls under the hood.
The fastest way to try MCP is Claude Desktop with an open-source server. The MCP registry at modelcontextprotocol.io lists 100+ ready-made servers for GitHub, Postgres, Slack, Notion, Google Drive, and more — most installable in under five minutes.
Building your own server
An MCP server is just a process that speaks JSON-RPC 2.0. The official SDKs for Python and TypeScript handle all the protocol boilerplate — you only write the tool logic.
# Minimal MCP server in Python from mcp import FastMCP app = FastMCP("my-server") @app.tool() async def search_products(query: str, limit: int = 10) -> list: """Search the product catalogue by keyword.""" results = await db.query( "SELECT * FROM products WHERE name ILIKE $1 LIMIT $2", f"%{query}%", limit ) return results @app.resource("catalogue://schema") async def get_schema() -> str: """Expose the DB schema as a resource.""" return await db.fetch_schema() # Run via stdio (local) or HTTP (remote) app.run(transport="stdio")
Install the SDK
pip install mcp or npm i @modelcontextprotocol/sdk
Define your tools
Decorate functions with @app.tool(). Type hints become the JSON schema automatically.
Register with a host
Add your server to Claude Desktop’s config or any MCP-compatible host. Done.