agentleFS
Sign inSign up

mcp-builder

TheDecipherist/claude-code-mastery-project-starter-kit/.claude/skills/mcp-builder/SKILL.md

Build a high-quality MCP server that exposes a service or API to an LLM through well-designed tools. Use when asked to create, scaffold, or add an MCP server, wrap an API as MCP tools, or expose a service to Claude/agents. Writes files, so it runs only when invoked explicitly.

Skill337 starsChanged 3 months ago
---
name: mcp-builder
description: Build a high-quality MCP server that exposes a service or API to an LLM through well-designed tools. Use when asked to create, scaffold, or add an MCP server, wrap an API as MCP tools, or expose a service to Claude/agents. Writes files, so it runs only when invoked explicitly.
when_to_use: |
  - User asks to build, scaffold, or add an MCP server
  - User wants to wrap an API, service, or database as MCP tools
  - User says "MCP server", "expose this as tools", "make this callable by an agent"
  - Do NOT auto-run; this writes files
disable-model-invocation: true
allowed-tools: "Read, Write, Edit, Bash"
---

# Build an MCP Server

An MCP server is judged by one thing: whether an LLM can use its tools to finish real tasks. Tool count, endpoint coverage, and cleverness are means, not the goal. Build for the agent that will call it.

## Default stack

- **TypeScript, on the MCP SDK.** Strong typing and good model familiarity. Drop to Python (FastMCP) only when the service it wraps is Python-native.
- **Transport: streamable HTTP with stateless JSON for remote servers; stdio for local.** Stateless scales and debugs far more easily than session streaming.
- **Resolve the SDK version at build time**, don't hardcode from memory. The current SDK README is the source of truth.

## The four phases

**1. Understand the target.** Read the service's API or schema first. Identify the handful of tasks a user actually wants done through it, not every endpoint. A wrapper that mirrors 60 REST routes one-to-one is worse than 8 tools shaped around real workflows.

**2. Design the tools.** This is where quality is won or lost.

- **Discoverable names**: `verb_noun`, scoped by service, for example `github_create_issue`, `orders_find_by_customer`. The name should tell the model when to reach for it.
- **Descriptions written for the model**, stating what the tool does and when to use it, not just what it returns.
- **Explicit input and output schemas.** Constrain inputs; return structured, parseable output, not prose the model has to scrape.
- **Annotations**: mark each tool `readOnlyHint`, `destructiveHint`, or `idempotentHint` so the client can reason about safety.
- **Actionable errors.** "Invalid date" is useless; "expected ISO 8601, got 03/04/2026, did you mean 2026-03-04" lets the model self-correct.
- **Balance coverage against workflow tools.** Comprehensive low-level tools give the agent room to compose; a few high-level workflow tools cut steps for the common path. Most good servers ship both.

**3. Implement.** Shared infrastructure first (client, auth, pagination, error handling), then the tools on top. If the server touches a database, it follows the same kit rules as everything else: one shared client, data access through the adapter, StrictDB if installed otherwise the native driver, never Mongoose.

**4. Test with evaluations.** Write 10 realistic, multi-step questions a user would ask, then verify an LLM can answer each using only the tools. Solve each yourself first so you know the right answer. Failing evals point at a missing tool, a vague description, or output the model can't parse, fix those, not the eval.

## Project shape

    src/
      server.ts        transport + registration, thin
      client.ts        the upstream API/service client (the one place it's touched)
      tools/           one file per tool or tight tool group
      schemas/         input/output schemas (zod)
    evals/
      evals.json       the 10 questions and verified answers

Keep `server.ts` thin, the same discipline as `api-conventions`: it wires transport and registers tools, nothing more. Tool logic lives in `tools/`, upstream calls in `client.ts`. No file over 300 lines.

## What to avoid

- Dumping every endpoint as a tool with no workflow shaping.
- Tool names only the author understands.
- Returning raw upstream JSON the model has to guess the shape of.
- Skipping evals, an MCP server you haven't watched an LLM drive is untested.

Discussion

Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.

Posts are public.Sign in to post

No one has posted yet. Be the first.