> ## Documentation Index
> Fetch the complete documentation index at: https://learn.orbexa.io/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP资源与提示词深入使用指南

> MCP Resources资源与Prompts提示词深入使用指南，系统讲解RFC 6570 URI模板设计方法、Annotations元数据标注与audience优先级设定、资源变更订阅通知机制。涵盖提示词参数化模板定义与嵌套资源引用技术，帮助开发者为AI应用提供结构化上下文数据

# 资源与提示词

## 6.1 Resources（资源）详解

Resources让Server向AI应用暴露数据。和Tools的区别：

|         | Tools          | Resources    |
| ------- | -------------- | ------------ |
| **性质**  | 执行操作           | 提供数据         |
| **控制方** | AI模型决定调用       | 应用（Host）主动读取 |
| **副作用** | 可能有（写数据库、调API） | 无（只读）        |
| **场景**  | "帮我查库存"        | "这是商品分类结构"   |

### 资源URI

每个资源有唯一的URI标识：

```
commerce://catalog/categories     # 商品分类
commerce://store/info             # 店铺信息
file:///path/to/config.json       # 本地文件
https://api.example.com/data      # 远程数据
```

### URI模板（RFC 6570）

MCP支持RFC 6570 URI模板语法，用于定义动态资源。Server在 `resources/list` 返回中可以包含URI模板，Client通过模板变量填充来请求具体资源：

```json theme={null}
{
  "uriTemplate": "commerce://products/{sku}",
  "name": "商品详情",
  "description": "按SKU获取指定商品的详细信息",
  "mimeType": "application/json"
}
```

常用URI模板模式：

```
commerce://products/{sku}              # 单个商品
commerce://orders/{orderId}/items      # 订单明细
commerce://categories/{categoryId}     # 分类详情
commerce://inventory/{sku}/{warehouse} # 指定仓库的库存
```

Client使用时填充变量：

```json theme={null}
{
  "method": "resources/read",
  "params": {
    "uri": "commerce://products/SHOE-001"
  }
}
```

### Annotations（资源注解）

每个资源可以携带Annotations元数据，帮助Host决定如何使用资源：

```json theme={null}
{
  "uri": "commerce://catalog/categories",
  "name": "商品分类",
  "description": "完整的商品分类层级结构",
  "mimeType": "application/json",
  "annotations": {
    "audience": ["user", "assistant"],
    "priority": 0.8,
    "lastModified": "2026-04-10T08:00:00Z"
  }
}
```

**Annotations字段说明**:

| 字段             | 类型          | 说明                                                |
| -------------- | ----------- | ------------------------------------------------- |
| `audience`     | 字符串数组       | 目标受众。`"user"` 表示适合展示给用户，`"assistant"` 表示适合提供给AI模型 |
| `priority`     | 数字（0-1）     | 优先级。1为最高。Host可据此决定在上下文窗口有限时优先加载哪些资源               |
| `lastModified` | ISO 8601字符串 | 最后修改时间。帮助Client决定是否需要重新读取                         |

### 资源订阅

如果Server在初始化时声明 `resources: { subscribe: true }`，Client可以订阅资源变化：

```json theme={null}
// Client → Server: 订阅资源
{
  "method": "resources/subscribe",
  "params": { "uri": "commerce://inventory/SHOE-001" }
}

// Server → Client: 资源内容变化通知
{
  "method": "notifications/resources/updated",
  "params": { "uri": "commerce://inventory/SHOE-001" }
}
```

收到通知后，Client重新调用 `resources/read` 获取最新数据。这种模式适合实时性要求高的场景，如库存监控。

取消订阅：

```json theme={null}
{
  "method": "resources/unsubscribe",
  "params": { "uri": "commerce://inventory/SHOE-001" }
}
```

### 资源列表变更通知

当Server的资源集合发生变化（新增或移除资源），可通知Client：

```json theme={null}
{ "method": "notifications/resources/list_changed" }
```

Client收到后重新调用 `resources/list` 获取最新的资源列表。

### 实现示例

```typescript theme={null}
// 静态资源
server.resource(
  "commerce://catalog/categories",
  "商品分类",
  "application/json",
  async () => {
    const categories = await db.categories.getAll();
    return JSON.stringify(categories, null, 2);
  }
);

// 动态资源（URI模板）
server.resource(
  "commerce://products/{sku}",
  "商品详情",
  "application/json",
  async (uri) => {
    const sku = uri.pathname.split("/").pop();
    const product = await db.products.findBySku(sku);
    if (!product) throw new Error(`商品 ${sku} 不存在`);
    return JSON.stringify(product, null, 2);
  }
);
```

## 6.2 Prompts（提示词模板）详解

Prompts是Server预定义的交互模板。与Tools和Resources不同，Prompts是**用户控制**的 — 用户在Host应用中主动选择使用哪个模板。

### 提示词结构

```json theme={null}
{
  "name": "product_comparison",
  "description": "对比两个商品的优劣",
  "arguments": [
    { "name": "product1", "description": "第一个商品SKU", "required": true },
    { "name": "product2", "description": "第二个商品SKU", "required": true },
    { "name": "focus", "description": "关注维度（价格/性能/评价）", "required": false }
  ]
}
```

### 获取提示词（带参数）

```json theme={null}
// Client → Server
{
  "method": "prompts/get",
  "params": {
    "name": "product_comparison",
    "arguments": {
      "product1": "SHOE-001",
      "product2": "SHOE-002",
      "focus": "性价比"
    }
  }
}

// Server → Client
{
  "result": {
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "请从性价比角度对比以下商品：\n\n商品1: Nike Air Max (SHOE-001) - 899元\n商品2: Adidas Ultra Boost (SHOE-002) - 1299元\n\n分析各自优劣并给出购买建议。"
        }
      }
    ]
  }
}
```

### 商务场景的提示词示例

```typescript theme={null}
// 商品对比
server.prompt(
  "product_comparison",
  "对比两个商品的优劣",
  [
    { name: "product1", description: "第一个商品SKU", required: true },
    { name: "product2", description: "第二个商品SKU", required: true }
  ],
  async ({ product1, product2 }) => {
    const p1 = await db.products.findBySku(product1);
    const p2 = await db.products.findBySku(product2);
    return {
      messages: [{
        role: "user",
        content: {
          type: "text",
          text: `请对比以下两个商品：\n\n商品1: ${JSON.stringify(p1)}\n\n商品2: ${JSON.stringify(p2)}\n\n从价格、功能、评价三个维度分析各自优劣。`
        }
      }]
    };
  }
);

// 订单摘要
server.prompt(
  "order_summary",
  "生成用户订单的摘要报告",
  [
    { name: "userId", description: "用户ID", required: true },
    { name: "period", description: "时间范围（如 last_month）", required: false }
  ],
  async ({ userId, period = "last_month" }) => {
    const orders = await db.orders.getByUser(userId, period);
    return {
      messages: [{
        role: "user",
        content: {
          type: "text",
          text: `以下是用户最近的订单数据：\n\n${JSON.stringify(orders, null, 2)}\n\n请生成一份简洁的消费摘要，包括总消费、常购品类、消费趋势。`
        }
      }]
    };
  }
);
```

### 多消息提示词

Prompts可以返回多条消息，包括system角色：

```typescript theme={null}
server.prompt(
  "customer_service",
  "启动客服助手模式",
  [],
  async () => {
    const policies = await db.policies.getAll();
    return {
      messages: [
        {
          role: "assistant",
          content: {
            type: "text",
            text: `你是一个专业的客服助手。以下是店铺政策：\n\n${JSON.stringify(policies)}\n\n请始终基于政策回答用户问题。`
          }
        }
      ]
    };
  }
);
```

### 嵌入资源的提示词

Prompts中的消息可以使用 `embedded_resource` 类型嵌入资源数据：

```typescript theme={null}
server.prompt(
  "analyze_catalog",
  "分析商品目录结构",
  [],
  async () => {
    return {
      messages: [{
        role: "user",
        content: {
          type: "resource",
          resource: {
            uri: "commerce://catalog/categories",
            mimeType: "application/json",
            text: await db.categories.getJsonString()
          }
        }
      }]
    };
  }
);
```

### 何时用Prompt vs Tool vs Resource

| 场景       | 推荐                     | 原因                |
| -------- | ---------------------- | ----------------- |
| 固定的交互模式  | Prompt                 | 模板化，用户可选          |
| 动态的操作    | Tool                   | AI模型自主决策          |
| 需要特定提问格式 | Prompt                 | 控制输入质量            |
| 需要执行动作   | Tool                   | Prompt只提供模板       |
| 静态上下文数据  | Resource               | 无副作用，Host控制读取时机   |
| 高优先级背景信息 | Resource + Annotations | priority字段控制加载优先级 |

***

**下一章**: [安全与认证](/zh/book-5/ch7-security) — OAuth 2.1集成和权限管理
