Contents
1. MCP とは何か
MCP は LLM(大規模言語モデル)と外部システムを統一インタフェースで結ぶことを目的としたプロトコルです。以下の 3 つのコンポーネントから構成されます。
| コンポーネント | 主な役割 |
|---|---|
| Context Engine | ユーザー発話・対話履歴・外部データを統合し、プロンプト生成用の「コンテキスト」オブジェクトを作成 |
| Model Registry | 複数モデル(GPT‑4 系列、Claude 系列、LLaMA 系列など)とそのエンドポイント情報・認証情報を一元管理 |
| Transport Layer | HTTP/2 や gRPC での通信を抽象化し、TLS による暗号化や API キーの自動注入を標準化 |
ポイント
- 「コンテキスト駆動」設計により、リクエストごとに個別実装が必要だった認証・フォーマット統一問題を解消。
- 各層は独立したマイクロサービスとしてデプロイできるため、スケールアウトや障害切り分けが容易。
2. MCP の設計原則とメリット
| 設計原則 | 内容 | 期待される効果 |
|---|---|---|
| モジュラリティ | コンポーネントは Docker イメージとして提供し、Compose / Kubernetes で組み合わせ可能 | 再利用性・テスト容易性 |
| 宣言的設定 | YAML/JSON にすべてのパラメータを記述し、CI/CD パイプラインで差分管理 | 環境間の齟齬削減 |
| 安全な通信 | Transport Layer で TLS 必須化、シークレットは Kubernetes Secret / AWS Secrets Manager に保存 | データ漏洩リスク低減 |
| マルチモデル対応 | Model Registry がモデルごとのエンドポイントとパラメータを保持し、リクエスト時に動的に切り替え | コスト最適化・ベンダーロック回避 |
3. 実装例 ― Docker Compose を用いたローカル環境構築
以下は 公式サンプル(SIOS Tech Lab)を元にした、最低限の構成です。Docker Desktop の最新版と docker compose がインストールされている前提です。
3.1 ディレクトリ構成
|
1 2 3 4 5 6 |
mcp-demo/ ├─ docker-compose.yml ├─ .env # API キー等のシークレット ├─ mcp-config.yaml # MCP 全体設定 └─ README.md |
3.2 docker‑compose.yml
|
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 |
services: context-engine: image: sios/mcp-context:latest container_name: mcp_context networks: [mcp-net] env_file: .env model-registry: image: sios/mcp-registry:latest container_name: mcp_registry networks: [mcp-net] env_file: .env transport-proxy: image: sios/mcp-transport:latest container_name: mcp_transport networks: [mcp-net] ports: ["8080:8080"] healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 5s retries: 3 networks: mcp-net: driver: bridge |
注記
-latestタグは公式リポジトリが提供する最新版イメージを指します。安定版を利用したい場合はバージョンタグ(例:v2.3.1)に置き換えてください。
3.3 MCP 設定ファイル mcp-config.yaml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
context: ttl: 3600 # コンテキスト保持時間(秒) maxTokens: 4096 registry: models: - name: gpt-4.1 endpoint: https://api.openai.com/v1/chat/completions apiKeyEnv: OPENAI_API_KEY - name: claude-2 endpoint: https://api.anthropic.com/v1/complete apiKeyEnv: ANTHROPIC_API_KEY transport: protocol: grpc # http2 / grpc のいずれかを選択可能 tls: enabled: true certPath: /certs/server.crt keyPath: /certs/server.key |
3.4 シークレット .env(例)
|
1 2 3 |
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx ANTHROPIC_API_KEY=ak-xxxxxxxxxxxxxxxxxxxx |
安全対策
- 本番環境では.envファイルをリポジトリにコミットしません。代わりにdocker secretかクラウドのシークレット管理サービスを利用してください。
3.5 起動手順
|
1 2 3 4 5 6 |
# 1️⃣ ネットワーク作成とコンテナ起動 docker compose up -d # 2️⃣ ヘルスチェックが通ることを確認 docker compose ps # status が "healthy" であること |
4. 開発環境のセットアップ(公式サンプルインストール)
| 項目 | 推奨バージョン(執筆時点) | インストール例 |
|---|---|---|
| Docker Desktop | 最新版(2026 年 4 月リリース) | https://www.docker.com/products/docker-desktop |
| Python | 3.12 系列 | brew install python@3.12 (macOS) / winget install Python.Python.3.12 (Windows) |
| Node.js | 20 系列(LTS) | brew install node@20 / winget install OpenJS.NodeJS.LTS |
| Poetry (Python パッケージ管理) | 最新版 | pip install poetry |
4.1 リポジトリ取得と依存関係インストール
|
1 2 3 4 5 6 7 8 9 |
git clone https://github.com/sios-tech/mcp-sample-agent.git cd mcp-sample-agent # Python 環境構築(Poetry) poetry install # Node.js (optional) npm ci |
出典: SIOS Tech Lab が提供するサンプルリポジトリは 2025‑12‑01 に最終更新されています【[2]】。
4.2 ローカルでの動作確認
|
1 2 3 4 5 |
docker compose up -d # 前節の docker-compose.yml を利用 curl -X POST http://localhost:8080/v1/context \ -H "Content-Type: application/json" \ -d '{"user":"Alice","message":"箱に赤い玉を入れて"}' |
contextId と生成テキストが返ってくれば、MCP サーバーは正常に稼働しています。
5. クライアント実装と外部サービス連携
5.1 MCP リクエストフォーマット(JSON Schema)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MCPRequest", "type": "object", "properties": { "contextId": { "type": "string" }, "model": { "type": "string", "enum": ["gpt-4.1","claude-2"] }, "prompt": { "type": "string" }, "parameters": { "type": "object", "properties": { "maxTokens": { "type": "integer", "minimum": 1 }, "temperature":{ "type": "number", "minimum": 0, "maximum": 2 } }, "required": ["maxTokens"] } }, "required": ["contextId","model","prompt"] } |
MCP サーバーは受信したリクエストを上記スキーマで検証し、違反があれば 400 Bad Request を返します。
5.2 Python クライアント例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import os, httpx, json BASE_URL = "http://localhost:8080/v1" def call_mcp(context_id: str, model: str, prompt: str): payload = { "contextId": context_id, "model": model, "prompt": prompt, "parameters": {"maxTokens": 1024, "temperature": 0.7}, } resp = httpx.post(f"{BASE_URL}/completion", json=payload, timeout=10) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"] # 使用例 if __name__ == "__main__": cid = "example-context-id" print(call_mcp(cid, "gpt-4.1", "箱に青い玉を入れて")) |
5.3 外部データ取得パターン
a. Google スプレッドシート
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
from google.oauth2.service_account import Credentials from googleapiclient.discovery import build SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"] creds = Credentials.from_service_account_file("service-account.json", scopes=SCOPES) svc = build('sheets', 'v4', credentials=creds) def fetch_sheet(sheet_id: str, range_name: str): result = svc.spreadsheets().values().get( spreadsheetId=sheet_id, range=range_name ).execute() return result.get("values", []) rows = fetch_sheet("1AbC...XYZ", "Sheet1!A:B") # rows をプロンプト生成に組み込む例 prompt = f"以下は在庫情報です。{rows}\n次の発注候補を教えて" |
b. REST API からの取得
|
1 2 3 4 5 6 7 8 |
def get_inventory(): r = httpx.get("https://api.example.com/v1/inventory", timeout=5) r.raise_for_status() data = r.json() return f"在庫は {data['stock']} 個です。" prompt = get_inventory() + " 次に何をすべきか教えて" |
取得した外部データは Context Engine の externalData フィールドに格納し、モデル側で参照させます。
5.4 Qiita 記事から学ぶ実装パターン
Qiita に掲載された「玉の箱を管理するAIエージェント」では、フロントエンド(React)とバックエンド(FastAPI + MCP)を C/S 分離 させることで、以下の利点が得られています。
| 項目 | 内容 |
|---|---|
| UI/UX の独立性 | フロントは純粋に表示・入力だけを担当し、ビジネスロジックはすべてサーバ側に集約 |
| 二段階 AI 処理 | ユーザー要求 → Context Engine でプロンプト生成 → Model Registry が適切な LLM に委譲 → 生成結果を UI に返却【[1]】 |
6. テスト・デバッグ・本番デプロイのベストプラクティス
6.1 ローカルテスト(pytest / jest)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# tests/test_context.py (pytest) import pytest, httpx from app.main import create_app @pytest.fixture def client(): app = create_app() return httpx.AsyncClient(app=app, base_url="http://test") async def test_create_context(client): resp = await client.post("/v1/context", json={"user":"Bob","message":"リセット"}) assert resp.status_code == 200 assert "contextId" in resp.json() |
|
1 2 3 4 5 6 7 8 9 10 |
// tests/context.test.js (jest) const request = require('supertest'); const app = require('../src/app'); test('POST /v1/context returns contextId', async () => { const res = await request(app).post('/v1/context').send({user:'Bob',message:'リセット'}); expect(res.statusCode).toBe(200); expect(res.body).toHaveProperty('contextId'); }); |
6.2 よくあるエラーと対処法
| エラーコード | 発生条件 | 解決策 |
|---|---|---|
MCP-001 |
model.endpoint が無効な URL になっている |
正しい https:// スキーマのエンドポイントに修正 |
MCP-014 |
TLS 証明書が期限切れまたは自己署名で検証できない | 新しい証明書を /certs/ に配置し、コンテナ再起動 |
MCP-027 |
ttl が 0 以下に設定されている |
正の整数(例: 3600)へ変更 |
401 Unauthorized (LLM) |
環境変数に API キーが未設定または期限切れ | .env に正しいキーを書き、コンテナを再起動 |
6.3 本番環境へのデプロイ
a. Kubernetes(推奨シナリオ)
|
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 |
apiVersion: apps/v1 kind: Deployment metadata: name: mcp-context spec: replicas: 3 selector: matchLabels: {app: mcp-context} template: metadata: labels: {app: mcp-context} spec: containers: - name: context-engine image: sios/mcp-context:latest ports: [{containerPort: 8080}] envFrom: - secretRef: {name: mcp-secrets} --- apiVersion: v1 kind: Service metadata: name: mcp-context-svc spec: selector: {app: mcp-context} ports: - port: 80 targetPort: 8080 |
- 水平スケーリングは
HorizontalPodAutoscalerで CPU 使用率 >70% 時に自動拡張。 - モニタリングは Prometheus に
/metricsエンドポイントを公開し、Grafana ダッシュボードでrequest_latency_ms,error_rate,context_active_countを可視化。
b. Serverless(AWS Lambda + API Gateway)
- Docker イメージを ECR にプッシュ
- Lambda のコンテナイメージとしてデプロイ
- API Gateway がフロントエンドの入口に設定
| 項目 | Kubernetes | Serverless |
|---|---|---|
| スケール | HPA で手動/自動調整 | 完全自動(リクエスト単位) |
| コスト | 常駐リソース分だけ課金 | 実行時間に応じて従量課金 |
| デバッグ | kubectl logs が即時取得可能 |
CloudWatch Logs の遅延がある |
6.4 セキュリティの重要ポイント
- シークレット管理
- API キーは Kubernetes Secret または AWS Secrets Manager に格納し、Pod の環境変数として注入。
- TLS 強制化
- Transport Layer の
tls.enabled: trueを必ず有効にし、内部通信も暗号化。自己署名証明書は社内 CA で発行したものを使用。 - 最小権限の RBAC
- Context Engine と Model Registry は別々の ServiceAccount を作成し、必要なリソースへのアクセスのみ許可する。
7. まとめ
- MCP は「コンテキスト駆動」+「モジュラ設計」によって、LLM と外部システムの統合を標準化したプロトコルです。
- Docker Compose を用いたローカル構築から、Kubernetes / Serverless への本番デプロイまで、一貫した設定ファイルと CI/CD パイプラインで管理できます。
- テスト・モニタリング・セキュリティを組み込めば、AI エージェントは 信頼性の高いサービスとして運用可能です。
参考文献
-
Qiita 記事「玉の箱を管理する AI エージェント」
https://qiita.com/username/items/xxxxxxxxxxxx -
SIOS Tech Lab GitHub リポジトリ ― MCP サンプルエージェント
https://github.com/sios-tech/mcp-sample-agent -
Docker Official Documentation – Compose v2
https://docs.docker.com/compose/ -
Kubernetes Documentation – Horizontal Pod Autoscaler
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
本稿は執筆時点の情報に基づくものであり、将来のバージョンアップや製品リリースに伴う変更が生じた場合は公式ドキュメントをご参照ください。