---
name: mcp-builder
description: Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node.js (MCP SDK).
---

# MCP Builder Guide

## What is an MCP Server?

Model Context Protocol (MCP) servers expose tools that AI agents (Claude Code, Cursor, Windsurf, etc.) can call directly. You can build custom MCP servers to integrate any API or service.

## Python -- FastMCP

```bash
pip install fastmcp
```

```python
# my_mcp_server.py
from fastmcp import FastMCP
import requests

mcp = FastMCP("my-tools")
API_KEY = "your_api_key"
BASE = "https://your-api.example.com"

@mcp.tool()
def get_status() -> dict:
    """Get current service status."""
    return requests.get(
        f"{BASE}/api/v1/status",
        headers={"X-API-Key": API_KEY}
    ).json()

@mcp.tool()
def search_items(query: str, limit: int = 5) -> dict:
    """Search items by query."""
    return requests.post(
        f"{BASE}/api/v1/search",
        headers={"X-API-Key": API_KEY},
        json={"query": query, "limit": limit}
    ).json()

if __name__ == "__main__":
    mcp.run()
```

```bash
python my_mcp_server.py
```

## Node.js -- MCP SDK

```bash
npm install @modelcontextprotocol/sdk
```

```typescript
// server.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new Server(
  { name: 'my-mcp-server', version: '1.0.0' },
  { capabilities: { tools: {} } }
);

server.setRequestHandler('tools/list', async () => ({
  tools: [{
    name: 'get_status',
    description: 'Get current service status',
    inputSchema: { type: 'object', properties: {} }
  }]
}));

server.setRequestHandler('tools/call', async (request) => {
  if (request.params.name === 'get_status') {
    const resp = await fetch('https://your-api.example.com/api/v1/status', {
      headers: { 'X-API-Key': process.env.API_KEY! }
    });
    return { content: [{ type: 'text', text: JSON.stringify(await resp.json()) }] };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);
```

## Configure in Claude Code

```json
// .claude/mcp.json
{
  "mcpServers": {
    "my-tools": {
      "command": "python",
      "args": ["my_mcp_server.py"],
      "env": { "API_KEY": "your_api_key" }
    }
  }
}
```

For a published npm package:
```json
{
  "mcpServers": {
    "my-tools": {
      "command": "npx",
      "args": ["my-mcp-package"],
      "env": { "API_KEY": "your_api_key" }
    }
  }
}
```

## SKILL.md Format

Every MCP tool should have a matching skill file so agents know when to call it:

```markdown
---
name: my-tool-name
description: One-line description. Use when (1) scenario, (2) scenario, (3) scenario.
---

# Tool Name

Brief description and usage examples.
```

Place in `.claude/skills/my-tool-name/SKILL.md`.

## Publish to npm

```bash
# package.json
{
  "name": "my-mcp-server",
  "version": "1.0.0",
  "bin": { "my-mcp-server": "./dist/server.js" },
  "main": "./dist/server.js"
}

npm publish
```

## References

- MCP spec: `https://modelcontextprotocol.io`
