Contents
基本概念と役割
MCP の目的
AI モデルが外部データベース・REST API・オブジェクトストレージなどのリソースへ、統一されたインターフェイス だけでアクセスできるようにする標準プロトコルです。従来はベンダーごとに認証方式やリクエスト形式がバラバラだったため、以下の問題がありました。
| 問題点 | 従来の状況 |
|---|---|
| 実装重複 | 各ツールで同じ DB 接続ロジックを個別に書く必要があった |
| 保守コスト増大 | 認証方式やエンドポイント変更時に全ツールを改修 |
| セキュリティリスク | クレデンシャルが散在し、管理が煩雑になる |
MCP はこれらを 「リクエスト‑レスポンス層」 と 「認可‑メタデータ層」 に分離することで解決します。
- リクエスト‑レスポンス層:JSON‑RPC 形式で「何を取得したいか」を宣言
- 認可‑メタデータ層:OAuth2・API キー・RBAC をサーバ側で一括管理
この二層構造により、AI エージェントは 「MCP に PostgreSQL のクエリを投げる」 だけで済み、接続文字列やドライバの選択はすべて MCP が内部で処理します。
Envader と Connector Hub の概要
Envader とは?
Envader は 「AI ツールと外部サービスを統合するプラットフォーム」 を提供するベンダーです。主に以下の機能を持ちます。
| 機能 | 説明 |
|---|---|
| Connector Hub | 複数のアダプタ(PostgreSQL、REST API、S3 など)を一元管理し、外部リソースへの接続ロジックを集中化 |
| MCP Server 連携 | Hub 上で動作する MCP インスタンスが認可・コンテキスト変換を担い、AI ツールは統一エンドポイントだけを呼び出す |
| スケーラビリティ支援 | Kubernetes の Horizontal Pod Autoscaler (HPA) と連携し、負荷に応じて自動拡張可能 |
Connector Hub とは?
Connector Hub は「接続のハブ」=全外部リソースへの入り口です。各アダプタは次のような構造で実装されます。
|
1 2 3 4 5 6 |
[AI Tool] ──► (MCP Request) ──► [Connector Hub] │ ├─ PostgreSQL Adapter ─────┘ ├─ REST API Adapter ──────── └─ S3 Object Storage Adapter |
- 統一エンドポイント:
POST /mcp/v1/contextにすべてのリクエストが集約されます。 - 認可・変換はサーバ側で完結:AI ツールは認証情報や DB の種類を意識しません。
この仕組みを採用することで、データフローの一本化 + 保守性向上 + スケーラビリティ確保 が実現します。
MCP サーバーのインストールと初期設定
1. デプロイ方式の比較
| 方法 | 主な利点 | 想定ユースケース |
|---|---|---|
| Docker Compose | 手軽にローカル・開発環境で起動可能。単一ファイルで完結 | 開発、デモ、CI の単体テスト |
| Kubernetes (Helm) | 本番向けの自動復旧・水平スケーリングが容易 | 大規模サービス、マルチテナント環境 |
Docker Compose 用 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 |
# docker-compose.yml version: "3.8" services: mcp-server: image: ghcr.io/mcp/protocol-server:latest container_name: mcp_server ports: - "8080:8080" environment: - MCP_LOG_LEVEL=info # DB 接続情報は環境変数で注入(例:docker compose の .env) - MCP_DB_URL=${MCP_DB_URL} volumes: - ./config/mcp.yaml:/app/config/mcp.yaml db: image: postgres:15-alpine environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - pgdata:/var/lib/postgresql/data volumes: pgdata: |
|
1 2 3 4 |
# デプロイ手順(Docker Compose v2 前提) docker compose up -d # コンテナ起動 curl -s http://localhost:8080/healthz # 200 が返れば OK |
Helm 用デプロイ例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# Helm リポジトリ追加 helm repo add mcp https://charts.mcp.io helm repo update # values.yaml(抜粋) cat > values.yaml <<'EOF' replicaCount: 3 image: tag: latest service: type: LoadBalancer env: MCP_LOG_LEVEL: info MCP_DB_URL: "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db-service:5432/${POSTGRES_DB}" configMap: mcpConfig: | adapters: postgres: dsn: ${MCP_DB_URL} EOF # デプロイ実行 helm install mcp-server mcp/protocol -f values.yaml |
2. 初期設定ファイル mcp.yaml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
adapters: postgres: type: sql driver: pgx dsn: ${MCP_DB_URL} restapi: type: http base_url: https://api.example.com/v1 auth: type: oauth2 token_endpoint: https://auth.example.com/token security: rbac: enabled: true policies: - role: admin resources: ["*"] actions: ["read", "write", "manage"] - role: analyst resources: ["postgres", "restapi"] actions: ["read"] |
ポイント
機密情報はすべて${ENV_VAR}形式で記述し、Docker/K8s の secret・.env ファイルから注入します。mcp.yamlに平文のパスワードを書かないことがベストプラクティスです。
AI ツール側からの MCP 接続例
1️⃣ Cursor(VS Code 互換エディタ)プラグイン
|
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 |
// cursor.extension.ts import * as vscode from 'vscode'; import axios from 'axios'; export function activate(context: vscode.ExtensionContext) { const disposable = vscode.commands.registerCommand('cursor.fetchCustomers', async () => { const payload = { jsonrpc: "2.0", method: "executeAdapter", params: { adapter: "postgres", query: "SELECT id, name FROM customers LIMIT 10" }, id: Date.now() }; try { const res = await axios.post('http://localhost:8080/v1/context', payload); vscode.window.showInformationMessage(`取得件数: ${res.data.result.length}`); } catch (e:any) { vscode.window.showErrorMessage(`MCP エラー: ${e.message}`); } }); context.subscriptions.push(disposable); } |
依存関係: axios と VS Code の拡張 API(vscode)だけで完結。認証情報は MCP 側の RBAC に委譲します。
2️⃣ ChatGPT プラグイン(OpenAI Functions)
Function 定義(JSON Schema)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "name": "query_customers", "description": "顧客テーブルから名前と ID を取得する", "parameters": { "type": "object", "properties": { "limit": { "type": "integer", "default": 5 } }, "required": [] } } |
Node.js バックエンド(Express)
|
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 |
// server.js import express from 'express'; import axios from 'axios'; const app = express(); app.use(express.json()); app.post('/openai/function/query_customers', async (req, res) => { const limit = req.body.arguments?.limit ?? 5; const payload = { jsonrpc: "2.0", method: "executeAdapter", params: { adapter: "postgres", query: `SELECT id, name FROM customers LIMIT ${limit}` }, id: Date.now() }; try { const mcpRes = await axios.post('http://mcp-server:8080/v1/context', payload); res.json({ result: mcpRes.data.result }); } catch (e:any) { res.status(500).json({ error: e.message }); } }); app.listen(3000, () => console.log('OpenAI function server listening on :3000')); |
3️⃣ 汎用的な DB・API・S3 接続設定例
| リソース | mcp.yaml の記述例 |
利用シーン |
|---|---|---|
| PostgreSQL | yaml<br>adapters:<br> postgres:<br> type: sql<br> driver: pgx<br> dsn: ${POSTGRES_DSN}<br> |
データ分析、レポート生成 |
| REST API | yaml<br>adapters:<br> restapi:<br> type: http<br> base_url: https://api.example.com/v1<br> auth:<br> type: apiKey<br> header_name: X-API-Key<br> value: ${API_KEY}<br> |
外部 SaaS のデータ取得 |
| AWS S3 | yaml<br>adapters:<br> s3:<br> type: object_storage<br> provider: aws<br> bucket: my-data-bucket<br> region: ap-northeast-1<br> credentials:<br> access_key_id: ${AWS_ACCESS_KEY_ID}<br> secret_access_key: ${AWS_SECRET_ACCESS_KEY}<br> |
大容量ファイルの保存・配布 |
設定手順
mcp.yamlに上記アダプタを追記。- 環境変数(
${API_KEY}など)は Docker/K8s の Secret として注入。 - AI ツールは adapter 名 と パラメータ を JSON‑RPC で送信するだけ。
認証・権限管理のベストプラクティス
推奨構成(mcp.yaml の抜粋)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
security: oauth2: providers: azure: token_endpoint: https://login.microsoftonline.com/${AZURE_TENANT}/oauth2/v2.0/token client_id: ${AZURE_CLIENT_ID} client_secret: ${AZURE_CLIENT_SECRET} scopes: ["mcp.read", "mcp.write"] api_keys: - name: analytics_key value: ${ANALYTICS_API_KEY} rbac: enabled: true policies: - role: admin resources: ["*"] actions: ["read","write","manage"] - role: analyst resources: ["postgres","s3"] actions: ["read"] |
主なポイント
| 項目 | 内容 |
|---|---|
| OAuth2 | 外部 IdP(Azure AD・Google)と連携し、アクセストークンの有効期限やスコープを一元管理。 |
| API キー | マシン間通信で軽量に認証でき、K8s の Secret に安全に格納。 |
| RBAC | ロールごとに アクセス可能なアダプタ と 実行可能な操作 を定義し、最小権限を徹底。 |
よくある認証エラーと対処法
| エラーメッセージ | 原因例 | 確認手順 |
|---|---|---|
401 Unauthorized – Invalid token |
トークン期限切れ、スコープ不足 | 1. JWT をデコードし exp と scope を確認 2. IdP のコンソールで再取得 |
403 Forbidden – RBAC policy violation |
ロールが対象アダプタにアクセス権を持たない | /admin/rbac/policies API で現在のポリシーを取得し、ロールとリソース名を照合 |
500 Internal Server Error – Missing API key |
環境変数未設定、Secret がマウントされていない | コンテナログに [SECURITY] プレフィックスが出力されるので確認 kubectl describe pod <pod> で Secret の状態をチェック |
デバッグ支援ツール
mcp-cli logs --tail– リアルタイムで認証エラーは[SECURITY]タグ付きで出力。- Postman / Insomnia – OAuth トークン取得フローや API キーの送信を手動テスト可能。
- Kubernetes Dashboard(Secrets ビュー) – 平文保存がないか視覚的に確認。
実装後のテスト・パフォーマンス測定
3 段階の検証フロー
- 統合テスト – AI ツールから MCP エンドポイントへリクエストし、ステータスコードと JSON スキーマが期待通りか確認。
- 負荷テスト –
k6で同時接続数・RPS を増やし、スループット・レイテンシを測定。 - モニタリング – Prometheus + Grafana で主要指標(latency, error rate, CPU/Memory)を可視化し、SLA 達成度をリアルタイム監視。
k6 スクリプト例
|
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 |
import http from 'k6/http'; import { check, sleep } from 'k6'; export const options = { stages: [ { duration: '30s', target: 50 }, // ランプアップ { duration: '2m', target: 200 }, // ステディステート { duration: '30s', target: 0 } // ランプダウン ], }; export default function () { const payload = JSON.stringify({ jsonrpc: "2.0", method: "executeAdapter", params: { adapter: "postgres", query: "SELECT COUNT(*) FROM orders" }, id: Date.now() }); const res = http.post('http://localhost:8080/v1/context', payload, { headers: { 'Content-Type': 'application/json' } }); check(res, { 'status is 200': (r) => r.status === 200, 'has result': (r) => JSON.parse(r.body).result !== undefined, }); sleep(1); } |
| 指標 | 推奨閾値(例) |
|---|---|
| 平均レスポンスタイム | < 150 ms |
| 95% パーセンタイルレイテンシ | < 300 ms |
| エラーレート | < 0.1 % |
| CPU 使用率 (MCP Server) | 70 % 未満(スケールアウトの目安) |
CI/CD への組み込み例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# .github/workflows/mcp-ci.yml name: MCP CI on: push: branches: [ main ] jobs: test-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Docker Compose run: docker compose up -d - name: Run integration tests run: | npm ci npm test # ここで統合テストを実行 - name: Deploy to Kubernetes (if tests pass) if: success() run: | helm upgrade --install mcp-server ./helm/mcp -f values.yaml |
📌 まとめ(全体の要点)
- MCP は AI と外部リソース間の統一インターフェイス を提供し、実装重複と保守コストを大幅に削減。
- Envader の Connector Hub が接続ロジックを集中管理し、Kubernetes 上で水平スケーリングが容易になる。
- デプロイは Docker Compose か Helm のどちらでも数ステップで完了し、
mcp.yamlにアダプタ・認可設定を一元化できる。 - AI ツール側の実装は JSON‑RPC 呼び出しだけ とシンプルに保ち、認証情報はサーバー側で管理。
- セキュリティは OAuth2 + API キー + RBAC の二層構造 がベストプラクティス。機密情報は必ず環境変数/K8s Secret 経由で注入すること。
- テスト・負荷測定・モニタリングを自動化 すれば、本番運用でも安定したレイテンシと低エラーレートが保証される。
これらの手順とベストプラクティスを踏むことで、AI アプリケーションは 安全かつ拡張性の高い外部データ連携基盤 を迅速に構築でき、ビジネス価値の向上につながります。