AI / Protocols

Model Context Protocol (MCP) Explained: The Standard for Connecting AI to Everything

/15 min read

The Model Context Protocol (MCP) is an open protocol, originally released by Anthropic in November 2024, that standardizes how AI applications connect to external data sources and tools. It is often described as “USB-C for AI”: instead of writing a custom integration for every model provider and every tool, you write one MCP server and any MCP-capable host can use it.

What Problem MCP Solves

Before MCP, an AI application that needed to read a database, query an issue tracker, and send a message to Slack required three bespoke integrations — each written against a specific function-calling schema, specific to one model provider, and maintained by hand. Multiply that by every AI application and every tool, and you get an N × M integration problem: N models times M tools, each with its own adapter.

MCP collapses this to N + M. A tool author writes one MCP server. Every MCP host — Claude Desktop, Claude Code, VS Code Copilot, Cursor, Zed, Cline, and dozens of others — can discover and call it without custom glue code. The protocol handles capability negotiation, tool discovery, schema exchange, and invocation so the application layer does not have to.

How MCP Works: Architecture

MCP follows a client-host-server architecture. Three roles are defined by the specification:

  1. Host: The AI application itself (an IDE agent, a chat client, a custom agent loop). The host owns the LLM, the user interaction, and the permission model.
  2. MCP client: A connector inside the host, maintaining a one-to-one, stateful session with a single server.
  3. MCP server: A service that exposes a specific capability set — a database, a filesystem, a browser, an API — over the protocol.

Communication is JSON-RPC 2.0 in both directions. The protocol is not limited to requests from client to server: servers can send notifications and even issue server-initiated requests back to the client, which is how features like sampling (asking the host LLM to complete a prompt) and elicitation (asking the user a question) work.

Client                                Server
  |                                      |
  | -------- initialize ---------------> |   protocolVersion, capabilities
  | <------- initializeResult ---------- |
  |                                      |
  | -------- notifications/initialized ->|   handshake complete
  |                                      |
  | -------- tools/list ---------------> |
  | <------- tools/listResult ---------- |   available tools + schemas
  |                                      |
  | -------- tools/call ---------------> |
  | <------- tools/callResult ---------- |   tool output
  |                                      |
  | -------- shutdown ----------------> |
  | <------- acknowledge -------------- |

The Three Primitives: Tools, Resources, Prompts

MCP exposes three core primitives. Confusing them is the most common conceptual error when teams start designing servers.

Tools

Tools are model-controlled actions. They are functions the LLM can choose to invoke: run a search, create a record, execute a query. Every tool declares a name, a human-readable description, and a JSON Schema for its inputs. The description is load-bearing — it is the only thing the model sees when deciding whether and how to call the tool.

Resources

Resources are application-controlled data. They are URI-addressable content the host can read — a file, a database row, a ticket — similar to GET endpoints. Resources are meant for context the application supplies to the model, not for actions the model performs.

Prompts

Prompts are user-controlled templates. They are reusable, parameterized instruction templates the user selects — a code review template, a triage template — rather than something the model invokes autonomously.

Later protocol revisions added more primitives: elicitation for servers to request structured input from the user, sampling for servers to request LLM completions from the host, and notifications for long-running operation progress.

Transports: stdio and Streamable HTTP

MCP defines two production transports. stdio runs the server as a local subprocess: the host spawns the process, speaks JSON-RPC over stdin/stdout, and kills it on shutdown. This is the default for local integrations — filesystem access, local dev tools, CLI wrappers — and has zero network configuration.

Streamable HTTP replaced the older HTTP+SSE transport. A single HTTP endpoint accepts JSON-RPC messages and can respond with either a plain JSON response or a Server-Sent Events stream, enabling server-push notifications over a stateless-or-stateful connection with session management via aMcp-Session-Id header. This is the transport for remote servers, shared team integrations, and anything that lives behind an API gateway.

TransportWhere it runsDiscoveryBest for
stdioLocal subprocessConfig fileLocal tools, CLIs, file access
Streamable HTTPRemote serverURL, OAuth-protectedTeam/server integrations
Streamable HTTP + OAuthRemote, multi-tenantWell-known discoveryPublic, third-party servers

Building an MCP Server

Official SDKs exist for TypeScript, Python, Java, Kotlin, C#, Ruby, and Go. A minimal server registers tools with JSON Schema inputs and returns content arrays. The following TypeScript server exposes a single order-lookup tool over stdio:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "orders-server",
  version: "1.0.0",
});

server.registerTool(
  "get_order",
  {
    title: "Look up order",
    description: "Fetch an order by its ID, including status and totals.",
    inputSchema: {
      orderId: z.string().describe("The order ID, e.g. ORD-10482"),
    },
  },
  async ({ orderId }) => {
    const order = await db.orders.findById(orderId);
    if (!order) {
      return { content: [{ type: "text", text: "Order not found" }] };
    }
    return {
      content: [{ type: "text", text: JSON.stringify(order, null, 2) }],
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

The host side is equally small: connect a transport, complete the handshake, list tools, and call them. In a real agent the model chooses which tool to call; the host only executes the call the model selected and returns the result as a tool message.

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

const transport = new StdioClientTransport({
  command: "node",
  args: ["dist/orders-server.js"],
});

const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(transport);

// Discover what the server exposes
const { tools } = await client.listTools();

// Call a tool the model selected
const result = await client.callTool({
  name: "get_order",
  arguments: { orderId: "ORD-10482" },
});

Once a server is registered in the host's configuration, it appears in every compatible client automatically. That reuse is the entire value proposition of the protocol.

MCP vs Function Calling vs Plugins

MCP is not the only way to give a model tools. The practical differences decide which approach fits a project:

DimensionRaw function callingProvider pluginsMCP
PortabilityPer-provider schemasOne vendorAny MCP host
RuntimeIn-process codeVendor-hostedLocal or remote process
DiscoveryHard-codedStore catalogRuntime listTools
StateStateless callsStatelessStateful sessions
Server → model requestsNoNoYes (sampling, elicitation)

Verdict: raw function calling is still the right tool when the integration is internal, single-provider, and simple — one API, one model, three tools. MCP earns its complexity when multiple applications should share the same integration, when third-party servers should be pluggable, or when the integration surface is expected to grow. The break-even point is usually the second consumer of the same tool.

Security Risks You Must Design For

Exposing tools to a model is exposing capability to a system that can be manipulated by untrusted input. The MCP security working group catalogs the primary attack classes, and each has a concrete mitigation:

  • Tool poisoning: A malicious server crafts tool descriptions containing hidden instructions aimed at the model. Mitigate by reviewing every server you install, pinning versions, and surfacing tool descriptions to the user before first call.
  • Rug pulls: A server behaves benignly during review, then changes its tool descriptions after approval. Mitigate by re-prompting approval when a server's advertised tools change.
  • Indirect prompt injection: Content returned by a resource — a web page, a document — contains instructions that hijack the agent. Mitigate by treating all tool output as untrusted data, never as system instructions.
  • Confused deputy: A server asks the host to act with the user's authority on data the user should not access. Mitigate with per-tool permission prompts, scope-limited OAuth tokens, and strict separation between read and write capabilities.
  • Excessive permission: A file-access server granted the whole home directory. Mitigate by running stdio servers in sandboxes with least-privilege filesystem and network access.

The rule of thumb: treat every MCP server like a third-party dependency you have not audited — because that is exactly what it is.

Ecosystem and Adoption

MCP was donated to the Linux Foundation's JDF in late 2025, moving governance beyond any single vendor. Registry aggregators (the official MCP Registry, Smithery, PulseMCP, Glama) catalog thousands of servers covering everything from Postgres and GitHub to browser automation and design tools.

On the client side, official or first-party support now ships in Claude Desktop, Claude Code, VS Code (Copilot agent mode), Cursor, Zed, Windsurf, Cline, Replit, Amazon Q, and JetBrains AI — plus a growing list of agent frameworks (LangChain, LlamaIndex, the OpenAI Agents SDK, and Vercel's AI SDK) that can act as MCP clients. Near-universal client support is what turned MCP from a promising idea into infrastructure.

When (Not) to Use MCP

MCP is the right choice when you are building an integration intended to be reused across hosts, when you want users to install your tool in the AI client they already use, or when you are assembling an agent from multiple heterogeneous capability providers.

Skip it when your tool set is small and private to one application: three hard-coded functions inside your own agent loop do not need a protocol, a handshake, and a schema negotiation. It is also a poor fit for high-throughput inference paths — MCP adds serialization, process, and network overhead that belongs in the control plane, not the hot path.

Conclusion

MCP succeeded where earlier integration attempts failed not because the protocol is clever — JSON-RPC with three primitives is deliberately mundane — but because it arrived at the moment every AI team was drowning in one-off tool plumbing, and because every major host adopted it. Standardized discovery, stateful sessions, and a shared security vocabulary turned tool integration from a bespoke craft into a commoditized interface.

If you build tools, build them once as MCP servers. If you build agents, assume your next integration will arrive as one.

Key Takeaways

  • MCP is an open JSON-RPC 2.0 protocol that standardizes AI-to-tool connections, turning an N × M integration problem into N + M.
  • Architecture has three roles: host (the AI app), client (one per server session), and server (the capability provider).
  • Three primitives: tools (model-controlled actions), resources (application-controlled data), prompts (user-controlled templates).
  • Two transports: stdio for local subprocesses, Streamable HTTP for remote servers, with OAuth for third-party access.
  • Security is the deployment bottleneck: tool poisoning, rug pulls, indirect prompt injection, and confused-deputy attacks all need explicit mitigations.

FAQ

What is MCP in simple terms?

MCP (Model Context Protocol) is an open standard that lets AI applications connect to external tools and data sources using one shared protocol. A developer writes an MCP server once, and any MCP-compatible AI client — Claude, VS Code, Cursor, and others — can discover and use it without custom integration code.

Is MCP the same as function calling?

No. Function calling is a model-provider feature where the LLM emits a structured call to code you hard-code in one application. MCP is a transport and discovery protocol layered above that: it standardizes how tools are advertised, schema-validated, and invoked across different applications and hosts. MCP servers typically use function calling underneath.

Which companies support MCP?

Anthropic created MCP in November 2024; OpenAI, Google DeepMind, Microsoft, and Amazon subsequently announced support, and the protocol was donated to the Linux Foundation. Official clients ship in Claude Desktop, VS Code Copilot agent mode, Cursor, Zed, Windsurf, Cline, and most major agent frameworks.

Is MCP secure enough for production agents?

MCP is a transport, not a security boundary. Production deployments need per-tool approval prompts, pinned and audited server versions, sandboxed stdio processes with least privilege, OAuth scopes on remote servers, and the assumption that all tool output is untrusted input. With those controls, MCP is suitable for production; without them, it exposes your agent to tool poisoning and prompt injection.

Do I need MCP if I only use one AI tool?

Usually not. If your application has a small, fixed set of internal tools and a single model provider, direct function calling is simpler and faster. MCP pays off when multiple clients should share the same integration, when third parties need to install your tools, or when your tool surface is large enough that runtime discovery beats hard-coded schemas.

References

  1. Anthropic. "Introducing the Model Context Protocol." Anthropic Engineering, November 2024. anthropic.com/news/model-context-protocol
  2. Model Context Protocol. "Architecture Overview." modelcontextprotocol.io. modelcontextprotocol.io/docs/architecture
  3. Model Context Protocol. "Security Best Practices." modelcontextprotocol.io. modelcontextprotocol.io/docs/security
  4. Simon Willison. "Tool poisoning attacks." Simon's Notes, 2025. simonwillison.net
  5. Linux Foundation. "MCP Joins the Linux Foundation." Linux Foundation News, 2025. linuxfoundation.org
Summarize with AI
Page