What Is MCP (Model Context Protocol)? A Practical Introduction for Developers
The Problem MCP Solves
If you've built anything with LLMs beyond a chat window, you've hit the same wall: every new data source or tool needs its own custom integration. Want your agent to read files, query a database, hit an internal API, and check a calendar? That's four bespoke integrations, each with its own auth, schema, and error handling, and each tied to whatever LLM framework you happened to pick that week.
Model Context Protocol (MCP) is an open protocol, originally introduced by Anthropic, that standardizes how AI applications connect to external tools and data. Instead of writing custom glue code for every model-to-tool pairing, you implement the integration once, as an MCP server, and any MCP-compatible client can use it. It's less a new capability and more a standardization layer, similar in spirit to how the Language Server Protocol let one language server work with many editors instead of every editor writing its own support for every language.
The Core Architecture
MCP defines three main roles. A host is the application the user interacts with, e.g. a chat client, an IDE, or an autonomous agent runtime. A client lives inside the host and manages a connection to a single server. A server is the piece that exposes actual capabilities: tools to call, data to read, or prompt templates to use. Hosts can maintain many client connections at once, each talking to a different server.
Communication happens over JSON-RPC 2.0, and servers can run locally as a subprocess communicating over stdio, or remotely over HTTP with server-sent events for streaming. This dual-transport design matters in practice: local stdio servers are great for developer tools and desktop apps that need filesystem or local process access, while remote HTTP servers are what you want for anything hosted, multi-tenant, or usable from a web-based agent.
Tools, Resources, and Prompts
MCP servers expose capabilities through three primitives. Tools are callable functions with a defined input schema, the equivalent of function calling but decoupled from any specific model vendor. A tool might be summarize_document, run_query, or send_email, and the server declares its name, description, and parameters in a machine-readable format the client can pass along to the LLM.
Resources are addressable pieces of data, think of them as GET endpoints, that a client can read and inject into context, such as a file, a database row, or a log excerpt. Prompts are reusable, parameterized templates that servers can offer, letting a server package up a well-tested prompt structure rather than leaving prompt engineering entirely to the client. Most real-world servers, especially ones focused on document workflows, lean heavily on tools and resources, since those map most directly onto "do something" and "give me data" operations.
How a Request Actually Flows
Here's the practical sequence: the host starts up and its client connects to a server, performing a handshake where the server advertises its available tools, resources, and prompts. When a user asks something the LLM decides requires an external capability, the host's client sends a structured call to the appropriate server, for example invoking a find_red_flags tool with a document ID as the argument. The server executes the logic, whatever that involves internally, and returns a structured result. The host then feeds that result back into the model's context so it can generate a final response grounded in real data rather than a hallucinated guess.
Crucially, the LLM never needs custom training or fine-tuning to use a new MCP server. As long as the client surfaces the server's tool definitions to the model in its context window, and the model supports function/tool calling, it can decide when and how to invoke them. This is why MCP has been adopted quickly by multiple model providers and agent frameworks rather than staying vendor-specific.
Why Not Just Use a Regular API?
A fair question. You can absolutely give an LLM raw API access. MCP's value is in the standardization and discovery layer on top of that. Servers self-describe their capabilities in a format LLMs can consume directly, so an agent can be pointed at a new server and immediately understand what it offers, without a developer hand-writing a new tool schema for every model or framework combination. It also decouples the tool provider from the AI application: a team building a document-analysis capability can ship one MCP server, and it becomes usable from Claude, from custom agent frameworks, from IDE plugins, or from any other MCP-aware client, without rewriting anything.
That said, MCP isn't a replacement for your existing APIs, it usually sits in front of them. A well-built MCP server is often a fairly thin wrapper that translates protocol calls into the internal API requests, database queries, or scripts you already have, while handling the auth and schema-description work needed to make that logic legible to an LLM.
Getting Started as a Developer
If you're building your own server, the SDKs (available for several languages) handle the JSON-RPC plumbing so you mostly write tool handler functions and declare their input schemas. Start local: a stdio server you can test with an MCP-compatible client running on your machine is the fastest way to see the protocol in action before dealing with remote hosting, auth, or multi-tenant concerns.
If you just need capabilities rather than infrastructure, it's often faster to use an existing server than to build one. For document-heavy workflows specifically, this site's own Document Analysis MCP is a hosted server exposing summarize_document and find_red_flags tools, callable directly by any MCP-compatible client through a subscription, no server to deploy or maintain.
Either way, the protocol itself is worth understanding even if you never write a line of server code: it's quickly becoming the common substrate for how agents discover and use tools, and that's useful context for evaluating any AI tooling you adopt going forward.