MCP Protocol Explained: A Complete Guide for Developers
Understand the Model Context Protocol from first principles to production.
The Model Context Protocol (MCP) is one of the most important developments in AI infrastructure. It standardizes how AI agents interact with external tools, data sources, and APIs. This guide explains MCP from the ground up β what it is, how it works, and why it matters.
What Is MCP?
MCP (Model Context Protocol) is an open protocol that defines how AI models discover, understand, and use external capabilities. It's like USB-C for AI β a universal standard that any tool can implement and any AI agent can use.
The Problem MCP Solves
Before MCP:
- Every AI platform had its own tool format
- Developers built separate integrations for Claude, GPT, Gemini
- Tools couldn't be shared across platforms
- No standard way to discover or price capabilities
After MCP:
- Build a tool once β works with every AI agent
- Standardized discovery, invocation, and pricing
- Open ecosystem where tools are interchangeable
- Marketplace-compatible (publish once, sell everywhere)
Core Concepts
1. Tools
Tools are the primary capability exposed by an MCP server. Each tool has:
{
"name": "search_web",
"description": "Search the web and return results",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search query" },
"maxResults": { "type": "integer", "default": 10 }
},
"required": ["query"]
},
"outputSchema": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": { "type": "string" },
"url": { "type": "string" },
"snippet": { "type": "string" }
}
}
}
}
}
}
2. Resources
Resources are data sources that agents can read:
// A resource provides data to agents
server.resource("docs://api-reference", async () => {
return {
content: "# API Reference\n\n...",
mimeType: "text/markdown",
};
});
server.resource("data://product-catalog", async () => {
return {
content: JSON.stringify(catalog),
mimeType: "application/json",
};
});
3. Prompts
MCP servers can provide pre-configured prompts:
server.prompt("code-review", {
description: "Review code for best practices",
template: `Review the following ${language} code:\n\n${code}\n\nCheck for: security, performance, readability.`,
});
Protocol Architecture
Transport Layers
MCP supports multiple transport mechanisms:
stdio Transport
Agent βstdin/stdoutβ MCP Server (local process)
Best for: Local development, CLI tools, desktop applications
HTTP/SSE Transport
Agent βHTTPβ MCP Server (remote)
Best for: Production deployment, shared services, cloud
WebSocket Transport
Agent βWebSocketβ MCP Server (persistent connection)
Best for: Real-time communication, streaming results
Message Format
MCP uses JSON-RPC 2.0:
// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_web",
"arguments": {
"query": "MCP protocol tutorial"
}
}
}
// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{\"results\": [...]}"
}
]
}
}
Discovery: How Agents Find Tools
When an MCP agent connects to a server, it automatically discovers available capabilities:
1. Agent connects to MCP Server
2. Agent sends "tools/list" request
3. Server returns list of tools with schemas
4. Agent sends "resources/list" request
5. Server returns available resources
6. Agent now knows everything the server can do
This eliminates manual configuration. Point an agent at an MCP server, and it immediately knows what tools are available and how to use them.
Lifecycle of a Tool Call
βββββββββββ βββββββββββ
β Agent β β Server β
ββββββ¬βββββ ββββββ¬βββββ
β β
β 1. tools/list β
ββββββββββββββββββββββββββββββββ
β 2. Tool catalog β
ββββββββββββββββββββββββββββββββ
β β
β 3. tools/call (search_web) β
ββββββββββββββββββββββββββββββββ
β β
β 4. progress notification β
ββββββββββββββββββββββββββββββββ
β β
β 5. progress notification β
ββββββββββββββββββββββββββββββββ
β β
β 6. Final result β
ββββββββββββββββββββββββββββββββ
β β
Progress Streaming
For long-running operations, MCP supports streaming progress:
server.tool("process_video", schema, async (args, context) => {
for (let i = 0; i < frames.length; i++) {
await processFrame(frames[i]);
// Report progress to the agent
context.reportProgress({
progress: (i / frames.length) * 100,
message: `Processing frame ${i}/${frames.length}`,
});
}
return { content: [{ type: "text", text: "Done!" }] };
});
Security Model
Authentication
MCP supports multiple authentication mechanisms:
// API Key authentication
server.use(authMiddleware({
type: "api_key",
headerName: "x-api-key",
validate: async (key) => {
return await db.apiKeys.isValid(key);
},
}));
// OAuth 2.0
server.use(authMiddleware({
type: "oauth2",
issuer: "https://auth.example.com",
audience: "my-mcp-server",
}));
Authorization
Fine-grained tool-level permissions:
server.setPermissions({
"user_role:viewer": {
allowed: ["read_data", "search"],
denied: ["write_data", "delete"],
},
"user_role:admin": {
allowed: ["*"],
},
});
Data Protection
- Encryption β TLS for transport, optional field-level encryption
- Audit logging β Every tool call is logged with full context
- Rate limiting β Per-client, per-tool, and global limits
- Sandboxing β Tool execution can be sandboxed (Docker, WASM)
MCP vs Other Protocols
MCP vs REST API
| Aspect | REST API | MCP |
|---|---|---|
| Consumer | Human developers | AI agents |
| Discovery | Read docs manually | Automatic |
| Schema | OpenAPI/Swagger | JSON Schema (embedded) |
| Versioning | URL paths / headers | Protocol version negotiation |
| Streaming | Limited (chunked) | Native (SSE/WebSocket) |
| State | Stateless | Session support |
MCP vs GraphQL
| Aspect | GraphQL | MCP |
|---|---|---|
| Purpose | Data querying | Tool invocation |
| Consumer | Frontend developers | AI agents |
| Real-time | Subscriptions | Progress streaming |
| Complexity | Medium | Low |
| Standardization | Per-service | Universal |
MCP vs gRPC
| Aspect | gRPC | MCP |
|---|---|---|
| Transport | HTTP/2 | stdio, HTTP, WebSocket |
| Schema | Protocol Buffers | JSON Schema |
| Consumer | Microservices | AI agents |
| Bidirectional | Yes | Yes |
| Discovery | Reflection | tools/list |
Versioning and Compatibility
MCP uses semantic versioning:
MCP/1.0.0
β β βββ Patch: Bug fixes, no breaking changes
β βββββ Minor: New features, backward compatible
βββββββ Major: Breaking changes
Backward Compatibility
// Servers can support multiple protocol versions
const server = new McpServer({
name: "my-server",
version: "1.0.0",
protocolVersions: ["1.0.0", "0.9.0"], // Support current and previous
});
// Version negotiation during connection
// Client: "I support MCP 1.0.0 and 0.9.0"
// Server: "Let's use 1.0.0"
Real-World Example: Complete MCP Server
import { McpServer } from "@modelcontextprotocol/sdk";
import { z } from "zod";
const server = new McpServer({
name: "analytics-tools",
version: "1.0.0",
});
// Tool: Query analytics database
server.tool(
"query_analytics",
"Query the analytics database with natural language",
{
question: z.string().describe("Natural language analytics question"),
dateRange: z.object({
start: z.string().describe("ISO date"),
end: z.string().describe("ISO date"),
}),
format: z.enum(["json", "chart", "summary"]).default("json"),
},
async (args) => {
const sql = await nlToSql(args.question);
const data = await db.query(sql, args.dateRange);
if (args.format === "chart") {
const chart = await generateChart(data);
return { content: [{ type: "image", data: chart }] };
}
return { content: [{ type: "text", text: JSON.stringify(data) }] };
}
);
// Tool: Generate report
server.tool(
"generate_report",
"Generate a formatted analytics report",
{
title: z.string(),
sections: z.array(z.object({
heading: z.string(),
query: z.string(),
})),
},
async (args) => {
const report = await buildReport(args);
return { content: [{ type: "text", text: report }] };
}
);
// Resource: Available metrics
server.resource("data://metrics", async () => {
const metrics = await getAvailableMetrics();
return {
content: JSON.stringify(metrics),
mimeType: "application/json",
};
});
// Start server
server.run({ transport: "http", port: 8000 });
The MCP Ecosystem
Major Implementations
| Platform | MCP Support | Notes |
|---|---|---|
| Claude | Native | First-class MCP integration |
| GPT (via adapter) | Supported | Through OpenAI's MCP adapter |
| LangChain | Supported | Via LangChain MCP integration |
| CrewAI | Supported | MCP tools in CrewAI agents |
| Custom agents | Via SDK | Any agent can implement MCP client |
Marketplaces
- SkillExchange β 50,000+ MCP skills
- OpenAI GPT Store β MCP-compatible GPTs
- LangChain Hub β MCP-compatible chains
Future of MCP
The protocol is evolving rapidly. Upcoming features include:
- Native streaming responses β Tools can stream text/token output
- File transfer β First-class file upload/download support
- Multi-agent sessions β Multiple agents sharing a single MCP session
- Built-in payments β Protocol-level pricing and payment
- Federated servers β One server proxying tools from others
- Edge deployment β MCP servers running on edge nodes
Conclusion
The Model Context Protocol represents the future of AI-tool interaction. By providing a universal standard for tool discovery, invocation, and pricing, MCP eliminates the integration overhead that has held back AI agent adoption.
Whether you're building tools, deploying agents, or running a business, understanding MCP is essential for navigating the AI-first economy of 2026 and beyond.
Learn More
- How to Build an MCP Server β Step-by-step tutorial
- MCP vs Function Calling β When to use each
- MCP Server Security β Hardening guide
- Claude MCP Integration β Claude-specific guide
Ready to explore MCP tools? Browse SkillExchange for thousands of MCP-compatible skills.