mcp-builder について
mcp-builder は、Model Context Protocol サーバーの設計、実装、テスト、デプロイの方法を示すスキルです。プロトコルの基本要素、ツールとリソースの設計、入力検証、エラー処理、セキュリティ、テストを扱い、TypeScript と Python の構成例も示します。
主な機能
- 01ツール、リソース、プロンプトの解説
- 02TypeScript と Python の構成例
- 03ツール入力の設計と検証
- 04エラー処理とサーバーのライフサイクル
- 05サーバーのテスト、保護、デプロイ
活用シーン
- 01MCP サーバーのツールとリソースを設計
- 02入力検証とエラー処理を実装
- 03SDK クライアントでプロトコル通信をテスト
- 04パッケージや Docker での配布を準備
MCP 対応
MCP サーバーの構築に焦点を当て、MCP クライアントにツール、リソース、プロンプトを公開する方法を説明します。プロトコルのテストとクライアント設定も扱います。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jnmetacode/ superpowers-zh --skill mcp-builderインストール後、Claude Code で/mcp-builderを入力して読み込まれたか確認します。
詳細
MCP サーバーの構築
Model Context Protocol サーバーを体系的に設計、実装、テスト、デプロイする方法論です。
1. プロトコルのコア概念
MCP では、次の 3 種類のプリミティブを定義します。
- Tools(ツール):AI アシスタントが能動的に呼び出す、副作用を伴う関数です。検索、作成、削除などの操作が該当します。
- Resources(リソース):AI アシスタントが読み取り専用でアクセスするデータソースです。URI で識別します。例:
users://{id}/profile。 - Prompts(プロンプトテンプレート):ユーザーがワークフローを開始できるように導く、あらかじめ定義された対話テンプレートです。
選択の原則: 操作の実行 → Tool | データの読み取り → Resource | 対話の誘導 → Prompt
2. プロジェクト構成の規約
TypeScript
my-mcp-server/
├── src/
│ ├── index.ts # 入口,注册 tools/resources
│ ├── tools/ # 按功能拆分
│ ├── resources/
│ └── lib/ # 客户端封装、校验逻辑
├── tests/
├── package.json
└── tsconfig.json
主要な依存関係:@modelcontextprotocol/sdk + zod
Python
my-mcp-server/
├── src/my_mcp_server/
│ ├── server.py
│ ├── tools/
│ └── lib/
├── tests/
└── pyproject.toml
主要な依存関係:mcp + pydantic
3. Tool の設計原則
命名
snake_case形式で、動詞から始めます:search_users、create_issue、delete_file- 名前だけで内容が分かるようにします。AI アシスタントは名前を基にツールを選択するため、曖昧な命名は誤った呼び出しにつながります。
パラメーター
- 各パラメーターに型制約と
.describe()による説明を付けます。 - オプションのパラメーターにはデフォルト値を設定し、AI の判断負担を減らします。
- ブール値の切り替えの代わりに列挙型を使用します。
server.tool("search_issues", {
query: z.string().describe("搜索关键词"),
status: z.enum(["open", "closed", "all"]).default("open").describe("状态筛选"),
limit: z.number().min(1).max(100).default(20).describe("返回上限"),
}, async ({ query, status, limit }) => { /* ... */ });
説明
用途 + 返される内容 + 制限事項を明記します。これは AI がツールを選択する際の重要な判断材料です。
server.tool("search_users",
"根据姓名或邮箱搜索用户。返回 ID、姓名、邮箱列表。模糊匹配,最多 50 条。",
schema, handler);
出力
- 構造化データには JSON、人間が読みやすい内容には Markdown を使用します。
- 常に
content: [{ type: "text", text: "..." }]の形式で返します。
4. 入力検証とエラー処理
Zod/Pydantic でスキーマレベルの検証を行い、ビジネスレベルの検証はハンドラーの先頭に配置します。
server.tool("get_user", { id: z.string() }, async ({ id }) => {
try {
const user = await db.getUser(id);
if (!user) {
return {
content: [{ type: "text", text: `用户 ${id} 不存在,请检查 ID。` }],
isError: true,
};
}
return { content: [{ type: "text", text: JSON.stringify(user, null, 2) }] };
} catch (err) {
return {
content: [{ type: "text", text: `查询失败:${err.message}` }],
isError: true,
};
}
});
エラー処理の 4 つの原則:
- サーバーを決してクラッシュさせない — すべての外部呼び出しを try/catch で囲みます。
- 対処可能なエラーメッセージを返す — 問題の内容と、可能な対処方法を AI に伝えます。
isError: trueを使用する — 呼び出しが失敗したことを AI に知らせます。- エラーの種類を区別する — パラメーターエラー、権限不足、リソースの不存在、サービスの利用不可を区別します。
5. リソース管理とライフサイクル
// 资源注册
server.resource("user-profile", "users://{userId}/profile", async (uri) => {
const profile = await db.getProfile(extractId(uri));
return { contents: [{ uri: uri.href, mimeType: "application/json", text: JSON.stringify(profile) }] };
});
// 生命周期:先初始化 → 再 connect → 监听关闭信号
const db = await Database.connect(config.dbUrl);
await server.connect(new StdioServerTransport());
process.on("SIGINT", async () => { await db.disconnect(); await server.close(); process.exit(0); });
重要なポイント:接続プールを使用し、すべての外部呼び出しにタイムアウトを設定し、終了時にリソースを適切にクリーンアップします。
6. テスト戦略
単体テスト — ビジネスロジックと MCP の登録を分離
// tools/search.ts 导出纯函数
export async function searchUsers(query: string, limit: number) { /* ... */ }
// search.test.ts 独立测试
test("返回匹配结果", async () => {
const results = await searchUsers("alice", 10);
expect(results[0].name).toContain("Alice");
});
統合テスト — SDK Client を使ったエンドツーエンド検証
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
await server.connect(serverTransport);
const client = new Client({ name: "test", version: "1.0.0" });
await client.connect(clientTransport);
const result = await client.callTool("search_users", { query: "test" });
expect(result.isError).toBeFalsy();
MCP Inspector — 対話的なデバッグ
npx @modelcontextprotocol/inspector node dist/index.js
ブラウザーですべての tools/resources を確認し、手動で呼び出して結果を確認します。
テストのポイント: 各 Tool で正常系と異常系、境界値、外部サービスの障害をシミュレートするケースをカバーします。
7. セキュリティに関する考慮事項
権限制御:
- 最小権限の原則に従い、読み取りと書き込みの Tool を分離します。
- 危険な操作には確認用パラメーターを必須にします(例:
confirm: true)。
入力の安全性:
- SQL インジェクション → パラメーター化クエリーを使用し、文字列を連結しないでください。
- パストラバーサル → パスを検証し、
../を禁止します。 - コマンドインジェクション →
execではなくexecFileを使用します。
機密データ:
- 秘密鍵は環境変数から渡し、ハードコードしません。
- ログに機密情報を完全な形で出力しません。
- 返却データはマスキングします。
サンドボックス: ファイル操作はディレクトリを制限し、ネットワークリクエストは許可リストで制限し、リソースのクォータを設定します。
8. デプロイと配布
npm での公開
{ "bin": { "mcp-server-myservice": "dist/index.js" }, "files": ["dist"] }
ユーザー設定:
{ "mcpServers": { "myservice": { "command": "npx", "args": ["@yourorg/mcp-server-myservice"], "env": { "API_KEY": "xxx" } } } }
pip での公開
[project.scripts]
mcp-server-myservice = "my_mcp_server.server:main"
Docker — 依存関係が複雑な場合や、隔離が必要な場合に適しています
FROM node:20-slim
WORKDIR /app
COPY package*.json ./ && RUN npm ci --production
COPY dist ./dist
ENTRYPOINT ["node", "dist/index.js"]
9. デバッグのヒント
重要:MCP は stdio で通信するため、console.log は使用できません。プロトコルのストリームが破損します。
// 错误
console.log("debug");
// 正确
console.error("[DEBUG]", info);
// 更好
server.sendLoggingMessage({ level: "info", data: "处理中" });
よくある問題:
| 症状 | 原因 | 解決方法 |
|---|---|---|
| 起動しても応答がない | transport が接続されていない | server.connect() を確認します |
| Tool が表示されない | connect の後に登録している | 先に登録し、その後で connect します |
| AI が Tool を呼び出さない | 説明が不明確 | 名前と説明を改善します |
| パラメーターがいつも間違っている | Schema が不明確 | .describe() を追加します |
| 呼び出しがタイムアウトする | 外部サービスの応答が遅い | タイムアウトとキャッシュを追加します |
デバッグの手順: Inspector で基本機能を検証 → 手動で呼び出して入出力を確認 → 実際の AI クライアントに接続し、呼び出しのパターンを観察 → 実際の動作に基づいて設計を調整します。
10. 構築チェックリスト
設計
- Tools、Resources、Prompts の役割分担を明確にする
- Tool 名は
動詞_名詞とし、説明には用途と返される内容を記載する - パラメーターを簡潔にし、オプションのパラメーターには適切なデフォルト値を設定する
実装
- Zod/Pydantic で入力を検証する
- 外部呼び出しに try/catch とタイムアウトを設定する
- エラーでは
isError: trueと対処可能な情報を返す -
console.logを使わない(stderr または SDK のログを使用する) - 機密データは環境変数から渡す
テスト
- コアロジックに単体テストがある
- MCP プロトコルのやり取りを検証する統合テストがある
- MCP Inspector で手動検証済み
- 実際の AI クライアントでテスト済み
デプロイ
- README にインストールと設定の説明がある
- クライアント設定の JSON サンプルを提供する
- semver に準拠し、秘密鍵をハードコードしない