mcp-patterns
MCP server building, advanced patterns, and security hardening. Use when building MCP servers, implementing tool handlers, choosing a transport, adding OAuth authentication, wiring MCP Apps UI with @mcp-ui, hardening MCP security, or debugging MCP integrations.
Works with
---
name: mcp-patterns
description: MCP server building, advanced patterns, and security hardening. Use when building MCP servers, implementing tool handlers, choosing a transport, adding OAuth authentication, wiring MCP Apps UI with @mcp-ui, hardening MCP security, or debugging MCP integrations.
license: MIT
---
# MCP Patterns
Patterns for building, composing, and securing Model Context Protocol servers. Based on the **2025-11-25 specification** — the latest stable release maintained by the [Agentic AI Foundation](https://agenticaifoundation.org/) (Linux Foundation), co-founded by Anthropic, Block, and OpenAI.
> **Scaffolding a new server?** Use Anthropic's `mcp-builder` skill (`claude install anthropics/skills`) for project setup and evaluation creation. This skill focuses on **patterns, security, and advanced features** after initial setup.
>
> **Deploying to Cloudflare?** See the `building-mcp-server-on-cloudflare` skill for Workers-specific deployment patterns.
> **Pin `mcp<2` until you migrate.** Every Python snippet in this skill targets the v1 SDK
> (`from mcp.server.fastmcp import FastMCP`). The Python SDK released **2.0.0**, `pip install mcp`
> now resolves to it, and upstream's own README says to keep a `<2` upper bound on your requirement
> until you have migrated. `FastMCP` does not appear anywhere in the 2.0 README, so treat these
> snippets as v1-only rather than assuming they still apply. v1.x continues to receive critical bug
> and security fixes on its own branch. Verified 2026-07-31.
> Migration guide: https://py.sdk.modelcontextprotocol.io/migration/
## Decision Tree — Which Rule to Read
```
What are you building?
│
├── New MCP server
│ ├── Setup & primitives ──────► rules/server-setup.md
│ ├── Transport selection ─────► rules/server-transport.md
│ └── Scaffolding ─────────────► mcp-builder skill (anthropics/skills)
│
├── Authentication & authorization
│ └── OAuth 2.1 + OIDC ───────► rules/auth-oauth21.md
│
├── Advanced server features
│ ├── Tool composition ────────► rules/advanced-composition.md
│ ├── Resource caching ────────► rules/advanced-resources.md
│ ├── Elicitation (user input) ► rules/elicitation.md
│ ├── Sampling (agent loops) ──► rules/sampling-tools.md
│ └── Interactive UI ──────────► rules/apps-ui.md
│
├── Client-side consumption
│ └── Connecting to servers ───► rules/client-patterns.md
│
├── Security hardening
│ ├── Prompt injection defense ► rules/security-injection.md
│ └── Zero-trust & verification ► rules/security-hardening.md
│
├── Testing & debugging
│ └── Inspector + unit tests ──► rules/testing-debugging.md
│
├── Discovery & ecosystem
│ └── Registries & catalogs ──► rules/registry-discovery.md
│
└── Browser-native tools
└── WebMCP (W3C) ───────────► rules/webmcp-browser.md
```
## Quick Reference
| Category | Rule | Impact | Key Pattern |
|----------|------|--------|-------------|
| **Server** | `server-setup.md` | HIGH | FastMCP lifespan, Tool/Resource/Prompt primitives |
| **Server** | `server-transport.md` | HIGH | stdio for CLI, Streamable HTTP for production |
| **Auth** | `auth-oauth21.md` | HIGH | PKCE, RFC 8707 resource indicators, token validation |
| **Advanced** | `advanced-composition.md` | MEDIUM | Pipeline, parallel, and branching tool composition |
| **Advanced** | `advanced-resources.md` | MEDIUM | Resource caching with TTL, LRU eviction, lifecycle |
| **Advanced** | `elicitation.md` | MEDIUM | Server-initiated structured input from users |
| **Advanced** | `sampling-tools.md` | MEDIUM | Server-side agent loops with tool calling |
| **Advanced** | `apps-ui.md` | MEDIUM | Interactive UI via MCP Apps + @mcp-ui/* SDK |
| **Client** | `client-patterns.md` | MEDIUM | TypeScript/Python MCP client connection patterns |
| **Security** | `security-injection.md` | HIGH | Description sanitization, encoding normalization |
| **Security** | `security-hardening.md` | HIGH | Zero-trust allowlist, hash verification, rug pull detection |
| **Quality** | `testing-debugging.md` | MEDIUM | MCP Inspector, unit tests, transport debugging |
| **Ecosystem** | `registry-discovery.md` | LOW | Official registry API, server metadata |
| **Ecosystem** | `webmcp-browser.md` | LOW | W3C browser-native agent tools (complementary) |
**Total: 14 rules across 6 categories**
## Key Decisions
| Decision | Recommendation |
|----------|----------------|
| Transport | stdio for CLI/Desktop, Streamable HTTP for production (SSE deprecated) |
| Language | TypeScript for production (better SDK support, type safety) |
| Auth | OAuth 2.1 with PKCE (S256) + RFC 8707 resource indicators |
| Server lifecycle | Always use FastMCP lifespan for resource management |
| Error handling | Return errors as text content (Claude can interpret and retry) |
| Tool composition | Pipeline for sequential, `asyncio.gather` for parallel |
| Resource caching | TTL + LRU eviction with memory cap |
| Tool trust model | Zero-trust: explicit allowlist + hash verification |
| User input | Elicitation for runtime input; never request PII via elicitation |
| Interactive UI | MCP Apps with @mcp-ui/* SDK; sandbox all iframes |
| Token handling | Never pass through client tokens to downstream services |
| Large results | Use `_meta["anthropic/maxResultSizeChars"]` annotation (up to 500K) for results that lose meaning when truncated (CC 2.1.91) |
## Spec & Governance
- **Protocol**: Model Context Protocol, spec version **2025-11-25** (latest stable)
- **Governance**: Agentic AI Foundation (Linux Foundation, Dec 2025)
- **Platinum members**: AWS, Anthropic, Block, Bloomberg, Cloudflare, Google, Microsoft, OpenAI
- **Adoption**: 10,000+ servers; Claude, Cursor, Copilot, Gemini, ChatGPT, VS Code
- **Spec URL**: https://modelcontextprotocol.io/specification/2025-11-25
- **2026 model**: Working Groups and Interest Groups are now the primary vehicle for protocol evolution (no more milestone-based releases). Enterprise readiness lands as extensions, not core spec changes.
### Feature Maturity
| Feature | Spec Version | Status |
|---------|-------------|--------|
| Tools, Resources, Prompts | 2024-11-05 | Stable |
| Streamable HTTP transport | 2025-03-26 | Stable (replaces SSE) |
| OAuth 2.1 + Elicitation (form) | 2025-06-18 | Stable |
| Sampling with tool calling | 2025-11-25 | Stable |
| Elicitation URL mode | 2025-11-25 | Stable |
| MCP Apps (UI extension) | 2026-01-26 | Extension (ext-apps) |
| WebMCP (browser-native) | 2026-02-14 | W3C Community Draft |
## SDK landscape (2026-Q2)
| Package | What it is | When to use |
|---------|-----------|-------------|
| `mcp` (PyPI) **>=1.27** | Official Python SDK — includes the `FastMCP` helper, transport adapters, Inspector | New Python servers. This is the canonical package. |
| `@modelcontextprotocol/sdk` (npm) **>=1.29** | Official TypeScript SDK | New TS servers |
| `fastmcp` (PyPI) | Standalone fork by jlowin — predates `mcp`; API-compatible but diverges on lifespan and middleware | Existing projects pinned to it. New projects should prefer `mcp`. |
> The `fastmcp` fork and the `mcp.server.fastmcp` module are *not the same package*. Imports and `pyproject.toml` entries must agree or stacktraces become cryptic.
### Debugging with Claude Code
Pass `--mcp-debug` to Claude Code when troubleshooting server wiring — it surfaces the raw JSON-RPC frames, handshake failures, and tool-registration events that the default logger swallows:
```bash
claude --mcp-debug "query the local test server"
# or per-session:
export CLAUDE_MCP_DEBUG=1
```
Use alongside the MCP Inspector (`npx @modelcontextprotocol/inspector <cmd>`) — Inspector gives you the client-side frame view, `--mcp-debug` gives you what Claude actually saw.
> **CC 2.1.128 — reconnect tool summarization**: when a server reconnects mid-session, re-announced tools are summarized as `mcp__<server>__* (N tools re-registered)` instead of being enumerated line-by-line. Use the **initial connect** event as the source of truth for tool inventory; treat reconnect summaries as deltas only. See `references/mcp-audit-runbook.md` for grep recipes that work across both formats.
> **CC 2.1.133 — MCP OAuth honors HTTP(S)_PROXY / NO_PROXY / mTLS**: the full MCP OAuth flow (discovery, dynamic client registration, token exchange, token refresh) now respects standard proxy and client-certificate env vars end-to-end. Enterprise deployments behind corporate proxies no longer need OAuth-specific workarounds — the same `HTTPS_PROXY` / `NO_PROXY` / `NODE_EXTRA_CA_CERTS` config that already routes MCP transport now also routes auth. See `configure/references/cc-version-settings.md` (CC 2.1.133 section) for the env-var example. The companion deployment skill `building-mcp-server-on-cloudflare` can drop any prior "proxy-aware OAuth requires manual handling" caveat at this floor.
> **CC 2.1.169 — managed MCP policies enforced everywhere:** enterprise `allowedMcpServers`/`deniedMcpServers` now apply on reconnect, IDE-typed configs, `--mcp-config` servers in the first session after install, and before remote settings load (previously all four paths skipped enforcement). Orgs without remote settings also get faster cold starts. If a previously-working server stops connecting after 2.1.169, check the managed policy before debugging the server.
> **CC 2.1.163 — stdio servers get `CLAUDE_CODE_SESSION_ID`:** on `--resume`, stdio MCP servers now receive the same `CLAUDE_CODE_SESSION_ID` env var that hooks and Bash already get. Read it inside the server to correlate logs/telemetry across resumed sessions instead of minting your own session key — but never store auth tokens keyed off it (see Common Mistake #7).
## Example
```python
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-server")
@mcp.tool()
async def search(query: str) -> str:
"""Search documents. Returns matching results."""
results = await db.search(query)
return "\n".join(r.title for r in results[:10])
```
## Common Mistakes
1. No lifecycle management (connection/resource leaks on shutdown)
2. Missing input validation on tool arguments
3. Returning secrets in tool output (API keys, credentials)
- CC 2.1.161 mitigates this at the CLI layer: `claude mcp list/get/add` no longer expands `${VAR}` references and redacts credential headers and URL secrets in terminal output — but server code must still never return secrets in tool *results*. `/mcp` also collapses never-signed-in connectors behind a "Show unused connectors" row.
- CC 2.1.186 adds `claude mcp login <name>` / `claude mcp logout <name>` for OAuth-backed servers (HTTP/SSE/connector). Pass `--no-browser` to print the authorization URL instead of opening a browser — the supported path for SSH/headless/remote sessions (paste the redirect URL back when prompted), so interactive-only auth never blocks automated setup.
4. Unbounded response sizes without `_meta` annotation — use `_meta["anthropic/maxResultSizeChars"]` to declare intentionally large results (DB schemas, API specs) so clients/hooks don't truncate them
5. Trusting tool descriptions without sanitization (injection risk)
6. No hash verification on tool invocations (rug pull vulnerability)
7. Storing auth tokens in session IDs (credential leak)
8. Blocking synchronous code in async server (use `asyncio.to_thread()`)
9. Using SSE transport instead of Streamable HTTP (deprecated since March 2025)
10. Passing through client tokens to downstream services (confused deputy)
## Ecosystem
| Resource | What For |
|----------|----------|
| `mcp-builder` skill (anthropics/skills) | Scaffold new MCP servers + create evals |
| `building-mcp-server-on-cloudflare` skill | Deploy MCP servers on Cloudflare Workers |
| `@mcp-ui/*` packages (npm) | Implement MCP Apps UI standard |
| MCP Registry | Discover servers: https://registry.modelcontextprotocol.io/ |
| MCP Inspector | Debug and test servers interactively |
## Related Skills
- `ork:llm-integration` — LLM function calling patterns
- `ork:security-patterns` — General input sanitization and layered security
- `ork:api-design` — REST/GraphQL API design patternsMore Debugging skills
diagnosing-bugs
mattpocock/skills
Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.
explore-code
lllllllama/rigorpilot-skills
Rigor Improve implementation leaf skill for auditable candidate implementation in deep learning research repositories. Use when the researcher explicitly authorizes exploratory work on an isolated branch or worktree to transplant modules, adapt a backbone, add LoRA or adapter layers, replace a head, or stitch together meaningful low-risk migration ideas with rollback-aware records in `explore_outputs/`. Do not use for end-to-end exploration orchestration on top of `current_research`, trusted baseline reproduction, conservative debugging, environment setup, verified contribution claims, or default repository analysis.
safe-debug
lllllllama/rigorpilot-skills
Rigor Debug / Rigor Audit skill for deep learning research work. Use when the user pastes a traceback, terminal error, CUDA OOM, checkpoint load failure, shape mismatch, NaN loss symptom, or training failure and wants conservative diagnosis before any patching, with debug fixes clearly separated from research contributions. Do not use for broad refactoring, speculative adaptation, automatic exploratory patching, or general repository familiarization.

