「Claude Codeは便利だけど、ファイルの読み書きとターミナル操作だけでは限界がある——」そう感じたことはないだろうか。データベースへの直接クエリ、ブラウザの自動操作、外部APIとの連携、クラウドサービスの監視。現実の開発現場では、コードの編集だけでなく、開発ワークフロー全体をAIに任せたい場面が数多くある。
その課題を根本から解決するのがMCP(Model Context Protocol)だ。MCPは、AIアプリケーションと外部ツール・データソースを接続するためのオープンスタンダードプロトコルであり、Claude Codeの能力を文字通り「10倍」に拡張する。2024年11月にAnthropicが公開し、2025年12月にはLinux Foundation傘下のAgentic AI Foundation(AAIF)に寄贈されたこのプロトコルは、現在10,000以上のサーバーがレジストリに登録され、SDK月間ダウンロード数は9,700万以上に達している。
本記事では、MCPの基本アーキテクチャから、Claude Codeへの導入・設定方法、現場で即使える必須サーバー10選、リモートMCPによるチーム開発の革新、.mcp.jsonのチーム設計パターン、そしてTypeScriptによるカスタムサーバーの自作まで、MCPの実践活用を完全網羅する。Claude Code初心者ガイドを読んで基本操作を習得済みの方が、次のステップとしてClaude Codeの真の力を引き出すための実践ガイドだ。
目次
- MCPとは何か——Claude Codeの能力を10倍にするプロトコルの全体像
- MCPサーバーの導入と設定——3つのスコープを使いこなす
- 現場で使える必須MCPサーバー10選——カテゴリ別導入ガイド
- リモートMCPの革命——HTTP Streamableで変わる開発体験
- .mcp.jsonチーム設計パターン——共有・分離・継承の実践テンプレート
- カスタムMCPサーバーを自作する——TypeScriptで30分ハンズオン
- MCPセキュリティ完全ガイド——権限管理・監査・組織ポリシー
- MCP Tool Search——大量サーバーの動的管理と最適化
- MCPデバッグ・トラブルシューティング実践
- MCPを活用した実践ワークフローパターン集
- MCPの未来——2025-11-25仕様とTasksの展望
- まとめ——MCPで実現するClaude Code開発の次のステージ
MCPとは何か——Claude Codeの能力を10倍にするプロトコルの全体像
MCP(Model Context Protocol)は、LLMアプリケーションと外部のツール・データソースを標準化された方法で接続するためのオープンプロトコルだ。USB-Cがデバイス接続を統一したように、MCPはAIと外部世界の接続を統一する。
Anthropicが2024年11月に初版仕様を公開し、その後急速にエコシステムが拡大。2025年12月にはLinux Foundation傘下のAgentic AI Foundation(AAIF)に寄贈され、Anthropic、OpenAI、Google、Microsoft、Amazon Web Services(AWS)、Cloudflareなど業界大手が参画する中立的なガバナンス体制へ移行した。
MCPの基本アーキテクチャ——ホスト・クライアント・サーバーの3層構造
MCPのアーキテクチャは、明確に分離された3つの層で構成される。
| 層 | 役割 | 具体例 |
|---|---|---|
| Host(ホスト) | ユーザーが直接操作するLLMアプリケーション。MCPクライアントのライフサイクルを管理し、セキュリティポリシーを適用する | Claude Code、Claude Desktop、Cursor、VS Code Copilot |
| Client(クライアント) | ホスト内に組み込まれたプロトコルクライアント。JSON-RPCメッセージングを担当し、サーバーとの1対1セッションを維持する | Claude Code内蔵のMCPクライアント |
| Server(サーバー) | 外部のツール・データ・APIを、MCPプロトコルに準拠した形で公開する。軽量プロセスまたはHTTPエンドポイントとして動作する | GitHub MCP、PostgreSQL DBHub、Playwright MCP |
セッション開始時に、クライアントとサーバーの間でCapability Negotiation(能力ネゴシエーション)が行われる。互いがサポートするTools、Resources、Promptsを宣言し、セッション中に利用可能な機能を確定する。これにより、サーバーの追加や変更があっても、ホスト側は統一されたインターフェースで操作できる。
Resources / Tools / Prompts——MCPが提供する3つのプリミティブ
MCPサーバーは、3種類のプリミティブ(基本要素)をクライアントに提供する。
| プリミティブ | 性質 | 説明 | 具体例 |
|---|---|---|---|
| Tools(ツール) | 実行可能アクション | AIが呼び出して副作用を伴う操作を実行する。APIリクエスト、DB操作、ファイル書き込み、外部サービスとの連携など | GitHub PRの作成、SQLクエリの実行、ブラウザ操作、Slackメッセージ送信 |
| Resources(リソース) | 読み取り専用データ | クライアントがコンテキストとして参照できるデータソース。URIベースでアクセスし、AIの判断材料として提供される | ファイル内容、ログデータ、DBスキーマ情報、設定ファイル |
| Prompts(プロンプト) | 再利用テンプレート | サーバーが定義する再利用可能なプロンプトテンプレート。ユーザーが/コマンドで呼び出し、引数を渡して実行する |
コードレビューテンプレート、PR要約テンプレート、バグレポート生成 |
💡 Toolsが最も重要
実際の開発現場では、Toolsが最も多用されるプリミティブだ。Claude Codeでは、MCPサーバーが提供するToolsをAIが自律的に判断して呼び出す。Resourcesは@メンションで参照でき、Promptsは/mcp__サーバー名__プロンプト名の形式でコマンドとして利用できる。
なぜClaude CodeにMCPが必要なのか——ファイル操作だけでは届かない領域
Claude Codeには、強力なビルトインツールが搭載されている。
- Read / Edit / Write — ファイルの読み取り・編集・作成
- Bash — シェルコマンドの実行
- Glob / Grep — ファイル検索・コンテンツ検索
しかし、これだけではカバーできない領域が数多く存在する。
| 必要な操作 | ビルトインツール | MCPサーバー |
|---|---|---|
| データベースへの直接クエリ | Bashでpsqlコマンドを叩けるが、構造化された結果は得にくい |
DBHubがスキーマ認識・型安全なクエリを提供 |
| ブラウザの自動操作 | 対応不可 | Playwright MCPがアクセシビリティツリー経由で操作 |
| GitHub PR / Issue操作 | Bashでgh CLIを使えるが、複雑な操作は困難 |
GitHub MCPがOAuth認証でフル機能を提供 |
| エラー監視・分析 | 対応不可 | Sentry MCPがスタックトレース・AI分析を提供 |
| 最新ライブラリドキュメント参照 | Web検索に依存 | Context7が公式ドキュメントを直接注入 |
| チームコミュニケーション | 対応不可 | Slack MCPがメッセージの読み書きを実現 |
MCPは、Claude Codeのビルトインツールでは届かない「外側」の世界へのアクセスを、安全かつ標準化された方法で実現する。Claude Code実践ワークフローガイドで紹介したワークフローに、MCPを組み合わせることで、開発プロセス全体をAIに委任できるようになる。
stdio vs HTTP Streamable——2つのトランスポート方式の使い分け
MCPは、クライアントとサーバー間の通信に2つのトランスポート方式を定義している。
| 項目 | stdio(標準入出力) | HTTP Streamable |
|---|---|---|
| 通信方式 | ローカルプロセスの標準入出力を使用 | HTTPエンドポイントへのPOSTリクエスト + SSEストリーミング |
| 動作場所 | ローカルマシン上 | ローカルまたはリモートサーバー |
| レイテンシ | 極めて低い(プロセス間通信) | ネットワーク遅延あり |
| 環境依存 | 高い(Node.jsバージョン、OS固有の問題) | 低い(HTTPエンドポイントのみ) |
| 認証 | OS権限に依存 | OAuth 2.0 / Bearer Token / APIキー |
| チーム共有 | 各開発者がローカルにセットアップ必要 | URLを共有するだけで即利用可能 |
| セッション管理 | プロセスのライフサイクルに紐付く | Mcp-Session-Idヘッダーで管理 |
| 代表的な用途 | ローカル開発ツール、カスタムスクリプト | クラウドサービス連携、チーム共有ツール |
📌 SSE(Server-Sent Events)トランスポートは非推奨
2025年3月26日の仕様改訂(2025-03-26)で、SSEトランスポートはHTTP Streamableに置き換えられ、非推奨となった。既存のSSEサーバーは引き続き動作するが、新規開発ではHTTP Streamableを使用すべきだ。Claude Codeでは--transport sseでSSEサーバーに接続することも可能だが、HTTP Streamableへの移行を推奨する。
MCPサーバーの導入と設定——3つのスコープを使いこなす
Claude CodeへのMCPサーバー導入は、CLIコマンドまたはJSON設定ファイルの編集で行う。ここでは、3つのスコープの使い分けと、実践的な設定方法を解説する。
CLIコマンドで即座に追加する方法(claude mcp add)
最も手軽な方法は、claude mcp addコマンドだ。構文は以下の通り。
claude mcp add [options] <name> [-- <command> [args...]]
重要なルールとして、すべてのオプション(--transport、--env、--scope、--header)はサーバー名の前に指定する。--(ダブルダッシュ)の後にサーバーのコマンドと引数を記述する。
例1: HTTP Streamableサーバーの追加
# GitHub MCPサーバー(リモートHTTP)
claude mcp add --transport http github https://api.githubcopilot.com/mcp/
# Sentry MCPサーバー(リモートHTTP)
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
例2: stdioサーバーの追加
# Playwright MCPサーバー(ローカルstdio)
claude mcp add --transport stdio playwright -- npx -y @playwright/mcp@latest
# DBHub(PostgreSQL接続)
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub --dsn "postgresql://user:pass@localhost:5432/mydb"
例3: 環境変数付きサーバーの追加
# 環境変数を渡してサーバーを起動
claude mcp add --transport stdio --env API_KEY=sk-xxx --env BASE_URL=https://api.example.com myserver -- node dist/index.js
例4: 認証ヘッダー付きHTTPサーバー
# Bearer tokenで認証
claude mcp add --transport http --header "Authorization: Bearer your-token" secure-api https://api.example.com/mcp
.mcp.jsonによるプロジェクトレベル設定
チームで共有するMCPサーバー設定は、プロジェクトルートに.mcp.jsonファイルを配置する。このファイルをGitにコミットすることで、チーム全員が同じMCPサーバーにアクセスできる。
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/"
},
"db": {
"command": "npx",
"args": ["-y", "@bytebase/dbhub", "--dsn", "${DATABASE_URL}"],
"env": {
"NODE_ENV": "development"
}
},
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"],
"env": {}
},
"sentry": {
"type": "http",
"url": "https://mcp.sentry.dev/mcp"
}
}
}
💡 HTTPとstdioの設定形式の違い
HTTPサーバーは"type": "http"と"url"で指定する。stdioサーバーは"command"と"args"で起動コマンドを指定する(typeの明示は不要)。いずれも"env"フィールドで環境変数を設定できる。
settings.jsonによるユーザーレベル設定
個人用の汎用ツール(全プロジェクトで使いたいもの)は、ユーザーレベル(~/.claude.json)に設定する。
# ユーザースコープでContext7を追加(全プロジェクトで利用可能に)
claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp
この設定は~/.claude.jsonに保存され、どのプロジェクトディレクトリで作業してもContext7が利用可能になる。プロジェクト固有ではない個人ツール(ドキュメント参照、汎用ユーティリティなど)に最適だ。
3つのスコープの優先順位と使い分け(local > project > user)
Claude CodeのMCPサーバー設定には、3つのスコープが存在する。同名のサーバーが複数のスコープに存在する場合、優先順位の高いスコープの設定が適用される。
| スコープ | 保存場所 | 優先順位 | 可視範囲 | 適した用途 |
|---|---|---|---|---|
| local(デフォルト) | ~/.claude.json(プロジェクトパス配下) |
最高 | 自分のみ・現プロジェクトのみ | 個人的な実験、秘密鍵を含む設定、プロジェクト固有の個人ツール |
| project | プロジェクトルートの.mcp.json |
中 | チーム全員(Git共有) | チーム共有サーバー、プロジェクト固有ツール、CI/CD連携 |
| user | ~/.claude.json |
最低 | 自分のみ・全プロジェクト | 個人用の汎用ツール(Context7等)、開発ユーティリティ |
# スコープを明示的に指定する
claude mcp add --scope local --transport http my-api https://api.example.com/mcp
claude mcp add --scope project --transport stdio shared-tool -- npx -y @team/tool
claude mcp add --scope user --transport stdio context7 -- npx -y @upstash/context7-mcp
⚙️ 実用的な使い分けの指針
- チーム全員が必要なサーバー(GitHub、DB、テストツール)→
projectスコープで.mcp.jsonにコミット - 自分だけが使う汎用ツール(Context7、個人用API)→
userスコープ - 実験的・一時的な設定(新サーバーの検証、秘密鍵付き設定)→
localスコープ
環境変数の展開——${VAR} と ${VAR:-default} の活用
Claude Codeは、.mcp.json内で環境変数の展開をサポートしている。これにより、秘密鍵やマシン固有のパスをハードコードすることなく、チームで安全に設定を共有できる。
サポートされる構文:
${VAR}— 環境変数VARの値に展開される${VAR:-default}—VARが未設定の場合、default値が使用される
展開可能なフィールド:
command— サーバーの実行コマンドargs— コマンド引数env— サーバーに渡す環境変数url— HTTPサーバーのURLheaders— HTTP認証ヘッダー
実践的な設定例:
{
"mcpServers": {
"api-server": {
"type": "http",
"url": "${API_BASE_URL:-https://api.example.com}/mcp",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
},
"database": {
"command": "npx",
"args": ["-y", "@bytebase/dbhub", "--dsn", "${DATABASE_URL}"],
"env": {
"NODE_ENV": "${NODE_ENV:-development}"
}
},
"custom-tool": {
"command": "${HOME}/.local/bin/my-mcp-server",
"args": ["--config", "${PROJECT_ROOT:-./config}/settings.json"],
"env": {
"LOG_LEVEL": "${LOG_LEVEL:-info}"
}
}
}
}
🚨 セキュリティ上の鉄則
.mcp.jsonにAPIキーやパスワードを絶対にハードコードしない- 必ず
${VAR}形式で環境変数を参照する - ローカル開発では
.envファイルに秘密鍵を記述し、.gitignoreに追加する - CI/CDではパイプラインのシークレット管理機能を使用する
- 必須の環境変数が未設定の場合、Claude Codeは設定のパースに失敗する(安全側に倒れる設計)
現場で使える必須MCPサーバー10選——カテゴリ別導入ガイド
MCPエコシステムには10,000以上のサーバーが登録されているが、実際の開発現場で頻繁に使用されるサーバーは限られている。ここでは、カテゴリ別に厳選した10のサーバーを、導入コマンド付きで紹介する。
開発基盤系(GitHub MCP, PostgreSQL/DB Hub, Docker MCP Toolkit)
1. GitHub MCP Server
GitHubが公式に提供するリモートMCPサーバー。HTTP Streamableトランスポートで、OAuth認証によるシームレスな接続を実現する。PR・Issue管理、コードサーチ、Actions連携、Dependabotアラート確認まで、GitHub上のあらゆる操作をClaude Codeから直接行える。
# GitHub MCPの追加(HTTP Streamable + OAuth)
claude mcp add --transport http github https://api.githubcopilot.com/mcp/
# 認証フローの開始(Claude Code内で実行)
/mcp
# → GitHubを選択 → ブラウザでOAuth認証
2025年6月にパブリックプレビュー、同年9月にGA(一般提供)となったリモート版は、ローカルにDockerやNode.jsをインストールする必要がない。Claude Code上級テクニックガイドで解説しているGit操作と組み合わせると、コードレビューからマージまでをAIに一任できる。
2. DBHub(Bytebase)
PostgreSQL、MySQL、SQLite、SQL Server、MariaDBに対応するゼロ依存のデータベースMCPサーバー。スキーマ認識、安全なクエリ実行、読み取り専用モード、行数制限、タイムアウト制御などのガードレールを備える。
# PostgreSQL接続
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub \
--dsn "postgresql://readonly:pass@localhost:5432/mydb"
# MySQL接続
claude mcp add --transport stdio db-mysql -- npx -y @bytebase/dbhub \
--dsn "mysql://user:pass@localhost:3306/mydb"
# SQLite接続
claude mcp add --transport stdio db-sqlite -- npx -y @bytebase/dbhub \
--dsn "sqlite:///path/to/database.db"
主要ツール: execute_sql(クエリ実行)、search_objects(スキーマ探索)、およびカスタムツール(再利用可能なパラメータ化SQLの定義)。
3. Docker MCP Toolkit
Docker Desktop 4.42以降に統合されたMCPサーバー管理ツールキット。100以上のコンテナ化されたMCPサーバーをワンクリックでデプロイできる。最大の特徴はセキュリティだ。通常のnpxやuvx経由の実行はホストシステムに広くアクセスできてしまうが、Docker MCP Toolkitはすべてのサーバーを分離されたコンテナ内で実行する。
# Docker CLIでMCPサーバーを管理
docker mcp list # 利用可能なサーバー一覧
docker mcp install <name> # サーバーのインストール
docker mcp start <name> # サーバーの起動
さらにDynamic MCP機能により、AIエージェントが会話中にカタログからサーバーを検索・追加・構成できる。手動設定なしで必要なツールを動的に利用可能にする、次世代のMCP体験だ。
テスト・品質系(Playwright MCP, Sentry MCP, Vitest MCP)
4. Playwright MCP(Microsoft)
Microsoftが開発したブラウザ自動操作MCPサーバー。スクリーンショットではなくアクセシビリティツリーを介して操作するため、軽量かつ正確なブラウザ操作を実現する。E2Eテストの自動生成、UIの動作確認、視覚的回帰テストに活用できる。
# Playwright MCPの追加
claude mcp add --transport stdio playwright -- npx -y @playwright/mcp@latest
# 使用例(Claude Code内で指示)
# 「http://localhost:3000 を開いてログインフローをテストして」
# 「モバイルビューでトップページのスクリーンショットを撮って」
Claude Code TDDガイドで解説しているテスト駆動開発と組み合わせると、ユニットテストだけでなくE2Eテストまでをカバーした品質保証ワークフローが構築できる。
5. Sentry MCP
エラー監視プラットフォームSentryの公式MCPサーバー。HTTP Streamableで提供され、OAuthでのワンクリック認証に対応する。16以上のツールを提供し、エラーの詳細分析、スタックトレースの取得、リリースごとのエラー比較、そしてSeer AIによる自動根本原因分析が可能だ。
# Sentry MCPの追加
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
# 認証(Claude Code内で実行)
/mcp
# → Sentryを選択 → ブラウザでOAuth認証
# 使用例
# 「過去24時間で最も多いエラーを教えて」
# 「エラーID abc123 のスタックトレースを見せて」
# 「最新のデプロイで新規発生したエラーはある?」
6. Vitest MCP
Vitestテストフレームワーク向けのMCPサーバー。テストの実行、結果の解析、テストカバレッジの確認をClaude Codeから直接行える。テスト生成の自動化と組み合わせると、コード変更に対する即座のフィードバックループを構築できる。
ドキュメント・知識系(Context7, Notion MCP)
7. Context7(Upstash)
LLMのハルシネーション(幻覚)対策として最も効果的なMCPサーバーの一つ。ライブラリやフレームワークの最新公式ドキュメントを直接コンテキストに注入する。LLMの学習データに含まれない最新API変更やバージョン固有の仕様を正確に参照できる。
# Context7の追加(userスコープ推奨:全プロジェクトで利用)
claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp
Context7は全プロジェクトで活用できるため、--scope userでの追加を推奨する。Next.js 16、React 19、Zod 4など、急速に進化するライブラリの開発で特に威力を発揮する。
8. Notion MCP
NotionのHTTP MCPサーバー。ページの読み書き、データベースの操作、コメントの追加などをClaude Codeから直接実行できる。プロジェクトのドキュメント管理やナレッジベースとの連携に最適だ。
# Notion MCPの追加
claude mcp add --transport http notion https://mcp.notion.com/mcp
外部サービス連携系(Slack MCP, Rube)
9. Slack MCP
Slackのチャンネル・メッセージ操作をClaude Codeから行えるMCPサーバー。デプロイ通知の送信、チームメンバーへの確認依頼、バグレポートの自動投稿などを、開発フローの中にシームレスに組み込める。
10. Rube(統合ハブ)
複数の外部サービスを単一のMCPサーバーとして統合するハブ型サーバー。個別にサーバーを追加する代わりに、Rubeを経由して複数サービスにアクセスできる。MCPサーバーの管理数を抑えつつ、幅広い連携を実現する選択肢だ。
一覧比較表
| 名称 | カテゴリ | トランスポート | 主要機能 | セットアップコマンド |
|---|---|---|---|---|
| GitHub MCP | 開発基盤 | HTTP | PR/Issue、コードサーチ、Actions、Dependabot | claude mcp add --transport http github https://api.githubcopilot.com/mcp/ |
| DBHub | 開発基盤 | stdio | PostgreSQL/MySQL/SQLiteクエリ、スキーマ探索 | claude mcp add --transport stdio db -- npx -y @bytebase/dbhub --dsn "..." |
| Docker MCP | 開発基盤 | stdio/HTTP | 100+サーバーのコンテナ管理、Dynamic MCP | Docker Desktop UIまたはdocker mcp CLI |
| Playwright | テスト・品質 | stdio | ブラウザ自動操作、E2Eテスト、スクリーンショット | claude mcp add --transport stdio playwright -- npx -y @playwright/mcp@latest |
| Sentry | テスト・品質 | HTTP | エラー監視、スタックトレース、Seer AI分析 | claude mcp add --transport http sentry https://mcp.sentry.dev/mcp |
| Vitest MCP | テスト・品質 | stdio | テスト実行、カバレッジ、結果解析 | claude mcp add --transport stdio vitest -- npx -y vitest-mcp |
| Context7 | ドキュメント | stdio | 最新ライブラリドキュメントの直接注入 | claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp |
| Notion | ドキュメント | HTTP | ページ/DB操作、コメント管理 | claude mcp add --transport http notion https://mcp.notion.com/mcp |
| Slack | 外部連携 | HTTP/stdio | メッセージ送受信、チャンネル操作 | claude mcp add --transport http slack https://mcp.slack.com/mcp |
| Rube | 外部連携 | stdio | 複数サービスの統合アクセス | サービスごとに設定 |
リモートMCPの革命——HTTP Streamableで変わる開発体験
MCPの初期は、ほとんどのサーバーがstdioトランスポートで提供されていた。しかし2025年、HTTP Streamableの普及とGitHub・Sentryなどの主要サービスによるリモートMCPサーバーの公開により、開発体験は根本的に変わった。
ローカルstdioの限界
stdioサーバーは手軽だが、チーム開発では以下の問題が顕在化する。
- 環境依存: Node.jsのバージョン、OS固有の動作差異、グローバルパッケージの競合など、「自分の環境では動くが他のメンバーでは動かない」問題が頻発する
- メンテナンスコスト: チームの各開発者がローカルに同じセットアップを行う必要がある。新規メンバーのオンボーディングに時間がかかる
- バージョン管理の困難:
npx -yで最新版を取得する場合、チーム内でバージョンが揃わない可能性がある - シークレットの分散管理: APIキーなどのシークレットが各開発者のローカル環境に散在する
HTTP Streamableの仕組みとメリット
HTTP Streamable(2025-03-26仕様で導入)は、これらの問題をプロトコルレベルで解決する。
仕組み:
- クライアントはHTTP POSTリクエストでJSON-RPCメッセージを送信する
- サーバーはJSON応答を返すか、SSEストリームで段階的にレスポンスする
- セッションは
Mcp-Session-Idヘッダーで管理される - 認証はOAuth 2.0 / Bearer Token / カスタムヘッダーをサポートする
メリット:
- ゼロインストール: URLを指定するだけで接続完了。ローカルにNode.jsやDockerは不要
- チーム統一: 同じURLを
.mcp.jsonに記述すれば全員同じサーバーに接続 - 集中管理: 認証・アクセス制御をサーバー側で一元管理
- 自動更新: サーバー側のアップデートが即座に全クライアントに反映
GitHub MCP / Sentry MCP——リモートMCPの実践セットアップ
リモートMCPの代表格であるGitHub MCPとSentry MCPの実践的なセットアップ手順を解説する。
GitHub MCPのセットアップ:
# Step 1: サーバーの追加
claude mcp add --transport http github https://api.githubcopilot.com/mcp/
# Step 2: Claude Code内で認証フローを開始
/mcp
# → 「GitHub」を選択
# → 「Authenticate」を選択
# → ブラウザが自動で開き、GitHubのOAuth認証画面が表示される
# → 認証を許可すると、自動的にClaude Codeに戻る
# Step 3: 動作確認
# Claude Codeに以下のように指示:
# 「自分にアサインされているPRを一覧表示して」
# 「Issue #123 の内容を要約して」
# 「新しいブランチを作成してPRを出して」
Sentry MCPのセットアップ:
# Step 1: サーバーの追加
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
# Step 2: Claude Code内で認証
/mcp
# → 「Sentry」を選択
# → 「Authenticate」を選択
# → ブラウザでSentryアカウントにログイン
# → 組織へのアクセスを許可
# Step 3: 実際に使用
# 「過去24時間の未解決エラーを重要度順に表示して」
# 「このエラーのスタックトレースを分析して修正案を出して」
# 「最新デプロイ後に新規発生したエラーを確認して」
📌 OAuthトークンの自動リフレッシュ
Claude Codeは認証トークンを安全に保存し、有効期限が切れた場合は自動的にリフレッシュする。手動での再認証が必要になることはほとんどない。トークンを無効化したい場合は、/mcpメニューから「Clear authentication」を選択する。
認証フロー(OAuth 2.0)とトークン管理
MCP仕様2025-06-18で、認証フローが大幅に整備された。MCPサーバーはOAuth 2.0 Resource Serverとして機能し、クライアントはOAuth 2.0クライアントとしてリソースオーナー(ユーザー)に代わって保護されたリソースにアクセスする。
認証フローの概要:
- Claude Code(クライアント)がMCPサーバーに初回接続を試みる
- サーバーが
401 Unauthorizedを返し、認可サーバーの情報を提供する - Claude Codeがブラウザを開き、ユーザーにOAuth認証を促す
- 認証成功後、アクセストークンとリフレッシュトークンが発行される
- 以降のリクエストはアクセストークンを使って自動的に認証される
- トークン期限切れ時はリフレッシュトークンで自動更新される
RFC 8707 Resourceパラメータ:
2025-06-18仕様では、セキュリティ強化のためRFC 8707(Resource Indicators)が組み込まれた。これにより、悪意のあるサーバーがアクセストークンを不正に取得・転用するリスクが軽減される。クライアントは認可リクエスト時に、トークンの使用先となるリソースサーバーを明示的に指定する。
事前設定済みOAuthクレデンシャルが必要な場合:
一部のMCPサーバーは動的クライアント登録をサポートしていない。その場合、サーバーの開発者ポータルでOAuthアプリを事前に登録し、クライアントIDとシークレットを取得してから接続する。
# 事前設定済みOAuthクレデンシャルでの接続
claude mcp add --transport http \
--client-id your-client-id --client-secret --callback-port 8080 \
my-server https://mcp.example.com/mcp
# --client-secret フラグは対話的にシークレットの入力を求める(マスク表示)
# CI環境では環境変数で渡す:
MCP_CLIENT_SECRET=your-secret claude mcp add --transport http \
--client-id your-client-id --client-secret --callback-port 8080 \
my-server https://mcp.example.com/mcp
.mcp.jsonチーム設計パターン——共有・分離・継承の実践テンプレート
MCPの真価は、チーム全体で統一された開発環境を構築できる点にある。.mcp.jsonをGitリポジトリにコミットすることで、全メンバーが同じMCPサーバーにアクセスし、一貫した開発体験を得られる。ここでは、実践的な設計パターンを紹介する。
プロジェクトルートに置く基本テンプレート
中規模のWebアプリケーションプロジェクトを想定した、実用的な.mcp.jsonテンプレートを示す。
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/"
},
"database": {
"command": "npx",
"args": [
"-y", "@bytebase/dbhub",
"--dsn", "${DATABASE_URL}",
"--readonly"
],
"env": {}
},
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"],
"env": {}
},
"sentry": {
"type": "http",
"url": "https://mcp.sentry.dev/mcp"
},
"notion": {
"type": "http",
"url": "https://mcp.notion.com/mcp"
}
}
}
💡 設計の意図
- GitHub / Sentry / Notion: リモートHTTPサーバーとして追加。ローカル依存なし、OAuth認証で安全にアクセス
- database:
${DATABASE_URL}で各開発者が自分のDB接続文字列を設定。--readonlyフラグで安全性を確保 - playwright: ローカルstdioで動作。E2Eテストの自動化に使用
モノレポでのMCP設定戦略
モノレポ構成では、ルートレベルの共通設定と、パッケージ固有の設定を組み合わせる。
ルートの.mcp.json(全パッケージ共通サーバー):
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/"
},
"sentry": {
"type": "http",
"url": "https://mcp.sentry.dev/mcp"
}
}
}
packages/api/.mcp.json(API固有サーバー):
{
"mcpServers": {
"database": {
"command": "npx",
"args": ["-y", "@bytebase/dbhub", "--dsn", "${API_DATABASE_URL}"],
"env": {}
}
}
}
packages/web/.mcp.json(フロントエンド固有サーバー):
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"],
"env": {}
}
}
}
この構成により、APIチームはデータベースアクセスを、フロントエンドチームはブラウザテストを、それぞれの作業ディレクトリで自然に利用できる。共通のGitHub・Sentry連携はルートレベルで全員に提供される。
シークレット管理
MCPサーバー設定におけるシークレット管理は、チーム開発で最も注意すべきポイントだ。
原則:
.mcp.jsonにシークレットを絶対にコミットしない- すべての秘密情報は
${ENV_VAR}形式で参照する - ローカル開発では
.envファイルを使用する - CI/CDではパイプラインのシークレット管理を使用する
ローカル開発での.envファイル:
# .env(.gitignoreに追加済み)
DATABASE_URL=postgresql://dev:devpass@localhost:5432/myapp_dev
API_KEY=sk-dev-xxxxxxxxxxxx
SENTRY_AUTH_TOKEN=sntrys_xxxxxxxxxxxx
CI/CDでの環境変数設定(GitHub Actions例):
# .github/workflows/ci.yml
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
API_KEY: ${{ secrets.API_KEY }}
HTTPサーバーのOAuth認証:
GitHub MCPやSentry MCPなどのHTTPサーバーは、OAuthフローで認証する。この場合、クレデンシャルはClaude Codeが安全に管理し(macOSではシステムキーチェーンに保存)、.mcp.jsonにシークレットを記述する必要はない。
チーム合意プロセス——reset-project-choicesの運用
セキュリティ上の理由から、Claude Codeは.mcp.json内のプロジェクトスコープサーバーを使用する前に、ユーザーの承認を求める。これは、信頼できないリポジトリのMCPサーバーが自動実行されることを防ぐためだ。
チームへの新サーバー追加フロー:
- 開発者Aが
.mcp.jsonに新しいサーバーを追加し、PRを作成する - チームレビューを経てマージされる
- 他のチームメンバーが
git pull後にClaude Codeを起動すると、新サーバーの承認プロンプトが表示される - 各メンバーが確認・承認してサーバーが有効になる
承認のリセットが必要な場合:
# プロジェクトスコープサーバーの承認をリセット(再承認を求める)
claude mcp reset-project-choices
このコマンドは、以下の場面で使用する。
- サーバーのURLやコマンドが変更された場合
- セキュリティ監査の一環として全サーバーを再確認したい場合
- 新規メンバーのオンボーディングで問題が発生した場合
カスタムMCPサーバーを自作する——TypeScriptで30分ハンズオン
既存のMCPサーバーでカバーできないプロジェクト固有の要件がある場合、カスタムサーバーを自作するのが最善のアプローチだ。MCP TypeScript SDKを使えば、30分で実用的なサーバーを構築できる。ここでは、プロジェクトのコーディング規約チェッカーを例に、ゼロからMCPサーバーを実装する。
MCP Server SDKのセットアップ
# プロジェクトの初期化
mkdir convention-checker-mcp && cd convention-checker-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
# TypeScript設定
npx tsc --init --target ES2022 --module NodeNext \
--moduleResolution NodeNext --outDir dist --rootDir src \
--strict true --esModuleInterop true
プロジェクト構造:
convention-checker-mcp/
├── src/
│ └── index.ts # メインサーバー実装
├── conventions.json # プロジェクト固有の規約定義
├── package.json
└── tsconfig.json
package.jsonに以下を追加する:
{
"type": "module",
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
}
}
Toolsの定義——入力スキーマとハンドラ実装
MCPサーバーの核心は、Toolsの定義だ。Zodスキーマで入力を定義し、ハンドラで処理を実装する。
以下は、コーディング規約チェッカーの完全な実装だ。命名規則のチェック、インポート順序の検証、禁止パターンの検出を行う。
// src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { readFileSync, existsSync } from "fs";
import { resolve, dirname } from "path";
// 規約定義の型
interface ConventionConfig {
naming: {
files: { pattern: string; message: string };
functions: { pattern: string; message: string };
components: { pattern: string; message: string };
constants: { pattern: string; message: string };
};
imports: {
order: string[];
forbiddenPatterns: { pattern: string; message: string }[];
};
prohibited: {
patterns: { regex: string; message: string; severity: "error" | "warning" }[];
};
}
// デフォルトの規約設定
const DEFAULT_CONVENTIONS: ConventionConfig = {
naming: {
files: {
pattern: "^[a-z][a-z0-9]*(-[a-z0-9]+)*\\.(ts|tsx|js|jsx)$",
message: "ファイル名はkebab-caseで記述してください"
},
functions: {
pattern: "^[a-z][a-zA-Z0-9]*$",
message: "関数名はcamelCaseで記述してください"
},
components: {
pattern: "^[A-Z][a-zA-Z0-9]*$",
message: "コンポーネント名はPascalCaseで記述してください"
},
constants: {
pattern: "^[A-Z][A-Z0-9_]*$",
message: "定数名はSCREAMING_SNAKE_CASEで記述してください"
}
},
imports: {
order: ["builtin", "external", "internal", "parent", "sibling", "index"],
forbiddenPatterns: [
{ pattern: "import .* from ['\"]\\.\\./.*/node_modules", message: "node_modulesからの相対インポートは禁止です" }
]
},
prohibited: {
patterns: [
{ regex: "\\bany\\b", message: "any型の使用は禁止です。適切な型を定義してください", severity: "error" },
{ regex: "console\\.log\\(", message: "console.logはデバッグ用です。loggerを使用してください", severity: "warning" },
{ regex: "TODO:", message: "未解決のTODOがあります", severity: "warning" },
{ regex: "eslint-disable", message: "ESLint無効化コメントは原則禁止です", severity: "error" }
]
}
};
// 規約設定のロード
function loadConventions(configPath?: string): ConventionConfig {
if (configPath && existsSync(configPath)) {
const raw = readFileSync(configPath, "utf-8");
return JSON.parse(raw) as ConventionConfig;
}
return DEFAULT_CONVENTIONS;
}
// 違反レポートの型
interface Violation {
line: number;
column: number;
rule: string;
message: string;
severity: "error" | "warning";
snippet: string;
}
interface CheckResult {
filePath: string;
violations: Violation[];
summary: {
errors: number;
warnings: number;
passed: boolean;
};
}
// 命名規則チェック
function checkNamingConventions(
code: string,
fileName: string,
conventions: ConventionConfig
): Violation[] {
const violations: Violation[] = [];
const lines = code.split("\n");
// ファイル名チェック
const fileBaseName = fileName.split("/").pop() ?? "";
const filePattern = new RegExp(conventions.naming.files.pattern);
if (fileBaseName && !filePattern.test(fileBaseName)) {
violations.push({
line: 1,
column: 1,
rule: "naming/file",
message: `${conventions.naming.files.message}: "${fileBaseName}"`,
severity: "error",
snippet: fileBaseName
});
}
// 関数名チェック
const funcPattern = new RegExp(conventions.naming.functions.pattern);
const funcRegex = /(?:function\s+|const\s+|let\s+|var\s+)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*(?:=\s*(?:async\s+)?(?:\([^)]*\)|[a-zA-Z_$][a-zA-Z0-9_$]*)\s*=>|\()/g;
for (let i = 0; i < lines.length; i++) {
let match;
while ((match = funcRegex.exec(lines[i])) !== null) {
const name = match[1];
// PascalCaseはコンポーネントとして許可
if (name && !funcPattern.test(name) && !/^[A-Z]/.test(name)) {
violations.push({
line: i + 1,
column: (match.index ?? 0) + 1,
rule: "naming/function",
message: `${conventions.naming.functions.message}: "${name}"`,
severity: "error",
snippet: lines[i].trim()
});
}
}
}
return violations;
}
// 禁止パターンチェック
function checkProhibitedPatterns(
code: string,
conventions: ConventionConfig
): Violation[] {
const violations: Violation[] = [];
const lines = code.split("\n");
for (const rule of conventions.prohibited.patterns) {
const regex = new RegExp(rule.regex, "g");
for (let i = 0; i < lines.length; i++) {
let match;
while ((match = regex.exec(lines[i])) !== null) {
violations.push({
line: i + 1,
column: (match.index ?? 0) + 1,
rule: "prohibited/" + rule.regex,
message: rule.message,
severity: rule.severity,
snippet: lines[i].trim()
});
}
}
}
return violations;
}
// インポート順序チェック
function checkImportOrder(
code: string,
conventions: ConventionConfig
): Violation[] {
const violations: Violation[] = [];
const lines = code.split("\n");
const importLines: { line: number; source: string; raw: string }[] = [];
for (let i = 0; i < lines.length; i++) {
const importMatch = lines[i].match(/^import\s+.*from\s+['"]([^'"]+)['"]/);
if (importMatch && importMatch[1]) {
importLines.push({ line: i + 1, source: importMatch[1], raw: lines[i] });
}
}
// 禁止パターンチェック
for (const imp of importLines) {
for (const forbidden of conventions.imports.forbiddenPatterns) {
if (new RegExp(forbidden.pattern).test(imp.raw)) {
violations.push({
line: imp.line,
column: 1,
rule: "imports/forbidden",
message: forbidden.message,
severity: "error",
snippet: imp.raw.trim()
});
}
}
}
return violations;
}
// ========================================
// MCPサーバーの構築
// ========================================
const server = new McpServer({
name: "convention-checker",
version: "1.0.0"
});
// Tool 1: コーディング規約チェック
server.registerTool(
"check_conventions",
{
title: "コーディング規約チェッカー",
description:
"指定されたコードがプロジェクトのコーディング規約に準拠しているかチェックします。" +
"命名規則、インポート順序、禁止パターンを検証します。",
inputSchema: z.object({
code: z.string().describe("チェック対象のソースコード"),
fileName: z.string().describe("ファイル名(命名規則チェックに使用)"),
configPath: z
.string()
.optional()
.describe("カスタム規約設定ファイルのパス(省略時はデフォルト規約)")
})
},
async ({ code, fileName, configPath }) => {
const conventions = loadConventions(configPath);
const namingViolations = checkNamingConventions(code, fileName, conventions);
const prohibitedViolations = checkProhibitedPatterns(code, conventions);
const importViolations = checkImportOrder(code, conventions);
const allViolations = [
...namingViolations,
...prohibitedViolations,
...importViolations
].sort((a, b) => a.line - b.line);
const errors = allViolations.filter((v) => v.severity === "error").length;
const warnings = allViolations.filter((v) => v.severity === "warning").length;
const result: CheckResult = {
filePath: fileName,
violations: allViolations,
summary: {
errors,
warnings,
passed: errors === 0
}
};
// 人間が読みやすい形式でフォーマット
let output = `## 規約チェック結果: ${fileName}\n\n`;
output += `状態: ${result.summary.passed ? "PASSED" : "FAILED"}\n`;
output += `エラー: ${errors} 件 / 警告: ${warnings} 件\n\n`;
if (allViolations.length > 0) {
output += "### 違反一覧\n\n";
for (const v of allViolations) {
const icon = v.severity === "error" ? "[ERROR]" : "[WARN]";
output += `${icon} L${v.line}:${v.column} - ${v.message}\n`;
output += ` | ${v.snippet}\n\n`;
}
} else {
output += "すべての規約チェックに合格しました。\n";
}
return {
content: [{ type: "text", text: output }]
};
}
);
// Tool 2: 規約設定の表示
server.registerTool(
"show_conventions",
{
title: "規約設定の表示",
description:
"現在適用されているコーディング規約の設定内容を表示します。",
inputSchema: z.object({
configPath: z
.string()
.optional()
.describe("カスタム規約設定ファイルのパス(省略時はデフォルト規約)")
})
},
async ({ configPath }) => {
const conventions = loadConventions(configPath);
return {
content: [
{
type: "text",
text: JSON.stringify(conventions, null, 2)
}
]
};
}
);
// Resource: プロジェクト規約ドキュメント
server.registerResource(
"conventions-doc",
"convention://current-rules",
{
title: "コーディング規約ドキュメント",
description: "現在のプロジェクトに適用されているコーディング規約の概要",
mimeType: "text/markdown"
},
async (uri) => {
const conventions = loadConventions();
let doc = "# プロジェクト コーディング規約\n\n";
doc += "## 命名規則\n\n";
doc += `- **ファイル名**: ${conventions.naming.files.message}\n`;
doc += `- **関数名**: ${conventions.naming.functions.message}\n`;
doc += `- **コンポーネント名**: ${conventions.naming.components.message}\n`;
doc += `- **定数名**: ${conventions.naming.constants.message}\n\n`;
doc += "## 禁止パターン\n\n";
for (const p of conventions.prohibited.patterns) {
doc += `- [${p.severity.toUpperCase()}] ${p.message}\n`;
}
return {
contents: [{ uri: uri.href, text: doc, mimeType: "text/markdown" }]
};
}
);
// サーバーの起動
async function main(): Promise<void> {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch((error: unknown) => {
console.error("Server failed to start:", error);
process.exit(1);
});
Resourcesの定義——動的データの提供
上記の実装に含まれるregisterResourceは、プロジェクトの規約ドキュメントをResourceとして公開している。Claude Codeから@convention-checker:convention://current-rulesのようにメンションすることで、現在の規約設定をコンテキストとして参照できる。
Resourcesは読み取り専用のデータ提供に特化している。動的に生成されるデータ(設定ファイルの内容、ログの要約、プロジェクトのメトリクスなど)をAIのコンテキストに注入するために活用する。
stdioトランスポートで接続テスト
実装が完了したら、ビルドしてローカルでテストする。
# ビルド
npm run build
# 手動でのスモークテスト(JSON-RPCリクエストを直接送信)
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' | node dist/index.js
デバッグのヒント:
- MCPサーバーは標準入出力で通信するため、
console.logを使うとプロトコルが破壊される。デバッグ出力はconsole.error(stderr)に書き出す - SDK内蔵のロギング機能(
ctx.mcpReq.log())を使用すると、クライアント側で構造化されたログを確認できる - 起動タイムアウトが発生する場合は、
MCP_TIMEOUT環境変数でタイムアウト値を延長する(例:MCP_TIMEOUT=10000)
Claude Codeへの登録と動作確認
# プロジェクトスコープでClaude Codeに登録
claude mcp add --scope project convention-checker -- node /path/to/convention-checker-mcp/dist/index.js
# サーバー一覧で確認
claude mcp list
# Claude Code内で動作確認:
# 「convention-checkerの規約設定を表示して」
# 「このファイルのコードを規約チェックして」
# 「src/配下のすべてのTypeScriptファイルを規約チェックして、違反を修正して」
📌 カスタムサーバー開発のベストプラクティス
- ツール名は明確に:
check_conventionsのように、AIが用途を理解しやすい名前をつける - descriptionを詳しく書く: AIがいつ・どのようにツールを使うべきか判断する材料になる
- Zodスキーマの
.describe()を活用: 各パラメータの説明がAIに伝わる - エラーハンドリングを徹底: ツールが例外を投げるとMCP接続が切れる場合がある。try-catchで確実に処理する
- 出力は人間が読める形式で: AIだけでなく人間にも理解しやすいMarkdown形式が推奨される
自作MCPサーバーをClaude Code Agent TeamsやVibe Codingと組み合わせることで、プロジェクト固有のルールを強制しながらAI駆動の開発を進められる。MCPサーバーの自作は、チームの開発体験を根本的にカスタマイズする最も強力な手段だ。MCP入門記事でプロトコルの基礎を学んだ上で、ぜひ自チーム固有のサーバー開発に挑戦してほしい。
Claude Codeをサーバーにする——エージェント・イン・エージェント・パターン
Claude Codeは単なるCLIツールではありません。claude mcp serveコマンドを使えば、Claude Code自体をMCPサーバーとして公開し、別のAIエージェントから呼び出すことができます。この「エージェントの中にエージェントがいる」パターンは、複雑なタスクを階層的に分割する強力なアーキテクチャです。
従来、AIエージェントがコードベースを操作するには、ファイルシステムAPIやGit操作を個別に実装する必要がありました。しかし、Claude Codeをサブエージェントとして使えば、すでに洗練されたコード操作能力を持つエージェントを「道具」として活用できます。メインエージェントは高レベルの意思決定に集中し、実際のコード操作はClaude Codeに委任する——この分離が、エージェント・イン・エージェント・パターンの本質です。
claude mcp serveの仕組みと公開されるツール
claude mcp serveは、Claude CodeをMCPサーバーとして起動するコマンドです。内部的にはJSON-RPCプロトコルを使い、標準入出力(stdio)経由で通信します。
# Claude CodeをMCPサーバーとして起動
claude mcp serve
このコマンドを実行すると、Claude Codeが持つ以下の組み込みツールがMCPツールとして外部に公開されます。
| 公開ツール | 機能 | 用途 |
|---|---|---|
View |
ファイル読み取り | ソースコードの参照・分析 |
Edit |
ファイル編集(差分ベース) | コードの修正・リファクタリング |
Write |
ファイル書き込み | 新規ファイル作成 |
LS |
ディレクトリ一覧 | プロジェクト構造の把握 |
Bash |
シェルコマンド実行 | ビルド・テスト・Git操作 |
Grep |
コード検索 | パターンマッチによるコード探索 |
Glob |
ファイルパターン検索 | ファイル名ベースの検索 |
重要なのは、通信がstdio(標準入出力)のみで行われる点です。ネットワークポートを開放しないため、外部からの不正アクセスリスクがありません。起動したプロセスだけが通信できるプロセス分離モデルを採用しています。
# JSON-RPC通信の例(内部的なメッセージフォーマット)
# リクエスト
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "View",
"arguments": {
"file_path": "/path/to/project/src/index.ts",
"limit": 100
}
}
}
# レスポンス
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "// ファイルの内容がここに返される"
}
]
}
}
メインエージェントからサブエージェントを呼び出す設計
エージェント・イン・エージェント・パターンを実現する最もシンプルな方法は、Claude DesktopのMCP設定にClaude Codeを追加することです。
# まずClaude Codeの実行パスを確認
which claude
# 出力例: /usr/local/bin/claude
Claude Desktopの設定ファイル(claude_desktop_config.json)に以下を追加します。
{
"mcpServers": {
"claude-code": {
"type": "stdio",
"command": "claude",
"args": ["mcp", "serve"]
}
}
}
💡 パスに関する注意
claudeコマンドにパスが通っていない場合は、which claudeで得られたフルパス(例: /usr/local/bin/claude)を"command"に指定してください。nvm等でNode.jsを管理している場合、シェルの初期化スクリプトが読み込まれないことがあるため、フルパス指定が確実です。
この設定により、Claude Desktop(メインエージェント)はClaude Code(サブエージェント)の全ツールにアクセスできるようになります。メインエージェントが「このファイルを読んで分析して」と指示すれば、Claude CodeのViewツールが自動的に呼び出されます。
同様に、他のMCPクライアント(Cursor、Windsurf、カスタムアプリケーションなど)からも同じ設定で接続できます。Claude Code CLIのmcp addコマンドを使ってプログラマティックに設定することも可能です。
# Claude Code自体に別のClaude Codeをサブエージェントとして追加
claude mcp add claude-sub-agent -- claude mcp serve
ユースケース
エージェント・イン・エージェント・パターンは、以下のような場面で特に威力を発揮します。
1. コードレビューエージェント
メインエージェントがGitHub MCPサーバーからPRの情報を受け取り、Claude Codeサブエージェントに実際のコード読み取り・分析を委任するパターンです。
# メインエージェントのワークフロー(概念図)
1. GitHub MCP → PR一覧を取得
2. 各PRについて:
a. GitHub MCP → diff情報を取得
b. Claude Code MCP → 変更ファイルを読み取り
c. Claude Code MCP → 関連テストの存在を確認
d. Claude Code MCP → 型チェック・lint実行
3. メインエージェント → レビューコメントを生成
4. GitHub MCP → レビューコメントを投稿
メインエージェントは「何をレビューするか」の判断に集中し、「どうやってコードを読むか」はClaude Codeに任せます。
2. ドキュメント生成エージェント
メインエージェントがドキュメントの構成を計画し、Claude Codeがコードベースを読み取って実装の詳細を把握、それをもとにメインエージェントがドキュメントを生成するパターンです。APIリファレンスの自動生成や、アーキテクチャドキュメントの作成に適しています。
3. マルチリポジトリ操作
複数のリポジトリにまたがる変更を一貫して行う場合、メインエージェントがオーケストレーターとなり、各リポジトリに対してClaude Codeサブエージェントを割り当てます。モノレポ内のパッケージ間依存の更新や、マイクロサービス間のインターフェース変更に有効です。
実装例と注意点
エージェント・イン・エージェント・パターンを導入する前に、いくつかの重要な制約を理解しておく必要があります。
🚨 MCPパススルーは非対応
Claude Codeに接続されているMCPサーバー(例: GitHub MCP)は、claude mcp serve経由で接続してきたクライアントからはアクセスできません。つまり、Claude CodeがGitHub MCPを持っていても、Claude Desktop → Claude Code → GitHub MCPという多段接続はできません。各レイヤーで必要なMCPサーバーは個別に接続する必要があります。
| 注意点 | 詳細 | 対策 |
|---|---|---|
| MCPパススルー非対応 | サブエージェントのMCPにはアクセス不可 | メインエージェント側で必要なMCPを直接接続 |
| セキュリティ | stdio通信のため起動プロセスのみ接続可能 | 追加設定不要(デフォルトで安全) |
| リソース消費 | claude mcp serveは完全なClaude Codeインスタンス |
必要時のみ起動、不要になったらプロセス終了 |
| 認証・権限 | サブエージェントは起動ユーザーの権限で動作 | 最小権限の原則を適用 |
| 同時接続 | 1つのclaude mcp serveに1クライアント |
複数接続が必要なら複数プロセスを起動 |
コミュニティでは、このパターンをより使いやすくするラッパーも開発されています。steipete/claude-code-mcpは、Claude Codeをプロキシ経由でMCPサーバーとして公開し、複数のクライアントから同時に利用できるようにするプロジェクトです。エンタープライズ環境でエージェント・イン・エージェントを大規模に展開する場合の参考になります。
エージェント・イン・エージェント・パターンについてさらに深く学びたい方は、Claude Code Agent Teams 完全ガイドもあわせてご覧ください。マルチエージェント設計の実践的な手法を詳しく解説しています。
MCPツール爆発問題を解決する——コンテキスト最適化戦略
MCPエコシステムが成熟するにつれ、利用可能なMCPサーバーは急増しています。2026年2月現在、公開されているMCPサーバーは3,000以上。チームが複数のサーバーを導入すれば、数十のMCPツールが同時にロードされる状況は珍しくありません。しかし、これは「ツール爆発」という新たな問題を引き起こします。
50+サーバー時代のツール検索問題
MCPサーバーを追加するたびに、そのサーバーが提供するツールの定義(名前、説明、パラメータスキーマ)がコンテキストウィンドウにロードされます。1つのツールの定義はおよそ200〜500トークン。20個のMCPサーバーが合計100のツールを提供する場合、それだけで20,000〜50,000トークンが消費される計算です。
実際の影響を示す象徴的な事例があります。開発者のScott Spence氏は、自身のMCP設定でセッション開始時に66,000トークンがツール定義に消費されることを報告しました。Claude CodeのOpus 4モデルのコンテキストウィンドウ(200Kトークン)の約3分の1が、実際の作業が始まる前に使い切られていたのです。
| MCPサーバー数 | 推定ツール数 | 推定トークン消費 | 200K中の割合 |
|---|---|---|---|
| 5個 | 15〜25 | 5,000〜12,000 | 2.5〜6% |
| 10個 | 30〜60 | 10,000〜30,000 | 5〜15% |
| 20個 | 60〜120 | 20,000〜60,000 | 10〜30% |
| 50個 | 150〜300 | 50,000〜150,000 | 25〜75% |
問題はトークン消費だけではありません。ツールが増えるとモデルの選択精度も低下します。数十のツールから最適な1つを選ぶ作業は、モデルにとっても認知的な負荷となり、誤ったツール選択やツール呼び出しの失敗が増加します。
Lazy Loading——95%のコンテキスト削減
この問題に対するClaude Codeの回答が、MCP Tool Search機能です。Claude Code 2.1.7以降で導入されたこの機能は、MCPツールの「遅延ロード」を実現します。
従来の方式では、セッション開始時にすべてのMCPツール定義をコンテキストに展開していました。Tool Searchを使うと、代わりに軽量な検索インデックスのみがロードされます。
# 従来のフロー(Eager Loading)
セッション開始
→ 全MCPサーバーに接続
→ 全ツール定義をコンテキストに展開(数万トークン消費)
→ ユーザーの指示を処理
# Tool Searchフロー(Lazy Loading)
セッション開始
→ 全MCPサーバーに接続
→ 軽量インデックスのみロード(数百トークン)
→ ユーザーの指示を分析
→ 必要なツールをオンデマンドで検索・ロード
→ 関連ツールのみコンテキストに展開
仕組みはシンプルです。Claude Codeは各MCPツールの名前と説明から検索インデックスを構築し、モデルがタスクを分析した結果「このツールが必要そうだ」と判断した時点で、該当するツールの完全な定義をロードします。使わないツールの定義はコンテキストに一切現れません。
ツール検索のしきい値設定
Tool Searchの挙動はENABLE_MCP_TOOL_SEARCH環境変数で細かく制御できます。
| 設定値 | 挙動 | 推奨用途 |
|---|---|---|
auto(デフォルト) |
MCPツールがコンテキストの10%を超えたら自動有効化 | ほとんどの環境に最適 |
auto:N |
しきい値をN%にカスタム(例: auto:5で5%) |
コンテキストを最大限活用したい場合 |
true |
常に有効 | MCPサーバーが多い環境 |
false |
無効(全ツールを事前ロード) | MCPサーバーが少なく精度を優先 |
# 環境変数で設定
export ENABLE_MCP_TOOL_SEARCH=auto:5
# または .claude/settings.json で設定
{
"env": {
"ENABLE_MCP_TOOL_SEARCH": "auto:5"
}
}
💡 対応モデル
Tool Searchはtool_reference機能をサポートするモデルで動作します。2026年2月時点では、Sonnet 4以上、Opus 4以上が対応しています。Haiku等の軽量モデルでは利用できない場合があります。
Tool Searchの効果は、Anthropic社内のベンチマークで明確に実証されています。
| 指標 | Tool Search なし | Tool Search あり | 改善幅 |
|---|---|---|---|
| セッション開始時のトークンオーバーヘッド | 数万トークン | 数百トークン | 最大95%削減 |
| Opus 4 ツール選択精度 | 49% | 74% | +25ポイント |
| Opus 4.5 ツール選択精度 | 79.5% | 88.1% | +8.6ポイント |
| ツール呼び出し失敗率 | 高い(選択ミス多発) | 低い(的確な選択) | 大幅改善 |
特に注目すべきは、Opus 4でのツール選択精度が49%から74%に跳ね上がっている点です。ツール定義が多すぎるとモデルが「迷う」問題が、必要なツールだけを提示することで劇的に改善されることがわかります。
CLAUDE.mdとの連携——どのMCPをいつ使うか指示する
Tool Searchはモデルの自律的な判断に基づいてツールを選択しますが、プロジェクト固有の運用ルールはモデルが知り得ません。そこで重要になるのが、CLAUDE.mdファイルにMCPの使用指針を記述することです。
# CLAUDE.md でのMCP使用指針の例
## MCP Usage Rules
- GitHub操作(PR作成、Issue管理、レビュー)は必ず @github MCPを使用する
- 新しいパッケージをインストールする前に @context7 で最新ドキュメントを確認する
- データベース操作には @postgres MCPを使用し、直接SQLを実行しない
- E2Eテストの作成時は @playwright MCPでブラウザ操作を記録する
- 本番環境のSentryエラーを調査する場合は @sentry MCPを使用する
さらに、MCPサーバーの作成者は、サーバー定義のinstructionsフィールドにサーバーの使い方を記述できます。この情報はTool Search時にモデルに提供され、適切なツール選択の判断材料となります。
# .mcp.json でのサーバー説明の例
{
"mcpServers": {
"internal-api": {
"type": "stdio",
"command": "node",
"args": ["./tools/internal-api-server.js"],
"instructions": "社内APIにアクセスするMCPサーバー。従業員情報の検索、勤怠データの取得、プロジェクト管理に使用する。外部公開情報には使わないこと。"
}
}
}
CLAUDE.mdとMCPの効果的な使い方については、Claude Code 上級テクニックガイドで詳しく解説しています。
エンタープライズMCPセキュリティ——本番環境で守るべき5つの原則
MCPはAIエージェントに強力な「手足」を与えます。しかしその力は、適切に管理されなければセキュリティリスクに直結します。2025年後半から2026年初頭にかけて、MCPエコシステムで複数の深刻な脆弱性が発見されました。エンタープライズ環境でMCPを安全に運用するためには、脅威モデルの理解と多層防御が不可欠です。
実際のCVEから学ぶ——MCPの脅威モデル
MCPの普及に伴い、実際に報告されたCVE(共通脆弱性識別子)を見てみましょう。これらは理論上の脅威ではなく、実際に発見された脆弱性です。
| CVE | 深刻度 | 対象 | 脆弱性の種類 | 影響 |
|---|---|---|---|---|
| CVE-2025-6514 | Critical 9.6 | mcp-remote npmパッケージ | OSコマンド実行 | リモートからの任意コマンド実行 |
| CVE-2025-49596 | Critical 9.4 | MCP Inspector | DNSリバインディング + RCE | 開発ツール経由でのリモートコード実行 |
| CVE-2025-68143 | High | mcp-server-git | パストラバーサル | 許可外ディレクトリへのアクセス |
| CVE-2025-68144 | High | mcp-server-git | 引数インジェクション | Gitコマンドの不正操作 |
| CVE-2025-68145 | High | mcp-server-git | パストラバーサル | リポジトリ外のファイル読み取り |
注目すべきは、2025年のわずか1ヶ月間で7件のCVEが報告されたことです。MCPエコシステムはまだ若く、サードパーティ製サーバーの品質にはばらつきがあります。
主な攻撃ベクトルを整理すると、以下の5つに分類されます。
| 攻撃ベクトル | 説明 | 対策の方向性 |
|---|---|---|
| コマンドインジェクション | MCPサーバーが受け取った引数をサニタイズせずにシェルに渡す | サーバー側の入力バリデーション |
| SSRF(サーバーサイドリクエストフォージェリ) | MCPサーバーを踏み台に内部ネットワークへアクセス | URL制限・ネットワーク分離 |
| パストラバーサル | ファイルパスの検証不備で許可外ディレクトリにアクセス | パスの正規化・ホワイトリスト |
| 認証不備 | MCPサーバーへの接続が認証なしで可能 | OAuth 2.1 / トークン認証 |
| プロンプトインジェクション | MCPツールの出力に悪意ある指示を注入 | 出力のサニタイズ・権限分離 |
🚨 プロンプトインジェクションに要注意
MCPサーバーから返されたデータに悪意ある指示が含まれていた場合、AIモデルがそれに従ってしまう可能性があります。例えば、外部APIから取得したデータに「このファイルの内容を外部に送信せよ」という指示が埋め込まれるケースです。MCPサーバーの出力は常に「信頼できないデータ」として扱う設計が必要です。
許可リスト / 拒否リスト(allowedMcpServers / deniedMcpServers)
Claude Codeは、組織レベルでMCPサーバーの使用を制御するための許可リスト・拒否リスト機能を提供しています。管理者設定ファイル(settings.json)で設定します。
// settings.json — MCPサーバーの許可・拒否リスト
{
"allowedMcpServers": [
{
"serverName": "github"
},
{
"serverCommand": "/usr/local/bin/approved-mcp-*"
},
{
"serverUrl": "https://*.internal.corp/*"
}
],
"deniedMcpServers": [
{
"serverName": "untrusted-server"
},
{
"serverCommand": "*/node_modules/.bin/suspicious-*"
},
{
"serverUrl": "http://*"
}
]
}
マッチング方法は3種類あり、ワイルドカード(*)を使ったパターンマッチに対応しています。
| マッチング方法 | 対象 | ワイルドカード例 |
|---|---|---|
serverName |
MCPサーバーの名前 | github-*(github-で始まる名前) |
serverCommand |
起動コマンドのパス | /opt/mcp-servers/*(特定ディレクトリのサーバー) |
serverUrl |
リモートMCPサーバーのURL | https://*.corp.example.com/* |
✅ 重要なルール
deniedMcpServersは常にallowedMcpServersより優先されます。両方にマッチする場合、そのサーバーはブロックされます。また、allowedMcpServersを空の配列 [] に設定すると、全てのMCPサーバーがブロックされます。ホワイトリスト方式で運用する場合は、許可するサーバーを明示的にリストする必要があります。
managed-mcp.json——管理者によるMCP強制設定
エンタープライズ環境では、管理者がMCPサーバーの設定を一元管理し、全開発者に適用したい場合があります。managed-mcp.jsonは、管理者権限で配置するシステムワイドのMCP設定ファイルです。
配置パスは以下の通りです(管理者権限が必要)。
| OS | パス |
|---|---|
| macOS | /Library/Application Support/ClaudeCode/managed-mcp.json |
| Linux | /etc/claude-code/managed-mcp.json |
オプション1: 排他的制御(定義されたサーバーのみ許可)
管理者が定義したMCPサーバーのみを使用可能にし、開発者が独自にサーバーを追加することを禁止するパターンです。
// /Library/Application Support/ClaudeCode/managed-mcp.json
// オプション1: 排他的制御
{
"exclusive": true,
"mcpServers": {
"company-github": {
"type": "stdio",
"command": "/opt/mcp-servers/github-mcp",
"args": ["--org", "our-company"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"company-db": {
"type": "stdio",
"command": "/opt/mcp-servers/postgres-mcp",
"args": ["--read-only"],
"env": {
"DATABASE_URL": "${DATABASE_URL}"
}
},
"approved-context7": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@latest"]
}
}
}
"exclusive": trueを設定すると、このファイルで定義されたサーバー以外は一切使用できなくなります。開発者がclaude mcp addで追加しようとしても、拒否されます。
オプション2: ポリシーベース制御(許可・拒否リストで制御)
開発者の自由度を維持しつつ、特定のサーバーだけをブロックまたは強制するパターンです。
// /Library/Application Support/ClaudeCode/managed-mcp.json
// オプション2: ポリシーベース制御
{
"exclusive": false,
"mcpServers": {
"company-github": {
"type": "stdio",
"command": "/opt/mcp-servers/github-mcp",
"args": ["--org", "our-company"]
}
},
"policy": {
"allowedMcpServers": [
{ "serverCommand": "/opt/mcp-servers/*" },
{ "serverName": "context7" },
{ "serverUrl": "https://*.internal.corp/*" }
],
"deniedMcpServers": [
{ "serverUrl": "http://*" },
{ "serverCommand": "*/untrusted/*" }
]
}
}
"exclusive": falseの場合、管理者定義のサーバーに加えて、ポリシーに合致する開発者追加のサーバーも使用できます。
ネットワーク分離とURL制限パターン
リモートMCPサーバー(Streamable HTTP / SSE)を使用する場合、ネットワークレベルでのアクセス制御が重要です。特に、MCPサーバーが内部システムにアクセスする場合、SSRF攻撃を防ぐための対策が必要です。
// URL制限パターンの例
{
"allowedMcpServers": [
// 社内ドメインのみ許可
{ "serverUrl": "https://*.internal.corp/*" },
{ "serverUrl": "https://mcp.ourcompany.com/*" },
// 信頼できる外部サービスのみ許可
{ "serverUrl": "https://api.github.com/*" },
{ "serverUrl": "https://mcp.sentry.dev/*" }
],
"deniedMcpServers": [
// HTTP(非暗号化)は全拒否
{ "serverUrl": "http://*" },
// ローカルホストへのリモート接続を防止
{ "serverUrl": "https://localhost*" },
{ "serverUrl": "https://127.0.0.1*" }
]
}
さらに、MCPサーバーをDockerコンテナ内で実行することで、ファイルシステムやネットワークのアクセスをコンテナレベルで制御できます。MCP入門記事で紹介したDocker MCP Toolkitは、この目的に適しています。
監査ログとコンプライアンス対応
エンタープライズ環境では、「誰が」「いつ」「どのMCPサーバーを」追加・削除したかを記録する監査ログが求められます。Claude CodeのConfigChangeフックを活用すれば、MCP設定の変更を自動的に記録できます。
// .claude/settings.json — 監査ログフック
{
"hooks": {
"ConfigChange": [
{
"matcher": "mcpServers",
"command": "audit-log --event mcp-config-change --user $USER --timestamp $(date -u +%Y-%m-%dT%H:%M:%SZ) --details"
}
]
}
}
以下のセキュリティチェックリストを、MCPの本番導入前に確認することを推奨します。
| # | チェック項目 | 対応方法 | 優先度 |
|---|---|---|---|
| 1 | 全MCPサーバーのソースコードを確認したか | npmパッケージの依存関係を含めて監査 | 必須 |
| 2 | managed-mcp.jsonで許可サーバーを制限したか |
ホワイトリスト方式での運用 | 必須 |
| 3 | HTTP(非暗号化)のリモートMCPを拒否したか | deniedMcpServersでhttp://*をブロック |
必須 |
| 4 | MCPサーバーの環境変数に本番シークレットを直書きしていないか | シークレットマネージャー経由での注入 | 必須 |
| 5 | ファイルアクセス可能なMCPサーバーのパスを制限したか | ルートディレクトリの明示的指定 | 高 |
| 6 | MCPサーバーの出力サイズを制限したか | MAX_MCP_OUTPUT_TOKENSの設定 |
高 |
| 7 | MCP設定変更の監査ログを有効化したか | ConfigChangeフックの設定 |
高 |
| 8 | MCPサーバーのバージョンを固定したか | @latestではなく特定バージョンを指定 |
中 |
| 9 | 定期的なMCPサーバーのCVEチェック体制があるか | 依存関係スキャンの自動化 | 中 |
| 10 | MCPサーバーをコンテナ環境で実行しているか | Docker MCP Toolkitの活用 | 推奨 |
実践ワークフロー5選——MCPで実現する高度な開発自動化
ここまでMCPの概念、設定、最適化、セキュリティについて学んできました。この章では、実際の開発現場で即座に使える5つの実践的ワークフローを紹介します。各ワークフローは、Claude Codeのプロンプト例と期待される出力を含んでおり、そのまま試すことができます。
ワークフロー1: GitHub MCP × PRレビュー自動化
チームのPRが溜まっている朝、全てのオープンPRの概要を把握し、優先度をつけてレビューを効率化するワークフローです。
前提条件: GitHub MCPサーバーが設定済みであること
# Claude Codeに入力するプロンプト
このリポジトリのオープンPRを全て確認して、以下の観点でサマリーを作成してください:
1. 各PRの変更内容の要約(1-2行)
2. 変更規模(S/M/L/XL)
3. リスク評価(Low/Medium/High)
4. 推奨レビュー順序
特にbreaking changeやセキュリティに影響する変更は赤旗を立ててください。
Claude Codeは以下のように処理します。
# Claude Codeの内部処理フロー
1. GitHub MCP → list_pull_requests でオープンPR一覧を取得
2. 各PRについて:
- GitHub MCP → get_pull_request_diff で差分を取得
- 変更ファイル数、追加/削除行数を分析
- コードの内容からリスク評価を実施
3. 結果を整理して表形式で出力
# 期待される出力例
## PRレビューサマリー(2026-02-26)
| # | PR | 概要 | 規模 | リスク | 備考 |
|---|-----|------|------|--------|------|
| 1 | #342 | 認証ミドルウェアのリファクタリング | L | 🔴 High | セッション管理に影響 |
| 2 | #345 | API rate limitの実装 | M | Medium | 新規ミドルウェア追加 |
| 3 | #348 | READMEの更新 | S | Low | ドキュメントのみ |
| 4 | #341 | 依存パッケージの更新 | M | Medium | major version bump含む |
### 推奨レビュー順序
1. #342(セキュリティ影響大 → 最優先)
2. #341(依存関係の破壊的変更を確認)
3. #345(新機能、テストカバレッジ要確認)
4. #348(低リスク、最後にマージ)
このワークフローにより、10個のPRがあっても数分で全体像を把握できます。
ワークフロー2: DB MCP × マイグレーション生成
既存のデータベーススキーマを分析し、要件に基づいてマイグレーションSQLを自動生成するワークフローです。
前提条件: PostgreSQL MCPサーバーが設定済みであること
# Claude Codeに入力するプロンプト
現在のデータベーススキーマを確認して、以下の要件に対応する
マイグレーションSQLを生成してください:
- usersテーブルに `mfa_enabled` (boolean, default false) を追加
- usersテーブルに `last_login_at` (timestamp with time zone) を追加
- 新しい `audit_logs` テーブルを作成(user_id, action, metadata jsonb, created_at)
- audit_logsにuser_idの外部キー制約とcreated_atのインデックスを追加
ロールバック用のDOWNマイグレーションも生成してください。
# Claude Codeが生成するマイグレーションSQL
-- UP Migration: 20260226_add_mfa_and_audit_logs.sql
BEGIN;
-- 1. usersテーブルにカラム追加
ALTER TABLE users
ADD COLUMN mfa_enabled BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN last_login_at TIMESTAMP WITH TIME ZONE;
-- 2. audit_logsテーブル作成
CREATE TABLE audit_logs (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
action VARCHAR(255) NOT NULL,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
-- 3. インデックス作成
CREATE INDEX idx_audit_logs_created_at ON audit_logs (created_at);
CREATE INDEX idx_audit_logs_user_id ON audit_logs (user_id);
COMMENT ON TABLE audit_logs IS 'ユーザー操作の監査ログ';
COMMENT ON COLUMN audit_logs.metadata IS '操作の詳細情報をJSON形式で格納';
COMMIT;
-- DOWN Migration: 20260226_add_mfa_and_audit_logs_down.sql
BEGIN;
DROP TABLE IF EXISTS audit_logs;
ALTER TABLE users
DROP COLUMN IF EXISTS mfa_enabled,
DROP COLUMN IF EXISTS last_login_at;
COMMIT;
DB MCPサーバーが現在のスキーマを読み取るため、既存のテーブル構造との整合性が自動的に担保されます。カラム名の重複や外部キーの参照先の存在確認もClaude Codeが行います。
ワークフロー3: Playwright MCP × E2Eテスト自動生成
実際のWebアプリケーションをブラウザで操作しながら、E2Eテストコードを自動生成するワークフローです。
前提条件: Playwright MCPサーバーが設定済みであること
# Claude Codeに入力するプロンプト
Playwrightを使って、以下のユーザーフローのE2Eテストを作成してください:
1. https://staging.example.com/login にアクセス
2. メールアドレスとパスワードでログイン
3. ダッシュボードが表示されることを確認
4. 「新規プロジェクト」ボタンをクリック
5. プロジェクト名を入力して作成
6. プロジェクト一覧に新しいプロジェクトが表示されることを確認
各ステップでスクリーンショットを取得し、適切なアサーションを追加してください。
# Claude Codeが生成するテストコード
import { test, expect } from '@playwright/test';
test.describe('プロジェクト作成フロー', () => {
test('ログインから新規プロジェクト作成まで', async ({ page }) => {
// Step 1: ログインページにアクセス
await page.goto('https://staging.example.com/login');
await expect(page.getByRole('heading', { name: 'ログイン' })).toBeVisible();
await page.screenshot({ path: 'screenshots/01-login-page.png' });
// Step 2: 認証情報を入力してログイン
await page.getByLabel('メールアドレス').fill(process.env.TEST_EMAIL!);
await page.getByLabel('パスワード').fill(process.env.TEST_PASSWORD!);
await page.getByRole('button', { name: 'ログイン' }).click();
// Step 3: ダッシュボードの表示を確認
await expect(page).toHaveURL(/.*dashboard/);
await expect(page.getByRole('heading', { name: 'ダッシュボード' })).toBeVisible();
await page.screenshot({ path: 'screenshots/02-dashboard.png' });
// Step 4: 新規プロジェクト作成
await page.getByRole('button', { name: '新規プロジェクト' }).click();
await expect(page.getByRole('dialog')).toBeVisible();
// Step 5: プロジェクト名を入力して作成
const projectName = `E2E Test Project ${Date.now()}`;
await page.getByLabel('プロジェクト名').fill(projectName);
await page.getByRole('button', { name: '作成' }).click();
await page.screenshot({ path: 'screenshots/03-project-created.png' });
// Step 6: プロジェクト一覧に表示されることを確認
await expect(page.getByText(projectName)).toBeVisible();
await page.screenshot({ path: 'screenshots/04-project-list.png' });
});
});
Playwright MCPサーバーは実際にブラウザを操作してDOM構造を取得するため、セレクタの正確性が高いテストコードが生成されます。Claude Code TDDガイドと組み合わせることで、テスト駆動開発のワークフローにE2Eテストを自然に統合できます。
ワークフロー4: Sentry MCP × バグ自動修復
Sentryで報告されたエラーを自動的に分析し、根本原因を特定して修正するワークフローです。
前提条件: Sentry MCPサーバーが設定済みであること
# Claude Codeに入力するプロンプト
Sentryで直近24時間に発生した未解決エラーを確認して、
最も影響度の高いエラーを特定し、根本原因を分析して修正してください。
修正にあたっては:
- エラーのスタックトレースから原因箇所を特定
- 再現条件を推測
- 修正コードを実装
- 関連するテストを追加または更新
- 修正後にlintとテストが通ることを確認
# Claude Codeの処理フロー(実際の出力例)
## Sentry エラー分析レポート
### 最も影響度の高いエラー
**TypeError: Cannot read properties of undefined (reading 'email')**
- イベント数: 1,247件(直近24時間)
- 影響ユーザー数: 89人
- 初出: 2026-02-25 14:32 JST
- ファイル: src/services/notification.ts:47
### 根本原因
`sendNotification`関数で、ユーザーオブジェクトの`email`プロパティに
アクセスする前にnullチェックが行われていない。
退会済みユーザーへの通知処理で`user`がundefinedとなるケースが
ハンドリングされていなかった。
### 修正内容
# src/services/notification.ts の変更
- const email = user.email;
+ if (!user?.email) {
+ logger.warn('Notification skipped: user or email not found', { userId });
+ return { success: false, reason: 'user_not_found' };
+ }
+ const email = user.email;
### テスト追加
# src/services/__tests__/notification.test.ts に追加
it('should handle undefined user gracefully', async () => {
const result = await sendNotification(undefined, mockPayload);
expect(result.success).toBe(false);
expect(result.reason).toBe('user_not_found');
});
### 検証結果
✓ lint: パス
✓ テスト: 48 passed, 0 failed
✓ 型チェック: エラーなし
Sentry MCPがエラー情報を提供し、Claude Codeの組み込みツールがコードの読み取り・修正・テスト実行を担当します。人間のデバッグプロセスを忠実に再現しつつ、数分で完了する点が強みです。
ワークフロー5: Context7 MCP × 最新ドキュメント参照
新しいライブラリやAPIを使う前に、最新のドキュメントを取得してから実装するワークフローです。LLMの学習データにまだ反映されていない最新情報を活用できます。
前提条件: Context7 MCPサーバーが設定済みであること
# Claude Codeに入力するプロンプト
Next.js 16のServer Actionsの最新APIを確認してから、
ユーザープロフィール更新フォームを実装してください。
Context7で以下を確認してから実装に入ってください:
- Server Actionsの最新の書き方
- useActionState(旧useFormState)の使い方
- バリデーションのベストプラクティス
# Claude Codeの処理フロー
1. Context7 MCP → resolve-library-id("next.js") でライブラリIDを解決
2. Context7 MCP → get-library-docs(id, topic="Server Actions useActionState")
→ 最新ドキュメントを取得
3. 取得したドキュメントに基づいて実装
# Context7から取得した最新情報に基づく実装例
// app/profile/actions.ts
'use server'
import { z } from 'zod'
const profileSchema = z.object({
name: z.string().min(1, '名前は必須です').max(100),
bio: z.string().max(500, '自己紹介は500文字以内です').optional(),
})
export type ProfileState = {
errors?: { name?: string[]; bio?: string[] }
message?: string
success?: boolean
}
export async function updateProfile(
prevState: ProfileState,
formData: FormData
): Promise<ProfileState> {
const result = profileSchema.safeParse({
name: formData.get('name'),
bio: formData.get('bio'),
})
if (!result.success) {
return { errors: result.error.flatten().fieldErrors }
}
// DB更新処理
await db.user.update({
where: { id: currentUser.id },
data: result.data,
})
return { success: true, message: 'プロフィールを更新しました' }
}
// app/profile/edit/page.tsx
'use client'
import { useActionState } from 'react'
import { updateProfile, type ProfileState } from '../actions'
const initialState: ProfileState = {}
export default function EditProfilePage() {
const [state, formAction, isPending] = useActionState(
updateProfile,
initialState
)
return (
<form action={formAction}>
<div>
<label htmlFor="name">名前</label>
<input id="name" name="name" required />
{state.errors?.name && (
<p className="error">{state.errors.name[0]}</p>
)}
</div>
<div>
<label htmlFor="bio">自己紹介</label>
<textarea id="bio" name="bio" />
{state.errors?.bio && (
<p className="error">{state.errors.bio[0]}</p>
)}
</div>
<button type="submit" disabled={isPending}>
{isPending ? '更新中...' : '更新する'}
</button>
{state.success && <p className="success">{state.message}</p>}
</form>
)
}
Context7 MCPを使うことで、モデルの学習データのカットオフに関係なく、常に最新のAPIに基づいたコードが生成されます。これはバイブコーディングの精度を大幅に向上させるテクニックです。
よくある質問(FAQ)
Q. MCPサーバーは無料で使えますか?
A. MCPサーバー自体は無料です。MCPはオープンプロトコルであり、サーバーのほとんどはオープンソースで公開されています。ただし、MCPサーバーが接続する外部サービス(GitHub API、Sentry、データベース等)の利用料は別途発生する場合があります。また、Claude Code自体の利用にはAnthropic APIの料金またはClaude Pro/Maxプランのサブスクリプションが必要です。MCPサーバーを追加してもClaude Code側の追加課金はありませんが、ツール呼び出しによりトークン消費が増えるため、API利用の場合はコストが増加する可能性があります。
Q. MCPサーバーが起動しない場合のトラブルシューティングは?
A. まずclaude mcp listでサーバーの状態を確認してください。「not connected」と表示される場合は、以下の順序でチェックします。(1) whichコマンドでサーバーの実行ファイルのパスを確認(特にnvm/nodenv環境ではパスが通っていないことが多い)、(2) npx -yで手動実行してエラーメッセージを確認、(3) 環境変数(APIキー等)が正しく設定されているか確認、(4) claude mcp removeで一度削除してから再追加。それでも解決しない場合は、~/.claude/logs/ディレクトリのログファイルで詳細なエラーを確認できます。
Q. .mcp.jsonをGitにコミットしても安全ですか?
A. .mcp.jsonは原則としてGitにコミットすべきファイルです。このファイルにはMCPサーバーの接続設定(コマンド、引数)のみが含まれ、APIキーやトークンは環境変数参照(${VARIABLE_NAME})形式で記述するため、シークレット自体はファイルに含まれません。チーム全体で同じMCPサーバー構成を共有するために、積極的にコミットしてください。ただし、envフィールドにAPIキーを直書きしている場合は絶対にコミットしてはいけません。.mcp.jsonをコミットする前に、必ずgrep -r "sk-\|ghp_\|token" .mcp.json等でシークレットの混入をチェックしてください。
Q. MCPサーバーの数に上限はありますか?
A. プロトコル上の上限はありません。ただし実用上は、セクション「コンテキスト最適化戦略」で解説した通り、サーバー数が増えるとツール定義によるコンテキスト消費が問題になります。Tool Search(Lazy Loading)を有効にすれば数十のサーバーを問題なく運用できますが、それでも起動時の接続オーバーヘッドが発生します。目安として、常時接続するサーバーは10個以内に抑え、プロジェクト固有のサーバーは.mcp.jsonでスコープを限定することを推奨します。
Q. リモートMCPとローカルMCPはどちらを選ぶべき?
A. 判断基準は「認証の複雑さ」と「運用の手軽さ」のバランスです。ローカルMCP(stdio)は、セットアップが簡単でセキュリティリスクが低い反面、各開発者のマシンにサーバーをインストールする必要があります。リモートMCP(Streamable HTTP)は、チーム全体で共有でき、サーバー側でバージョン管理できる利点がありますが、OAuth認証の設定が必要です。個人開発やプロトタイピングにはローカル、チーム開発や本番環境にはリモートが適しています。セキュリティが最優先の場合は、ローカルMCPの方がアタックサーフェスが小さいためお勧めです。
Q. カスタムMCPサーバーをチームに配布する方法は?
A. 主に3つの方法があります。(1) npmパッケージとして公開: npx -y @your-org/mcp-serverで実行できるようにし、.mcp.jsonに設定を記述してリポジトリにコミット。最もシンプルな方法です。(2) Dockerイメージとして配布: Docker MCP Toolkitを使い、コンテナとして実行。環境依存を排除できます。(3) リモートMCPサーバーとしてホスティング: Streamable HTTPで公開し、チームメンバーはURLを追加するだけ。認証にはOAuth 2.1を使用します。いずれの場合も、managed-mcp.jsonで管理者が承認済みサーバーとして登録すると、セキュリティポリシーとの整合性が保てます。
Q. MCPはClaude Code以外のツールでも使えますか?
A. はい。MCPはオープンプロトコルであり、Claude Code以外にも多くのツールが対応しています。Claude Desktop、Cursor、Windsurf、Cline、Continue、Zed、Emacs(gptel)など、主要なAI開発ツールがMCPクライアント機能を実装しています。同じMCPサーバーを複数のクライアントから利用できるため、「サーバーは一度作れば、どのツールからでも使える」というエコシステムの利点があります。ただし、クライアントによって対応するMCPトランスポート(stdio、Streamable HTTP、SSE)やプロンプト/リソース機能のサポート状況が異なるため、事前に確認が必要です。
Q. MCP_TIMEOUTやMAX_MCP_OUTPUT_TOKENSの推奨値は?
A. MCP_TIMEOUTはMCPサーバーの接続・レスポンスのタイムアウト時間(ミリ秒)です。デフォルトは10,000ms(10秒)で、ほとんどのサーバーにはこれで十分です。外部APIを呼び出すサーバー(Web検索、DB操作等)では、30,000〜60,000ms(30〜60秒)に引き上げることを推奨します。MAX_MCP_OUTPUT_TOKENSはMCPサーバーの出力上限で、デフォルトは25,000トークンです。大量のデータを返すサーバー(DB検索結果、ログ取得等)では増やす必要がありますが、むやみに増やすとコンテキストを圧迫するため、50,000トークン程度を上限の目安としてください。いずれも環境変数またはsettings.jsonのenvフィールドで設定できます。
まとめ——MCPがClaude Codeを「ただのAI」から「開発基盤」に変える
本記事では、Claude CodeとMCPの実践的な活用方法を、設定から最適化、セキュリティ、実践ワークフローまで包括的に解説しました。MCPは単なる「プラグイン機構」ではありません。AIエージェントが外部の世界と対話するための標準プロトコルであり、Claude Codeを「コードを読み書きするだけのAI」から「開発プロセス全体を支える基盤」へと進化させる技術です。
本記事の要点(7つのキーポイント)
- MCPは「AIのUSB-Cポート」——標準化されたプロトコルにより、一度作ったサーバーはどのMCPクライアントからでも利用でき、ベンダーロックインを回避できる。
- 3つのスコープで管理する——ローカル(
~/.claude/settings.json)、プロジェクト(.mcp.json)、システム(managed-mcp.json)を使い分けることで、個人・チーム・組織レベルの設定を適切に分離できる。 - エージェント・イン・エージェント——
claude mcp serveでClaude Code自体をMCPサーバーとして公開し、メインエージェントからサブエージェントとして呼び出す高度なアーキテクチャが可能。 - Tool Searchでコンテキスト最適化——MCPツールの遅延ロードにより、数十のサーバーを導入してもコンテキスト消費を最小限に抑え、ツール選択精度を最大25ポイント向上させる。
- セキュリティは多層防御——許可リスト/拒否リスト、
managed-mcp.jsonによる管理者制御、ネットワーク分離、監査ログを組み合わせた多層防御が、エンタープライズ運用の鍵となる。 - 5つの実践ワークフロー——GitHub PR自動レビュー、DBマイグレーション生成、E2Eテスト自動生成、Sentryバグ修復、最新ドキュメント参照の各ワークフローが、即座に開発効率を引き上げる。
- 段階的に導入すべし——最初から全てを導入するのではなく、1つのMCPサーバーから始めて段階的に拡大することが、成功の鍵。
段階的導入の3ステップ
📋 MCPを組織に導入するロードマップ
ステップ1: 基礎導入(Week 1-2)
GitHub MCPとContext7 MCPを個人環境にインストールし、日常の開発フローに組み込みます。まずは「MCPでこんなことができる」という実感を得ることが目標です。CLAUDE.mdにMCPの使い分けルールを記述する習慣もこの段階で身につけましょう。
ステップ2: チーム展開(Week 3-4)
.mcp.jsonをリポジトリにコミットし、チーム全体で同じMCPサーバー構成を共有します。セキュリティの観点から、allowedMcpServers/deniedMcpServersの設定も行います。Tool Searchの有効化としきい値調整で、パフォーマンスも最適化します。
ステップ3: 高度活用(Month 2+)
プロジェクト固有のカスタムMCPサーバーを開発し、社内システムとの連携を構築します。エージェント・イン・エージェント・パターンや、CI/CDパイプラインへのMCP統合など、高度なユースケースにも取り組みます。managed-mcp.jsonによる組織全体のガバナンスもこの段階で確立します。
今日から始める最初のMCPサーバー
ここまで読んでいただいたあなたへの提案は、「今すぐ1つだけMCPサーバーを追加してみること」です。
おすすめの最初の一歩は、Context7 MCPです。ライブラリの最新ドキュメントをリアルタイムで取得できるため、日常のコーディングで即座に効果を実感できます。
# 今すぐ実行できる1行コマンド
claude mcp add context7 -- npx -y @upstash/context7-mcp@latest
これだけで、次回のClaude Codeセッションから「最新のNext.jsのドキュメントを確認して」「React 19のuseフックの使い方を調べて」といった指示が可能になります。
GitHub MCPを使いたい場合は、さらに簡単です。
# GitHub MCPの追加(ghコマンドが認証済みの場合)
claude mcp add github -- npx -y @modelcontextprotocol/server-github
MCPの世界は広大ですが、入口は驚くほどシンプルです。1つのサーバーから始めて、必要に応じて拡張していく——それがMCPの正しい始め方です。
Claude Codeの基本的な使い方をまだ押さえていない方は、まずClaude Code 初心者ガイドから始めることをお勧めします。本記事の内容をさらに深掘りしたい方は、Claude Code 実践ワークフローガイドが次のステップに最適です。
関連記事(Claude Codeシリーズ)
- Claude Code 初心者ガイド——インストールから最初のプロジェクトまで、Claude Codeの基礎を網羅的に解説
- Claude Code 実践ワークフロー——日常開発でClaude Codeを最大限に活用するためのワークフロー集
- Claude Code 上級テクニック——CLAUDE.md、フック、サブエージェントなど、パワーユーザー向けの高度な活用法
- Claude Code TDDガイド——テスト駆動開発とClaude Codeを組み合わせた品質重視の開発手法
- Claude Code Agent Teams——マルチエージェントで大規模タスクを並列処理する最新パターン
Claude Code × MCPの導入でお困りですか?
AQUA LLC はAI導入コンサルティングを提供しています
MCPの設計・カスタムサーバー開発・セキュリティ設定まで、プロがサポートします
参考文献
- Model Context Protocol — Official Documentation
- Claude Code — MCP Documentation
- MCP Specification 2025-03-26 — Protocol Specification
- GitHub MCP Server — Official Reference Implementation
- Playwright MCP — Browser Automation for AI Agents
- Context7 — Up-to-date Documentation for LLMs
- Docker MCP Toolkit — Containerized MCP Server Management
- Sentry MCP Server — Error Monitoring Integration
- MCP TypeScript SDK — Build Custom MCP Servers
- Agentic AI Foundation — Open Standards for AI Agents