Model Context Protocol Series — Presentation 05

Ecosystem & Patterns

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”.

Hosts Reference Servers Registry Patterns uvx / npx Versioning
Hosts → Servers → Registry → Data → Tool → Agent → Multi-server → Distribution
00

Topics We'll Cover

01

The Host Landscape — Who Speaks MCP

Within fourteen months of the spec going public, MCP went from one Anthropic host to a dozen mainstream ones. The list as of early 2026:

HostClassTransportsNotes
Claude DesktopChat appstdio, Streamable HTTPReference implementation. Config in claude_desktop_config.json. Users add “Connectors” from the UI.
Claude CodeCLI agentstdio, Streamable HTTP, SSEServers configured per-project (.mcp.json) or globally. First-class plugin model on top.
CursorIDEstdio, Streamable HTTPOne of the earliest non-Anthropic adopters. Strong tool-call surfacing in chat.
VS Code (Copilot Chat)IDEstdio, Streamable HTTPMCP servers run in the workspace; per-folder configuration.
ZedIDEstdioNative Rust client; Slash-command bridge to MCP prompts.
ContinueIDE pluginstdio, Streamable HTTPCross-IDE (VS Code, JetBrains). MCP servers feed the agent's tool surface.
Windsurf (Cascade)IDEstdio, Streamable HTTPCodeium's agentic IDE; full MCP server support.
OpenAI Agents SDKSDK / frameworkstdio, Streamable HTTPOpenAI added MCP-client support; Anthropic servers are first-class peers of OpenAI “hosted tools”.
LangGraph / LangChainFrameworkstdio, Streamable HTTPMCP integrations turn any server into a LangChain tool node.
OpenWebUI, LibreChatSelf-hosted UIsstdio, Streamable HTTPBring-your-own-model UIs with MCP server hooks.
What this convergence means

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.

02

Reference Servers — What Anthropic Ships

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.

The reference set, by category

Data servers (read-only)

  • filesystem — tree under a root
  • git — repo introspection
  • sqlite / postgres — SQL query
  • fetch — HTTP GET with content extraction
  • memory — persistent KV across sessions

Tool servers (side-effecting)

  • github — full GitHub API surface
  • gitlab
  • slack — post messages, search
  • brave-search — web search
  • puppeteer — headless browser actions

Mixed / specialised

  • everything — demonstrates every primitive
  • sequential-thinking — reasoning scaffolding
  • time — timezone-aware now/convert
  • aws-kb-retrieval — Bedrock KB search
  • gdrive, google-maps

How to read one

Pick servers/src/sqlite or servers/src/filesystem in the repo. Each is < 500 lines. The structure is the same across all of them:

  1. Argument parsing — root path, db path, etc.
  2. Server construction with declared capabilities.
  3. Tool definitions with input schema.
  4. Resource definitions (where applicable).
  5. Single run() call binding stdio transport.
Tip

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.

03

The MCP Registry

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.

Registry record — what it captures

A registry entry (excerpt)
{
  "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:…"
}

What the host does with this

Why this matters

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.

04

Pattern A — Data Servers (Read-Only Context)

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.

Shape

  • Resources, possibly templated (db://users/{id}/profile)
  • One or two read-only tools as ergonomic shortcuts (query, search)
  • Optional resources/subscribe for live data
  • No destructiveHint tools at all

When to reach for it

  • You have a corpus the model should be able to read
  • Wikis, ticket trackers, documentation, CRM, log archives
  • Anything where the answer is “here's the page, model goes brrr”

Worked example shape

Skeleton: a Confluence-style data server
resources/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:[…]}}
Why resources, not tools, for reads

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.

05

Pattern B — Tool Servers (Side-Effecting Actions)

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.

Shape

  • Tools with accurate annotations — destructiveHint set honestly
  • Tight input schemas (regex on names, enums on operations)
  • Output schema where possible — downstream code needs structure
  • Idempotency hints where they apply
  • OAuth-protected if remote

Anti-patterns

  • One mega-tool that takes a free-text command
  • Lying annotations (readOnlyHint:true on a write tool)
  • Putting destructive operations on the same tool name as reads
  • Returning success for partial failures

Annotation discipline carries the security model

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.

A correct destructive tool
{
  "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
  }
}
Confirmations vs schema

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.

06

Pattern C — Agent Servers (Sampling-Driven) Sampling deprecated in 2026-07-28

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.

Why this is different

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.

Host (with LLM) Agent server tools/call { "research_topic", topic:"quark plasma" } sampling/createMessage { "draft outline" } [user gate] { outline } sampling/createMessage { "expand section 1" } { section text } notifications/progress { 0.6, "synthesising" } tools/call result — final report
Cost & trust model

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.

Pattern C in 2026-07-28 2026-07-28

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).

07

Pattern D — Multi-Server Orchestration

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.

Friction 1 — Tool name collisions

Two servers can both expose a search tool. The host needs to disambiguate. Two strategies:

Server-prefixed names (host-side)

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.

Namespaced by the server author

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.

Friction 2 — Roots and resource scoping before 2026-07-28

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:

Host → servers, on workspace change
// 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 in 2026-07-28 2026-07-28

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).

Friction 3 — Cross-server data flow

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.

Practical implication

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.

08

Distribution — uvx / npx / Docker

How servers reach users. Almost every community server falls into one of three distribution shapes:

ShapeCommandWhenTrade-offs
uvx (Python)uvx mcp-server-fooServer is published to PyPIZero-install for the user, downloads on first run, uv's caching makes second run instant. Python-only.
npx (Node)npx -y @scope/mcp-server-fooServer is published to npmSame UX for Node. The -y auto-confirms the install prompt.
Dockerdocker run --rm -i ghcr.io/acme/mcp-foo:1.4Server has system deps or you want sandboxingHeavier, but ships the runtime. Pin by digest in production.
Native binary/usr/local/bin/mcp-fooStatic binary, e.g. Go serverFastest startup. Distribution is your problem (Homebrew, cargo, releases).
Streamable HTTPhttps://mcp.acme.ioHosted SaaSNo install. OAuth required. Versioning happens server-side.

Versioning & protocol-version pinning

MCP date-stamped versions and your server's semver are independent. Best practice:

Source: MCP specification 2026-07-28 — Versioning and compatibility; Discovery (accessed 2026-10-08).

A note on Docker for stdio

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.”

09

What to Take Away

The whole series, in one paragraph

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.