Model Context Protocol (MCP), introduced by Anthropic in late 2024, is an open standard that provides a universal method for AI systems, particularly large language models (LLMs), to connect with external data sources, tools, and services. By standardizing how applications supply context to LLMs, MCP acts as a versatile interface, allowing developers to seamlessly integrate AI models with various databases, APIs, and utilities without needing custom adapters. This aims to eliminate information silos and enhance AI responses by ensuring models have consistent and secure access to necessary data and tools.
Updated October 2026: MCP has changed a lot since this was first written. The protocol was donated to the Linux Foundation’s Agentic AI Foundation in December 2025, and the 2026-07-28 specification made the protocol stateless (no more initialize handshake or sessions), dropped the old HTTP+SSE transport in favour of Streamable HTTP, and moved features like long-running Tasks and MCP Apps into optional extensions. The official Python SDK is now version 2.x, where the FastMCP import used in this guide’s original example no longer exists. I rewrote the architecture, transport and security sections to match the current spec and replaced the code example with one I ran against the current SDK.
Analogy: think of MCP as a USB-C port for AI applications. Any host that speaks MCP can plug into any MCP server, whether it fronts a database, a SaaS app or a file system, without a custom cable for every pair. The port defines how the connection works; it does not decide when the AI should use it. That decision stays with the model and the host application.
Why Do We Need Model Context Protocol?
Modern AI assistants often require information beyond their trained knowledge, from real-time stock prices to internal documents, and sometimes need to perform actions like executing code or querying a database. Before MCP, developers had to build N×M custom integrations between each AI system and each tool or data source, a process Anthropic described as an expensive scaling challenge. Previous stop-gap solutions (like OpenAI’s 2023 function-calling API or ChatGPT’s plugin framework) addressed parts of this problem but remained vendor-specific and fragmented. Every new tool often meant yet another bespoke connector, each with its own API quirks and maintenance burdens.
MCP remedies this by establishing a common protocol for AI-tool interactions. Rather than writing separate integration code for each service, developers can “plug and play” tools via MCP. This standardization drastically reduces integration overhead: AI applications and tool providers speak the same language. As the official documentation highlights, MCP brings several advantages out-of-the-box:
- A growing ecosystem of ready-made servers: connectors already exist for common cloud apps, databases, code hosts and search. The official MCP Registry (launched in preview in September 2025) is a public catalogue for discovering them.
- Vendor flexibility: a tool exposed as an MCP server works with any MCP-capable host. Claude, ChatGPT, Gemini, GitHub Copilot in VS Code, Cursor and Microsoft’s Copilot products all support MCP to varying degrees, so you can switch models or clients without rebuilding integrations.
- Security hooks, not security by default: the spec defines OAuth-based authorization for remote servers and says hosts must get user consent before invoking tools. But MCP itself cannot enforce those rules. Whether an MCP setup is actually secure depends on the host and server implementations (see the security section below).
By introducing a unifying layer, MCP simplifies complex AI workflows. As IBM’s AI team describes, MCP essentially serves as a standard “integration layer” for AI agents, not unlike how REST standardized web APIs. It doesn’t replace higher-level agent orchestration frameworks (like LangChain or LlamaIndex); rather, it complements them. In other words, MCP doesn’t decide when or why an AI should use a tool – that logic resides in the agent or LLM – but it ensures that whenever a tool needs to be used, there’s a consistent, reliable mechanism to do so. The benefit is that an AI developer can focus on what their AI should accomplish, trusting MCP to handle how data/tool access is invoked under the hood.
How MCP Works: Architecture and Components
MCP follows a client–host–server architecture built on JSON-RPC 2.0 messages. A host (the AI application) creates and manages several clients, each of which talks to exactly one server that provides context or capabilities. This separation lets the host mediate everything: it decides which servers to connect to, what they may see, and when the user must approve an action.
Since the 2026-07-28 revision, the protocol is stateless: every request is self-contained and carries its own protocol version and the client’s capabilities, rather than relying on a connection-level session set up by an initialize handshake. In practice that means a remote MCP server can sit behind an ordinary load balancer with no sticky sessions or shared session store. A server that really needs state across calls hands out explicit handles that the model passes back as normal tool arguments.
Let’s break down the core components of MCP in this architecture:
- MCP host: the AI application the user interacts with, such as a chat assistant, an IDE, or Claude Desktop. It creates and manages MCP clients, enforces security policy and consent, and coordinates the LLM. It owns the full conversation; servers do not get to read it.
- MCP client: the connector inside the host that talks to a single server (a 1:1 relationship). It attaches the protocol version and capabilities to each request, routes messages, handles timeouts and cancellation, and keeps the boundary between servers. A host can run many clients at once, for example one for GitHub and one for a database.
- MCP server: the program that exposes tools, resources or prompts, and does the real work: wrapping an API, querying a database, reading files. Servers can be local processes or remote services. A core design principle is that a server should not be able to read the whole conversation or see into other servers; it receives only what the host sends it for the task. Note that this is a design principle enforced by the host, not something the protocol can guarantee on its own.
Transports: stdio and Streamable HTTP
The message format is always JSON-RPC 2.0, but there are two standard ways to carry it:
- stdio: the host launches the server as a local subprocess and exchanges newline-delimited messages over its standard input and output. Ideal for local tools. One consequence: a stdio server must never print to stdout, or it corrupts the message stream. Log to stderr instead.
- Streamable HTTP: each message is an HTTP POST to a single MCP endpoint, and the reply comes back either as a plain JSON response or as a streamed (SSE) response for that request. This is how remote and cloud-hosted servers work. It replaced the older “HTTP + SSE” transport, which was deprecated in the 2025-03-26 spec and is now formally marked deprecated, so new servers should not use it.
Capabilities and discovery
Clients and servers declare what they support so each side only uses features the other understands. Under the current spec, a client sends its capabilities with every request, and a server advertises its supported protocol versions, capabilities and identity in response to a server/discover call. Older implementations instead negotiated this once in the initialize handshake; the spec describes how new clients fall back for older servers. New features arrive as optional extensions that both sides must opt in to, which is how MCP can evolve without breaking existing integrations.
MCP Resources, Tools, and Prompts
MCP servers expose their abilities through three core primitives. A useful way to remember them is who controls each one:
| Primitive | What it is | Who decides to use it | Examples |
|---|---|---|---|
| Tools | Functions that do something and return a result; they may have side effects. | The model (with user approval) | Search the web, run a query, create a ticket, post a message |
| Resources | Read-only context the application or model can pull in, addressed by URI. | The application or the user | A file, a database schema, a document, API reference data |
| Prompts | Reusable templated messages and workflows. | The user, who picks them explicitly | A “review this pull request” template, a slash-command workflow |
A server can offer any combination. A Slack MCP server might offer a resource (channel history) and tools (post a message, create a channel); our weather server below offers only tools. Because every server describes its tools with a name, a description and a JSON Schema for the inputs, the host can give the model an accurate menu of what is available, and the model can call a tool with well-formed arguments.
Tools represent arbitrary code execution, so treat them with caution: the spec says hosts must obtain explicit user consent before invoking a tool, and that tool descriptions and annotations should be considered untrusted unless they come from a trusted server.
Beyond the basics: elicitation, extensions and what is deprecated
- Elicitation: a server can ask the user for more information mid-task (for example, “which account?”), through the host. In the current spec this works by the server returning an “input required” result that the client answers by retrying the request, rather than the server sending a request of its own.
- Extensions: optional add-ons negotiated by both sides. Notable ones are Tasks (long-running asynchronous operations that you poll for), MCP Apps (interactive UI such as charts and forms rendered inside the conversation) and Skills over MCP (structured workflow instructions).
- Deprecated: Roots, Sampling and Logging remain in the spec but are deprecated and scheduled for removal after a minimum twelve-month window; new implementations should not adopt them. If you read older guides that describe sampling or roots as core features, that is why they differ.
Using MCP: Practical Integration Scenarios
Now that we understand what MCP is and how it’s structured, let’s explore how a developer can actually use it. There are two main ways to leverage MCP in your projects:
- Use an existing MCP server. If you want an AI app to reach a common tool (GitHub, a database, a search API, a SaaS product), look for a maintained server in the registry or the vendor’s own docs, and point your host at it. Most hosts let you add servers through a settings screen or a JSON config file. Local servers run over stdio; vendor-hosted ones are a URL you connect to over Streamable HTTP, usually with an OAuth sign-in. Only install servers from sources you trust, for the reasons covered below.
- Build your own MCP server. For internal systems or specialised needs, write a server with an official SDK (Python, TypeScript and several other languages). You supply the logic; the SDK handles the protocol.
Example: Creating a Weather Tool via MCP
Suppose we want an AI assistant to answer weather questions like “What’s the forecast for Dallas?” A model has no live weather data on its own, but an MCP server can fetch it from the US National Weather Service API and expose it as tools. This mirrors the official quickstart and uses the Python MCP SDK. You need Python 3.10 or newer and SDK 2.0 or later:
uv init weather && cd weather
uv add "mcp[cli]"
# or, without uv: python -m venv .venv && source .venv/bin/activate && pip install "mcp[cli]"
Create weather.py. The server object, the @mcp.tool() decorator and the docstrings are all it takes: the SDK reads the type hints and docstrings to generate each tool’s name, description and input schema automatically.
from typing import Any
import httpx2
from mcp.server import MCPServer
mcp = MCPServer("weather")
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
async def make_nws_request(url: str) -> dict[str, Any] | None:
"""Call the National Weather Service API; return None on any failure."""
headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
async with httpx2.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
def format_alert(feature: dict) -> str:
props = feature["properties"]
return (
f"Event: {props.get('event', 'Unknown')}\n"
f"Area: {props.get('areaDesc', 'Unknown')}\n"
f"Severity: {props.get('severity', 'Unknown')}\n"
f"Description: {props.get('description', 'No description available')}"
)
@mcp.tool()
async def get_alerts(state: str) -> str:
"""Get active weather alerts for a US state.
Args:
state: Two-letter US state code (e.g. CA, NY)
"""
data = await make_nws_request(f"{NWS_API_BASE}/alerts/active/area/{state}")
if not data or "features" not in data:
return "Unable to fetch alerts."
if not data["features"]:
return "No active alerts for this state."
return "\n---\n".join(format_alert(f) for f in data["features"])
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
"""Get the weather forecast for a location.
Args:
latitude: Latitude of the location
longitude: Longitude of the location
"""
points = await make_nws_request(f"{NWS_API_BASE}/points/{latitude},{longitude}")
if not points:
return "Unable to fetch forecast data for this location."
forecast = await make_nws_request(points["properties"]["forecast"])
if not forecast:
return "Unable to fetch the detailed forecast."
periods = forecast["properties"]["periods"][:5] # next five periods
return "\n---\n".join(
f"{p['name']}: {p['temperature']}°{p['temperatureUnit']}, "
f"wind {p['windSpeed']} {p['windDirection']}. {p['detailedForecast']}"
for p in periods
)
if __name__ == "__main__":
mcp.run(transport="stdio")
Code verified against MCP Python SDK 2.2 and the live National Weather Service API. If you have seen older tutorials that import FastMCP from mcp.server.fastmcp, that is the 1.x SDK; in 2.x the class is MCPServer, imported from mcp.server.
Two details worth noting. First, print() must not be used anywhere in a stdio server, because stdout carries the protocol; use the logging module, which writes to stderr. Second, the NWS API only covers US locations, and failing requests return None so the tool can answer politely instead of crashing. Run it with uv run weather.py; it then waits for messages from a host.
To connect it to a host such as Claude Desktop, add an entry to the host’s MCP configuration (for Claude Desktop, claude_desktop_config.json), using the absolute path to your project:
{
"mcpServers": {
"weather": {
"command": "uv",
"args": ["--directory", "/ABSOLUTE/PATH/TO/weather", "run", "weather.py"]
}
}
}
On macOS and Linux you may need the full path to the uv executable in command (run which uv to find it). Restart the host, and the new tools appear. Other hosts use a similar configuration; the official build-a-server quickstart covers the details.
Now ask “What are the active weather alerts in Texas?” and this happens:
- The host sends your question to the LLM along with the list of available tools (
get_alerts,get_forecast) and their schemas. - The model decides it needs live data and responds with a request to call
get_alertswithstate="TX". - The host (usually after asking for your approval) has its MCP client send that call to the weather server as a JSON-RPC request.
- The server runs
get_alerts, calls the NWS API and returns the result as text. - The host passes the result back to the model, which writes a plain-English answer using it.
Throughout this flow, MCP ensures the exchange is smooth and standardized. The developer didn’t have to write any custom parsing of API responses for the LLM or worry about mismatched data formats – the server provided exactly the data the model needed in a model-friendly form. Similarly, if the weather API changed its response format slightly, only the server code might need updating, while the AI (client/host side) remains untouched. This decoupling is a huge win for maintainability.
MCP is being utilized in various practical applications, allowing developers to connect AI copilots to code repositories and issue trackers, enabling business chatbots to access CRM data, and facilitating personal assistants’ integration with email and calendars. In research labs, MCP can enable AI agents to interface with scientific databases and lab equipment in a standardized manner. Additionally, MCP enhances multi-agent systems by providing a shared workspace with common tools, simplifying collaboration and reducing the complexity of direct integrations between agents.
Benefits of MCP for AI Systems
Here are the main benefits of MCP from a system-design perspective, along with honest caveats:
- Interoperability: MCP is an open standard, now governed by the vendor-neutral Agentic AI Foundation under the Linux Foundation, with Anthropic, OpenAI, Google, Microsoft, AWS and others among its members. A server you write once works across hosts and models, which reduces lock-in.
- Plug-and-play tooling: adding a capability usually means connecting an existing server rather than building an integration project. When none exists, building one follows a familiar pattern, as the example above shows.
- Cleaner architecture: tool access is centralised in the host rather than scattered through custom code. When an API changes, you update one server, not every AI application that uses it. And because the 2026 spec is stateless, remote servers scale like ordinary web services.
- Better answers from fresh context: the model can pull in current or private data when needed instead of relying only on what it memorised in training, which reduces hallucination on up-to-date or niche questions. (For how this relates to retrieval, see how to use RAG to ground LLM answers; for the broader discipline of choosing what the model sees, see what is context engineering.)
- Room to evolve: a formal feature-lifecycle policy (with a twelve-month minimum deprecation window) and an extensions framework mean the protocol can grow without constantly breaking existing integrations.
Security: What MCP Does and Doesn’t Protect You From
MCP’s own spec is candid here: the protocol “enables powerful capabilities through arbitrary data access and code execution paths,” and while MCP “cannot enforce these security principles at the protocol level,” implementers should build consent flows and access controls. In other words, connecting an MCP server is much like installing software that your AI can run. The practical risks:
- Untrusted or malicious servers: a local stdio server runs code on your machine with your permissions. Only install servers you trust, review what they do, and prefer ones from verified publishers.
- Prompt injection through tool output and descriptions: anything a tool returns (a web page, an email, a ticket) or describes about itself is text the model reads, and an attacker can embed instructions in it. The spec itself says tool descriptions and annotations should be treated as untrusted unless they come from a trusted server.
- Over-broad permissions: a server connected with a token that can read and write everything is a bigger risk than one limited to what the task needs. Use least-privilege scopes, and require human approval for actions that change data or spend money.
- Weak authentication on remote servers: authorization is optional in the spec. For HTTP servers it recommends OAuth 2.1 (the MCP server acts as a resource server, and tokens must be issued for that specific server); stdio servers take credentials from the environment instead. Check that a remote server you connect to actually uses it.
MCP gives you the standard plumbing to do these things well (OAuth flows, consent prompts, per-server isolation in the host), but it does not do them for you.
Conclusion
Model Context Protocol has moved from “a promising Anthropic spec” to a vendor-neutral standard supported across the industry. By defining one way for AI applications to connect to tools and data, it replaces the N×M tangle of custom integrations with a single protocol that servers and hosts implement once. The 2026 revision made it simpler to run at scale (stateless, Streamable HTTP, extensions), and the governance move to the Linux Foundation reduces the risk of it being steered by a single vendor.
What MCP does not do is decide when an agent should use a tool, or make those tools safe. Those remain design problems for the agent builder: keep tool sets small, scope permissions tightly, and keep humans in the loop for consequential actions. If you are building agents, MCP is now the default way to give them tools; see what is an agentic AI for how that fits into the larger picture, or our n8n RAG assistant for a workflow-builder approach to connecting AI to your data.
People Also Ask:
What is the Model Context Protocol (MCP)?
MCP is an open standard that lets AI applications connect to external tools, data sources and services through a common interface. A host application (like a chat assistant or IDE) runs MCP clients that connect to MCP servers, which expose tools, resources and prompts. It was introduced by Anthropic in November 2024 and is now governed by the Agentic AI Foundation under the Linux Foundation.
Is MCP only for Anthropic’s Claude?
No. MCP is vendor-neutral. Claude, ChatGPT, Gemini, GitHub Copilot in VS Code, Cursor and Microsoft Copilot products all support it to varying degrees, and any application can implement the protocol. A server written once can be used by any compatible host, regardless of the underlying model.
How is MCP different from function calling?
Function calling is a model feature: you describe functions to one provider’s API and the model returns a request to call them. You still write the code that executes the call and wire it up for every app. MCP standardises the layer around that: how tools are described, discovered and invoked across applications and providers, so a tool is built once as a server and reused everywhere. They work together; an MCP host typically uses the model’s function calling to decide when to call an MCP tool.
Do I need to write code to use MCP?
Not necessarily. Many hosts let you add existing MCP servers through settings or a config file, and vendors publish servers for popular services. To expose your own data or an internal system, you would build a server with an official SDK in Python, TypeScript or another supported language; a simple tool takes a few dozen lines, as in the weather example above.
Is MCP secure?
It provides the building blocks for security (OAuth-based authorization for remote servers, a requirement that hosts get user consent before calling tools, and server isolation enforced by the host), but it cannot guarantee security by itself. Risks include malicious servers, prompt injection through tool output, and over-broad permissions. Only use servers you trust, grant least privilege, and require approval for sensitive actions.
What transports does MCP use?
Two standard ones: stdio, where the host launches a local server process and exchanges messages over standard input and output, and Streamable HTTP, where each message is an HTTP POST to a single endpoint with replies as JSON or a streamed response. The older HTTP+SSE transport is deprecated.
Which version of the MCP spec is current?
As of this update, the 2026-07-28 revision. It made the protocol stateless (removing the initialize handshake and sessions), moved Tasks and MCP Apps into optional extensions, and deprecated Roots, Sampling and Logging. Official SDKs track it; the Python SDK is at version 2.x.