MCP コンセプト : リソース / 実装サンプル

リソースは Model Context Protocol (MCP) の中核となるプリミティブで、サーバが (クライアントにより読み取られ、LLM インタラクション用にコンテクストとして使用できる) データとコンテンツを公開することを可能にします。

Model Context Protocol (MCP) : コンセプト : リソース / 実装サンプル

作成 : クラスキャット・セールスインフォメーション
作成日時 : 05/23/2025

* 本記事は github modelcontextprotocol の以下のページを独自に翻訳した上でまとめ直し、補足説明を加えています :

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス ⭐️ リニューアルしました 😉

クラスキャット は人工知能に関する各種サービスを提供しています。お気軽にご相談ください :

  • 人工知能導入個別相談会(無償)実施中! [詳細]

  • 人工知能研究開発支援 [詳細]
    1. 自社特有情報を含むチャットボット構築支援
    2. 画像認識 (医療系含む) / 画像生成

  • PoC(概念実証)を失敗させないための支援 [詳細]

お問合せ : 下記までお願いします。

  • クラスキャット セールス・インフォメーション
  • sales-info@classcat.com
  • ClassCatJP

 

 

Model Context Protocol (MCP) : コンセプト : リソース / 実装サンプル

サーバから LLM にデータとコンテンツを公開します。

Resources は Model Context Protocol (MCP) の中核となるプリミティブで、サーバが (クライアントにより読み取られ、LLM インタラクション用にコンテクストとして使用できる) データとコンテンツを公開することを可能にします。

Note : Resources は アプリケーションにより制御が可能 (application-controlled) なように設計されています、つまりクライアント・アプリケーションはどのようにいつそれらが使用される必要があるかを決定することができます。異なる MCP クライアントはリソースを異なる方法で処理する可能性があります。例えば :

  • Claude Desktop は現在、ユーザがリソースを (それらを使用する前に) 明示的に選択することを必要とします。

  • 他のクライアントはヒューリスティクスに基づいてリソースを自動的に選択するかもしれません。

  • ある実装は AI モデル自体がどのリソースを使用するか決定することを許容する場合があるかもしれません。

サーバ開発者は、リソースサポートを実装する場合、これらのインタラクション・パターンのいずれも処理できるように準備する必要があります。データをモデルに自動的に公開するためには、サーバ開発者は Tools のような モデルにより制御可能 (model-controlled) なプリミティブを使用する必要があります。

 

概要

Resources は、MCP サーバがクライアントに利用可能にしたいあるゆる種類のデータを表します。以下が含まれます :

  • ファイル・コンテンツ
  • データベース・レコード
  • API レスポンス
  • Live システムデータ
  • スクリーンショットと画像
  • ログファイル
  • その他

各リソースは一意な URI により識別され、テキストまたはバイナリデータのいずれかを含むことができます。

 

Resource URIs

Resources は次の形式に従う URI を使用して識別されます :

[protocol]://[host]/[path]

例えば :

  • file:///home/user/documents/report.pdf
  • postgres://database/customers/schema
  • screen://localhost/display1

プロトコルとパス構造は MCP サーバ実装により定義されます。サーバは独自のカスタム URI スキーマを定義できます。

 

リソース・タイプ

リソースは 2 つのタイプのコンテンツを含むことができます :

 

テキスト・リソース

テキスト・リソースは UTF-8 エンコードされたテキストデータを含みます。これらは以下に適しています :

  • ソースコード
  • 設定ファイル
  • ログファイル
  • JSON/XML データ
  • プレーンテキスト

 

バイナリ・リソース

バイナリ・リソースは base64 でエンコードされた raw バイナリ・データを含みます。これらは以下に適しています :

  • 画像
  • PDF
  • 音声ファイル
  • 動画ファイル
  • その他の非テキスト形式

 

リソースの検出 (discovery)

クライアントは 2 つの主要なメソッドを通して利用可能なリソースを検出できます :

 

直接 (Direct) リソース

サーバは resources/list エンドポイント経由で具体的なリソースのリストを公開します。各リソースは以下を含みます :

{
  uri: string;           // Unique identifier for the resource
  name: string;          // Human-readable name
  description?: string;  // Optional description
  mimeType?: string;     // Optional MIME type
}

 

リソース・テンプレート

動的リソースについては、サーバは、クライアントが使用して有効なリソース URI を構築できる、URI テンプレート を公開できます :

{
  uriTemplate: string;   // URI template following RFC 6570
  name: string;          // Human-readable name for this type
  description?: string;  // Optional description
  mimeType?: string;     // Optional MIME type for all matching resources
}

 

リソースの読み取り

リソースを読むには、クライアントはリソース URI を使用して resources/read リクエストを行います。

サーバはリソース・コンテンツのリストとともにレスポンスします。

{
  contents: [
    {
      uri: string;        // The URI of the resource
      mimeType?: string;  // Optional MIME type

      // One of:
      text?: string;      // For text resources
      blob?: string;      // For binary resources (base64 encoded)
    }
  ]
}

 

リソースの更新

MCP は 2 つのメカニズムを通してリソースのリアルタイム更新をサポートします :

 

リストの変更

サーバは、利用可能なリソースのリストが変更された場合、notifications/resources/list_changed 通知経由でクライアントに通知できます。

 

コンテンツの変更

クライアントは特定のリソース用に更新を subscribe できます :

  1. クライアントは resource URI を使用して resources/subscribe を送信します。

  2. サーバはリソースが変更されたとき notifications/resources/updated を送信します。

  3. クライアントは resources/read を使用して最新のコンテンツを取得 (fetch) できます。

  4. クライアントは resources/unsubscribe を使用して unsubscribe できます。

 

サンプル実装

MCP サーバにおけるリソース・サポートを実装する単純なサンプルがあります :

TypeScript

const server = new Server({
  name: "example-server",
  version: "1.0.0"
}, {
  capabilities: {
    resources: {}
  }
});

// List available resources
server.setRequestHandler(ListResourcesRequestSchema, async () => {
  return {
    resources: [
      {
        uri: "file:///logs/app.log",
        name: "Application Logs",
        mimeType: "text/plain"
      }
    ]
  };
});

// Read resource contents
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const uri = request.params.uri;

  if (uri === "file:///logs/app.log") {
    const logContents = await readLogFile();
    return {
      contents: [
        {
          uri,
          mimeType: "text/plain",
          text: logContents
        }
      ]
    };
  }

  throw new Error("Resource not found");
});

Python

app = Server("example-server")

@app.list_resources()
async def list_resources() -> list[types.Resource]:
    return [
        types.Resource(
            uri="file:///logs/app.log",
            name="Application Logs",
            mimeType="text/plain"
        )
    ]

@app.read_resource()
async def read_resource(uri: AnyUrl) -> str:
    if str(uri) == "file:///logs/app.log":
        log_contents = await read_log_file()
        return log_contents

    raise ValueError("Resource not found")

# Start server
async with stdio_server() as streams:
    await app.run(
        streams[0],
        streams[1],
        app.create_initialization_options()
    )

 

以上