5 分で読めます

MCPサーバー実装ガイド——ツール・リソース・プロンプトの公開設計

自社のデータベースや社内ツールをAIエージェントに接続したい——そう考えたとき、最初に向き合うのがMCP(Model Context Protocol)サーバーの実装です。MCPは2024年11月にAnthropicが公開し、2025年にLinux Foundation傘下のAgentic AI Foundation(AAIF)へ移管されたオープンプロトコルです。LLMがツールを呼び出す仕組みの事実上の標準となりつつある一方、「3つのプリミティブの使い分け」「エラーハンドリングの2層設計」「transportの選択」の3点でつまずくエンジニアが多く見られます。

本記事はMCPサーバーを設計・実装するバックエンドエンジニア向けに、公式仕様(2025-11-25版)に基づいて整理したものです。エージェントガバナンスの実装基盤として位置づけており、Kuuのエージェントガバナンスアプローチと合わせて参照してください。

MCPの3プリミティブ——ツール・リソース・プロンプトの役割

MCPはTools・Resources・Promptsの3プリミティブをJSON-RPCで公開し、LLMが自律的に呼び出すmodel-controlled設計です。

MCPサーバーが公開できるのは3種類のプリミティブです。役割を混同すると、LLMに意図が正しく伝わりません。

| プリミティブ | 制御主体 | 主な用途 |
|---|---|---|
| Tools | LLM(model-controlled) | API呼び出し・DB操作・副作用を伴う実行 |
| Resources | クライアント(application-controlled) | ファイル・DBレコード・APIレスポンスのコンテキスト提供 |
| Prompts | ユーザー(user-controlled) | 引数付き再利用テンプレート・スラッシュコマンド |

Toolsは「実行して結果を返す」、Resourcesは「読み込ませるデータを提供する」、Promptsは「ユーザーが選んで使う定型テンプレート」と覚えると整理しやすいです。副作用(書き込み・外部API呼び出し等)はTools、参照データはResourcesという原則で設計します。

Toolsの実装——inputSchema設計とJSON-RPC

ToolsはinputSchemaで入力型を厳密に定義し、LLMが自律判断で呼び出すmodel-controlled実行モデルで動きます。

ツール定義の必須フィールドはnamedescriptioninputSchemaの3つです。descriptionはLLMがツールを選択する際の判断根拠になるため、「どんな状況で使うべきか」を含めた自然言語の説明が効果的です。

``json
{
"name": "search_products",
"description": "商品カタログを全文検索する。カテゴリ・価格帯で絞り込み可能。在庫確認や商品提案の際に使う。",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "検索クエリ" },
"category": { "type": "string", "enum": ["electronics", "clothing", "food"] },
"max_price":{ "type": "number" }
},
"required": ["query"]
}
}
``

TypeScript SDKではZodによる型定義がinputSchemaに自動変換されます。Python SDKのFastMCPはデコレータ形式で型アノテーションから同等の定義を生成します。requiredフィールドの漏れは、LLMが不完全な引数でツールを呼び出す直接原因になるため要注意です。

outputSchema(2025年仕様追加)

MCP仕様2025年版ではoutputSchemaフィールドが追加されました。構造化データを返すツールではoutputSchemastructuredContentを組み合わせることで、クライアント側の型検証が可能になります。後方互換のため、構造化レスポンスはTextContentにもJSONシリアライズして同梱するのが推奨です。

エラーハンドリングの2層設計

MCPのエラーはプロトコルエラー(JSON-RPCエラー応答)と実行エラー(isError: trueのtool result)の2層で分離され、処理経路が異なります。

MCPのエラー処理は必ず2層で設計します。混同すると、LLMが適切なリトライ判断をできなくなります。

第1層:プロトコルエラー(JSON-RPCエラー)

存在しないツール名の呼び出し・不正なJSON-RPCリクエスト・サーバー初期化失敗などを返します。HTTPの4xx/5xxに相当し、クライアントはリクエスト自体を再考すべきシグナルとして扱います。

``json
{
"jsonrpc": "2.0",
"id": 3,
"error": {
"code": -32602,
"message": "Unknown tool: invalid_tool_name"
}
}
``

第2層:ツール実行エラー(isError: true

外部APIのレート制限・DBコネクション失敗・業務ロジック上の不正入力は、HTTP 200でtool resultを返しながらisError: trueを付与します。LLMがエラー内容を読んでリトライや代替手段を検討できる設計です。

``json
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [{ "type": "text", "text": "在庫APIへの接続失敗: タイムアウト。30秒後に再試行してください。" }],
"isError": true
}
}
``

isError: truecontent.textにはリトライ可否と代替アクションを明示することがポイントです。LLMはこのメッセージを読んで次の行動を決定します。エラーメッセージが曖昧だと、LLMが同じ呼び出しを繰り返すループに陥ります。

ResourcesとPromptsの公開設計

ResourcesはURIで識別したデータをコンテキストとして提供し、Promptsは引数付きテンプレートをサーバーで管理します。

Resourcesの設計

ResourcesはURIで識別したデータをLLMのコンテキストに提供します。URIスキームはfile://(ファイル)・database://(DBレコード)・api://(外部APIレスポンス)など任意に定義できます。変更通知が必要なリソースはsubscribe/unsubscribeメソッドを実装し、更新時にnotifications/resources/updatedをプッシュするモデルが仕様標準です。テキスト・画像・バイナリのいずれも返却できますが、LLMへの提供はUTF-8テキストが基本です。

Promptsの設計

Promptsはスラッシュコマンドや選択UIと連動する再利用テンプレートです。引数定義を持ち、埋め込みリソースを含む構造化メッセージを返せます。社内向けMCPサーバーでは「週次レポート生成」「コードレビュー依頼」などをPromptsとして定義すると、ユーザーが一貫したフォーマットでエージェントを呼び出せます。ToolsとPromptsを混同すると、本来ユーザーが制御すべきフローをLLMが自律判断で実行するリスクが生じます。

transportの選択——stdioとStreamable HTTP

ローカル統合にはstdio、リモート接続にはStreamable HTTP(2025年3月導入)を使い、旧SSEは非推奨です。

MCPが定義するtransportは主に2種類です。

stdioはサーバーをサブプロセスとして起動し、stdin/stdoutでJSON-RPCメッセージを交換します。セットアップが最もシンプルで、ローカル開発・CI・単一クライアント接続に適しています。メッセージは改行区切りで、埋め込み改行を含んではならない制約があります。

Streamable HTTPは2025年3月の仕様更新で追加されたリモート接続向けtransportです。単一HTTPエンドポイントへのPOST/GETで双方向通信を行い、オプションでSSEによるストリーミングもサポートします。複数クライアントへの同時対応・認証・スケーリングが必要な本番環境ではStreamable HTTPが標準です。旧来のSSE transportは現行仕様で非推奨(deprecated)となっており、新規実装での使用は避けてください。

規模別の留意点(SMB / エンタープライズ)

SMB(中小企業)向け

社内ツールを最初の1〜2本MCPサーバーとして実装するケースでは、stdioで始めるのが最速です。FastMCP(Python)またはTypeScript SDKのMcpServerクラスを使えば、既存APIのラッパーを数十行で書けます。完璧な設計より「動くツールを1本」を優先し、エラーハンドリングは第2フェーズで厚くしていく段階的アプローチが現実的です。Kuuのエージェントガバナンス支援では実装コンサルティングも対応しています。

エンタープライズ向け

複数チームが独立したMCPサーバーを持つ場合、認証・認可の標準化が最初の壁です。MCP仕様はOAuth 2.0ベースの認証をサポートしており、スコープ付きトークンでツール呼び出しを制御できます。Streamable HTTP transport上でLLMゲートウェイと組み合わせることで、トークンコスト計装・レート制限・監査ログを一元管理できます。マルチテナント構成や大規模コンプライアンス対応についてはRDEサービスのエンタープライズ設計支援を参照してください。

参考

まとめ

MCPサーバーの実装で押さえるべきポイントは3点です。①Tools・Resources・Promptsの制御主体と用途を正しく区別する、②エラーをプロトコルエラーと実行エラー(isError: true)の2層で設計する、③transportはローカルにstdio・リモートにStreamable HTTPを選ぶ(旧SSEは使わない)。この設計判断を最初に固めることで、自社のAPIや社内ツールをAIエージェントが安全に利用できる接続基盤を構築できます。

MCPサーバーの設計・実装から本番運用まで一貫したサポートが必要な場合は、Kuuのエージェントガバナンス支援にご相談ください。

関連記事

A2AプロトコルとMCPの使い分け——認証・委譲設計の実装Model Context Protocol(MCP)とは?中小企業がAI連携を標準化できる理由プロンプトインジェクションをアーキテクチャで止める5層防御設計AIエージェントの人間監視設計——ヒューマン・イン・ザ・ループで「暴走」を防ぐ5つのパターン