Skip to content
Back to skills

Mcp Builder

ASecurity

Build production-grade Model Context Protocol (MCP) servers — stdio + streamable HTTP transports, tool / resource / prompt primitives, capability negotiation, auth model, idempotency, observability, testing via MCP Inspector, 10-question evaluation framework. Use when designing a new MCP server to expose an internal API / data source / workflow as a Claude (or any MCP client) tool. Sister to install-allowlist.md (publisher gates for downstream consumers), secrets-management.md (no secrets in ...

  • 12 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 6, 2026
ai-agentstypescriptpythonrustgojavanodeawstestingrefactoringcode-review

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned October 6, 2026

npx -y skills add Nmor/the-council --skill mcp-builder --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mcp Builder?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Mcp Builder
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nmor-mcp-builder-the-council/badge)](https://www.skillsdirectory.com/skills/nmor-mcp-builder-the-council)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: mcp-builder
description: Build production-grade Model Context Protocol (MCP) servers — stdio + streamable HTTP transports, tool / resource / prompt primitives, capability negotiation, auth model, idempotency, observability, testing via MCP Inspector, 10-question evaluation framework. Use when designing a new MCP server to expose an internal API / data source / workflow as a Claude (or any MCP client) tool. Sister to install-allowlist.md (publisher gates for downstream consumers), secrets-management.md (no secrets in MCP code), api-design.md (tool surface design), idempotency.md (safe retries on tool calls).
disable-model-invocation: true
---

# mcp-builder — Building Production-Grade MCP Servers

> **Size budget: 25 KB.** Check: `wc -c`. Gate: `node ~/.claude/scripts/token-budget.mjs --check`
>
> Principal-level guide for authoring MCP servers. Auto-fires when
> work touches `mcp-server/**`, `mcp_servers/**`, `*.mcp.json`,
> files importing `@modelcontextprotocol/sdk` (TypeScript) or
> `mcp` / `fastmcp` (Python), or any task described as
> "build an MCP server / MCP tool / MCP integration".

## Reference map

The detail lives in `references/`, loaded only when the topic is needed. Read the row that
matches the task rather than the whole directory.

| Topic | Reference |
| --- | --- |
| Process — 4 phases | [`references/process-4-phases.md`](references/process-4-phases.md) |
| Core patterns | [`references/core-patterns.md`](references/core-patterns.md) |
| Security + supply-chain considerations | [`references/security-supply-chain-considerations.md`](references/security-supply-chain-considerations.md) |

## Purpose

The Model Context Protocol (MCP) is the canonical interface for
exposing tools, resources, and prompts to LLM agents. A well-built
MCP server lets Claude (or any MCP-compatible client) invoke real
operations against your APIs, databases, internal services, or
workflows with predictable schemas, structured errors, and safe
retry semantics.

This skill covers the FULL build lifecycle — research +
implementation + review + evaluation — at the depth required for a
server that ships to production and gets consumed by agents whose
failure modes are expensive (cost amplification, data corruption,
side-effect duplication).

## When to use

- Building an MCP server that wraps an internal API / database /
  workflow for agent consumption
- Migrating an existing custom integration layer to MCP for
  standardisation
- Designing a new tool surface for org-internal agents
- Refactoring an existing MCP server that has surface-area /
  context / error-shape problems
- Evaluating whether MCP is the right interface vs a direct SDK
  call, REST API, or function call

## When NOT to use

- **An MCP server already exists** that covers the use case —
  consume it instead (per `~/.claude/rules-library/common/reuse-first.md`)
- The workload is a one-time script — write the script, not an
  MCP server
- The integration is purely intra-process (one app calling another
  in the same runtime) — use direct SDK
- The consumer is NOT an LLM agent — use a normal HTTP / RPC API

## Standards cited

- **MCP Specification** (modelcontextprotocol.io) — current
  draft + stable revisions
- **Anthropic Agent Skills v1.0 spec** (Dec 2025) — open standard
  that MCP builders frequently pair with
- **JSON-RPC 2.0** (jsonrpc.org/specification) — the wire protocol
  MCP rides on
- **JSON Schema Draft 2020-12** — input / output schema validation
- **RFC 9110 §9.2.2** — idempotency semantics for tool calls
  (sister: `~/.claude/rules-library/common/idempotency.md`)
- **W3C Trace Context** — for distributed tracing through MCP
  servers (sister: `~/.claude/rules-library/common/observability.md`)
- **OAuth 2.1** — when the MCP server fronts a third-party API
  that requires user-scoped auth

## Anti-patterns

| Anti-pattern | Fix |
| --- | --- |
| Tool name not prefixed with server identity (`create_user`) | Prefix: `shop_create_user`, `crm_create_user` — disambiguates when agent has multiple servers loaded |
| `inputSchema` accepts `any` / unconstrained `object` | Define every field with type + constraint + description |
| Tool returns raw API response without sanitisation | Strip sensitive fields (PII, secrets) before returning; transform to a documented `outputSchema` |
| Single mega-tool with 30 parameters | Split into named tools per use case (`shop_search_orders` vs `shop_get_order_by_id`) |
| Server logs unstructured `console.log` | Structured logger with required fields (per `~/.claude/rules-library/common/observability.md`) |
| Auth checked once at startup, never per-request | Per-request auth check; revoked tokens fail fast |
| `outputSchema` omitted on structured returns | Define it — lets the client + LLM both reason about shape before parsing |
| Tools fire-and-forget side effects (email, payment) without idempotency key | Always require an idempotency_key on side-effecting tools (per `~/.claude/rules-library/common/idempotency.md`) |

## Verification checklist

```text
MCP server build (this turn):
  - MCP spec read for target version + cited in docs/provider-research/mcp.md
  - Transport selected + rationale documented (stdio | streamable HTTP)
  - Every tool has: name, description ≤ 3 sentences, inputSchema, outputSchema, annotations
  - Structured logger wired with request_id + trace_id + tool name + duration_ms + error_code
  - Stable error codes per ~/.claude/rules-library/common/error-codes.md
  - No secrets in source; vault-retrieval pattern per secrets-management.md
  - Rate limit + circuit breaker on every downstream call
  - Idempotency keys on side-effecting tools
  - MCP Inspector smoke test PASSED on every tool
  - 10-question eval set written + run against the server
  - Pass rate ≥ 80% on the eval set
  - tsc --strict / mypy --strict: zero errors
  - eslint --max-warnings 0 / ruff check --select=ALL: zero
  - Coverage ≥ 90% on touched files (per extreme-lint-policy.md)
```

## Cross-references

- `~/.claude/rules-library/common/install-allowlist.md` — MCP publisher
  allowlist (consumer side)
- `~/.claude/rules-library/common/secrets-management.md` — vault-only
  secret retrieval
- `~/.claude/rules-library/common/error-codes.md` — stable error code
  registry
- `~/.claude/rules-library/common/error-handling-with-context.md` —
  wrapping + structured logging
- `~/.claude/rules-library/common/idempotency.md` — side-effecting tools
  require idempotency keys
- `~/.claude/rules-library/common/rate-limiting.md` — protect downstreams
- `~/.claude/rules-library/common/circuit-breaker.md` — open the breaker
  on cascading failures
- `~/.claude/rules-library/common/observability.md` — structured logs +
  metrics + traces
- `~/.claude/rules-library/common/api-versioning.md` — version the tool
  surface
- `~/.claude/rules-library/common/contract-testing.md` — contract tests
  prevent silent breakage
- `~/.claude/rules-library/common/local-testability.md` — every tool
  testable locally before claim
- `~/.claude/rules/common/principal-level-mandate.md` — the
  template this skill follows
- `~/.claude/skills/api-design/SKILL.md` — tool surface design
  principles
- `~/.claude/skills/observability-patterns/SKILL.md` — logger
  shape + metric naming
- Claude's bundled `/claude-api` skill, when available in the runtime, for
  Claude API applications; it is not a file shipped in this repository.
  Otherwise consult the official provider documentation.
- `~/.claude/skills/aws-serverless-patterns/SKILL.md` — when MCP
  server runs as a Lambda
- Reference implementations:
  `github.com/anthropics/skills/tree/main/skills/mcp-builder`
  (Apache-2.0)
- `github.com/modelcontextprotocol/typescript-sdk`
- `github.com/modelcontextprotocol/python-sdk`

## Why this skill exists

MCP is the canonical interface for tool exposure to agents in
2026. Building one without a structured process produces servers
with:

- Vague tool descriptions that LLMs can't reliably choose
  between
- Untyped inputs that fail mid-execution
- Raw error strings agents can't recover from
- Missing annotations that force clients to treat every call as
  destructive
- No idempotency on side-effecting operations → duplicate
  charges, duplicate emails, corrupted state when an agent
  retries on timeout
- No evaluations → "works in dev, fails in real usage" without
  anyone noticing until production

The cost of the 4-phase discipline is one focused day. The cost
of skipping it is a server that other teams refuse to consume
and that the original author has to keep fixing as agents find
new ways to misuse the loose surface.

## Standards Cited

- **Model Context Protocol Specification (modelcontextprotocol.io)** —
  Stdio + Streamable HTTP transports, capability negotiation,
  tool / resource / prompt primitives, JSON-RPC 2.0 message
  envelope
- **JSON-RPC 2.0 Specification** — Request / response / notification
  envelope MCP wraps
- **JSON Schema Draft 2020-12** — Tool input + output schema
  validation (every MCP tool MUST declare a schema)
- **OAuth 2.1 + RFC 7591 (Dynamic Client Registration) + RFC 8628
  (Device Authorization)** — Authentication for remote MCP servers
- **OWASP ASVS 4.0.3 §V13.1** — Generic web service security (MCP
  server ↔ client contract)
- **OWASP Top 10 for LLM Applications (2025) LLM06 Excessive
  Agency + LLM10 Unbounded Consumption** — MCP tool annotations
  (`readOnlyHint`, `destructiveHint`, `idempotentHint`) limit
  agency; rate-limiting addresses unbounded consumption
- **NIST SP 800-218 SSDF §PW.4** — Reuse + third-party software
  considerations (MCP server is a supply-chain attachment)
- **NIST SP 800-53 Rev 5 §AC-6** — Least privilege (tool scope
  - capability negotiation enforce this)
- **CWE-1059** — Insufficient technical documentation (tool
  descriptions are the LLM's only context)
- **CWE-1284** — Improper validation of specified quantity in
  input (every MCP tool argument validated against its schema)
- **`~/.claude/rules-library/common/install-allowlist.md`** — Publisher
  trust gate before registering a new MCP

## Cross-References

- `api-design` skill — tool surface design (request / response
  shapes, idempotency, error envelopes)
- `prompt-engineering` skill — prompt + resource primitive design
- `~/.claude/agents/security-reviewer.md` — auth model + prompt-
  injection surface review
- `~/.claude/agents/code-reviewer.md` — Zod / JSON Schema
  correctness + annotation discipline
- `~/.claude/agents/architect.md` — transport choice (stdio vs
  streamable HTTP), single-server vs federated design
- `~/.claude/rules-library/common/install-allowlist.md` — publisher
  allowlist
- `~/.claude/rules-library/common/error-handling-with-context.md` — MCP
  error envelope shape

## Anti-Patterns

| Pattern | Why bad | Correct alternative |
| --- | --- | --- |
| Tool that mutates without `destructiveHint: true` | LLM may invoke destructively without confirmation | Annotate every mutator; flag DROP / DELETE / archive ops |
| Returning unstructured prose from tools | LLM has to re-parse; brittle to phrasing changes | Structured response with stable keys; per `api-design` envelope |
| Single-shot tool call for multi-step workflow | LLM cannot recover from intermediate failures | Decompose into smaller tools; use resources for state |
| Server holds secrets in plain-text config | Source-control leak risk | Vault / Keychain; per `secrets-management.md` |
| Tool description over 1000 tokens | Bloats every prompt; reduces effective context | Concise description; link to canonical docs for detail |
| Server makes outbound calls without rate-limiting | DoS amplification surface | Rate-limit per `~/.claude/rules-library/common/rate-limiting.md` |
| Tool args validated only at server, not in schema | Bad LLM calls produce confusing errors | Schema-validate at the boundary; reject with clear error |
| Logs tool inputs in plaintext | Sensitive PII / secrets leak | Redact per `log-levels.md`; structured fields only |
| New MCP installed without source review | Supply-chain attack surface | Publisher allowlist per `install-allowlist.md` |

## Learning hooks

Per `~/.claude/rules/common/continuous-learning-mandate.md`:

**Signals to watch**:

- New MCP server shipped without an `evals/` directory + 10-question eval set (Phase 4 weakening)
- Tool name without server-identity prefix (`create_user` instead of `shop_create_user`) — collision
  risk when multiple MCPs loaded
- Tool description > 3 sentences OR generic ("Get user info") — LLM-selection ambiguity
- `inputSchema` permits `any` / unconstrained `object` (Phase 2 schema discipline weakening)
- `outputSchema` omitted on a structured-return tool (LLM cannot pre-reason about shape)
- Side-effecting tool missing `idempotency_key` parameter (sister rule `idempotency.md` weakening)
- Annotations missing (`readOnlyHint` / `destructiveHint` / `idempotentHint` / `openWorldHint` all
  defaulted) — client UX degrades to "everything is destructive"
- Server logs `console.log` instead of structured logger (sister rule `observability.md` weakening)
- New tool added without contract test (sister rule `contract-testing.md` weakening)
- MCP Inspector smoke skipped before claiming done (Phase 3 verification weakening)
- Same eval question fails > 3 times across iterations — tool surface is genuinely too hard for the
  LLM

**Refinement candidates**:

- New transport row when MCP gains an additional canonical transport beyond stdio + streamable HTTP
- New annotation entry when the MCP spec adds further hint fields (e.g., cost / latency / scope
  hints)
- New pattern entry when a recurring failure mode emerges (e.g., agent retry storms, context-budget
  blowups)
- Tightening of the "≥ 80% eval pass rate" threshold when production usage shows the bar should be
  higher
- New cross-reference when a sister rule (auth boundary, schema evolution, error-codes) adds a
  load-bearing gate for MCP authors
- New per-language SDK row when an MCP SDK ships in a new language (Go, Rust, Java)

Files in this skill

  • SKILL.md13.9 KB
  • references/core-patterns.md2.1 KB
  • references/process-4-phases.md8.9 KB
  • references/security-supply-chain-considerations.md1.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…