資源

協議版本: 2024-11-05

模型上下文協議(MCP)為服務器向客戶端公開資源提供了標準化方式。資源允許服務器共享為語言模型提供上下文的數據,如文件、數據庫模式或應用程序特定信息。每個資源由URI唯一標識。

用戶交互模型

MCP 中的資源被設計為應用程序驅動,由宿主應用程序根據其需求決定如何合併上下文。

例如,應用程序可以:

  • 通過 UI 元素公開資源以供明確選擇,在樹或列表視圖中
  • 允許用戶搜索和過濾可用資源
  • 實現基於啟發式或 AI 模型選擇的自動上下文包含

資源上下文選擇器示例

然而,實現可以通過任何適合其需求的接口模式公開資源—協議本身不強制任何特定的用戶交互模型。

能力

支持資源的服務器必須聲明 resources 能力:

{
  "capabilities": {
    "resources": {
      "subscribe": true,
      "listChanged": true
    }
  }
}

該能力支持兩個可選功能:

  • subscribe:客戶端是否可以訂閱以接收有關單個資源更改的通知。
  • listChanged:服務器是否會在可用資源列表更改時發出通知。

subscribelistChanged 都是可選的—服務器可以不支持、支持其中之一或兩者都支持:

{
  "capabilities": {
    "resources": {} // 兩個功能都不支持
  }
}
{
  "capabilities": {
    "resources": {
      "subscribe": true // 僅支持訂閱
    }
  }
}
{
  "capabilities": {
    "resources": {
      "listChanged": true // 僅支持列表更改通知
    }
  }
}

協議消息

列出資源

要發現可用資源,客戶端發送 resources/list 請求。此操作支持分頁

請求:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "resources/list",
  "params": {
    "cursor": "可選的遊標值"
  }
}

響應:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resources": [
      {
        "uri": "file:///project/src/main.rs",
        "name": "main.rs",
        "description": "應用程序主入口點",
        "mimeType": "text/x-rust"
      }
    ],
    "nextCursor": "下一頁遊標"
  }
}

讀取資源

要檢索資源內容,客戶端發送 resources/read 請求:

請求:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "resources/read",
  "params": {
    "uri": "file:///project/src/main.rs"
  }
}

響應:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "contents": [
      {
        "uri": "file:///project/src/main.rs",
        "mimeType": "text/x-rust",
        "text": "fn main() {\n    println!(\"Hello world!\");\n}"
      }
    ]
  }
}

資源模板

資源模板允許服務器使用URI 模板公開參數化資源。參數可以通過補全 API自動補全。

請求:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "resources/templates/list"
}

響應:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "resourceTemplates": [
      {
        "uriTemplate": "file:///{path}",
        "name": "項目文件",
        "description": "訪問項目目錄中的文件",
        "mimeType": "application/octet-stream"
      }
    ]
  }
}

列表更改通知

當可用資源列表更改時,聲明瞭 listChanged 能力的服務器應該發送通知:

{
  "jsonrpc": "2.0",
  "method": "notifications/resources/list_changed"
}

訂閱

協議支持可選的資源更改訂閱。客戶端可以訂閱特定資源並在其更改時接收通知:

訂閱請求:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "resources/subscribe",
  "params": {
    "uri": "file:///project/src/main.rs"
  }
}

更新通知:

{
  "jsonrpc": "2.0",
  "method": "notifications/resources/updated",
  "params": {
    "uri": "file:///project/src/main.rs"
  }
}

消息流程

  sequenceDiagram
    participant Client
    participant Server

    Note over Client,Server: 資源發現
    Client->>Server: resources/list
    Server-->>Client: 資源列表

    Note over Client,Server: 資源訪問
    Client->>Server: resources/read
    Server-->>Client: 資源內容

    Note over Client,Server: 訂閱
    Client->>Server: resources/subscribe
    Server-->>Client: 訂閱確認

    Note over Client,Server: 更新
    Server--)Client: notifications/resources/updated
    Client->>Server: resources/read
    Server-->>Client: 更新的內容

數據類型

資源

資源定義包括:

  • uri:資源的唯一標識符
  • name:人類可讀名稱
  • description:可選描述
  • mimeType:可選 MIME 類型

資源內容

資源可以包含文本或二進制數據:

文本內容

{
  "uri": "file:///example.txt",
  "mimeType": "text/plain",
  "text": "資源內容"
}

二進制內容

{
  "uri": "file:///example.png",
  "mimeType": "image/png",
  "blob": "base64編碼數據"
}

常見 URI 方案

協議定義了幾種標準 URI 方案。此列表並非詳盡無遺—實現始終可以自由使用額外的自定義 URI 方案。

https://

用於表示在網絡上可用的資源。

服務器應該僅在客戶端能夠自行從網絡直接獲取和加載資源時使用此方案—也就是說,它不需要通過 MCP 服務器讀取資源。

對於其他用例,服務器應該優先使用另一個 URI 方案,或定義一個自定義方案,即使服務器自己將通過互聯網下載資源內容。

file://

用於標識表現為文件系統的資源。但是,資源不需要映射到實際的物理文件系統。

MCP 服務器可以使用XDG MIME 類型(如 inode/directory)標識 file:// 資源,以表示沒有標準 MIME 類型的非常規文件(如目錄)。

git://

Git 版本控制集成。

錯誤處理

服務器應該為常見的失敗情況返回標準 JSON-RPC 錯誤:

  • 未找到資源:-32002
  • 內部錯誤:-32603

錯誤示例:

{
  "jsonrpc": "2.0",
  "id": 5,
  "error": {
    "code": -32002,
    "message": "未找到資源",
    "data": {
      "uri": "file:///nonexistent.txt"
    }
  }
}

安全考慮

  1. 服務器必須驗證所有資源 URI
  2. 應該為敏感資源實現訪問控制
  3. 二進制數據必須被正確編碼
  4. 在操作前應該檢查資源權限