Model Context Protocol (MCP) Explained for Engineers
What the Model Context Protocol is, how MCP clients and servers work, tools vs resources vs prompts, transports, security considerations and when to build an MCP server.
Before the Model Context Protocol, every AI application wired up its own integrations. Want your assistant to read GitHub issues, query Postgres and search Slack? Write three custom connectors, then write them again for the next AI app. MCP standardizes that layer. Build a server once, and any MCP-compatible client can use it.
This guide explains what MCP is, how it works under the hood, and when it's worth adopting.
Key takeaways
- MCP is an open protocol that standardizes how AI applications connect to external tools and data. Anthropic introduced it in late 2024, and it has since been adopted widely across AI tools.
- It uses a client–server architecture: AI apps (hosts) run clients that connect to MCP servers exposing capabilities.
- Servers expose three main primitives: tools (actions), resources (data) and prompts (templates).
- Messages use JSON-RPC 2.0, over stdio for local servers or HTTP for remote ones.
- MCP solves integration reuse. It doesn't solve security for you. Permissions, auth and prompt-injection defenses still matter.
The problem MCP solves
Think of the "M × N" problem. With M AI applications and N tools or data sources, custom integrations mean up to M × N connectors. MCP turns that into M + N: each app implements the client side once, each integration implements a server once.
The analogy people use is a USB port for AI: a standard shape that lets any compatible device plug into any compatible host.
Architecture
text┌──────────── Host application (IDE, chat app, agent) ────────────┐
│ LLM ◀──▶ MCP client ──┐ MCP client ──┐ MCP client ──┐ │
└───────────────────────────┼────────────────┼────────────────┼───┘
▼ ▼ ▼
MCP server: MCP server: MCP server:
GitHub Postgres Internal CRM
- Host: the application the user interacts with, such as a desktop assistant, IDE or custom agent.
- Client: a component inside the host that maintains a connection to one server.
- Server: a program that exposes capabilities from some system: files, databases, SaaS APIs, internal services.
The three core primitives
Tools: things the model can do
Functions with a name, a description and a JSON Schema for inputs, exactly like LLM tool calling. The host exposes them to the model; when the model calls one, the client sends the request to the server, which executes it.
json{
"name": "create_issue",
"description": "Create a GitHub issue in the given repository.",
"inputSchema": {
"type": "object",
"properties": {
"repo": {"type": "string"},
"title": {"type": "string"},
"body": {"type": "string"}
},
"required": ["repo", "title"]
}
}
Resources: data the application can read
Addressable content identified by URIs, such as a file, a database schema or a document. Resources are typically application-controlled: the host decides what to fetch and include as context, rather than the model calling them like tools.
Prompts: reusable templates
Predefined prompt templates a server offers, often surfaced to users as commands ("summarize this PR", "explain this query plan"). They're user-controlled shortcuts.
MCP also defines client-side features that servers can request, such as sampling (asking the host's model to generate text) and elicitation (asking the user for input), which enable richer interactions when the host supports them.
How a session works
- Initialize. The client and server exchange protocol versions and capabilities.
- Discover. The client lists the available tools, resources and prompts.
- Use. The host exposes tools to the model. When the model calls one, the client sends a
tools/callrequest, and the server executes it and returns content. - Notify. Servers can signal changes, such as the tool list being updated.
All messages are JSON-RPC 2.0:
json{"jsonrpc": "2.0", "id": 7, "method": "tools/call",
"params": {"name": "create_issue",
"arguments": {"repo": "acme/web", "title": "Fix login redirect"}}}
Transports
- stdio: the host launches the server as a local subprocess and communicates over standard input and output. Simple and common for desktop and developer tools.
- Streamable HTTP: the server runs as a web service, typically remote and multi-user, and supports streaming responses. Remote servers use standard web authentication, with OAuth-based authorization defined in the specification.
Building a minimal MCP server
Official SDKs exist for several languages. In Python, a small server looks like this:
pythonfrom mcp.server.fastmcp import FastMCP
mcp = FastMCP("orders")
@mcp.tool()
def get_order_status(order_id: str) -> str:
"""Return the shipping status for an order ID like 'A10293'."""
order = db.get_order(order_id)
return f"{order.id}: {order.status}, ETA {order.eta}" if order else "Order not found."
if __name__ == "__main__":
mcp.run() # stdio by default
Point an MCP-capable host at this server and the model can check order statuses. No host-specific integration code is needed.
Security: what MCP does not do for you
MCP standardizes the plumbing. The risks of giving AI access to tools remain (see AI guardrails and safety):
- Tool poisoning and injection. Tool descriptions and tool outputs are text the model reads. A malicious or compromised server can include instructions. Only install servers you trust, and review what they expose.
- Excessive permissions. A server with a broad API token gives the model broad power. Scope credentials to the minimum.
- Confused deputy problems. Remote servers acting on behalf of users must authenticate and authorize each user properly, not share one powerful token.
- Human approval. Hosts should let users review and approve sensitive tool calls. Keep that enabled for write actions.
- Supply chain. Pin versions of third-party servers and treat them like any other dependency.
When should you build an MCP server?
Build one when:
- You want your product or internal system usable from multiple AI clients (IDEs, assistants, custom agents).
- You're a SaaS company and want customers' AI tools to integrate with you easily.
- Several internal agents need the same integrations, and you want one maintained implementation.
Skip it when:
- You have one agent, one app and a couple of tools. Plain tool calling in your code is simpler.
- Latency-critical, tightly coupled logic lives in the same service as the agent anyway.
MCP vs plain function calling vs plugins
| Function calling | MCP | |
|---|---|---|
| Scope | One app's code | Standard across apps |
| Where tools live | Inside your application | In separate, reusable servers |
| Discovery | Hard-coded | Dynamic (tools/list) |
| Reuse across AI clients | No | Yes |
| Overhead | Minimal | A protocol layer and a separate process or service |
MCP doesn't replace function calling. It's a standardized way to deliver tools that the model then uses through function calling.
FAQ
Is MCP only for Anthropic's Claude?
No. MCP is an open specification with open-source SDKs, and many AI applications, IDEs and agent frameworks from different vendors support it.
Is MCP the same as an API?
MCP servers usually wrap APIs, but MCP adds a standard way for AI applications to discover capabilities, describe them to models and invoke them. It's an AI-oriented integration layer on top of existing APIs.
Can an MCP server access my whole computer?
A local server can do whatever its process is allowed to do, which is why you should only run trusted servers, restrict their permissions and file access, and keep human approval on for sensitive actions.
Do I need MCP to build AI agents?
No. Agents work fine with plain tool calling. MCP becomes valuable when you want tools shared across many agents or AI clients. See what are AI agents.