Every host that speaks MCP, the reference servers worth reading, the Registry, the four canonical server-design patterns, and how distribution really works in 2026. Updated for revision 2026-07-28 (stateless MCP, Sampling and Roots deprecated); handshake-era material is tagged “before 2026-07-28”.
uvx / npx / DockerWithin fourteen months of the spec going public, MCP went from one Anthropic host to a dozen mainstream ones. The list as of early 2026:
| Host | Class | Transports | Notes |
|---|---|---|---|
| Claude Desktop | Chat app | stdio, Streamable HTTP | Reference implementation. Config in claude_desktop_config.json. Users add “Connectors” from the UI. |
| Claude Code | CLI agent | stdio, Streamable HTTP, SSE | Servers configured per-project (.mcp.json) or globally. First-class plugin model on top. |
| Cursor | IDE | stdio, Streamable HTTP | One of the earliest non-Anthropic adopters. Strong tool-call surfacing in chat. |
| VS Code (Copilot Chat) | IDE | stdio, Streamable HTTP | MCP servers run in the workspace; per-folder configuration. |
| Zed | IDE | stdio | Native Rust client; Slash-command bridge to MCP prompts. |
| Continue | IDE plugin | stdio, Streamable HTTP | Cross-IDE (VS Code, JetBrains). MCP servers feed the agent's tool surface. |
| Windsurf (Cascade) | IDE | stdio, Streamable HTTP | Codeium's agentic IDE; full MCP server support. |
| OpenAI Agents SDK | SDK / framework | stdio, Streamable HTTP | OpenAI added MCP-client support; Anthropic servers are first-class peers of OpenAI “hosted tools”. |
| LangGraph / LangChain | Framework | stdio, Streamable HTTP | MCP integrations turn any server into a LangChain tool node. |
| OpenWebUI, LibreChat | Self-hosted UIs | stdio, Streamable HTTP | Bring-your-own-model UIs with MCP server hooks. |
If you ship one MCP server, you reach all of these hosts on day one. That's the M+N payoff — and the reason the protocol stuck where every previous standardisation attempt failed.
The modelcontextprotocol/servers repo on GitHub is a working library of reference implementations. They're worth reading for two reasons: they exercise every primitive correctly, and they're the canon hosts test against.
filesystem — tree under a rootgit — repo introspectionsqlite / postgres — SQL queryfetch — HTTP GET with content extractionmemory — persistent KV across sessionsgithub — full GitHub API surfacegitlabslack — post messages, searchbrave-search — web searchpuppeteer — headless browser actionseverything — demonstrates every primitivesequential-thinking — reasoning scaffoldingtime — timezone-aware now/convertaws-kb-retrieval — Bedrock KB searchgdrive, google-mapsPick servers/src/sqlite or servers/src/filesystem in the repo. Each is < 500 lines. The structure is the same across all of them:
run() call binding stdio transport.The everything server is the one to read if you want to see every feature in one place. It's deliberately not useful as a tool — it's a working catalogue.
Through 2025 the discovery story was “read READMEs”. The official MCP Registry, generally available in early 2026, fixes that. It's an open, JSON-Schema-driven catalogue of servers with metadata, capabilities, and install instructions.
{
"name": "io.acme/postgres",
"version": "2.4.1",
"description": "Read and write a PostgreSQL database.",
"homepage": "https://github.com/acme/mcp-postgres",
"license": "MIT",
"publisher": { "id": "io.acme", "verified": true },
"transports": ["stdio","http"],
"protocol_versions": ["2025-03-26","2025-06-18"],
"capabilities": {
"tools": [
{ "name":"query", "annotations":{ "readOnlyHint": true } },
{ "name":"mutate", "annotations":{ "destructiveHint": true } }
],
"resources": ["pg://schema/{table}"]
},
"install": {
"uvx": "uvx mcp-server-postgres",
"docker": "ghcr.io/acme/mcp-postgres:2.4.1"
},
"auth": {
"type": "oauth2",
"scopes_required": ["postgres.read","postgres.write"]
},
"signature": "sha256:…"
}
uvx if Python is available, fallback to Docker).The Registry is the link that turns MCP from a protocol into a marketplace. It's also the easiest place to enforce a security posture organisation-wide: enterprise registries can shadow the public one and only surface vetted servers.
The simplest and most common pattern. The server exposes resources — addressable read-only chunks of context. No side effects, no authentication beyond the user's own credentials, low risk surface.
db://users/{id}/profile)query, search)resources/subscribe for live datadestructiveHint tools at allresources/list → { resourceTemplates:[
{ uriTemplate:"wiki://{space}/{slug}", name:"Wiki page" },
{ uriTemplate:"wiki://search?q={q}", name:"Search"}
]}
resources/read → { contents:[{ uri, mimeType:"text/markdown", text:… }]}
tools/list → [{ name:"recent_changes",
annotations:{ readOnlyHint:true }}]
tools/call → { content:[{type:"resource_link", uri:"wiki://…"}],
structuredContent:{ pages:[…]}}
Resources are URIs — the host can cache, link, and reference them. A tool result is opaque text. If your “tool” is conceptually fetch(URI) → bytes, model it as a resource and the host gets all the address-tracking benefits for free.
The riskier sibling. The server exposes tools that change something in the world — create issues, send messages, deploy services, mutate data. Annotations and confirmations carry the safety weight.
destructiveHint set honestlyreadOnlyHint:true on a write tool)The host decides UX based on annotations — auto-approve, prompt, confirm-with-typed-acknowledgement. You, the server author, are the only one who knows whether a tool is destructive. Be honest.
{
"name": "force_push",
"title": "Force Push Branch",
"description": "git push --force-with-lease to remote.",
"inputSchema": {
"type":"object",
"properties":{
"remote":{"type":"string"},
"branch":{"type":"string"},
"expected_sha":{"type":"string","pattern":"^[a-f0-9]{40}$"}
},
"required":["remote","branch"]
},
"annotations":{
"readOnlyHint": false,
"destructiveHint":true,
"idempotentHint": false,
"openWorldHint": true
}
}
Don't try to enforce destructive-action confirmations through clever schema (a confirm: "yes" field). The host's UI gates are the right place. Rely on destructiveHint and let the host decide whether to show a typed-acknowledgement prompt.
The server runs an inner agent loop that calls back into the host's LLM via sampling/createMessage. The host owns the model and the user gates each sample — the server brings the workflow.
A normal tool call is a one-shot RPC. An agent server is multi-turn: it samples, inspects the result, samples again, possibly calls its own tools internally, and only returns to the host when its inner loop terminates.
An agent server can fire many sample requests for one tool call. The host charges those samples to the user. Hosts let users approve sampling per-server with rate caps. Keep your inner loops bounded; emit notifications/progress generously so the user knows they're paying for something.
The diagram shows sampling as server-initiated requests (before 2026-07-28). In 2026-07-28 Sampling is deprecated (still functional; earliest removal in the first revision on or after 2027-07-28) and its suggested migration is for the server to call an LLM provider API itself. Where sampling is still used, each sampling/createMessage travels in the inputRequests of an input_required result and the client retries the tool call with the completion (deck 03, slide 06b), so an inner loop of n samples becomes up to n retries of the same tools/call, with the loop's state carried in requestState.
Source: MCP specification 2026-07-28 — Deprecated features; Multi round-trip requests (accessed 2026-10-08).
Hosts routinely run 5–15 servers concurrently. The host is the orchestrator: it sees the union of all tool catalogues, decides which server to call for each step, and stitches results together. Two friction points emerge.
Two servers can both expose a search tool. The host needs to disambiguate. Two strategies:
Host renames search from server github to github__search in the model's tool catalogue, dispatches based on the prefix on call. Server stays oblivious.
Server author names tools gh_search, jira_search, etc. Less elegant; works without host help. Pick one and stick with it across your tool surface.
The user opens project ~/code/api in their IDE. Three running servers care: filesystem, git, postgres. The host's roots mechanism is how it tells them all in one shot:
// from each connected server’s perspective
{"jsonrpc":"2.0","method":"notifications/roots/list_changed"}
// servers respond with
{"jsonrpc":"2.0","id":99,"method":"roots/list"}
// host returns the current set
{"jsonrpc":"2.0","id":99,"result":{
"roots":[
{"uri":"file:///Users/me/code/api","name":"api"}
]
}}
Servers MUST honour roots: filesystem only serves files under the listed roots; git opens the repos inside them; postgres may key its connection on the project. Roots are the user's consent boundary materialised on the wire.
Roots are deprecated and notifications/roots/list_changed is removed; a server can no longer call roots/list on its own, only ask for it inside an input_required result. The suggested migration is to pass directories or files as tool parameters, resource URIs or server configuration. The consent boundary moves into the host's per-call arguments and the server's config.
Source: MCP specification 2026-07-28 — Roots; Deprecated features (accessed 2026-10-08).
Servers don't talk to each other. The host is the only thing that sees output from server A go into the prompt that produces a tool call to server B. That's deliberate; it keeps the trust topology star-shaped instead of mesh-shaped.
If a tool's output is meant to flow into another server's tool, design that output to be small, structured, and self-describing. The host won't know which fields are stable contracts and which are transient prose unless your output schema tells it.
uvx / npx / DockerHow servers reach users. Almost every community server falls into one of three distribution shapes:
| Shape | Command | When | Trade-offs |
|---|---|---|---|
| uvx (Python) | uvx mcp-server-foo | Server is published to PyPI | Zero-install for the user, downloads on first run, uv's caching makes second run instant. Python-only. |
| npx (Node) | npx -y @scope/mcp-server-foo | Server is published to npm | Same UX for Node. The -y auto-confirms the install prompt. |
| Docker | docker run --rm -i ghcr.io/acme/mcp-foo:1.4 | Server has system deps or you want sandboxing | Heavier, but ships the runtime. Pin by digest in production. |
| Native binary | /usr/local/bin/mcp-foo | Static binary, e.g. Go server | Fastest startup. Distribution is your problem (Homebrew, cargo, releases). |
| Streamable HTTP | https://mcp.acme.io | Hosted SaaS | No install. OAuth required. Versioning happens server-side. |
MCP date-stamped versions and your server's semver are independent. Best practice:
initialize, accept the highest mutually-supported value the client offers before 2026-07-28. From 2026-07-28 there is no initialize: implement server/discover, judge the version on every request and answer an unsupported one with -32022 listing supported; a dual-era server also keeps answering initialize for legacy clients.protocol_versions when you tested against a new spec.Source: MCP specification 2026-07-28 — Versioning and compatibility; Discovery (accessed 2026-10-08).
You can run a stdio server inside a container by attaching the host's stdin/stdout (docker run -i …). The container becomes a sandbox without changing the protocol. This is the path of least resistance for “I want isolation, I don't want to rewrite my server.”
modelcontextprotocol/servers; everything shows them all in one place.uvx and npx for local, Docker for sandboxed, Streamable HTTP for SaaS. Pin versions, advertise honestly, support a window.MCP is JSON-RPC primitives over stdio or Streamable HTTP, with capability negotiation and version stamping (deck 01), wire-level transports designed for resumable streams and session reuse (deck 02; revision 2026-07-28 replaced both with stateless, self-describing requests), an SDK ecosystem that gets you a useful server in 30 lines (deck 03), security mechanisms (OAuth 2.1, audience binding, sandboxing) that defuse a real threat surface (deck 04), and a converged host ecosystem with four canonical server-design patterns (deck 05). It's not a complicated protocol — the hard part is shipping a server that's a good citizen.