Refactor high-complexity React components in Dify frontend. Use when `pnpm analyze-component...
npx skills add kody-w/RAPP_Store --skill "mcp-builder"
Install specific skill from multi-skill repository
# Description
Guide for creating high-quality Model Context Protocol (MCP) servers. Use this skill when the user wants to build an MCP server to extend Claude's capabilities.
# SKILL.md
name: mcp-builder
description: Guide for creating high-quality Model Context Protocol (MCP) servers. Use this skill when the user wants to build an MCP server to extend Claude's capabilities.
MCP Server Builder
You are an expert at building Model Context Protocol (MCP) servers that extend Claude's capabilities. MCP servers provide tools, resources, and prompts that Claude can use to interact with external systems.
MCP Overview
The Model Context Protocol enables:
- Tools: Functions Claude can call to perform actions
- Resources: Data sources Claude can read from
- Prompts: Pre-defined conversation templates
Server Architecture
Python MCP Server Template
#!/usr/bin/env python3
"""
MCP Server: [Server Name]
Description: [What this server does]
"""
import asyncio
import json
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent, Resource
# Initialize server
server = Server("your-server-name")
# Define tools
@server.list_tools()
async def list_tools():
return [
Tool(
name="tool_name",
description="What this tool does",
inputSchema={
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "Parameter description"
}
},
"required": ["param1"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "tool_name":
param1 = arguments.get("param1")
# Tool implementation
result = f"Processed: {param1}"
return [TextContent(type="text", text=result)]
raise ValueError(f"Unknown tool: {name}")
# Define resources (optional)
@server.list_resources()
async def list_resources():
return [
Resource(
uri="resource://your-server/resource-name",
name="Resource Name",
description="What this resource provides",
mimeType="text/plain"
)
]
@server.read_resource()
async def read_resource(uri: str):
if uri == "resource://your-server/resource-name":
# Return resource content
return "Resource content here"
raise ValueError(f"Unknown resource: {uri}")
# Main entry point
async def main():
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream)
if __name__ == "__main__":
asyncio.run(main())
Node.js MCP Server Template
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const server = new Server(
{ name: "your-server-name", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "tool_name",
description: "What this tool does",
inputSchema: {
type: "object",
properties: {
param1: {
type: "string",
description: "Parameter description",
},
},
required: ["param1"],
},
},
],
}));
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === "tool_name") {
const param1 = args?.param1 as string;
// Tool implementation
return {
content: [{ type: "text", text: `Processed: ${param1}` }],
};
}
throw new Error(`Unknown tool: ${name}`);
});
// Start server
const transport = new StdioServerTransport();
server.connect(transport);
Best Practices
Tool Design
- Clear naming: Use descriptive, action-oriented names (
get_weather,send_email) - Detailed descriptions: Explain what the tool does and when to use it
- Comprehensive schemas: Define all parameters with types and descriptions
- Error handling: Return clear error messages for invalid inputs
Resource Design
- Meaningful URIs: Use hierarchical, descriptive URI paths
- Appropriate MIME types: Match content type to data format
- Efficient retrieval: Cache when appropriate, paginate large resources
Security
- Input validation: Never trust input data
- Least privilege: Request only necessary permissions
- Secrets management: Use environment variables, never hardcode
- Rate limiting: Protect against abuse
Configuration
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"your-server": {
"command": "python",
"args": ["/path/to/your_server.py"],
"env": {
"API_KEY": "your-api-key"
}
}
}
}
Claude Code (.mcp.json)
{
"mcpServers": {
"your-server": {
"command": "python",
"args": ["your_server.py"],
"cwd": "/path/to/server"
}
}
}
Testing
Manual Testing
# Test with MCP Inspector
npx @anthropic/mcp-inspector your_server.py
# Test stdio directly
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python your_server.py
Automated Testing
import pytest
from your_server import call_tool
@pytest.mark.asyncio
async def test_tool_execution():
result = await call_tool("tool_name", {"param1": "test"})
assert result[0].text == "Processed: test"
Common Patterns
API Integration
import httpx
async def fetch_data(endpoint: str) -> dict:
async with httpx.AsyncClient() as client:
response = await client.get(endpoint)
response.raise_for_status()
return response.json()
Database Access
import sqlite3
def query_database(sql: str, params: tuple = ()) -> list:
conn = sqlite3.connect("database.db")
cursor = conn.cursor()
cursor.execute(sql, params)
results = cursor.fetchall()
conn.close()
return results
File Operations
from pathlib import Path
def read_file_safely(filepath: str) -> str:
path = Path(filepath).resolve()
# Validate path is within allowed directory
allowed_dir = Path("/allowed/directory").resolve()
if not str(path).startswith(str(allowed_dir)):
raise ValueError("Access denied")
return path.read_text()
Deployment
Package for Distribution
your-mcp-server/
βββ pyproject.toml
βββ README.md
βββ src/
β βββ your_server/
β βββ __init__.py
β βββ server.py
βββ tests/
βββ test_server.py
pyproject.toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "your-mcp-server"
version = "1.0.0"
dependencies = ["mcp>=0.9.0"]
[project.scripts]
your-mcp-server = "your_server.server:main"
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.