look-before-you-leap/skills/mcp-builder/SKILL.md
Build production-quality MCP (Model Context Protocol) servers that expose APIs, databases, and services as tools for LLMs. Use this skill whenever the user asks for: MCP server, Model Context Protocol, building MCP tools, MCP tool integration, MCP resource provider, creating tools for Claude, tool server, LLM tool API wrapper, exposing an API as MCP tools, MCP transport setup, stdio server, streamable HTTP server, MCP Inspector testing, or any request to build a server that makes external services available to AI assistants via the Model Context Protocol. Do NOT use when: using existing MCP tools without modification, calling MCP tools from client code, non-MCP API integrations (REST/GraphQL clients), general backend development without MCP, or configuring MCP servers in claude_desktop_config.json — this skill is for building MCP servers, not consuming them.
npx skillsauth add miospotdevteam/claude-control mcp-builderInstall 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.
Build MCP servers that wrap APIs, databases, and services into tools that LLMs can use reliably. A well-built MCP server has clear tool boundaries, validated inputs, structured responses optimized for LLM consumption, and thorough error handling.
The difference between an MCP server that works and one that works well is tool design: each tool does one thing, descriptions tell the LLM exactly when and how to use it, responses are structured text (not raw JSON dumps), and errors guide the LLM toward recovery rather than confusion.
Announce at start: "I'm using the mcp-builder skill to build this MCP server."
This skill operates within the conductor's Step 1-3:
Read the appropriate language reference before starting implementation:
references/mcp-typescript.mdreferences/mcp-python.mdreferences/mcp-best-practices.md (always read this)With engineering-discipline: All MCP servers are code — the standard engineering discipline rules apply. Explore before editing, track blast radius, verify after changes.
With test-driven-development: If the project uses TDD, write tool handler tests before implementing the handlers. Mock the external API and verify the MCP response format.
With systematic-debugging: When an MCP tool returns unexpected results or the Inspector shows errors, use systematic-debugging's root cause tracing to isolate whether the issue is in input validation, API call, response formatting, or transport.
Entry criteria: User has asked to build an MCP server or wrap an API. Exit criteria: You have a clear list of tools to implement, their inputs/outputs, and which API endpoints they map to.
Before writing any code, fully understand what you are wrapping:
mcp-server-{service}
on npm and PyPI. If one exists, evaluate whether it covers the needed
operations before building from scratch.Decide what becomes a tool vs. a resource:
Is it read-only data retrieval with a stable URI pattern?
├── YES → Consider making it a Resource
│ ├── Does the LLM need to discover and browse it? → Resource
│ └── Does the LLM need to pass dynamic parameters? → Tool
│
└── NO (creates side effects, requires complex parameters)
└── Make it a Tool
Naming convention: {verb}_{noun} — e.g., list_issues,
create_comment, get_pull_request, search_repositories.
For each tool, define before writing any code:
| Field | What to specify |
|-------|----------------|
| Name | verb_noun, lowercase with underscores |
| Description | When to use, what it returns, any caveats |
| Input schema | Every parameter with type, description, required/optional |
| Output format | What the structured text response looks like |
| Error cases | What can go wrong, how the LLM should handle it |
| Annotations | readOnlyHint, destructiveHint, idempotentHint, openWorldHint |
See references/mcp-best-practices.md for annotation guidance.
Entry criteria: Tool list and schemas are defined from Phase 1. Exit criteria: All tools are registered, handle errors, return structured text, and the server starts without errors.
Choose language and set up the project:
TypeScript:
mkdir mcp-server-{name} && cd mcp-server-{name}
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
npx tsc --init
Python:
mkdir mcp-server-{name} && cd mcp-server-{name}
uv init # or: python -m venv .venv && source .venv/bin/activate
uv add mcp # or: pip install mcp
See references/mcp-typescript.md or references/mcp-python.md for
complete scaffolding including tsconfig, project structure, and entry
points.
Register each tool with:
verb_noun pattern, matches the API operationlist_issues instead if you
want all issues for a repository."readOnlyHint: true for GET-like operationsdestructiveHint: true for DELETE or irreversible operationsidempotentHint: true for PUT-like operationsopenWorldHint: true if the tool accesses external servicesFormat responses for LLM consumption, not raw API passthrough:
hasMore and nextCursor
(or equivalent) when results are paginated.{"error": "404"}, return
"Repository 'owner/repo' not found. Check that the repository exists
and is accessible with the current authentication."Example response format:
Found 3 issues matching "bug":
1. #42: Login button not responding (open)
Author: alice | Labels: bug, priority-high
Created: 2025-01-15 | Comments: 5
2. #38: Dashboard data not loading (closed)
Author: bob | Labels: bug, resolved
Created: 2025-01-10 | Comments: 3
3. #35: Mobile layout broken on Safari (open)
Author: carol | Labels: bug, frontend
Created: 2025-01-08 | Comments: 2
Showing 3 of 3 results. No more pages.
Every tool handler must catch and handle errors:
Use the isError: true flag in the MCP response to signal errors.
Configure at least one transport:
Most MCP servers should support stdio at minimum. Add streamable HTTP if the server will be deployed remotely.
See language-specific references for transport setup code.
Entry criteria: All tools are implemented and the server starts. Exit criteria: Every tool has been tested with valid input, invalid input, and error scenarios. MCP Inspector shows clean results.
Use the MCP Inspector to verify every tool:
npx @modelcontextprotocol/inspector
For each tool:
Add the server to claude_desktop_config.json and test with real prompts:
{
"mcpServers": {
"your-server": {
"command": "node",
"args": ["path/to/dist/index.js"],
"env": {
"API_TOKEN": "your-token"
}
}
}
}
Test with prompts that exercise the tools naturally:
Verify that all tool schemas are complete:
descriptionEntry criteria: All tools pass Inspector testing and manual verification. Exit criteria: Eval prompts exercise all tools and produce correct, well-formatted results.
Write 5-10 evaluation prompts that exercise the full tool surface:
For each eval prompt:
Before declaring the server complete, verify:
isError: true| Reference | When to read |
|-----------|-------------|
| references/mcp-best-practices.md | Always — covers naming, tool design, responses, security |
| references/mcp-typescript.md | Building a TypeScript MCP server |
| references/mcp-python.md | Building a Python MCP server |
development
Use after discovery to write implementation plans with TDD-granularity steps. Produces plan.json (immutable definition, frozen after approval), progress.json (mutable execution state), and masterPlan.md (user-facing proposal for Orbit review). Every step is one component/feature; TDD rhythm (test, verify fail, implement, verify pass, commit) lives in its progress items. Consumes discovery.md from exploration phase. Make sure to use this skill whenever the user says discovery is done, exploration is finished, discovery.md is ready, or asks to write/create/draft the implementation plan — even if they don't mention plan.json or masterPlan.md by name. Also use when the user references completed exploration findings, blast radius analysis, or consumer mappings and wants them converted into actionable steps. Do NOT use when: the user says 'just do it' or 'no plan', resuming or executing an existing plan, during exploration or brainstorming (discovery not yet complete), debugging, or code review.
tools
End-to-end webapp testing with Playwright MCP integration. Use when: writing Playwright tests, E2E testing, browser testing, webapp testing, visual regression testing, accessibility testing with axe-core, testing user flows through a web UI, verifying frontend behavior in a real browser. Integrates with test-driven-development skill for test-first browser tests and engineering-discipline for verification. Do NOT use when: unit tests only (no browser UI involved), API tests without UI, mobile native testing (use react-native-mobile), testing CLI tools, or writing backend-only integration tests.
development
Test-Driven Development workflow enforcing red-green-refactor cycles. Use when writing new features, adding behavior, or implementing functions where tests should drive design. Requires explicit test-first prompting because Claude naturally writes implementation first. Integrates with writing-plans (TDD rhythm in Progress items) and engineering-discipline (verification). Do NOT use when: fixing a bug in existing tested code (use systematic-debugging), writing tests for existing untested code (characterization tests are a different workflow), refactoring without behavior change (use refactoring), or the project has no test infrastructure.
development
Use when encountering any bug, test failure, or unexpected behavior. Enforces root cause investigation before fixes. Four phases: investigate, analyze patterns, form hypotheses, implement. Prevents guess-and-check thrashing. Use ESPECIALLY when under pressure or when 'just one quick fix' seems obvious. Do NOT use for: learning unfamiliar APIs (use exploration), performance optimization without a specific regression, or code review without a reported bug.