Last updated: May 2026

The Model Context Protocol,
explained the way agents actually use it.

A practical, practitioner-grade reference: what MCP is, how it works, how to build one well, and how to keep it secure - with animated diagrams of every flow.

97M+
SDK downloads
10K+
Active public servers
2
Standard transports
M+N
Replaces M x N integration
// 01 - Definition

What is MCP?

An open JSON-RPC 2.0 standard that gives any LLM a single, uniform way to call tools, read data, and use reusable prompts from any compliant external system. The "USB-C for AI" - one connector, every device.

The M x N -> M+N integration collapse
BEFORE MCP - M x N adapters Host A Host B Host C Tool 1 Tool 2 Tool 3 9 custom integrations -> MCP WITH MCP - M + N connectors Host A Host B Host C M C P B U S Tool 1 Tool 2 Tool 3 6 standard connectors

A short history

The mental model -> A Host (Claude Desktop, an IDE, your agent) runs one Client per Server. The server is the program that exposes capabilities from some external system. One host, many clients, many servers - all speaking the same protocol.
// 02 - Primitives

The building blocks

MCP organizes capabilities into a small set of named primitives. Three live on the server, three live on the client, and a handful are protocol-level. Know them cold.

Server-side primitives what your server exposes

T

Tools

Functions the model can invoke - query a DB, send an email, create a GitHub issue. Each has a name, description and JSON Schema.

model-controlled
R

Resources

Read-only data identified by URI - file contents, DB rows, API responses. Pulled into context by the host or user.

application-controlled
P

Prompts

Reusable, parameterized templates the server exposes - slash commands, workflows. The user picks them from a menu.

user-controlled

Client-side primitives what the server can ask the host to do

S

Sampling

Server asks the host's LLM to run a completion - so an agentic server can reason without shipping its own API key. User must approve.

sampling/createMessage

Roots

Client tells the server "you may operate within these URIs" - filesystem paths, repo URLs, namespaces. Dynamic, updatable.

scope boundary
?

Elicitation

Server asks the user a structured follow-up question mid-flow - "Which environment do you want to deploy to?"

elicitation/create

Protocol-level primitives

// 03 - Mechanics

How MCP works, end-to-end

Built on JSON-RPC 2.0. Every message is a request, response, or notification. Two standardized transports: stdio for local, Streamable HTTP for remote.

JSON-RPC 2.0 stdio transport Streamable HTTP Server-Sent Events Bidirectional
Animated session lifecycle - initialize -> discover -> operate -> notify -> shutdown
MCP Client (in Host) MCP Server 1 initialize { capabilities } 2 result { server capabilities } 3 notifications/initialized 4 tools/list · resources/list · prompts/list -> catalog returned 5 tools/call { name, args } 6 result { structured content } 7 notifications/tools/list_changed 8 shutdown

The two transports, side by side

stdio

Host spawns the server as a subprocess. Talks over stdin/stdout. Best for local, single-user integrations - IDE plugins, desktop apps. Trust the host process.

Streamable HTTP

Server runs as a remote service. Client POSTs JSON-RPC; server streams responses and notifications over SSE on the same connection. This is how multi-tenant production servers run.

// 04 - Build Checklist

What to consider when building a server

A "hello world" MCP server is 50 lines. A production-grade one is a product. Here's the checklist that separates toys from tools agents love.

  1. Define the agent story first. Write the user-and-agent workflows you want to support, then design the minimum tools to satisfy them in one or two calls - not seven.
  2. Pick the right transport. stdio for local; Streamable HTTP for remote multi-tenant.
  3. Choose stateful vs stateless deliberately. Default to stateless; externalize session state to Redis/DynamoDB.
  4. Budget your tool surface. 5-8 tools per server is the sweet spot. Past ~12, agent performance degrades.
  5. Write tool descriptions for the LLM. Action-first, disambiguating, under ~200 tokens. They go straight into the context window.
  6. Design payloads for context economy. Return only what the agent needs for the next decision. Offer a verbose flag if power users need more.
  7. Errors are guidance, not just failures. "Permission denied" is bad. "Reauthenticate with repo:write scope" is useful.
  8. Version gracefully. Tool names and schemas are a public API. Add fields as optional; never repurpose existing ones.
  9. Observability from day one. Structured logs, per-tool latency, audit trail of who called what.
// 05 - Comparison

Why MCP and not just APIs?

MCP and REST solve different problems for different consumers. The fastest way to misuse MCP is to think of it as "an API with extra steps." It isn't.

Dimension
REST API
MCP
consumer
Human developer writing code
LLM agent at runtime
discovery
Docs at build time
tools/list at runtime
state
Stateless request/response
Stateful JSON-RPC session
direction
Client -> server only
Bidirectional (push, sample, elicit)
schema
OpenAPI (for humans)
JSON Schema + natural-language
errors
HTTP status codes
Guidance text agents can act on
auth
Many flavors, ad hoc
OAuth 2.1 + PKCE + Resource Indicators
best for
Deterministic system-to-system
Open-ended agent workflows

When to reach for each

Use MCP when...

An agent dynamically chooses what to do · three+ tools combine in one chat · you want the same integration to work across Claude, ChatGPT, Cursor, your in-house agent · destructive actions need user-consent flow.

Keep REST when...

A scheduled job calls a known endpoint with known params · mobile app needs deterministic CRUD with strict latency · the caller is human-written code, not a model.

The honest framing -> MCP sits on top of your APIs, it doesn't replace them. Your REST API is still the system of record. The MCP server is the agent-friendly facade in front of it.
// 06 - Agent Interaction

How agents interact with MCP

From the agent's point of view, MCP tools look identical to natively defined functions - but richer, with semantic descriptions and live discovery.

Animated tool invocation flow - user prompt to system response
User prompt Agent LLM picks tool Client JSON-RPC Server executes tool API DB · SaaS "refund this" stripe_refund tools/call REST POST

The five phases of agent ↔ MCP

  1. Connection - host spawns/connects each configured server, runs the initialize handshake.
  2. Discovery - client calls tools/list; descriptions land in the agent's system prompt.
  3. Decision - LLM, given the catalog, decides whether to answer or call a tool. MCP's richer descriptions improve tool-selection accuracy materially.
  4. Invocation - chosen call goes out as tools/call; server executes; result feeds back as a tool message.
  5. Streaming & callbacks - long tools stream progress; servers can push list_changed, run sampling, elicit user input.
// 07 - Security

Security designs for your MCP server

Public MCP deployments have already shown familiar security failures: leaked credentials, broad tokens, weak audit trails, and prompt-injection exposure. Treat the bar as high from day one.

The five recurring attack classes

Prompt injection

Malicious instructions hidden in data the agent reads - an issue title, an email body - that hijack the agent into calling tools it shouldn't.

indirect injection

Tool poisoning / rug pulls

Hosted server ships benign tools, then mutates them with hidden directives later. Defend with pinning and signature verification.

MCPTox vector

Over-privileged tokens

User grants a broad scope once; every agent action runs with the union. Least-privilege per tool is essential.

scope sprawl

Credential sprawl

Every dev spins up their own server with their own keys, stored insecurely in source or env files. Leaked keys turn a small server into a large incident.

secret hygiene

Audit blind spots

No record of which agent called which tool, on whose behalf, with what arguments. Compliance fails when you can't answer.

governance gap

Cross-server token replay

Token issued for server A reused at server B. Mitigated by RFC 8707 Resource Indicators binding tokens to a server URI.

RFC 8707
OAuth 2.1 + PKCE + Resource Indicators flow for protected HTTP servers
Agent / Client Auth Server MCP Server 1 authorize + PKCE challenge + resource=mcp.example.com 2 authorization code (user consents) 3 code + PKCE verifier -> exchange 4 access_token { aud: mcp.example.com, exp: 30m } 5 tools/call + Bearer token 6 validates aud + scope -> result

The compact security rule

The six commandments -> Authenticate every request. Authorize every tool call. Validate every input. Sanitize every output. Encrypt every connection. Log every action.

Security baseline for HTTP deployments

// 08 - Wrapping Existing APIs

Designing MCP when you already have rich APIs

The most common starting point - and the most commonly bungled. The trap: one MCP tool per REST endpoint. It works. It's frustrating. Simple goals take five calls.

The rule -> Do not mirror your API surface. Your REST API was designed for human developers with a debugger and docs open. Your agent has neither. MCP design is a product exercise, not an export job.

Patterns that work

Workflow tools, not CRUD tools

Instead of list_issues + get_issue + update_issue + list_comments + add_comment, expose triage_issue that does the obvious orchestrated thing.

Service-prefixed names

Pattern: {service}_{verb}_{noun} - slack_send_message, linear_create_issue, stripe_refund_charge. Avoids collisions across loaded servers.

Domain-sharded servers

A 400-endpoint API != one MCP server with 400 tools. It's 10-20 small servers, each scoped to a coherent domain. Hosts load only what they need.

Generated scaffold, hand-tuned surface

Stainless, FastMCP, Azure APIM auto-generate stubs from OpenAPI. Treat as starting point. Hand-curate names, collapse endpoints, prune fields.

Server-side ranking + pagination

500 results is fine for REST. For MCP it's broken. Default to 5-20, rank by relevance server-side, let the model ask for more.

Anti-patterns to avoid

Every endpoint "for completeness" · raw API JSON unchanged · HTTP status codes as errors · agent forced to know internal IDs.

A migration path

  1. Stand up a thin generated server from your OpenAPI spec to validate plumbing.
  2. Instrument it. Log which tools the agent actually uses for real workflows.
  3. Identify the top 3-5 workflows by frequency.
  4. Replace each cluster of fine-grained tools with one workflow tool.
  5. Retire unused fine-grained tools, or move behind a "power user" flag.
  6. Re-evaluate quarterly - usage shifts as agents and users learn what's possible.
// 09 - Session Management

Session management - shared vs per-agent

One of the most consequential decisions in MCP architecture. The 2026 roadmap highlights transport scalability, stateless operation, and explicit session handling.

Stateful vs stateless tradeoffs

Stateful - the upside

Handshake paid once. Subsequent calls are compact and fast. Multi-step workflows hold server-side state (cursors, transactions). Bidirectional flow stays open for notifications, sampling, elicitation.

Stateful - the cost

Sticky routing fights load balancers and rolling deploys. Restart drops sessions unless externalized. Horizontal scaling has to plan for concurrent open sessions, not just request rate.

Recommended pattern - one MCP session per (user, agent_session), state externalized
User A · Agent session: a1 User B · Agent session: b1 User C · Agent session: c1 Load balancer MCP Server #1 stateless MCP Server #2 stateless MCP Server #3 stateless Shared State Store Redis · DynamoDB session metadata cursors · checkpoints

Shared session vs one-per-agent

One per agent recommended

Each agent session gets its own MCP session. State is isolated. A misbehaving agent can't pollute another. Auth scopes bound to the calling user. What virtually all production hosts do.

Shared across agents dangerous

Cross-tenant leakage risk · auth confusion (whose scopes?) · concurrent-modification bugs. If you need shared expensive resources, share the resource, not the session.

// 10 - Architecture Best Practices

Architectural best practices

Consolidated from the official spec, the 2026 roadmap, and what production teams have learned the hard way.

Scope & structure

One server, one domain 5-8 tools sweet spot Service-prefixed names Workflow over CRUD No "and" in elevator pitch

Schema & contracts

Strict JSON Schema LLM-readable descriptions Versioned, additive changes Structured content returns

Transport & deployment

Stateless by default Externalized session state Health + readiness probes Horizontal scale assumed

Security

OAuth 2.1 + PKCE Resource Indicators Short-lived tokens Least-privilege scopes Human confirm destructive ops Allow-list egress

Reliability

Idempotency keys Timeouts + circuit breakers Classified errors with guidance Never leak stack traces

Observability

Structured logs per call p50/p95/p99 latency per tool Distributed traces Audit trail for compliance Tool-definition pinning

Developer experience