AIエージェント入門

Claude MCP入門:Model Context Protocolの基礎と実装

Claude MCP入門:Model Context Protocolの基礎と実装

この記事の結論

Claude MCP(Model Context Protocol)は、Claudeと外部ツール/データソースを接続するための標準プロトコルです。この記事では、MCPの基本概念と実際の実装方法を解説します。

Claude MCPとは

Claude MCP(Model Context Protocol)は、Anthropicが提供する標準プロトコルで、Claude AIと外部ツール・データソース間の通信を簡素化します。API直接呼び出しやカスタムインテグレーションの複雑さを解消し、統一的なインターフェースを提供します。

  • 標準化された通信:JSON-RPC 2.0ベースの一貫したプロトコル
  • ツール抽象化:API、データベース、ローカルファイルを統一的に扱う
  • サーバーモデル:MCP Serverとして機能拡張を提供

MCP Serverの基本構造

MCP Serverは、stdioまたはSSE(Server-Sent Events)を通じてClaudeと通信するプロセスです。以下の主要コンポーネントで構成されますされます:

{
  "jsonrpc": "2.0",
  "method": "tools/list",
  "params": {},
  "id": 1
}
  • tools/list:利用可能なツール一覧を返す
  • tools/call:ツールを実行する
  • resources/list:利用可能なリソース一覧
  • resources/read:リソースの内容を読み込む

実装例:ファイルシステムMCP Server

以下は、PythonでシンプルなファイルシステムMCP Serverを実装する例です:

#!/usr/bin/env python3
import sys
import json
import os

def handle_tools_list():
    return {
        "jsonrpc": "2.0",
        "result": {
            "tools": [
                {
                    "name": "read_file",
                    "description": "ファイルの内容を読み込む",
                    "inputSchema": {
                        "type": "object",
                        "properties": {
                            "path": {
                                "type": "string",
                                "description": "ファイルパス"
                            }
                        },
                        "required": ["path"]
                    }
                }
            ]
        },
        "id": None
    }

def handle_tools_call(params):
    tool_name = params.get("name")
    arguments = params.get("arguments", {})
    
    if tool_name == "read_file":
        path = arguments.get("path")
        try:
            with open(path, "r") as f:
                content = f.read()
            return {
                "jsonrpc": "2.0",
                "result": {
                    "content": [
                        {
                            "type": "text",
                            "text": content
                        }
                    ]
                },
                "id": None
            }
        except Exception as e:
            return {
                "jsonrpc": "2.0",
                "error": {
                    "code": -1,
                    "message": str(e)
                },
                "id": None
            }

def main():
    for line in sys.stdin:
        try:
            request = json.loads(line.strip())
            method = request.get("method")
            
            if method == "initialize":
                response = {
                    "jsonrpc": "2.0",
                    "result": {
                        "protocolVersion": "2024-11-05",
                        "serverInfo": {
                            "name": "filesystem-server",
                            "version": "1.0.0"
                        },
                        "capabilities": {
                            "tools": {}
                    "
                    }
                },
                "id": request.get("id")
            }
            elif method == "tools/list":
                response = handle_tools_list()
            elif method == "tools/call":
                response = handle_tools_call(request.get("params", {}))
            else:
                response = {
                    "jsonrpc": "2.0",
                    "error": {
                        "code": -32601,
                        "message": "Method not found"
                    },
                    "id": request.get("id")
                }
            
            print(json.dumps(response))
            sys.stdout.flush()
        except Exception as e:
            error_response = {
                "jsonrpc": "2.0",
                "error": {
                    "code": -32700,
                    "message": str(e)
                },
                "id": None
            }
            print(json.dumps(error_response))
            sys.stdout.flush()

if __name__ == "__main__":
    main()

MCP Serverのデプロイ方法

作成したMCP ServerをClaude Desktopで使用するには、以下の設定ファイルを作成します:

{
  "mcpServers": {
    "filesystem": {
      "command": "python3",
      "args": ["/path/to/filesystem_server.py"]
    }
  }
}

応用例:データベースMCP Server

データベースに接続し、SQLクエリを実行するMCP Serverも簡単に実装できます。以下はSQLiteを使用する例の主要部分です:

import sqlite3

def handle_query(arguments):
    query = arguments.get("query")
    try:
        conn = sqlite3.connect("database.db")
        cursor = conn.cursor()
        cursor.execute(query)
        rows = cursor.fetchall()
        conn.close()
        
        return {
            "jsonrpc": "2.0",
            "result": {
                "content": [
                    {
                        "type": "text",
                        "text": json.dumps(rows)
                    }
                ]
            },
            "id": None
        }
    except Exception as e:
        return {
            "jsonrpc": "2.0",
            "error": {
                "code": -1,
                "message": str(e)
            },
            "id": None
        }

ベストプラクティス

  • エラーハンドリング:すべてのコマンドで適切なエラー処理を実装する
  • 入力バリデーション:引数を検証し、不正な入力を拒否する
  • 非同期処理:長時間実行される操作はバックグラウンドで処理する
  • ログ出力:デバッグ用に詳細なログを記録する

よくある問題と解決方法

Q: MCP Serverが認識されない
A: 設定ファイルのパスと権限を確認してください。コマンドの絶対パスを使用することを推奨します。

Q: JSON-RPCエラーが発生する
A: リクエストとレスポンスのJSONフォーマットを確認してください。jsonrpcバージョンが”2.0″であることを確認します。

公式ドキュメント:Model Context Protocol — Anthropic Documentation

次に読む

LangGraph実践ガイド:複雑なAIエージェントの構築方法

AIエージェント設計パターン:ベストプラクティス集

この記事を読んで導入イメージが固まってきた方へ

UravationではAIエージェント導入の研修・コンサルを行っています。

MCP server カタログ 2026年6月版

MCP のサーバーエコシステムは 2025 年末から 2026 年にかけて爆発的に拡大し、公式レジストリには 1 万件超のサーバーが登録されている(Anthropic 発表、2025年12月時点)。ここでは開発・運用現場で実際に使われているサーバーを機能カテゴリ別に整理する。

ファイル・コード管理

サーバー名 npm / パッケージ 主な用途
filesystem @modelcontextprotocol/server-filesystem ローカルファイルの読み書き・ツリー取得
GitHub @modelcontextprotocol/server-github PR 作成・Issue 管理・コード検索
GitLab @modelcontextprotocol/server-gitlab GitLab API 一式(MR・pipeline)

コミュニケーション・通知

サーバー名 npm / パッケージ 主な用途
Slack @modelcontextprotocol/server-slack チャンネル投稿・検索・DM 送信
Linear Linear 公式リモートエンドポイント Issue 作成・ステータス更新・プロジェクト管理
Notion Notion 公式 MCP サーバー ページ作成・DB クエリ・ブロック編集

データベース・ストレージ

サーバー名 npm / パッケージ 主な用途
PostgreSQL @modelcontextprotocol/server-postgres SQL クエリ実行・スキーマ参照
Supabase Supabase 公式リモート MCP テーブル CRUD・Edge Functions 呼び出し
SQLite @modelcontextprotocol/server-sqlite ローカル SQLite 操作・メモリ DB

UI・デザイン

サーバー名 提供元 主な用途
Figma Dev Mode MCP Figma 公式 選択レイヤーの構造・オートレイアウト・トークンを Claude に直接渡す
Playwright @executeautomation/playwright-mcp-server ブラウザ自動操作・E2E テスト生成

モニタリング・可観測性

サーバー名 提供元 主な用途
Sentry Sentry 公式リモート MCP エラー・スタックトレースをリアルタイムで取得、修正候補を生成
Datadog Datadog 公式 MCP メトリクス・ログ・トレースをクエリし障害診断を自動化

ブラウザ・Web

サーバー名 npm / パッケージ 主な用途
Brave Search @modelcontextprotocol/server-brave-search リアルタイム Web 検索・情報収集
fetch @modelcontextprotocol/server-fetch URL 取得・HTML → Markdown 変換

2026 年 4 月時点でリモート HTTP エンドポイントとして稼働するサーバーは 25 件超に達し、1 月時点の 16 件から急増している(builder.io 調査)。Atlassian(Jira/Confluence)・HubSpot・Vercel・Neon も公式リモート MCP を提供開始しており、エコシステムは週単位で拡大中だ。


Claude Code × MCP 統合実装 5パターン

Claude Code は ~/.claude/mcp.json(または .mcp.json)に MCP サーバーを宣言するだけで、ツールとして直接呼び出せる。以下に実務で頻出する 5 パターンを示す。

パターン1: ローカル stdio サーバー(開発・検証向け)

最もシンプルな接続形式。Node.js や Python プロセスを子プロセスとして起動し、stdin/stdout で JSON-RPC を交換する。ネットワーク設定不要で手元環境でのデバッグに最適。

// .mcp.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/workspace"],
      "type": "stdio"
    }
  }
}

Claude Code から /mcp コマンドで接続確認後、list_directoryread_file ツールがそのまま使えるようになる。

パターン2: リモート HTTP サーバー + OAuth 認証

Linear・Notion・GitHub などの SaaS は OAuth 2.0 で保護されたリモートエンドポイントを提供している。type: "http" で URL を指定し、トークンは環境変数から渡す。

{
  "mcpServers": {
    "linear": {
      "type": "http",
      "url": "https://mcp.linear.app/mcp",
      "headers": {
        "Authorization": "Bearer ${LINEAR_API_KEY}"
      }
    }
  }
}

エンタープライズ環境では OAuth トークンの自動リフレッシュと、IdP(Okta・Azure AD)との OIDC 連携が標準になりつつある。静的シークレットの直書きは 2026 年以降の MCP ベストプラクティスで明示的に非推奨とされている。

パターン3: MCP ゲートウェイ経由の集中管理

複数のサーバーを 1 つのゲートウェイ経由でルーティングする構成。Claude Code → ゲートウェイ(認証・レート制限・監査ログ)→ 各 MCP サーバー の流れで、エンタープライズの統制要件を満たせる。

# ゲートウェイ経由の一元エンドポイント
{
  "mcpServers": {
    "gateway": {
      "type": "http",
      "url": "https://mcp-gateway.internal/v1/mcp",
      "headers": {
        "Authorization": "Bearer ${GATEWAY_TOKEN}",
        "X-Team-ID": "engineering"
      }
    }
  }
}

ゲートウェイ製品としては Maxim・TrueFoundry などが 2026 年に実プロダクション実績を積んでいる。JWT の検証はゲートウェイがインメモリでキャッシュした公開鍵で処理するため、IdP への毎回アクセスが不要になる。

パターン4: カスタム MCP サーバーの最小実装(Python)

社内 API や独自データソースに接続する場合は自作サーバーを構築する。Python SDK を使えば 30 行程度でツールを公開できる。

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
import mcp.types as types

app = Server("my-internal-api")

@app.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(
            name="get_sales_data",
            description="社内売上DBから指定期間のデータを取得",
            inputSchema={
                "type": "object",
                "properties": {
                    "start_date": {"type": "string", "description": "YYYY-MM-DD"},
                    "end_date":   {"type": "string", "description": "YYYY-MM-DD"}
                },
                "required": ["start_date", "end_date"]
            }
        )
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
    if name == "get_sales_data":
        # 実際には社内 API を呼び出す
        data = fetch_internal_sales(arguments["start_date"], arguments["end_date"])
        return [TextContent(type="text", text=str(data))]

if __name__ == "__main__":
    import asyncio
    asyncio.run(stdio_server(app))

パターン5: Streamable HTTP + ステートレス水平スケール(2026年新仕様)

MCP 2026-07-28 RC で採用された Streamable HTTP 新仕様では、Mcp-Session-Id ヘッダが廃止され、プロトコル層でステートレスになった。これによりロードバランサーへの sticky-session 設定が不要になり、コンテナオーケストレーターで水平スケールが自然に実現できる。

# docker-compose.yml 例(ステートレス MCP サーバー × 3レプリカ)
services:
  mcp-server:
    image: my-mcp-server:latest
    deploy:
      replicas: 3
    environment:
      - REDIS_URL=redis://redis:6379  # セッション状態は Redis で共有
    # sticky session 不要 — リクエストはどのレプリカにルーティングしてもよい
  redis:
    image: redis:7-alpine

各リクエストには Mcp-MethodMcp-Name ヘッダが付与されるため、ゲートウェイやレート制限ミドルウェアがボディのパースなしにオペレーションを識別できる。


MCP 実装の落とし穴 5選

MCP は仕様がシンプルな分、実装時に見落としがちなポイントが存在する。本番環境で問題が起きやすい 5 つの落とし穴と対策を整理する。

落とし穴1: 認証トークンのハードコード

開発初期に mcp.json へ API キーを直書きしてそのまま本番運用してしまうケースが多い。MCP サーバーは LLM から直接呼び出されるため、プロンプトインジェクション経由でトークンが漏洩するリスクが通常の API 呼び出しより高い。

対策: 環境変数参照(${ENV_VAR})を使い、本番では Secrets Manager(AWS Secrets Manager・GCP Secret Manager・HashiCorp Vault)から動的取得する。静的シークレットは 2026 年 MCP ベストプラクティスで非推奨とされている。

落とし穴2: ツールスキーマの権限過剰定義

「とりあえず全操作を公開」とツールを定義すると、Claude が意図しない破壊的操作(ファイル削除・DB レコード一括変更など)を実行する可能性がある。MCP の inputSchema で操作範囲を絞り込むことが重要だ。

対策: 読み取り専用ツールと書き込みツールを分離し、書き込み系ツールには confirmation_required: true に相当する人間確認ステップを挟む。Claude Code の allowedTools 設定で呼び出し可能ツールを絞り込む方法も有効。

落とし穴3: レート制限の未実装によるコスト爆発

LLM がループや再試行を繰り返す際、MCP サーバーへの呼び出しが無制限に実行されるケースがある。特に外部 SaaS(Notion・Slack など)は API クォータを超えると 429 エラーになり、エージェントが別経路で再試行するループに陥る。

対策: サーバー側でスライディングウィンドウのレート制限を実装し、指数バックオフ(最大 5 リトライ・フルジッター付き)を標準実装にする。ゲートウェイ利用時はゲートウェイのレート制限機能に委ねるのが現実的。

import asyncio, random

async def call_with_retry(tool_fn, *args, max_retries=5):
    for attempt in range(max_retries):
        try:
            return await tool_fn(*args)
        except RateLimitError:
            wait = min(2 ** attempt + random.random(), 60)  # フルジッター
            await asyncio.sleep(wait)
    raise Exception("Max retries exceeded")

落とし穴4: エラーレスポンスの情報漏洩

MCP サーバーが詳細な内部エラー(スタックトレース・SQL クエリ・内部 URL)をそのままツールレスポンスとして返すと、Claude がその情報を次のプロンプトや出力に含めてしまう。プロンプトインジェクション攻撃で悪意あるコンテンツがツール経由で LLM に注入されるリスクもある。

対策: ツールレスポンスはユーザー向けのサニタイズ済みメッセージのみ返す。詳細ログはサーバー側のオブザーバビリティ基盤(Sentry・Datadog)に流す。MCP の isError: true フラグを正しく設定し、エラー時は必ず構造化レスポンスを返す。

落とし穴5: ツール呼び出しの監視・監査ログ欠如

MCP のツール呼び出しは非同期で大量発生するため、問題発生後に「どのツールが何を実行したか」を追跡できないケースが多い。特にエンタープライズ環境では監査証跡が法的・コンプライアンス要件になる場合がある。

対策: 各ツール呼び出しに一意のリクエスト ID を付与し、ツール名・引数・呼び出し元・タイムスタンプ・レスポンスバイト数を構造化ログとして出力する。Datadog MCP を使えばこれらのメトリクスをダッシュボードで一元可視化できる。


2026年6月のMCP最新動向

Anthropic 公式アップデート: プロトコル移管と RC リリース

2025 年 12 月、Anthropic は MCP を Linux Foundation 傘下の Agentic AI Foundation(AAIF) に移管した。Anthropic・Block・OpenAI が共同創設者として参加し、特定ベンダーへの依存を排除した中立的なガバナンス体制が整った。

2026 年に入り、次期仕様の RC(Release Candidate)が公開されている。「MCP 2026-07-28」と呼ばれるこの RC の主要変更点は次の 4 点だ。

  • ステートレス化: initialize ハンドシェイクと Mcp-Session-Id ヘッダが廃止され、通常の HTTP インフラで水平スケールが可能になる
  • MCP Server Cards: .well-known/ URL でサーバーのメタデータを公開する標準仕様。ブラウザ・クローラー・レジストリが接続なしで能力を発見できる
  • MCP Apps: サーバーがサンドボックス iframe でインタラクティブな HTML UI を提供できる Extensions フレームワーク
  • Tasks 拡張: 長時間実行ジョブをプロトコルレベルでサポート。非同期エージェントワークフローの標準化が進む

npm パッケージの動向

MCP Python SDK・TypeScript SDK の月間ダウンロードは 2025 年 12 月時点で合計 9,700 万件超に達している(Anthropic 公式発表)。2026 年 H1 では以下の傾向が観測されている。

  • TypeScript SDK のダウンロード数が Python SDK を上回り、フロントエンド・フルスタック開発者への普及が加速
  • @modelcontextprotocol/* スコープの公式パッケージに加え、サードパーティ製の mcp-* プレフィックスパッケージが npm に急増
  • Zod スキーマを使った型安全なツール定義パターンがコミュニティで標準化されつつある

コミュニティ MCP サーバーの急増

2025 年末に 1 万件を超えた公式レジストリ登録数は、2026 年 H1 でさらに増加が続いている。特に以下のカテゴリで新規サーバーが増えている。

  • BI・データ分析: Tableau・PowerBI・Looker 接続サーバー
  • クラウドインフラ: AWS・GCP・Azure のリソース操作サーバー(Pulumi Neo など)
  • 決済・CRM: Stripe・Salesforce・HubSpot の公式リモート MCP
  • セキュリティ: Snyk・Semgrep・Checkmarx の脆弱性スキャン MCP

リモート HTTP エンドポイントとして提供されるサーバーは 2026 年 4 月時点で 25 件超となり、ローカル stdio サーバーとリモートサーバーのハイブリッド構成が実用的になっている。


FAQ: MCP に関するよくある質問(拡張版)

MCP と Function Calling の違いは何ですか?

Function Calling は各 LLM プロバイダー固有の仕様で、OpenAI の JSON スキーマ定義を Claude や Gemini に移植するには書き直しが必要です。MCP はプロバイダー非依存の標準プロトコルであり、一度実装したサーバーを Claude・ChatGPT・Gemini など複数のクライアントで再利用できます。またサーバー側がツールリストを動的に公開するため、クライアント側のコード変更なしにサーバー機能を追加・削除できる点も異なります。

MCP サーバーはどこで動かすべきですか?

開発・個人用途ではローカル stdio(npm/Python プロセス)が最も手軽です。チーム共有・本番運用では Docker コンテナでホストし、ゲートウェイ経由で認証と監査ログを集中管理するのが推奨パターンです。SaaS ツール(Linear・Notion・Figma など)は公式リモートエンドポイントを提供しているため、自前でホストする必要はありません。

MCP の認証はどのように実装しますか?

2026 年の MCP ベストプラクティスでは OAuth 2.0 / OIDC が推奨されます。ローカルサーバーは環境変数でトークンを渡し、リモートサーバーは Authorization ヘッダで Bearer トークンを使います。エンタープライズ環境では MCP ゲートウェイが Okta・Azure AD などの IdP と連携し、JWT を自動検証する構成が一般的です。静的 API キーのハードコードは非推奨です。

Claude Code で MCP サーバーを追加するにはどうすればよいですか?

プロジェクトルートに .mcp.json を作成し、mcpServers オブジェクトにサーバー定義を記述します。claude mcp add コマンドでも追加可能です。設定後は Claude Code の /mcp コマンドで接続状態を確認し、ツール一覧が表示されれば利用可能な状態です。

MCP はどのトランスポートをサポートしていますか?

現行の MCP 2024-11-05 仕様は stdio と Streamable HTTP(SSE ベース)をサポートします。2026-07-28 RC では Streamable HTTP がステートレス化され、セッション管理が不要になります。stdio はローカルプロセス向け、Streamable HTTP はネットワーク越しのサーバーで使います。WebSocket は公式にはサポートされていません。

MCP サーバーの本番運用でまず整備すべき監視指標は何ですか?

最低限整備すべき指標は「ツール呼び出し成功率」「P95 レイテンシ」「レート制限到達回数(429 エラー率)」「エラー種別の内訳」の 4 つです。Datadog MCP を使えばこれらをエージェントから直接クエリでき、障害時の根本原因分析を自動化できます。Sentry との組み合わせでエラーのスタックトレースもエージェントが直接参照できます。

MCP 2026-07-28 RC の正式リリースはいつですか?

RC(Release Candidate)の名称が示す通り、正式仕様のリリースは 2026 年 7 月 28 日を目標としています(modelcontextprotocol.io ロードマップより)。RC は現在テスト可能な状態で公開されており、破壊的変更に関する正式な deprecation ポリシーも新設されています。本番移行は正式リリース後に段階的に進めることが推奨されています。

参照・一次ソース

Need help moving from reading to rollout?

この記事を読んで導入イメージが固まってきた方へ

Uravationでは、AIエージェントの要件整理、PoC設計、社内導入、研修まで一気通貫で支援しています。

この記事をシェア

X Facebook LINE

※ 本記事の情報は2026年7月時点のものです。サービスの料金・仕様は変更される可能性があります。最新情報は各サービスの公式サイトをご確認ください。

関連記事