なぜカスタムMCPサーバーが必要なのか
MCP(Model Context Protocol)は、AIエージェントが外部ツールやデータソースと安全に接続するためのオープンプロトコルです。homulaは、エンタープライズ企業向けにAIエージェントの戦略策定・PoC・実装・運用・内製化までを一気通貫で支援するAIインテグレーターです。
2026年2月現在、10,000以上の公開MCPサーバーが稼働し、Slack・GitHub・Salesforce・Google Cloudなど主要SaaSベンダーが公式MCPサーバーを提供しています。しかしエンタープライズの現場では、SaaS接続だけでは要件を満たせないケースが必ず発生します。
具体的には、以下の3つの場面でカスタムMCPサーバーの構築が求められます。
- 社内APIの接続: 独自開発の基幹システム、ERPのカスタムモジュール、社内マイクロサービス群など、公開MCPサーバーが存在しないシステムとの連携
- レガシーDBの参照: オンプレミスのOracle/SQL ServerやメインフレームのDB2など、既存のデータ資産をAIエージェントに安全に公開する必要がある場合
- 独自認証が必要なシステム: SAML/LDAP連携、クライアント証明書認証(mTLS)、IP制限付きのイントラネットシステムなど、標準的なOAuth以外の認証が求められる場合
MCPサーバーの構築は、JSON-RPC 2.0ベースの仕様に則った実装であり、公式SDKを使えば数十行のコードから始められます。ただし本番運用に耐えるエンタープライズグレードの品質を実現するには、設計段階での判断が極めて重要です。
MCPサーバーの基本アーキテクチャ
MCPサーバーを構築する前に、プロトコルの基本構造を押さえておく必要があります。MCPは3つのプリミティブ(基本要素)で構成されています。
[AIエージェント / Host]
│
▼
[MCP Client] ── JSON-RPC 2.0 ── [MCP Server]
├─ Tools : AIが実行できるアクション(関数)
├─ Resources : AIが参照できるデータ(読み取り専用)
└─ Prompts : 再利用可能なプロンプトテンプレート
| プリミティブ | 役割 | 社内システム連携での用途例 |
|---|---|---|
| Tool | AIが実行するアクション(副作用あり) | 受注データの登録、承認ワークフローの起動、レポート生成 |
| Resource | AIが参照するデータ(読み取り専用) | 商品マスタの参照、在庫状況の取得、社内Wiki |
| Prompt | 定型のプロンプトテンプレート | 月次レポートの要約指示、問い合わせ対応テンプレート |
通信トランスポートは2種類あり、用途に応じて選択します。
| 方式 | プロトコル | 適用場面 | 特徴 |
|---|---|---|---|
| stdio | 標準入出力 | ローカル開発、IDE連携(Claude Desktop, Cursor等) | 低遅延だが単一クライアント限定 |
| Streamable HTTP | HTTPS | 本番運用、複数クライアント、リモートアクセス | スケーラブル。OAuth 2.1認証が必須 |
エンタープライズ用途では、開発時はstdioで迅速に検証し、本番ではStreamable HTTPでリモート公開する構成が標準的です。2025年後半にHTTP+SSE方式が非推奨となりStreamable HTTPに統合されたことで、リバースプロキシ配置もシンプルになりました。
実装ステップ:6段階で本番デプロイまで
Step 1: ツール定義 — 入出力スキーマの設計
MCPサーバー構築の最初の工程は、AIエージェントに「何をさせるか」を定義することです。ここでの設計品質が、エージェントの精度と安全性を左右します。
設計時に検討すべき観点は3つあります。
粒度の設計: ツールは「1つのアクションに対して1つのツール」が原則です。「受注の検索・作成・更新・削除」を1つのツールにまとめるのではなく、search_orders、create_order、update_order_status のように分割します。LLMがツールを正しく選択するためには、各ツールの責務が明確である必要があります。
スキーマの厳密さ: 入力パラメータにはJSON Schemaによる型定義と説明文を必ず付与します。TypeScript SDKではZodによるバリデーション、Python SDKでは型ヒントが自動的にスキーマへ変換されます。曖昧なパラメータ定義はLLMの誤呼び出しの原因になります。
Tool Annotationsの活用: 2025年11月の仕様で導入されたTool Annotationsにより、各ツールに readOnlyHint(読み取り専用)や destructiveHint(破壊的操作)といったメタ情報を付与できます。これによりクライアント側のUIが自動的に確認ダイアログを表示する等のガードレールが機能します。
Step 2: MCPサーバーのスケルトン生成
公式SDKを使い、最小構成のサーバーを立ち上げます。TypeScriptとPythonの2つのSDKが提供されており、2026年2月時点でいずれもv1.26.0が安定版です。
TypeScript SDK(@modelcontextprotocol/sdk)の場合:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "internal-order-api",
version: "1.0.0"
});
// ツールの登録
server.tool(
"search_orders",
"Search orders by customer ID or date range",
{
customer_id: z.string().optional().describe("Customer ID to filter"),
from_date: z.string().optional().describe("Start date (YYYY-MM-DD)"),
to_date: z.string().optional().describe("End date (YYYY-MM-DD)")
},
async ({ customer_id, from_date, to_date }) => {
// Step 3 で社内APIとの接続ロジックを実装
const results = await fetchOrdersFromInternalAPI({ customer_id, from_date, to_date });
return {
content: [{ type: "text", text: JSON.stringify(results) }]
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
Python SDK(FastMCP)の場合:
from mcp.server.fastmcp import FastMCP, Context
mcp = FastMCP("internal-order-api")
@mcp.tool()
def search_orders(
customer_id: str | None = None,
from_date: str | None = None,
to_date: str | None = None,
ctx: Context = None
) -> str:
"""Search orders by customer ID or date range."""
ctx.info(f"Searching orders: customer={customer_id}")
results = fetch_orders_from_internal_api(customer_id, from_date, to_date)
return json.dumps(results, ensure_ascii=False)
if __name__ == "__main__":
mcp.run(transport="stdio")
SDK選定の判断基準は明確です。社内にNode.js/TypeScriptのエコシステムがあればTypeScript SDK、Pythonベースのデータ基盤やML環境があればPython SDKを選択します。FastMCPはFastAPIに似たデコレータ記法で、Pythonエンジニアの学習コストが低い点が利点です。
TypeScript SDK v2が2026年Q1に安定版リリース予定です。現時点ではv1系(1.26.0)を使用し、v2リリース後に計画的に移行することを推奨します。Anthropicはv2安定化後もv1系のバグ修正を6ヶ月以上継続すると表明しています。
Step 3: 社内APIとの接続ロジック実装
スケルトンが動作したら、ツールのハンドラ内に社内システムとの接続ロジックを実装します。ここで重要なのは、MCPサーバーを「薄いアダプタ層」として設計することです。
MCPサーバーに複雑なビジネスロジックを持たせるべきではありません。MCPサーバーの責務は、LLMからのリクエストを社内APIの仕様に変換し、レスポンスをLLMが解釈しやすい形式に整形することに留めます。
[LLM] → [MCP Server(アダプタ層)] → [社内REST API / GraphQL / gRPC]
├─ リクエスト変換
├─ エラーハンドリング
└─ レスポンス整形
実装上のポイントは3つあります。
エラーハンドリングの標準化: 社内APIのエラーをMCPのエラーレスポンスに適切にマッピングします。HTTP 404は「該当データなし」のテキストレスポンスに変換し、HTTP 500はMCPのInternalError(コード-32603)として返します。LLMにスタックトレースを返してはいけません。
レスポンスの整形: 社内APIが返すJSONが巨大な場合、必要なフィールドだけを抽出してLLMに渡します。コンテキストウィンドウの浪費を防ぎ、LLMの判断精度を向上させるためです。
タイムアウトの設計: 社内APIのレスポンスが遅い場合を想定し、適切なタイムアウトを設定します。2025年11月仕様で追加されたTasksプリミティブ(非同期実行)を活用すれば、長時間処理の進捗をクライアントに通知しながら完了を待つことも可能です。
Step 4: 認証・認可の設計
エンタープライズにおける最大の設計判断が認証・認可です。MCPサーバーへの不正アクセスは、社内システム全体へのアクセスを意味するため、ここの設計は妥協できません。
2025年後半以降のMCP標準は、OAuth 2.1 + PKCE です。リモートMCPサーバーを公開する場合、以下の構成が推奨されます。
| 認証方式 | 適用場面 | 実装の複雑さ |
|---|---|---|
| OAuth 2.1 + PKCE | リモート公開、複数クライアント対応 | 高(IdP連携が必要) |
| APIキー(Bearer Token) | 社内限定、少数クライアント | 低(ただしトークンの安全管理が必須) |
| mTLS(相互TLS認証) | 閉域網内のマシン間通信 | 中(証明書管理の運用負荷) |
OAuth 2.1を採用する場合、MCP仕様が定める以下の3つの標準に対応する必要があります。
- 動的クライアント登録(DCR): ChatGPTやClaude Desktopなどのクライアントが初回接続時に自動的にクライアントIDを取得する仕組み
- 保護されたリソースメタデータ(PRM): RFC 9728に基づき、MCPサーバーがどの認可サーバーを使うべきかをクライアントに通知するエンドポイント
- PKCE: 認可コードの漏洩を防ぐために必須の拡張
社内のIdP(Azure AD、Okta、Keycloak等)をOAuth認可サーバーとして利用し、MCPサーバーをリソースサーバーとして構成するのが最もセキュアな設計です。
Step 5: テスト・デバッグ — MCP Inspectorの活用
MCPサーバーの動作検証には、公式デバッグツール MCP Inspector を使用します。
npx @modelcontextprotocol/inspector
MCP InspectorはブラウザベースのGUIを提供し、以下の検証が可能です。
- ツール一覧・リソース一覧の表示と、各定義のスキーマ確認
- 任意のパラメータを指定した手動ツール呼び出し
- JSON-RPCメッセージのリアルタイムトレース
- エラーレスポンスの確認とデバッグ
テスト工程で検証すべき項目は以下の通りです。
| テスト項目 | 確認内容 |
|---|---|
| 正常系 | 各ツールが期待通りの結果を返すか |
| 異常系 | 不正なパラメータ、APIダウン時のエラーハンドリング |
| 境界値 | 大量データのレスポンス、長い文字列入力 |
| 認証 | トークン期限切れ時の挙動、権限不足時のエラー |
| パフォーマンス | レスポンスタイム、同時接続数 |
IDE上での検証には、VS Code拡張の MCP: List Servers コマンドやClaude Codeの /doctor コマンドも活用できます。
Step 6: 本番デプロイ — Docker化と運用設計
本番環境へのデプロイでは、Docker化とStreamable HTTPトランスポートへの切り替えが標準的な構成です。
Dockerfileの例(Python FastMCPの場合):
FROM python:3.12-slim
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN pip install uv && uv sync --frozen
COPY src/ ./src/
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s \
CMD curl -f http://localhost:8080/health || exit 1
CMD ["uv", "run", "python", "-m", "src.server", "--transport", "streamable-http", "--port", "8080"]
本番運用で設計すべき項目は以下の5つです。
ヘルスチェック: /health エンドポイントを実装し、コンテナオーケストレーター(Kubernetes、ECS等)からの死活監視を受け付けます。社内API先への接続確認も含めたDeep Health Checkを推奨します。
ログ設計: ツール実行のリクエスト/レスポンス、実行時間、エラー詳細を構造化ログ(JSON形式)で出力します。将来的なガバナンス要件を見据え、「どのユーザーがどのツールをいつ実行したか」の監査証跡を残す設計が重要です。
Rate Limiting: 社内APIへの過負荷を防ぐため、MCPサーバー側でリクエストレートを制限します。特にLLMはツールを高頻度で連続呼び出しする場合があるため、バックエンドAPI側のRate Limitに合わせた制御が必要です。
HTTPS/TLS: リモート公開時はTLS終端を必ず実施します。Cloudflare OneやNginxリバースプロキシでのTLS終端が一般的です。MCP仕様が推奨するOriginヘッダの検証も忘れずに実装します。
バージョニング: MCPサーバーのツール定義を変更する際、既存クライアントとの互換性を維持する戦略が必要です。ツールの追加は後方互換ですが、既存ツールのスキーマ変更は破壊的変更となるため、サーバーバージョンの明示とクライアントへの通知が求められます。
Kubernetes上でのMCPサーバー運用には、kmcp CLIによるデプロイ管理やHelmチャートの活用が有効です。Postgres MCP Proの開発元はKubernetes用HelmチャートとHashiCorp Vault連携の構成例を公開しています。
エンタープライズでの注意点
本番運用に入る前に、情報セキュリティ部門と連携して以下のレビューを実施することを推奨します。
セキュリティレビューの主要チェック項目:
| 項目 | 確認内容 |
|---|---|
| データ分類 | MCPサーバー経由でAIに渡されるデータの機密区分は適切か |
| 最小権限の原則 | 社内APIへのアクセス権限はツールの責務に必要な最小限か |
| PII(個人情報)の取り扱い | 個人情報がLLMのコンテキストに含まれる場合の匿名化・マスキング |
| プロンプトインジェクション | ユーザー入力がツールパラメータに直接渡る場合のサニタイズ |
| 監査ログ | 5年保存要件等のコンプライアンス対応 |
| DLP連携 | 機密情報のLLMへの送信を検知・ブロックする仕組み |
Elicitation機能(サーバーからユーザーへの追加確認要求)を活用すれば、破壊的な操作の実行前に人間の承認を挟むワークフローを標準的な方法で実装できます。社内DBへの書き込み操作を伴うツールでは、この仕組みの導入を強く推奨します。
よくある質問
MCPサーバーの運用コストはどの程度か?
MCPサーバー自体は軽量なHTTPサーバーであり、コンピューティングコストは小さいです。AWS FargateやCloudflare Workersであれば月額数千円〜数万円程度で運用可能です。コストの大部分はMCPサーバーが呼び出す先の社内APIやLLM APIの利用料が占めます。サーバーレス構成(AWS Lambda + API Gateway等)を採用すればリクエスト数に応じた従量課金となり、コスト予測も容易になります。
既存のREST APIをMCPサーバー化するのは大変か?
公式SDKを使えば、既存のREST APIをラップする形で比較的短期間に構築できます。1つのAPIエンドポイントをMCPツールに変換する作業は、SDK選定済みであれば1-2時間程度です。ただし本番グレードの認証・エラーハンドリング・監査ログまで含めると、1つのMCPサーバー(5-10ツール規模)の構築に1-2週間を見込むのが現実的です。
MCPとOpenAPI(Swagger)の違いは何か?
OpenAPIはREST APIの仕様記述フォーマットであり、「APIの構造を文書化する」ことが主目的です。一方MCPは、AIエージェントが動的にツールを発見・実行するための「双方向通信プロトコル」です。MCPはJSON-RPC 2.0ベースで、ツール定義の取得からパラメータの検証、非同期実行、認証フローまでを一貫してプロトコル内で扱います。OpenAPIで定義されたAPIを「MCPサーバー化」するアプローチは相互補完的であり、両者は競合ではなく共存する関係です。
関連記事
- MCP対応ツール一覧【2026年最新版】 — 主要MCPサーバーの網羅的カタログ
- Slack × MCPで業務通知・ワークフローを自動化する方法 — Slack連携の具体例
- GitHub × MCPでコードレビュー・開発ワークフローを自動化する方法 — 開発プロセスの自動化
自社システムのMCPサーバー構築は、AIエージェントの業務活用を本格化させる上で避けて通れないステップです。homulaは、n8nやLangGraphとカスタムMCPサーバーを組み合わせた社内システム連携の設計・構築・運用までを一気通貫で支援しています。
関連記事: