mcpField
M
mcp-builder

mcp-builder

github.com/21307369開発041 回インストール10 週間前に更新
リポジトリ

mcp-builder について

mcp-builderは、MCPサーバーの設計、実装、テスト、デプロイを案内する方法論です。MCP連携を開発する人を対象に、ツール、リソース、プロンプトの設計から検証、安全性、配布まで扱います。

主な機能

  1. 01ツール、リソース、プロンプトの使い分け
  2. 02TypeScriptとPythonの構成設計
  3. 03パラメーター、説明、出力形式の設計
  4. 04入力検証とエラー処理
  5. 05ユニットテストと統合テストの計画
  6. 06セキュリティ、デプロイ、デバッグの確認

活用シーン

  1. 01MCPサーバーのプロジェクト構成を計画
  2. 02AIクライアント向けのツールやリソースを設計
  3. 03MCP通信のテストと問題の調査

MCP 対応

MCPクライアントにツール、リソース、プロンプトを公開するMCPサーバーの構築を案内します。プロトコル通信、テスト、デプロイも扱います。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/21307369/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 つの原則:

  1. サーバーを決してクラッシュさせない — すべての外部呼び出しを try/catch で囲みます。
  2. 対処可能なエラーメッセージを返す — 問題の内容と、可能な対処方法を AI に伝えます。
  3. isError: true を使用する — 呼び出しが失敗したことを AI に知らせます。
  4. エラーの種類を区別する — パラメーターエラー、権限不足、リソースの不存在、サービスの利用不可を区別します。

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 に準拠し、秘密鍵をハードコードしない

コメント