AIコーディング 2026.08.29

Model Context Protocol(MCP)をClaude CodeとChatGPT APIで活用する方法|ツール連携の標準化と実装パターン【2026年版】

タグ:Model Context Protocol / Claude Code / AIコーディング / ツール連携 / LLM

Model Context Protocol(MCP)とは?ツール連携の標準化が進む2026年

Model Context Protocol(MCP)は、Anthropicが推し進めるLLM(大規模言語モデル)とツール・データソースを接続するための標準仕様です。2026年現在、Claude Code、ChatGPT API、その他のAIコーディングツールの間で、ツール連携設計の「標準」として急速に採用が広がっています。

従来、各LLMがツール連携を実装する際は、独自の仕様を使っていました。そのため開発者は、同じ機能を複数のLLMに対応させようとするたびに、異なるAPI設計を学び直す必要がありました。MCPはこの課題を解決し、一度設計したツール連携インターフェースを複数のLLMプラットフォーム間で再利用できるようにします。

MCPの主要な特徴と利点

標準化による開発効率の向上

MCPの最大の利点は、ツール連携の仕様を統一することで、開発者の学習コストと実装時間を削減することです。

  • クロスプラットフォーム対応: Claude Code、ChatGPT API、その他のLLMサービスに同じインターフェースで接続可能
  • 再利用性: 一度実装したツール連携ロジックを複数のプロジェクトで流用できる
  • 保守性: 業界標準に従うため、チーム内での知識共有とコード管理が容易

パイプランアーキテクチャによるエージェント制御

MCPは「パイプラインレイヤー」という考え方を導入しています。これは、LLMの指示内容に頼るのではなく、データフロー自体に制御ロジックを埋め込むアーキテクチャを指します。

具体的には:

  • エージェント境界の明確化: エージェント(自動判断するシステム)と知識ベース(参照用データ)の責任を分離
  • パイプラインレイヤーでの制御: LLMの指示文に「〜しないでください」と書くのではなく、パイプラインの設計時点で不正なデータフローを物理的に遮断
  • 自己参照の防止: デフォルトでは同じデータソースへの重複参照を避け、意図しない無限ループを防止

これにより、プロンプトの書き方だけに頼った曖昧な制御から、設計段階で保証された堅牢なエージェントシステムへシフトします。

Claude CodeでMCPを実装する基本パターン

Claude CodeのMCP統合方法

Claude Codeは、MCPサーバーに接続することで、外部ツール・API・データベースへのアクセスを標準化できます。

ステップ1: MCPサーバーの仕様を理解する

MCPサーバーは、以下の機能を提供します:

  1. Tool(ツール): LLMが直接呼び出せる関数型のインターフェース
  2. Resource(リソース): 参照可能なテキスト・ファイル・データソース
  3. Prompt(プロンプト): テンプレート化された事前設定プロンプト

ステップ2: 基本的なMCPツール定義

MCPサーバー上でツールを定義する際の一般的なパターンは以下の通りです:

{
  "tools": [
    {
      "name": "execute_code",
      "description": "JavaScriptコードを実行して結果を返す",
      "inputSchema": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "実行するJavaScriptコード"
          }
        },
        "required": ["code"]
      }
    },
    {
      "name": "fetch_api",
      "description": "HTTPリクエストを送信してレスポンスを取得",
      "inputSchema": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "リクエスト先のURL"
          },
          "method": {
            "type": "string",
            "enum": ["GET", "POST", "PUT", "DELETE"],
            "description": "HTTPメソッド"
          }
        },
        "required": ["url"]
      }
    }
  ]
}

ステップ3: Claude CodeでMCPサーバーに接続

Claude Codeの設定ファイル(通常は.claudercまたはclaude-config.json)にMCPサーバーのエンドポイントを登録します:

{
  "mcp_servers": [
    {
      "name": "local_tools",
      "url": "http://localhost:3000",
      "auth": {
        "type": "none"
      }
    },
    {
      "name": "api_gateway",
      "url": "http://api-gateway.internal:5000",
      "auth": {
        "type": "bearer",
        "token": "${MCP_API_TOKEN}"
      }
    }
  ]
}

環境変数をセットして接続を確認します:

export MCP_API_TOKEN="your-token-here"
claude-code --config claude-config.json

ChatGPT APIでMCPを活用する実装方法

ChatGPT APIのツール連携との互換性

ChatGPT APIも、MCPの標準仕様に段階的に対応しています。これにより、MCPで定義されたツールをChatGPT API経由でも呼び出せるようになります。

実装パターン: MCPツールをOpenAI関数呼び出しにマッピング

MCPツール定義をOpenAI Assistants APIのツール定義に変換するブリッジを構築します:

import json
import requests
from openai import OpenAI

# MCPサーバーからツール定義を取得
mcp_url = "http://localhost:3000"
mcp_tools_response = requests.get(f"{mcp_url}/tools")
mcp_tools = mcp_tools_response.json()

# MCPツール定義をOpenAI形式に変換
def convert_mcp_to_openai_tool(mcp_tool):
    return {
        "type": "function",
        "function": {
            "name": mcp_tool["name"],
            "description": mcp_tool["description"],
            "parameters": mcp_tool["inputSchema"]
        }
    }

openai_tools = [convert_mcp_to_openai_tool(tool) for tool in mcp_tools]

# OpenAIクライアントを初期化
client = OpenAI(api_key="your-openai-api-key")

# MCPツールをOpenAI Assistants APIに登録
assistant = client.beta.assistants.create(
    name="MCP-Integrated Assistant",
    model="gpt-4",
    tools=openai_tools
)

# ツール呼び出しを処理
def handle_tool_call(tool_name, tool_input):
    # MCPサーバーに要求を転送
    response = requests.post(
        f"{mcp_url}/tools/{tool_name}/call",
        json=tool_input
    )
    return response.json()

ステップバイステップ: ChatGPT APIでの統合

  1. MCPサーバーの起動
# ローカルでMCPサーバーを起動(Node.js例)
npm install -g mcp-server-core
mcp-server --port 3000 --config ./mcp-config.json
  1. OpenAI Assistantsの設定
# MCPツールを使用したアシスタントの作成
tools = [
    {
        "type": "function",
        "function": {
            "name": "search_database",
            "description": "指定されたクエリでデータベースを検索",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string"},
                    "limit": {"type": "integer", "default": 10}
                },
                "required": ["query"]
            }
        }
    }
]

assistant = client.beta.assistants.create(
    name="Database Query Assistant",
    model="gpt-4",
    tools=tools
)
  1. スレッドでの会話実行とツール呼び出し
# スレッドを作成
thread = client.beta.threads.create()

# ユーザーメッセージを追加
client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="最近のログを検索してください"
)

# アシスタントに実行させ、ツール呼び出しを待つ
run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id
)

# ツール呼び出しをポーリング
import time
while run.status in ["queued", "in_progress"]:
    run = client.beta.threads.runs.retrieve(
        thread_id=thread.id,
        run_id=run.id
    )
    time.sleep(0.5)

# ツール呼び出しが必要な場合は処理
if run.status == "requires_action":
    tool_calls = run.required_action.submit_tool_outputs.tool_calls
    tool_outputs = []
    
    for tool_call in tool_calls:
        result = handle_tool_call(
            tool_call.function.name,
            json.loads(tool_call.function.arguments)
        )
        tool_outputs.append({
            "tool_call_id": tool_call.id,
            "output": json.dumps(result)
        })
    
    # ツール実行結果をアシスタントに返す
    run = client.beta.threads.runs.submit_tool_outputs(
        thread_id=thread.id,
        run_id=run.id,
        tool_outputs=tool_outputs
    )

MCPアーキテクチャの設計パターン

パイプランレイヤーでのエージェント制御設計

MCPを活用した堅牢なシステム設計では、以下のアーキテクチャパターンが推奨されます。

パターン1: 知識ベースとエージェント分離

┌─────────────────┐
│  LLM(Claude)  │
├─────────────────┤
│  エージェント   │
│  (判断・計画) │
└────────┬────────┘

    ┌────┴────────────────┬──────────┐
    │                     │          │
┌───▼────────────┐  ┌────▼──────┐  ┌▼──────────┐
│ 知識ベース     │  │ ツール    │  │API        │
│(読み取り)    │  │(実行)   │  │(外部連携)
└────────────────┘  └───────────┘  └───────────┘

このアーキテクチャでは:

  • LLMエージェント: ユーザー要求を解析し、実行計画を立てる
  • 知識ベース: 参照用データ(ドキュメント、FAQ、設定値)。LLMは読み込み専用
  • ツール層: 実際にシステム状態を変更(APIの呼び出し、ファイル作成、DB操作)

この分離により、LLMが「知識ベースを誤って上書きする」という問題を構造的に防ぎます。

パターン2: MCPリソースによる自己参照の防止

MCPの「Resource」機能を使い、デフォルトでは同じデータソースへの重複参照を排除します:

{
  "resources": [
    {
      "name": "user_database",
      "type": "database",
      "uri": "postgresql://db.internal/users",
      "access_control": {
        "read": "allowed",
        "write": "denied",
        "self_reference": "prohibited"
      }
    },
    {
      "name": "api_cache",
      "type": "cache",
      "uri": "redis://cache.internal:6379",
      "access_control": {
        "read": "allowed",
        "write": "agent_only",
        "self_reference": "with_version_check"
      }
    }
  ]
}

self_reference: "prohibited"の設定により、同一のリソースに対する複数アクセスがパイプレイヤーで自動的に統合されます。

実践的な設計チェックリスト

MCPを導入する際、以下の項目を確認してください:

項目確認ポイント
データフロー分離エージェント(判断)と知識ベース(参照)は物理的に分離されているか
自己参照対策同一リソースへの重複アクセスはパイプレイヤーで制御されているか
ツール呼び出しの原子性ツール実行は中途半端な状態(失敗時のロールバック)を起こさないか
エラーハンドリングツール呼び出し失敗時の復帰ロジックが明示的に実装されているか
監査ログすべてのツール呼び出しと結果がログに記録されているか
アクセス制御MCPサーバーへの接続は認証・暗号化されているか

実装例: Claude CodeでのMCP活用ケース

ケース1: 社内APIの標準化された統合

複数の社内マイクロサービス(ユーザー管理、請求、ログ分析)をClaude Codeから統一インターフェースでアクセスする例:

// mcp-server.js: MCPサーバーの実装
const express = require('express');
const app = express();

// ツール: ユーザー検索
const tools = {
  search_user: {
    name: "search_user",
    description: "ユーザーデータベースから指定条件で検索",
    inputSchema: {
      type: "object",
      properties: {
        email: { type: "string" },
        status: { type: "string", enum: ["active", "inactive", "suspended"] }
      },
      required: ["email"]
    },
    handler: async (input) => {
      // 社内APIを呼び出し
      const response = await fetch('http://user-service.internal/api/search', {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${process.env.SERVICE_TOKEN}` },
        body: JSON.stringify(input)
      });
      return response.json();
    }
  },
  
  get_billing_info: {
    name: "get_billing_info",
    description: "ユーザーの請求情報を取得",
    inputSchema: {
      type: "object",
      properties: {
        user_id: { type: "string" }
      },
      required: ["user_id"]
    },
    handler: async (input) => {
      const response = await fetch(`http://billing-service.internal/api/users/${input.user_id}`, {
        headers: { 'Authorization': `Bearer ${process.env.SERVICE_TOKEN}` }
      });
      return response.json();
    }
  }
};

// MCPエンドポイント
app.get('/tools', (req, res) => {
  res.json(Object.values(tools).map(t => ({
    name: t.name,
    description: t.description,
    inputSchema: t.inputSchema
  })));
});

app.post('/tools/:name/call', async (req, res) => {
  const tool = tools[req.params.name];
  if (!tool) {
    return res.status(404).json({ error: 'Tool not found' });
  }
  
  try {
    const result = await tool.handler(req.body);
    res.json(result);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000, () => console.log('MCP Server running on port 3000'));

Claude Codeでこのサーバーを使用:

# Claude設定ファイルに登録
cat >> claude-config.json << 'EOF'
{
  "mcp_servers": [
    {
      "name": "company_services",
      "url": "http://localhost:3000",
      "auth": { "type": "none" }
    }
  ]
}
EOF

# Claude Codeを起動
claude-code --config claude-config.json

Claude Code内でのプロンプト例:

ユーザー alice@example.com の請求状況を確認してください。
以下の手順で進めてください:
1. search_user ツールで alice@example.com を検索
2. 返ってきたユーザーIDを使用して get_billing_info を呼び出し
3. 結果をまとめてレポートしてください

Claude Codeは以下のステップを自動実行します。

ケース2: ChatGPT APIを使った多段階ワークフロー

データ分析・可視化のワークフローをMCP統合で実現:

from openai import OpenAI
import json
import subprocess

client = OpenAI(api_key="your-api-key")

# ステップ1: MCPサーバーを起動
subprocess.Popen([
    "node", "mcp-data-tools.js",
    "--port", "3001"
])

# ステップ2: MCPから利用可能なツール取得
import requests
mcp_response = requests.get("http://localhost:3001/tools")
mcp_tools = mcp_response.json()

openai_tools = [
    {
        "type": "function",
        "function": {
            "name": tool["name"],
            "description": tool["description"],
            "parameters": tool["inputSchema"]
        }
    }
    for tool in mcp_tools
]

# ステップ3: OpenAI Assistantを作成
assistant = client.beta.assistants.create(
    name="Data Analysis Assistant",
    model="gpt-4",
    tools=openai_tools
)

# ステップ4: 会話スレッド開始
thread = client.beta.threads.create()

# ステップ5: タスク実行
messages = [
    "過去30日間の売上データを取得して、グラフを作成してください"
]

for user_message in messages:
    client.beta.threads.messages.create(
        thread_id=thread.id,
        role="user",
        content=user_message
    )
    
    # 実行とツール呼び出しループ
    run = client.beta.threads.runs.create(
        thread_id=thread.id,
        assistant_id=assistant.id
    )
    
    import time
    while True:
        run = client.beta.threads.runs.retrieve(
            thread_id=thread.id,
            run_id=run.id
        )
        
        if run.status == "completed":
            break
        elif run.status == "requires_action":
            # ツール呼び出し処理
            tool_calls = run.required_action.submit_tool_outputs.tool_calls
            tool_outputs = []
            
            for tool_call in tool_calls:
                # MCPサーバーにツール呼び出しを委譲
                tool_result = requests.post(
                    f"http://localhost:3001/tools/{tool_call.function.name}/call",
                    json=json.loads(tool_call.function.arguments)
                ).json()
                
                tool_outputs.append({
                    "tool_call_id": tool_call.id,
                    "output": json.dumps(tool_result)
                })
            
            run = client.beta.threads.runs.submit_tool_outputs(
                thread_id=thread.id,
                run_id=run.id,
                tool_outputs=tool_outputs
            )
        
        time.sleep(1)

MCPの標準化による今後の展開

2026年のAIコーディング環境での役割

MCPは単なる技術仕様ではなく、業界全体での「ツール連携の民主化」を推し進めています。

  • エコシステムの統一: 複数のLLMプラットフォーム間でのツール資産の再利用が容易に
  • ベストプラクティスの共有: パイプレイヤーアーキテクチャなど、設計パターンの業界標準化
  • 開発効率の向上: 同じツール連携ロジックを複数プロジェクトで流用可能

今から準備すべきこと

MCPを組織に導入する際は、以下の準備が効果的です:

  1. 既存ツール連携の棚卸し: 現在使用している各種API・ツールをリスト化
  2. MCP対応の優先順位付け: ビジネスインパクトが大きい順に対応予定を立てる
  3. チーム教育: パイプレイヤーアーキテクチャの考え方をエンジニアチーム全体で共有

つまずきやすいポイントと解決策

問題1: MCPサーバーの認証設定でエラーが出る

現象: MCPサーバーに接続時に「401 Unauthorized」が返される

原因: 環境変数の設定漏れ、またはトークン形式の誤り

解決方法:

# 環境変数を確認
echo $MCP_API_TOKEN

# 設定が空の場合、以下を実行
export MCP_API_TOKEN="your-actual-token"

# Claude Codeを再起動
ps aux | grep claude-code | grep -v grep | awk '{print $2}' | xargs kill
claude-code --config claude-config.json

問題2: ChatGPT APIでツール呼び出しが実行されない

現象: OpenAI Assistantが「requires_action」ステータスに進まない

原因: toolsパラメータが正しい形式でないか、モデルがツール対応していない

解決方法:

# 正しい形式で定義
tools = [
    {
        "type": "function",  # 絶対必須
        "function": {
            "name": "tool_name",
            "description": "説明文",
            "parameters": {
                "type": "object",
                "properties": {...},
                "required": [...]
            }
        }
    }
]

# モデルを gpt-4 以降に指定
assistant = client.beta.assistants.create(
    model="gpt-4",  # gpt-3.5-turbo は未対応
    tools=tools
)

問題3: MCPサーバー上のツール定義と実装が不一致

現象: LLMはツール呼び出しを試みるが、実行時にエラー

原因: inputSchemaと実装の関数シグネチャがズレている

解決方法: スキーマ検証テストを実装

// mcp-server.js
app.post('/tools/:name/call', async (req, res) => {
  const tool = tools[req.params.name];
  const inputSchema = tool.inputSchema;
  
  // JSONスキーマ検証
  const Ajv = require('ajv');
  const ajv = new Ajv();
  const validate = ajv.compile(inputSchema);
  
  if (!validate(req.body)) {
    return res.status(400).json({
      error: "Invalid input",
      details: validate.errors
    });
  }
  
  // 以降の処理...
});

まとめ

Model Context Protocolは、Claude Code、ChatGPT API、その他のLLMプラットフォーム間での「ツール連携の標準化」を実現する技術です。2026年時点では、実務レベルでの導入が急速に進んでいます。

MCPを効果的に活用するポイント:

  1. パイプレイヤーアーキテクチャを理解する: LLMの指示に頼るのではなく、設計時点で制御を組み込む
  2. エージェントと知識ベースを分離する: 構造的にエラーを防ぐ
  3. 標準仕様に従う: 複数LLM間での資産再利用を実現

これらを実践することで、スケーラブルで堅牢なAIエージェントシステムを構築できます。


あわせて読みたい

参考ソース