skills/mcp-server-dev/SKILL.md
Use when the user asks to build an MCP server, create an MCP integration, wrap an API for AI agents, or expose tools via the Model Context Protocol. Guides through deployment model selection (remote HTTP, MCPB, local stdio), tool-design patterns, and framework choice before scaffolding code.
npx skillsauth add euxx/claude-skills-for-copilot mcp-server-devInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are guiding a developer through designing and building an MCP server. MCP servers come in many forms — picking the wrong shape early causes painful rewrites later. Your first job is discovery, not code.
Do not start scaffolding until you have answers to the questions in Phase 1. If the user's opening message already answers them, acknowledge that and skip straight to the recommendation.
Ask these questions conversationally (batch them into one message, don't interrogate one-at-a-time). Adapt wording to what the user has already told you.
| If it connects to… | Likely direction | | ----------------------------------------------- | -------------------------- | | A cloud API (SaaS, REST, GraphQL) | Remote HTTP server | | A local process, filesystem, or desktop app | MCPB or local stdio | | Hardware, OS-level APIs, or user-specific state | MCPB | | Nothing external — pure logic / computation | Either — default to remote |
This determines the tool-design pattern — see Phase 3.
@modelcontextprotocol/ext-apps.Based on the answers, recommend one path. Be opinionated. The ranked options:
A hosted service speaking MCP over streamable HTTP. This is the recommended path for anything wrapping a cloud API.
Why it wins:
Choose this unless the server must touch the user's local machine.
→ Fastest deploy: Cloudflare Workers — zero to live URL in two commands using the official Cloudflare MCP Workers template → Portable Node/Python: Express or FastMCP, runs on any host
If a tool just needs the user to confirm, pick an option, or fill a short form, elicitation does it with zero UI code. The server sends a flat JSON schema; the host renders a native form. Spec-native, no extra packages.
Caveat: Host support is new (Claude Code shipped it in v2.1.76; Desktop unconfirmed). The SDK throws if the client doesn't advertise the capability. Always check clientCapabilities.elicitation first and have a fallback.
Escalate to MCP app widgets when you need: nested/complex data, scrollable/searchable lists, visual previews, live updates.
Same as above, plus UI resources — interactive widgets rendered in chat. Rich pickers with search, charts, live dashboards, visual previews. Built once, renders in Claude and ChatGPT.
Choose this when elicitation's flat-form constraints don't fit — you need custom layout, large searchable lists, visual content, or live updates. Uses @modelcontextprotocol/ext-apps.
Usually remote, but can be shipped as MCPB if the UI needs to drive a local app.
A local MCP server packaged with its runtime so users don't need Node/Python installed. The sanctioned way to ship local servers.
Choose this when the server must run on the user's machine — it reads local files, drives a desktop app, talks to localhost services, or needs OS-level access.
A script launched via npx / uvx on the user's machine. Fine for personal tools and prototypes. Painful to distribute: users need the right runtime, you can't push updates. Scaffold it but note the MCPB upgrade path.
Every MCP server exposes tools. How you carve them matters more than most people expect — tool schemas land directly in the model's context window.
When the action space is small (< ~15 operations), give each a dedicated tool with a tight description and schema.
create_issue — Create a new issue. Params: title, body, labels[]
update_issue — Update an existing issue. Params: id, title?, body?, state?
search_issues — Search issues by query string. Params: query, limit?
add_comment — Add a comment to an issue. Params: issue_id, body
Why it works: The model reads the tool list once and knows exactly what's possible. No discovery round-trips. Each tool's schema validates inputs precisely.
When wrapping a large API (dozens to hundreds of endpoints), listing every operation as a tool floods the context window and degrades model performance. Instead, expose two tools:
search_actions — Given a natural-language intent, return matching actions
with their IDs, descriptions, and parameter schemas.
execute_action — Run an action by ID with a params object.
The server holds the full catalog internally. The model searches, picks, executes. Context stays lean.
Hybrid: Promote the 3–5 most-used actions to dedicated tools, keep the long tail behind search/execute.
Recommend one of these two. Others exist but these have the best MCP-spec coverage.
| Framework | Language | Use when |
| --------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Official TypeScript SDK (@modelcontextprotocol/sdk) | TS/JS | Default choice. Best spec coverage, first to get new features. |
| FastMCP 3.x (fastmcp on PyPI) | Python | User prefers Python, or wrapping a Python library. Decorator-based, low boilerplate. This is jlowin's package — not the frozen FastMCP 1.0 bundled in the official mcp SDK. |
If the user already has a language/stack in mind, go with it — both produce identical wire protocol.
Once you've settled the four decisions (deployment model, tool pattern, framework, auth), implement accordingly:
Server instance, register tools with server.tool(name, schema, handler), wrap in a Hono/Express app with streamableHttpHandler. For FastMCP: use @mcp.tool() decorators. For Cloudflare Workers deployment, use the workers-mcp template from Cloudflare.@modelcontextprotocol/ext-apps for iframe-based widget resources. Each widget binds to one tool.StdioServerTransport (TS) or fastmcp.run() with transport="stdio". Flag MCPB as the distribution upgrade path.When scaffolding, produce complete, runnable code. Do not leave placeholder TODOs for the core transport or tool registration.
Tools are one of three server primitives. Most servers start with tools and never need the others, but knowing they exist prevents reinventing wheels:
| Primitive | Who triggers it | Use when | | --------------- | -------------------- | --------------------------------------------- | | Resources | Host app (not model) | Exposing docs/files/data as browsable context | | Prompts | User (slash command) | Canned workflows ("/summarize-thread") | | Elicitation | Server, mid-tool | Asking user for input without building UI | | Sampling | Server, mid-tool | Need LLM inference in your tool logic |
| Scenario | Deployment | Tool pattern | | ------------------------------------- | ---------------- | ------------------ | | Wrap a small SaaS API | Remote HTTP | One-per-action | | Wrap a large SaaS API (50+ endpoints) | Remote HTTP | Search + execute | | SaaS API with rich forms / pickers | MCP app (remote) | One-per-action | | Drive a local desktop app | MCPB | One-per-action | | Local desktop app with in-chat UI | MCP app (MCPB) | One-per-action | | Read/write local filesystem | MCPB | Depends on surface | | Personal prototype | Local stdio | Whatever's fastest |
mcp SDKtesting
Analyzes type design quality by rating encapsulation, invariant expression, usefulness, and enforcement. Helps design types that make invalid states unrepresentable. Use when reviewing new types or data models.
testing
Reviews test coverage quality from a behavioral perspective, identifying critical gaps and test quality issues. Does not check line coverage — checks meaningful scenario coverage. Use after adding or modifying tests.
development
Audits error handling for silent failures, inadequate user feedback, and unjustified fallback behavior. Finds issues in catch blocks, fallbacks, and error paths. Use after modifying error handling code.
development
Repository-grounded threat modeling that enumerates trust boundaries, assets, attacker capabilities, abuse paths, and mitigations, and writes a concise Markdown threat model. Trigger only when the user explicitly asks to threat model a codebase or path, enumerate threats/abuse paths, or perform AppSec threat modeling. Do not trigger for general architecture summaries, code review, or non-security design work.