Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/tomevault-io/skills-registry --skill mcp-server-builder명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
| Use when this capability is needed.
> Use when this capability is needed.
Review architecture and API design for the vfs-s3 project. Use when the user mentions @architect, asks to review an issue's design, discuss module boundaries, API shape, or architectural decisions for vfs-s3. Also trigger when the user wants to create an ADR (Architecture Decision Record) or evaluate a technical approach for the project. Intended for dispatch from Codex automation or Claude routines; GitHub trigger phrase: @vfs-s3-bot please prepare design doc Use when this capability is needed.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | mcp-server-builder |
| description | > Use when this capability is needed. |
Build an MCP server that extends Claude Code with new tools, resources, or prompts.
Server Purpose: $ARGUMENTS
Before writing code, define what the MCP server will expose:
| MCP Primitive | Use When | Examples |
|---|---|---|
| Tools | Claude needs to perform actions or retrieve computed data | Query a database, create a ticket, run a deployment |
| Resources | Claude needs to read structured data | Config files, API schemas, documentation |
| Prompts | Claude needs reusable prompt templates | Code review checklist, incident response template |
MCP servers are consumed by AI agents, not humans. Design accordingly:
Build for workflows, not endpoints — Group related operations into tools that match how an agent thinks about a task. One tool that "creates a PR with tests" beats three tools for "create branch", "commit files", "open PR".
Optimize for limited context — Return only what the agent needs. A tool that returns a 10,000-line log is worse than one that returns the 20 relevant lines with context.
Make errors actionable — Instead of "Error: 403", return "Permission denied: the API token lacks 'write:issues' scope. Add this scope at https://...". The agent should be able to fix the problem from the error message alone.
Provide discovery — Include a tool that lists available resources or explains what the server can do. Agents need to understand capabilities at runtime.
Idempotent where possible — Agents may retry tools. Design create/update operations to be safe to call multiple times with the same input.
For each tool, define:
Tool: <name>
Description: <what it does — this is what Claude reads to decide whether to use it>
Input: <parameters with types and descriptions>
Output: <what it returns>
Side effects: <what it changes in the external system>
Error cases: <what can go wrong and what the error message should say>
Description quality matters. Claude selects tools based on their descriptions. A vague description like "manage issues" produces poor tool selection. Be specific: "Create a new GitHub issue with title, body, labels, and assignee. Returns the issue URL and number."
FastMCP is the recommended Python SDK — minimal boilerplate, decorator-based.
# Initialize project
mkdir mcp-server-<name> && cd mcp-server-<name>
python -m venv .venv && source .venv/bin/activate # or .venv/Scripts/activate on Windows
pip install fastmcp
Scaffold:
# server.py
from fastmcp import FastMCP
mcp = FastMCP(
name="<server-name>",
description="<what this server does>",
)
@mcp.tool()
def example_tool(param: str) -> str:
"""Description that Claude reads to decide when to use this tool.
Args:
param: What this parameter controls
"""
# Implementation here
return "result"
@mcp.resource("resource://{name}")
def example_resource(name: str) -> str:
"""Provides access to <what>."""
return "resource content"
if __name__ == "__main__":
mcp.run()
mkdir mcp-server-<name> && cd mcp-server-<name>
npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript @types/node
npx tsc --init
Scaffold:
// src/index.ts
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({
name: "<server-name>",
version: "1.0.0",
});
server.tool(
"example-tool",
"Description that Claude reads to decide when to use this tool",
{ param: { type: "string", description: "What this parameter controls" } },
async ({ param }) => {
// Implementation here
return { content: [{ type: "text", text: "result" }] };
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
For each tool:
Validate inputs and return helpful messages:
@mcp.tool()
def create_issue(title: str, body: str, labels: list[str] | None = None) -> str:
"""Create a GitHub issue in the current repository.
Args:
title: Issue title (required, max 256 chars)
body: Issue body in markdown
labels: Optional list of label names (must already exist in repo)
"""
if not title.strip():
return "Error: title is required and cannot be empty."
if len(title) > 256:
return f"Error: title is {len(title)} chars, max is 256. Shorten the title."
# ... implementation
try:
result = external_api.call(params)
return format_result(result)
except AuthenticationError:
return (
"Error: Authentication failed. Check that your API token is set in the "
"environment variable EXAMPLE_API_TOKEN and has the required scopes: "
"read:data, write:data. Generate a token at https://example.com/settings/tokens"
)
except RateLimitError as e:
return f"Error: Rate limited. Retry after {e.retry_after} seconds."
except Exception as e:
return f"Error: Unexpected failure — {type(e).__name__}: {e}"
Return structured, scannable output:
# BAD: Wall of text
return json.dumps(full_api_response)
# GOOD: Curated summary
return f"""Issue created successfully.
- URL: {issue.html_url}
- Number: #{issue.number}
- Labels: {', '.join(issue.labels)}
Next: assign the issue with the assign-issue tool, or link it to a PR."""
Resources provide read-only data that Claude can reference:
@mcp.resource("config://settings")
def get_settings() -> str:
"""Current project settings including API endpoints and feature flags."""
settings = load_settings()
# Return only what's relevant, not the entire config
return yaml.dump({
"api_base": settings["api_base"],
"features": settings["features"],
"environment": settings["environment"],
})
docs://, config://, schema://docs://{topic} is better than dumping all docs at onceAdd the server to the project's .mcp.json:
{
"mcpServers": {
"<server-name>": {
"command": "python",
"args": ["path/to/server.py"],
"env": {
"EXAMPLE_API_TOKEN": "${EXAMPLE_API_TOKEN}"
}
}
}
}
For Node.js:
{
"mcpServers": {
"<server-name>": {
"command": "node",
"args": ["path/to/dist/index.js"]
}
}
}
NEVER hardcode credentials in the server. Use environment variables:
import os
API_TOKEN = os.environ.get("EXAMPLE_API_TOKEN")
if not API_TOKEN:
raise RuntimeError(
"EXAMPLE_API_TOKEN environment variable is required. "
"Set it in .mcp.json env block or your shell profile."
)
# Test with MCP Inspector (if available)
npx @modelcontextprotocol/inspector python server.py
# Or test directly by running the server and sending JSON-RPC
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python server.py
Write tests for each tool:
# test_server.py
import pytest
from server import mcp
@pytest.fixture
def client():
"""Create a test client for the MCP server."""
return mcp.test_client()
def test_example_tool_happy_path(client):
result = client.call_tool("example-tool", {"param": "test"})
assert "expected output" in result
def test_example_tool_missing_param(client):
result = client.call_tool("example-tool", {})
assert "Error:" in result
def test_example_tool_error_is_actionable(client):
result = client.call_tool("example-tool", {"param": "invalid"})
# Error messages MUST tell the agent how to fix the problem
assert any(word in result.lower() for word in ["try", "check", "use", "set"])
Beyond unit tests, evaluate how well Claude uses your tools:
If Claude struggles with any of these, improve the tool descriptions and error messages — don't blame the model.
Create a README with:
requirements.txt or package.jsonSource: abhayla/claude-best-practices — distributed by TomeVault.