Modern AI assistants are remarkably good at reasoning over text. But they have a problem: by default, they are stuck inside a chat box. They cannot read your database, query your CRM, search your codebase, or trigger your CI pipeline — unless someone hand-builds a custom integration for every (AI client × external tool) combination.
That gap is what Model Context Protocol (MCP) was designed to close. If you have been hearing the term thrown around in 2026 and wondering what is behind the hype, this guide walks through MCP from scratch — what it is, why it exists, how it works, and when you would build one yourself.
What is Model Context Protocol?
Model Context Protocol is an open standard for connecting AI models to external tools, data sources, and systems. Anthropic released it as an open specification in late 2024, and adoption has accelerated rapidly through 2025-2026 across IDEs, desktop assistants, and developer platforms.
In one sentence: MCP is the USB-C of AI tooling. Instead of every AI app inventing its own way to talk to your database, your file system, or your favorite SaaS — MCP defines a single, universal handshake.
The problem MCP solves: M×N to M+N
Before MCP, integrating AI clients with external tools was an exponential mess.
Imagine you have:
- M AI clients (Claude Desktop, Cursor, ChatGPT plugins, your own AI agent…)
- N tools/data sources (Postgres, GitHub, Slack, internal APIs…)
To make any client work with any tool, you would need M × N custom integrations. That is how OpenAI plugins, LangChain custom tools, and bespoke AI connectors have historically worked — each ecosystem reinvents the same wiring.
MCP changes the math to M + N:
- Each AI client speaks MCP once.
- Each tool is wrapped in an MCP server once.
- Any client can now talk to any server.
That is the whole pitch — and it is why every major AI tool has rushed to support it.
How MCP works (architecture in plain English)
MCP follows a simple client-server model:
| Component | Role | Example |
|---|---|---|
| Host | The application a human uses | Claude Desktop, an IDE, a custom AI agent |
| Client | The MCP layer inside the host | Built into Claude Desktop |
| Server | A small program exposing tools/data | A Postgres MCP server, a Slack MCP server |
Messages are JSON-RPC 2.0 over one of two transports:
- stdio — the server runs as a subprocess; messages flow over stdin/stdout. Used for local servers.
- HTTP + SSE (or the newer Streamable HTTP) — for remote servers running on a network.
A typical conversation:
- The host launches an MCP server (or connects to a running one).
- The host asks: "What tools do you have?" → the server lists them.
- When the LLM decides to call a tool, the host forwards the call to the server.
- The server runs the work and returns a result.
- The host feeds the result back to the LLM.
The three primitives every MCP server can expose
MCP servers communicate three kinds of capabilities:
1. Tools — functions the LLM can call
A tool is a named function with input/output schemas. Examples: search_issues, create_pull_request, query_database, send_email. The LLM sees the tool's name, description, and JSON Schema for arguments, and decides when and how to invoke them.
2. Resources — data the LLM can read
Resources expose read-only context — files, database rows, web pages. They are identified by URIs like file:///project/README.md or postgres://db/users/42. The host typically lets the user pick which resources to attach to a conversation, similar to attaching files to a chat.
3. Prompts — reusable templates
Prompts are pre-baked instructions (with variables) that users can invoke. Useful for organizations that want consistent "do code review like this" or "summarize tickets in our format" patterns.
A minimal MCP server in Node.js
Here is the smallest useful MCP server — it exposes one tool that returns the current time:
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: 'time-server',
version: '1.0.0',
});
server.tool(
'current_time',
'Returns the current server time in ISO 8601 format',
{ timezone: z.string().optional().describe('IANA timezone, e.g. "Asia/Kolkata"') },
async ({ timezone }) => {
const now = timezone
? new Date().toLocaleString('en-US', { timeZone: timezone })
: new Date().toISOString();
return { content: [{ type: 'text', text: now }] };
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
That is it — fewer than 25 lines and you have a working MCP server. Any compliant client can now use the current_time tool, with proper argument validation handled by Zod.
To wire this up to Claude Desktop, you add an entry in claude_desktop_config.json:
{
"mcpServers": {
"time": {
"command": "node",
"args": ["/absolute/path/to/server.js"]
}
}
}
Restart Claude Desktop, and the new tool becomes available to the model.
Who is using MCP today?
A non-exhaustive list of MCP-aware clients in 2026:
- Claude Desktop (the original reference client)
- Claude Code (Anthropic's CLI)
- Cursor IDE
- Zed
- Continue
- Sourcegraph Cody
- A growing number of custom AI agents built on the official SDKs
On the server side, the open-source ecosystem has exploded — GitHub, GitLab, Postgres, Slack, Google Drive, Linear, Notion, Brave Search, and hundreds of community servers are already published.
MCP vs traditional APIs — what is the difference?
A common misconception: "Isn't MCP just another API?" Not quite.
| Aspect | Traditional API | MCP |
|---|---|---|
| Consumer | A human-written program | An LLM |
| Discovery | Read the docs, hand-code calls | LLM auto-discovers tools at runtime |
| Schema | OpenAPI / JSON / undocumented | Standardized JSON-RPC + JSON Schema |
| Streaming | Optional, varies | First-class (resources, progress, sampling) |
| Auth | Each API invents its own | Pluggable, standardized patterns emerging |
You can absolutely wrap an existing REST API as an MCP server — it is one of the most common patterns. But MCP is shaped specifically around how LLMs consume tools, not how human-written code does.
When should you build an MCP server?
Build one if:
- You have an internal tool or data source you want any AI assistant to be able to use.
- You want a single integration that works in Claude Desktop, Cursor, Zed, and any future MCP-aware client.
- You are tired of writing custom OpenAI function-calling wrappers for every project.
Skip MCP if:
- The tool you need already has an MCP server — use it instead (check the official registry).
- Your AI workflow is entirely browser-based and you cannot run a local subprocess (although Streamable HTTP solves this).
- You only need a one-off integration for a single proprietary client.
What is next?
This was the 30,000-foot view. From here, the natural next stops are:
- Read the official spec at modelcontextprotocol.io — it is surprisingly readable.
- Try a few servers in Claude Desktop before writing your own. The GitHub, Postgres, and filesystem servers are great starting points.
- Build your first server following the official quickstart — or wait for the next post in this series, where we will build one from scratch in Node.js.
Conclusion
MCP is not magic — under the hood, it is just JSON-RPC, well-designed primitives, and a sensible client-server split. What makes it matter is standardization. The same way HTTP turned the web from an academic experiment into the global internet, MCP is quietly turning AI assistants from clever chatbots into genuinely useful agents that can interact with the systems your work actually depends on.
If you are building anything LLM-shaped in 2026, MCP is worth a serious afternoon of your time.
Try it yourself
Once you have an MCP server wired into a host like Claude Desktop, a real conversation looks like this:
current_timeIt is currently 11:34 PM on Wednesday in Tokyo (JST, UTC+9).Behind the scenes: Claude listed your configured MCP servers, found the time-server from earlier in this post, called the current_time tool with timezone Asia/Tokyo, and used the returned text to answer. You wrote zero glue code — the protocol did the work.