home / skills / 0xdarkmatter / claude-mods / mcp-patterns

mcp-patterns skill

/skills/mcp-patterns

This skill helps you build and integrate MCP server patterns for Claude Code, enabling tool hosting, resource exposure, and robust server workflows.

npx playbooks add skill 0xdarkmatter/claude-mods --skill mcp-patterns

Review the files below or copy the command above to add this skill to your agents.

Files (8)
SKILL.md
4.5 KB
---
name: mcp-patterns
description: "Model Context Protocol (MCP) server patterns for building integrations with Claude Code. Triggers on: mcp server, model context protocol, tool handler, mcp resource, mcp tool."
compatibility: "Requires Python 3.10+ or Node.js 18+ for MCP server development."
allowed-tools: "Read Write Bash"
depends-on: []
related-skills: [claude-code-hooks, claude-code-debug]
---

# MCP Patterns

Model Context Protocol (MCP) server patterns for building integrations with Claude Code.

## Basic MCP Server (Python)

```python
from mcp.server import Server
from mcp.server.stdio import stdio_server

app = Server("my-server")

@app.list_tools()
async def list_tools():
    return [
        {
            "name": "my_tool",
            "description": "Does something useful",
            "inputSchema": {
                "type": "object",
                "properties": {
                    "query": {"type": "string", "description": "Search query"}
                },
                "required": ["query"]
            }
        }
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "my_tool":
        result = await do_something(arguments["query"])
        return {"content": [{"type": "text", "text": result}]}
    raise ValueError(f"Unknown tool: {name}")

async def main():
    async with stdio_server() as (read_stream, write_stream):
        await app.run(read_stream, write_stream, app.create_initialization_options())

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())
```

## Project Layout

```
my-mcp-server/
├── src/
│   └── my_server/
│       ├── __init__.py
│       ├── server.py       # Main server logic
│       ├── tools.py        # Tool handlers
│       └── resources.py    # Resource handlers
├── pyproject.toml
└── README.md
```

## Claude Desktop Configuration

### Basic Configuration

```json
{
  "mcpServers": {
    "my-server": {
      "command": "python",
      "args": ["-m", "my_server"],
      "env": {
        "MY_API_KEY": "your-key-here"
      }
    }
  }
}
```

### With uv (Recommended)

```json
{
  "mcpServers": {
    "my-server": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/my-server", "python", "-m", "my_server"],
      "env": {
        "MY_API_KEY": "your-key-here"
      }
    }
  }
}
```

## Quick Reference

| Pattern | Use Case | Reference |
|---------|----------|-----------|
| Tool validation | Input sanitization with Pydantic | `./references/tool-patterns.md` |
| Error handling | Graceful failure responses | `./references/tool-patterns.md` |
| Multiple tools | CRUD-style tool registration | `./references/tool-patterns.md` |
| Static resources | Config/settings exposure | `./references/resource-patterns.md` |
| Dynamic resources | Database-backed resources | `./references/resource-patterns.md` |
| Environment auth | API key from env vars | `./references/auth-patterns.md` |
| OAuth tokens | Token refresh with TTL | `./references/auth-patterns.md` |
| SQLite cache | Persistent state storage | `./references/state-patterns.md` |
| In-memory cache | TTL-based caching | `./references/state-patterns.md` |
| Manual testing | Quick validation script | `./references/testing-patterns.md` |
| pytest async | Unit tests for tools | `./references/testing-patterns.md` |

## Common Issues

| Issue | Solution |
|-------|----------|
| Server not starting | Check `command` path, ensure dependencies installed |
| Tool not appearing | Verify `list_tools()` returns valid schema |
| Auth failures | Check env vars are set in config, not shell |
| Timeout errors | Add timeout to httpx calls, use async properly |
| JSON parse errors | Ensure `call_tool` returns proper content structure |

## Official Documentation

- https://modelcontextprotocol.io - MCP specification
- https://modelcontextprotocol.io/docs/concepts/tools - Tools reference
- https://modelcontextprotocol.io/docs/concepts/resources - Resources reference
- https://github.com/modelcontextprotocol/python-sdk - Python SDK
- https://github.com/modelcontextprotocol/servers - Official MCP servers

## Additional Resources

For detailed patterns, load:

- `./references/tool-patterns.md` - Validation, error handling, multi-tool registration
- `./references/resource-patterns.md` - Static and dynamic resource exposure
- `./references/auth-patterns.md` - Environment variables, OAuth token refresh
- `./references/state-patterns.md` - SQLite persistence, in-memory caching
- `./references/testing-patterns.md` - Manual test scripts, pytest async patterns

Overview

This skill provides practical Model Context Protocol (MCP) server patterns for building integrations with Claude Code. It bundles example server code, project layout guidance, and configuration snippets to help you expose tools and resources to Claude via MCP. Use these patterns to implement reliable tool handlers, resource endpoints, auth, and state management for production or development servers.

How this skill works

The skill inspects common MCP server workflows and gives ready-to-use patterns: tool registration (list_tools), tool invocation (call_tool), and resource handling. It includes examples for running a Python MCP server over stdio or via a process manager (uv), plus recommended project layout, configuration fragments for Claude Desktop, and quick-reference patterns for validation, auth, caching, and testing. Common issues and solutions are documented to speed troubleshooting.

When to use it

  • Building a custom MCP server to expose tools to Claude Code
  • Validating and sanitizing tool inputs before execution
  • Adding resources (static or dynamic) accessible to the model
  • Implementing auth using environment variables or token refresh
  • Persisting state or caching tool results for faster responses

Best practices

  • Define strict input schemas (JSON Schema / Pydantic) for each tool to avoid runtime errors
  • Return well-formed MCP content arrays from call_tool (text or structured blocks)
  • Run the server under a supervisor (uv or similar) for stable process management
  • Store secrets in environment variables referenced by your MCP config, not in shell profiles
  • Add timeouts and async patterns for network calls to prevent server-wide stalls

Example use cases

  • Search tool: register a search tool with query input and return formatted results
  • CRUD tools: expose create/read/update/delete handlers for an internal DB via multiple tools
  • Resource exposure: provide static config or dynamic DB-backed resources to the model
  • Auth wrapper: implement API-key or OAuth token refresh and surface tokens as resources
  • Testing: write pytest-async tests for tool handlers and a manual script for quick validation

FAQ

How do I get tools to appear in Claude?

Ensure list_tools returns a valid JSON schema and that the MCP server process is started with the command configured in Claude Desktop; check server logs for schema errors.

What should call_tool return?

call_tool should return an MCP content array, typically objects like {type: "text", text: "..."}; follow the MCP spec for other content types.

How do I handle auth securely?

Load secrets from environment variables set in the Claude Desktop MCP server config and implement token refresh logic with TTL for OAuth flows.