MCPリソース管理(エムシーピーリソースカンリ)
MCPリソース管理とは、Model Context ProtocolにおけるResources機能を使い、MCPサーバーがファイル・データベースレコード・API応答などのデータソースをURIベースで公開し、LLMクライアントが構造化された方法でアクセスする仕組みである。
MCPリソース管理は、Model Context ProtocolのResourcesプリミティブを通じて、MCPサーバーが保有するデータソースをLLMクライアントに公開する機能である。ToolsがLLMの「手」(実行する能力)を提供するのに対し、Resourcesは「目」(情報を読み取る能力)を提供する。リソースはURIで一意に識別され、読み取り専用のデータアクセスを前提として設計されている。
リソースの基本構造
MCPリソースは以下の属性で定義される。
- uri: リソースの一意識別子。
file:///home/user/doc.md、postgres://localhost/mydb/users/123、screen://screenshotのようなURIスキームで表現する - name: 人間可読なリソース名。LLMとユーザーの両方が参照する
- description: リソースの内容と用途の説明(任意)
- mimeType: リソースのコンテンツタイプ。
text/plain、application/json、image/png等
リソースの内容はtext(UTF-8文字列)またはblob(base64エンコードバイナリ)で返却される。
静的リソースと動的リソース
MCPリソースには2つの提供方式がある。
直接リソース(Static Resources)
resources/listメソッドで返却される固定のリソース一覧。サーバー起動時に内容が決まっているファイルや設定情報など。
server.resource("config://app/settings", async () => ({
contents: [{
uri: "config://app/settings",
mimeType: "application/json",
text: JSON.stringify({ theme: "dark", language: "ja" }),
}],
}));
リソーステンプレート(Dynamic Resources)
URIテンプレートを使い、パラメータに応じて動的にリソースを生成する。RFC 6570準拠のテンプレート構文をサポート。
server.resourceTemplate(
"postgres://mydb/users/{userId}",
{ userId: { type: "string", description: "ユーザーID" } },
async ({ userId }) => ({
contents: [{
uri: `postgres://mydb/users/${userId}`,
mimeType: "application/json",
text: JSON.stringify(await db.query("SELECT * FROM users WHERE id = $1", [userId])),
}],
})
);
テンプレートにより、無限のリソースバリエーション(全ユーザーレコード、全ファイルパス等)をコンパクトに定義できる。
リソース vs ツール: 使い分け
| 特性 | Resources | Tools |
|---|---|---|
| 主目的 | データ読み取り | アクション実行 |
| 副作用 | なし(読み取り専用) | あり得る(書き込み・送信等) |
| 呼び出し主体 | アプリケーション(ホスト)が自動読み込み | LLMがモデル判断で呼び出し |
| ユーザー承認 | 不要(読み取りのため) | 推奨(副作用のあるツール) |
| 用途例 | 設定ファイル参照、DBスキーマ閲覧、ログ表示 | メール送信、ファイル作成、API実行 |
重要な違いは呼び出し主体である。ResourcesはホストアプリケーションがUIを通じてユーザーに提示し、ユーザーの選択でLLMのコンテキストに含める。一方ToolsはLLMが自律的に「このツールを呼ぶべきだ」と判断して呼び出す。
リソースの購読(Subscription)
MCPリソースは変更通知の仕組みを提供する。クライアントがresources/subscribeで特定のURIを購読すると、リソース内容が変更された際にサーバーがnotifications/resources/updated通知を送信する。
// 購読リクエスト
{"jsonrpc": "2.0", "id": 5, "method": "resources/subscribe", "params": {"uri": "file:///logs/app.log"}}
// 変更通知
{"jsonrpc": "2.0", "method": "notifications/resources/updated", "params": {"uri": "file:///logs/app.log"}}
クライアントは通知を受けてresources/readで最新内容を取得する。リアルタイムログ監視やダッシュボードデータの自動更新に有用である。
リソースURIスキーム一覧
| スキーム | 用途 | 例 |
|---|---|---|
file:// | ローカルファイル | file:///home/user/project/README.md |
postgres:// | PostgreSQLデータ | postgres://localhost/mydb/users |
screen:// | スクリーンキャプチャ | screen://primary/screenshot |
config:// | アプリ設定 | config://app/settings |
git:// | Gitリポジトリ情報 | git://repo/commits/latest |
env:// | 環境変数 | env://NODE_ENV |
https:// | Web APIレスポンス | https://api.example.com/status |
スキームはカスタム定義可能で、サーバーが独自のURIスキームを設計してドメイン固有のリソースを表現できる。
Embedding(埋め込みリソース)
ツール呼び出しの結果にリソースを埋め込む機能もサポートされている。ツールの実行結果が大量のデータを含む場合、テキスト全文ではなくリソースURIへの参照を返すことで、コンテキストウィンドウの効率的な利用が可能になる。
{
"content": [
{ "type": "text", "text": "クエリ結果:" },
{ "type": "resource", "resource": { "uri": "postgres://mydb/query-results/abc123", "mimeType": "application/json" } }
]
}
よくある質問(FAQ)
Q1: リソースとRAG(Retrieval-Augmented Generation)の違いは? A: RAGは非構造化データを埋め込みベクトルで検索・取得する手法であり、MCPリソースはURIベースの構造化アクセスを提供する。両者は競合ではなく補完関係にある。MCPリソースでベクトルDBの検索結果を公開し、RAGパイプラインの一部としてMCPサーバーを活用する設計も一般的である。
Q2: リソースのアクセス制御はどう実現しますか? A: MCPプロトコル自体にはリソースレベルのACL機能はないが、サーバー実装側でリソースごとにアクセス制御を実装できる。OAuth 2.1認証で取得したユーザー情報に基づき、リソース一覧のフィルタリングやリソース内容のスコープ制限を行うのが一般的なパターンである。
Q3: バイナリファイル(画像・PDF)もリソースとして提供できますか?
A: できる。リソース内容をbase64エンコードしたblobフィールドで返却する。mimeTypeにimage/pngやapplication/pdfを指定すれば、ホスト側が適切にレンダリングする。大きなバイナリファイルはコンテキストウィンドウを圧迫するため、サムネイル生成やメタデータ抽出をツールで行い、結果をリソースとして公開するハイブリッド設計が推奨される。
まとめ
- MCPリソースはURIベースで外部データを読み取り専用で公開する仕組み
- 静的リソース(固定URI)と動的テンプレート(パラメータ付きURI)の2方式
- Toolsが「実行する能力」ならResourcesは「参照する能力」を提供
- 購読(Subscribe)で変更通知を受けてリアルタイム更新が可能
- カスタムURIスキームでドメイン固有のデータソースを自在に表現