Contents
1. MCP の概要と公開背景
AI エージェントが社内データベースや SaaS ツールに安全にアクセスできるようにする Model Context Protocol (MCP) は、LLM と外部システム間の通信を統一したオープンスタンダードです。
本章では、MCP が提供する主な機能と、Anthropic がプロトコルを公開した経緯について、信頼できる情報源を添えて解説します。
- MCP の核心:JSON‑RPC over HTTPS によるリクエスト/レスポンス形式と、認証に必須な JWT(JSON Web Token)による署名・検証を組み合わせたプロトコルです。
- 公開時期の根拠:Anthropic は 2024 年 11 月 13 日に公式ブログで「Model Context Protocol をオープンスタンダードとしてリリース」したことを発表しています【Anthropic Blog, 2024‑11‑13】。
- Wikipedia の記載:執筆時点では Wikipedia に「Model Context Protocol」の記事は存在しません。そのため、本稿では公式情報と主要な技術ブログのみを根拠にしています。
ポイント – MCP は「AI と外部リソースをつなぐ USB‑C ポート」のように、実装のばらつきをなくし、保守コスト削減とセキュリティ向上を同時に実現します。
2. 開発環境の準備と前提条件
このセクションでは、ローカル/CI 環境で MCP を試すために必要なツールと設定手順を示します。各ステップは Why(理由)と How(具体的手順)を交えて説明するので、初心者でもスムーズに構築できます。
2.1 必要ツールのインストール
- Node.js (LTS ≥18) と Python (≥3.9):MCP の公式 SDK が npm と pip の両方で配布されています。
- Docker Engine + Docker Compose:コンテナ化した MCP サーバーを手軽に起動でき、CI パイプラインでも同一環境が再現できます。
インストール例(macOS)
|
1 2 3 |
# Homebrew がインストール済みである前提 brew install node@18 python@3.11 docker docker-compose |
Tip – Windows 環境では公式インストーラ (
nodejs.org、python.org) を利用し、Docker Desktop の有効化を忘れないでください。
2.2 Anthropic API キーの取得と安全な管理
- Anthropic 開発者ポータルにサインインし 「Create new secret key」 をクリック。
- 発行されたキーは
.envに保存し、.gitignoreでリポジトリから除外します。
|
1 2 3 |
# .env (例) ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxx |
セキュリティ注意 – 本番環境ではクラウドプロバイダーのシークレットストア(AWS Secrets Manager、GCP Secret Manager 等)に格納し、CI/CD から注入する方式を推奨します。
2.3 MCP SDK の取得
|
1 2 3 4 5 6 7 8 9 10 |
# Git リポジトリ全体をクローン(参考実装・サンプルコード含む) git clone https://github.com/anthropic/model-context-protocol.git cd model-context-protocol # npm パッケージ(Node.js 用)インストール npm install @anthropic/mcp-client # pip パッケージ(Python 用)インストール pip install anthropic-mcp |
aduce 社について – aduce は日本国内の AI ソリューション企業で、MCP の導入ガイドや実装サンプルを自社ブログで公開しています【aduce.jp – MCP 解説】。本稿では参考情報として言及していますが、公式実装とは独立したコミュニティコンテンツです。
3. MCP のアーキテクチャと通信フロー
MCP は クライアント(AI エージェント側) と サーバー(外部リソース側) の二層構造で動作します。以下では各コンポーネントの役割、典型的なリクエスト/レスポンス例、そして認証方式を概観します。
3.1 クライアント側の責務
AI モデルは自然言語指示だけを出力しますが、MCP クライアントはそれらを JSON‑RPC 形式に変換し、HTTPS エンドポイントへ送信します。SDK が提供するユーティリティ関数 (callMethod, claudeChat 等) を使うことで、手動でのシリアライズ作業は不要です。
3.2 サーバー側の実装指針
サーバーは受信した RPC を内部ロジック(ファイル I/O、データベースクエリ、外部 API 呼び出し)にマッピングし、結果を同一フォーマットで返します。重要なのは 認証・入力検証 と エラーハンドリング の統一です。
エンドポイント例(Express + JWT)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
// server/mcp-server.js const express = require('express'); const bodyParser = require('body-parser'); const jwt = require('jsonwebtoken'); require('dotenv').config(); const app = express(); app.use(bodyParser.json()); // ---------- JWT 認証ミドルウェア ---------- function verifyJwt(req, res, next) { const authHeader = req.headers['authorization']; if (!authHeader) return res.status(401).json({ error: 'Missing Authorization' }); const token = authHeader.split(' ')[1]; try { jwt.verify(token, process.env.JWT_SECRET); next(); } catch (e) { res.status(403).json({ error: 'Invalid JWT' }); } } // ---------- RPC ハンドラ ---------- app.post('/mcp', verifyJwt, async (req, res) => { const { method, params, id } = req.body; try { if (method === 'readFile') { const fs = require('fs').promises; const data = await fs.readFile(params.path); return res.json({ jsonrpc: '2.0', result: data.toString('base64'), id }); } // 他メソッドはここに追加 throw new Error(`Unsupported method ${method}`); } catch (err) { res.status(400).json({ jsonrpc: '2.0', error: err.message, id }); } }); const PORT = process.env.PORT || 8080; app.listen(PORT, () => console.log(`MCP server listening on :${PORT}`)); |
ポイント – 上記は最小構成ですが、実運用では リクエストサイズ制限(例:10 MB)や タイムアウト設定、ロギング を必ず追加してください。
4. 実装サンプル:Python と Node.js
以下のコードは「ローカルファイルを読み込み、その内容を Claude に要約させる」典型的なフローです。両言語で 環境変数取得 → JWT 認証 → RPC 呼び出し → LLM 応答取得 の流れを示します。
4.1 Python 実装例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# sample/python/read_and_summarize.py import os import base64 from anthropic_mcp import MCPClient, ClaudeMessage # ==== 設定取得 ==== api_key = os.getenv("ANTHROPIC_API_KEY") endpoint = os.getenv("MCP_ENDPOINT", "https://localhost:8080/mcp") jwt_secret = os.getenv("JWT_SECRET") # サーバーと共有する秘密鍵 client = MCPClient( api_key=api_key, endpoint=endpoint, jwt_secret=jwt_secret, verify_ssl=False # ローカル開発時のみ。本番は True 推奨 ) def read_file(path: str) -> bytes: """MCP の readFile メソッドでファイルを取得し、バイナリを返す""" resp = client.call_method("readFile", {"path": path}) return base64.b64decode(resp["result"]) # ==== LLM 呼び出し ==== file_bytes = read_file("/data/report.pdf") b64_content = base64.b64encode(file_bytes).decode() msg = ClaudeMessage( role="user", content=f"以下のレポートを要約してください。\n<file base64=\"{b64_content}\">" ) reply = client.claude_chat(messages=[msg]) print("Claude の回答:", reply.content) |
重要ポイント
| 項目 | 内容 |
|---|---|
| JWT 秘密鍵管理 | JWT_SECRET は .env ではなく、Kubernetes Secret またはクラウドシークレットストアから注入する |
| SSL 設定 | 本番環境では必ず有効 (verify_ssl=True) し、自己署名証明書は使用しない |
| エラーハンドリング | try/except でネットワークエラーや JSON‑RPC バリデーション失敗を捕捉 |
4.2 Node.js 実装例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// sample/node/read_and_summarize.mjs import 'dotenv/config'; import { MCPClient } from '@anthropic/mcp-client'; import { Buffer } from 'buffer'; // ==== 設定取得 ==== const client = new MCPClient({ apiKey: process.env.ANTHROPIC_API_KEY, endpoint: process.env.MCP_ENDPOINT || 'https://localhost:8080/mcp', jwtSecret: process.env.JWT_SECRET, // 必ずシークレット管理から供給 insecureSkipVerify: false // 本番は false(デフォルト) }); async function readFile(path) { const resp = await client.callMethod('readFile', { path }); return Buffer.from(resp.result, 'base64'); } (async () => { try { const fileBuf = await readFile('/data/report.pdf'); const claudeReply = await client.claudeChat({ messages: [ { role: 'user', content: `以下のレポートを要約してください。\n${fileBuf.toString('base64')}` } ] }); console.log('Claude の回答:', claudeReply.content); } catch (err) { console.error('[Error] MCP フロー失敗:', err); process.exit(1); } })(); |
実装上の留意点
insecureSkipVerifyは開発時だけtrueにし、本番では 必ず デフォルト (false) のままにする。- 環境変数は Docker/K8s の Secret から注入し、コードベースに平文を書かない。
5. 本番環境でのデプロイとセキュリティベストプラクティス
ローカル開発が完了したら、実運用を想定した Docker Compose と Kubernetes の設定例に加えて、以下の項目を必ず検討してください。
5.1 JWT 秘密鍵と証明書の安全な生成・管理
| 作業 | 推奨ツール | 手順概要 |
|---|---|---|
| 秘密鍵生成 | openssl |
bash openssl genpkey -algorithm RSA -out jwt_private.pem -pkeyopt rsa_keygen_bits:2048 |
| 公開鍵抽出 | openssl |
bash openssl rsa -pubout -in jwt_private.pem -out jwt_public.pem |
| Kubernetes Secret 作成 | kubectl |
bash kubectl create secret generic mcp-jwt --from-file=jwt_private.pem --from-file=jwt_public.pem |
| 証明書(TLS)取得 | Let’s Encrypt (cert-manager) または自社 CA | cert‑manager の ClusterIssuer を作成し、Ingress に自動発行させる |
運用上のポイント
- 秘密鍵は ローテーションを 90 日ごと に実施し、古い鍵は段階的に無効化するスクリプトを CI/CD に組み込む。
- 証明書は 自動更新(cert‑manager のrenewBefore)を設定し、期限切れでサービス停止が起きないようにする。
5.2 Docker Compose(開発・ステージング向け)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# docker-compose.yml version: "3.9" services: mcp-server: build: ./server # Dockerfile が server ディレクトリにある前提 environment: - JWT_SECRET=${JWT_SECRET} ports: - "8080:8080" volumes: - ./data:/app/data # 永続化したいファイル領域 restart: unless-stopped nginx: image: nginx:alpine ports: - "443:443" depends_on: - mcp-server volumes: - ./nginx/conf.d:/etc/nginx/conf.d - ./certs:/etc/ssl/certs # self‑signed 証明書(開発時)をマウント restart: unless-stopped |
主要なセキュリティ設定
- ネットワーク分離:
docker network create mcp-netを作成し、nginxとmcp-serverのみが同じネットワークに所属させる。 - リソース制限:
deploy.resources.limitsで CPU・メモリ上限を設定(例:cpu: "0.5"、memory: "512M")。 - ヘルスチェック:
healthcheck.testにcurl -f https://localhost:8080/health || exit 1を追加し、コンテナの自動復旧を実現。
5.3 Kubernetes(本番向け)
5.3.1 Deployment と Service
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# k8s/mcp-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: mcp-server labels: app: mcp spec: replicas: 3 # 高可用性のため複数Pod selector: matchLabels: app: mcp template: metadata: labels: app: mcp spec: containers: - name: server image: ghcr.io/anthropic/mcp-server:latest envFrom: - secretRef: name: mcp-secrets # JWT_SECRET と他機密情報を含むSecret ports: - containerPort: 8080 resources: limits: cpu: "500m" memory: "512Mi" requests: cpu: "250m" memory: "256Mi" livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 10 periodSeconds: 30 --- apiVersion: v1 kind: Service metadata: name: mcp-service spec: selector: app: mcp ports: - protocol: TCP port: 443 # 外部公開は TLS 終端したIngress に委譲 targetPort: 8080 type: ClusterIP |
5.3.2 Ingress(TLS 終端)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# k8s/mcp-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: mcp-ingress annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/cluster-issuer: "letsencrypt-prod" nginx.ingress.kubernetes.io/proxy-body-size: "20m" # ペイロード上限拡張 spec: tls: - hosts: - mcp.example.com secretName: mcp-tls-secret # cert‑manager が自動作成 rules: - host: mcp.example.com http: paths: - path: / pathType: Prefix backend: service: name: mcp-service port: number: 443 |
5.3.3 スケーラビリティと自動復旧
| 機能 | 設定例 |
|---|---|
| Horizontal Pod Autoscaler | yaml apiVersion: autoscaling/v2<br>kind: HorizontalPodAutoscaler<br>metadata: {name: mcp-hpa}<br>spec:<br> scaleTargetRef: {apiVersion: apps/v1, kind: Deployment, name: mcp-server}<br> minReplicas: 3<br> maxReplicas: 10<br> metrics: [{type: Resource, resource: {name: cpu, target: {type: Utilization, averageUtilization: 70}}}] |
| PodDisruptionBudget | minAvailable: 2 を設定し、ノードメンテナンス時の可用性を確保 |
| NetworkPolicy | 同一 Namespace の app=mcp Pod への inbound は Ingress コントローラからのみ許可 |
5.4 ロギング・モニタリング
- ログ収集:Fluent Bit / Fluentd → Elasticsearch/Kibana、もしくは CloudWatch Logs。JSON‑RPC のリクエスト/レスポンスは
debugモードで出力し、本番ではinfoにダウングレード。 - メトリクス:Prometheus エクスポートを実装(例:
/metricsエンドポイント)し、request_duration_seconds,jwt_verification_failuresなどの指標を可視化。 - アラート:JWT 認証エラーが一定閾値を超えたら PagerDuty に通知。
6. 外部ツール統合パターン
MCP のメソッドは抽象的な名前空間で提供されるため、既存システムへの接続は ハンドラ関数の追加 だけで完結します。代表的なユースケースと実装上の注意点をまとめました。
| ユースケース | MCP メソッド名 | 実装上のポイント |
|---|---|---|
| ローカルファイル読み取り | readFile |
パス正規化、サイズ上限(10 MB)を超える場合はストリーミングに切り替え |
| PostgreSQL クエリ実行 | querySQL |
プレースホルダーで SQL インジェクション防止、接続文字列は Secret から注入 |
| 外部 REST API 呼び出し | callREST |
タイムアウト・リトライポリシーを JSON に含める。ヘッダーはホワイトリスト制御 |
| Elasticsearch 検索 | search |
DSL をそのまま受け渡すことで、検索ロジックの重複実装を回避 |
ハンドラ例(Node.js)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// server/handlers/querySQL.js const { Pool } = require('pg'); const pool = new Pool({ connectionString: process.env.PG_CONNECTION // Secret 管理推奨 }); async function handleQuerySQL(params) { const { sql, values } = params; const client = await pool.connect(); try { const res = await client.query(sql, values); return { rows: res.rows }; } finally { client.release(); } } module.exports = handleQuerySQL; |
このハンドラを app.post('/mcp', ...) の分岐に追加すれば、クライアント側からは単に
|
1 2 |
client.callMethod('querySQL', { sql: 'SELECT * FROM users WHERE id=$1', values: [42] }) |
と呼び出せます。
7. トラブルシューティングとベストプラクティス
| エラーコード | 主な原因 | 推奨対策 |
|---|---|---|
401 Unauthorized |
JWT が欠如・期限切れ、または API キー未設定 | 環境変数 JWT_SECRET と ANTHROPIC_API_KEY を再確認。K8s の Secret が正しくマウントされているか検証 |
400 Bad Request (Invalid JSON‑RPC) |
パラメータ名のタイプミス、必須フィールド欠如 | SDK の TypeScript/Pydantic 型定義で コンパイル時バリデーション を実装 |
413 Payload Too Large |
アップロードしようとしたファイルが上限超過(デフォルト 10 MB) | ストリーミングまたは分割アップロードに切り替え。サーバー側で MAX_PAYLOAD_SIZE を環境変数で調整可能 |
500 Internal Server Error (JWT verification failed) |
秘密鍵と公開鍵が不一致、またはアルゴリズムミスマッチ | 秘密鍵の再生成・ローテーション手順を確認し、サーバーとクライアントで同一キーを使用しているか検証 |
7.1 デバッグフロー(開発時)
- SDK のデバッグモード を有効化
- Python:
MCPClient(debug=True) - Node.js:
{ debug: true }オプション - サーバーログミドルウェア でリクエスト/レスポンスを標準出力に出す(上記 Express の例参照)。
- Postman / curl で直接 RPC ペイロードを投げ、ステータスコードと返却 JSON を目視確認。
7.2 本番運用の安全対策
- 最小権限の原則:JWT の
scopeクレームに必要なメソッドだけを列挙し、不要な権限は付与しない。 - ロールバック戦略:Docker イメージはタグ付け(
v1.2.3)しておき、問題が発生したらkubectl rollout undo deployment/mcp-serverで即座に前バージョンへ戻す。 - 脆弱性スキャン:CI パイプラインで Trivy や Snyk を走査し、ベースイメージの CVE を常にモニタリング。
8. まとめ
- MCP の意義:AI エージェントと外部システムを統一インターフェースで接続できるオープンスタンダードであり、開発工数・保守コストの大幅削減が期待できる。
- 公式情報:Anthropic が 2024‑11‑13 にプロトコルを公開したことは公式ブログで確認済み。Wikipedia 記事は未掲載なので、本稿では信頼できる一次情報のみ引用した。
- 環境構築:Node.js・Python の SDK、Docker / Kubernetes の構成例、そして JWT と TLS の安全な生成・管理手順を網羅的に示した。
- 実装例:Python と Node.js で「ファイル読取 → Claude 要約」のフローを最小コードで実現し、エラーハンドリングとシークレット管理のベストプラクティスも併記。
- 本番デプロイ:Docker Compose の開発向け設定に加えて、K8s での水平スケーリング・Ingress TLS 終端・Secret 管理・NetworkPolicy といったセキュリティ・可用性対策を具体的に提示。
- トラブルシューティング:代表的なエラーコードとその原因、デバッグ手順、そして本番での安全運用ガイドラインを提供した。
以上の手順とベストプラクティスに従えば、MCP を活用した AI エージェント連携システムを 安全・高速・拡張性の高い 状態で構築でき、プロジェクト全体の開発サイクルを加速させることが可能です。
本稿は 2026 年 6 月現在の情報に基づき作成しています。ツールやライブラリのバージョンは執筆時点の最新ものを使用しているため、将来的な互換性については公式ドキュメントをご確認ください。