The Model Context Protocol (MCP) is an open standard that defines how AI applications connect to external tools and data. Instead of writing a custom integration for every pair of AI app and service, you build an MCP server once, and any MCP-compatible client, such as a chat app, an IDE assistant, or your own agent, can discover and use it. This article explains what MCP is, how the protocol works, and how to build a small server.
What is MCP and what problem does it solve?
Before MCP, connecting a model to your issue tracker, database, and file system meant writing glue code for each one inside each AI product. With M applications and N services, you ended up with up to M times N integrations, each with its own auth, schemas, and quirks.
MCP turns that into M plus N. Each service ships one server that speaks the protocol, and each application ships one client. It is often compared to USB-C for AI tools: one shape of connector, many devices. Anthropic introduced MCP as an open specification in late 2024, and it has since been adopted across many AI clients and developer tools.
For a shorter overview, see the what is MCP guide.
How does the Model Context Protocol work?
MCP has three roles:
- Host: the AI application the user interacts with, such as a desktop chat app or an IDE.
- Client: a connector inside the host that maintains a one-to-one session with a single server.
- Server: a program that exposes capabilities, such as tools, data, or prompt templates, over the protocol.
Messages use JSON-RPC 2.0. A session starts with an initialize handshake where client and server exchange protocol versions and capabilities. After that, the client can list what the server offers and invoke it.
MCP transports
| Transport | How it runs | Typical use |
|---|---|---|
| stdio | Host launches the server as a local subprocess and talks over stdin/stdout | Local tools: files, git, local databases |
| Streamable HTTP | Server runs as an HTTP service; clients POST requests and can receive streamed responses | Remote, shared, or multi-user servers |
Earlier versions of the spec used a separate HTTP plus Server-Sent Events transport; Streamable HTTP replaced it for remote servers.
MCP tools vs resources vs prompts
Servers expose three main primitives, and choosing the right one matters:
- Tools are functions the model can decide to call, like
create_ticketorrun_query. They can have side effects, so hosts usually ask the user before running them. - Resources are read-only data identified by a URI, like a file, a database schema, or a document. The application or user typically chooses which resources to attach as context.
- Prompts are reusable templates, such as "summarize this pull request", that users can invoke explicitly, often as slash commands.
A simple rule: if the model should decide when to use it, make it a tool. If it is context to be read, make it a resource. If a human triggers a workflow, make it a prompt.
Clients can also offer capabilities back to servers. For example, sampling lets a server ask the host's model for a completion, and elicitation lets a server request extra input from the user, both under the host's control.
MCP example: a tiny server in Python
The official Python SDK includes FastMCP, which turns decorated functions into protocol-compliant tools and resources. Type hints and docstrings become the schema and description the model sees.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("inventory")
STOCK = {"sku-100": 42, "sku-200": 0, "sku-300": 7}
@mcp.tool()
def check_stock(sku: str) -> dict:
"""Return the units on hand for a product SKU. Use before promising availability."""
if sku not in STOCK:
return {"sku": sku, "error": "unknown sku"}
return {"sku": sku, "units": STOCK[sku]}
@mcp.resource("inventory://skus")
def list_skus() -> str:
"""All known SKUs, one per line."""
return "\n".join(STOCK)
if __name__ == "__main__":
mcp.run() # defaults to the stdio transport
Point an MCP-capable host at this script and it will discover check_stock automatically. No host-specific plugin code is required.
What the messages look like
When the model decides to call the tool, the client sends a JSON-RPC request like this:
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "check_stock",
"arguments": { "sku": "sku-300" }
}
}
The server replies with a result containing content blocks, typically text or structured data, that the host passes back to the model. Other core methods follow the same pattern: tools/list, resources/list, resources/read, prompts/list, and prompts/get.
MCP vs regular APIs and function calling
MCP does not replace REST or GraphQL. Your MCP server will usually call those APIs underneath. What MCP adds is a standard way for an AI application to discover capabilities at runtime, understand them through schemas and descriptions, and invoke them consistently. Native function calling in a model API describes tools for a single request; MCP standardizes where those tool definitions come from and how they are executed. The MCP vs API guide goes deeper, and MCP vs A2A contrasts it with agent-to-agent protocols.
When to use MCP
MCP is a good fit when:
- You want the same tools available in several AI clients, such as an IDE, a chat app, and an internal agent.
- You are building a product that other teams' agents should integrate with.
- Your agent's tool list changes often and you want discovery instead of redeploys.
It is probably unnecessary when you have one application calling two or three internal functions. Plain function calling is simpler there. If you are building an agent from scratch, How to Build an AI Agent shows where MCP fits in the loop.
MCP security considerations
An MCP server is code that can act on your behalf, so treat it with the same care as any dependency with production credentials:
- Install servers only from sources you trust, and pin versions. A malicious server can return tool descriptions designed to manipulate the model.
- Scope credentials tightly. Give each server the minimum access it needs, and prefer per-user OAuth over shared tokens for remote servers.
- Keep humans in the loop for tools with side effects. Well-behaved hosts show the call and arguments before running it.
- Treat tool output as untrusted data. Content returned by a server, such as web pages or tickets, can carry prompt injection.
- Validate input on the server as you would for any public API.
Key takeaways
- MCP is an open protocol that standardizes how AI apps connect to tools and data.
- It uses JSON-RPC 2.0 between a client inside a host and one or more servers.
- Servers expose tools (model-invoked actions), resources (readable context), and prompts (user-triggered templates).
- Local servers typically use stdio; remote servers use Streamable HTTP.
- MCP complements your APIs rather than replacing them.
- Security depends on trusted servers, scoped credentials, and human approval for risky actions.
Frequently asked questions
Is MCP only for Claude?
No. Anthropic created the specification, but MCP is open and model-agnostic. Many AI clients, IDEs, and agent frameworks support it, and SDKs exist for several languages, so a single server can work with different hosts and models.
What is the difference between an MCP tool and a resource?
A tool is an action the model chooses to invoke, and it may change state. A resource is read-only data identified by a URI that the application or user attaches as context. Use tools for doing and resources for reading.
Can an MCP server run remotely?
Yes. Remote servers use the Streamable HTTP transport and can serve many users. For remote deployments, add proper authentication, commonly OAuth, and apply the same rate limiting and input validation you would use for any public API.
Do I need MCP to build an AI agent?
No. An agent can call tools through native function calling alone. MCP becomes valuable when you want tools to be reusable across multiple AI applications or discoverable at runtime without custom integration code.