必读前置:MCP 能力讲解 · 怎么接 MCP Tools
系列回顾:主循环 · 代码库工具 · REPL · 项目上下文 · Skills · 权限 + Write · Bash · compact 2.0
Tools 接线篇写过:mini只接 Tools。概念篇里的 Resources(挂材料)和 Prompts(点开场)当时刻意留空。
这篇补上两步:v4-mcp-capabilities先把 Resources / Prompts 接到工具表和 REPL slash;v4-mcp-resource-refs再把挂材料收成「只认@server:uri」——slash、普通输入、headless 共用同一套解析,无引用就不自动挂,也仍然不改query()。
从「知道」到「接上」
概念篇记住的总纲还在:
Tools = 做事;Resources = 给材料;Prompts = 给开场白。
Tools 实现篇解决了「做事」怎么进 ReAct。本篇解决另外两句:
| 概念 | 在 mini 里怎么落地 |
|---|---|
| Resources | 两个只读工具:ListMcpResourcesTool/ReadMcpResourceTool;Host 按文本里的@server:uri按需挂载(无引用不自动挂) |
| Prompts | REPL 斜杠:/tour:plan_trip 巴黎 3→prompts/get→ 解析引用 → meta 消息注入本轮 |
Client 侧 Sampling / Roots / Elicitation仍然没做——这篇不重开六大能力课,只讲「Server 侧三大能力」在 mini 里齐了没有。
一张图:启动时多发现了什么
.mcp.json → connectMcpSession ├─ list_tools → mcp__* 工具(实现篇) ├─ capabilities.resources? │ └─ sessionTools 追加 List/ReadMcpResource* └─ capabilities.prompts? └─ commands[] → REPL /help 与 /server:promptLoadedMcp不再只有tools+close:
typeLoadedMcp={tools:Tools clients:McpConnectedClient[]commands:McpSlashCommand[]hasResources:booleanclose:()=>Promise<void>}sessionTools(mcp):
builtin + MCP tools +(任一 server 声明 resources 时)ListMcpResourcesTool、ReadMcpResourceTool没有 resources 能力的 server(例如纯计算器)→ 工具表不加这两项,零开销。
Resources:两条通路
通路 A — 模型自己 List / Read(Tool)
和 Read 文件一样走tool_use:
模型:ListMcpResourcesTool(可选 server=tour) → 返回 [{ uri, name, server, mimeType, … }] 模型:ReadMcpResourceTool({ server: "tour", uri: "docs://handbook" }) → 正文进 tool_result → 模型据此回答要点:
- 只读(
isReadOnly: true),不进写类门卫 y/N - 二进制 blob不进上下文,只留占位说明
- 超长文本截断(约 10 万字符)
这对应概念篇里「也可以做成 Tool」的那条路——Host 把 Resource 能力暴露成标准 Tool,模型按需拉取。
通路 B — Host 按@server:uri挂材料(无引用不自动挂)
早期 slash 会在开场前全量读取该 server 的全部 Resources。资源一多就会污染上下文;而且 prompt 如果只写「差旅手册」,模型还容易跑去工作区搜同名文件。
现在只认显式引用:从文本解析@tour:docs://handbook,只对命中条目做resources/read。没有任何@server:uri时,Host 不自动挂任何 Resource——需要材料就写引用,或让模型自己走通路 A 的 List/Read。
这条通路不只服务 slash。同一个resolvePromptResourceMessages会吃三类文本:
| 入口 | 解析对象 | 注入方式 |
|---|---|---|
| MCP slash | prompts/get返回的开场文本 | injectBefore: [...resources, ...promptMessages] |
| REPL 普通输入 | 用户原文 | 材料先挂,再发送用户原文 |
| headless / pipe | 命令行 / stdin 的 prompt | messages = [...resources, userMessage] |
解析规则很简单:空白后的@server:uri,用第一个:拆开。所以 URI 里可以带://:
@tour:docs://handbook → { server: "tour", uri: "docs://handbook" }slash 路径大致是:
constpromptMessages=awaitmcpSlash.command.run(mcpSlash.argsLine)constresources=awaitresolvePromptResourceMessages(mcpClients,promptMessages,{warn:msg=>print(msg)},)awaitconsume(deps.engine.runTurn('',{injectBefore:[...resources,...promptMessages],}),)普通输入则是:
constresources=awaitresolvePromptResourceMessages(mcpClients,[createUserMessage(trimmed)],{warn:msg=>print(msg)},)awaitconsume(deps.engine.runTurn(trimmed,{injectBefore:resources.length>0?resources:undefined,}),)挂进去的是带meta: true的 user 消息,形如:
以下材料来自 MCP Resource,请严格遵守: server=tour uri=docs://handbook # 差旅手册(Demo) …QueryEngine.runTurn支持只有injectBefore、没有用户打字——slash 整轮可由 Host 组装上下文。
tour demo 的.mcp.jsonkey 须为tour,才能与 prompt / 用户输入中的@tour:docs://handbook对齐。
Prompts:REPL 斜杠,不经 SkillTool
启动时prompts/list→ 注册 slash 元数据:
用户面: /tour:plan_trip (MCP) [args…] 也可: /tour:plan_trip [args…] (省略 (MCP),已注册则命中) 内部名: mcp__tour__plan_trip/help会列出这些 MCP 命令。执行顺序是「先拿开场,再只按引用挂材料」:
1. parseMcpSlashCommand 2. prompts/get → promptMessages(meta user 消息) 3. resolvePromptResourceMessages ├─ 文本里有 @server:uri → 只读这些引用 └─ 完全没有 @server:uri → 不自动挂 Resource 4. engine.runTurn('', { injectBefore: [...resources, ...promptMessages] })tour demo 的plan_trip现在会显式写上引用:
请帮我规划去「巴黎」的 3 天差旅。 要求:先阅读 @tour:docs://handbook ,再给出日程草案。 不要编造公司政策;政策以手册为准。参数按 prompt 声明的arguments按空格顺序填:
/tour:plan_trip 巴黎 3 → { city: "巴黎", days: "3" }和 Skills 的差别(概念篇对照表的实现版):
| Skills | MCP Prompts(本篇) | |
|---|---|---|
| 触发 | 模型调Skill工具 | 用户敲 slash |
| 内容来源 | 本地SKILL.md | MCP Serverprompts/get |
| headless | 可用 Skill | 不自动跑MCP slash;但会解析 prompt 里的@server:uri |
所以:Skills 仍是「模型按需读说明书」;MCP Prompt 是「用户点开场模板」——两条产品路径,不要混成一个。
30 秒试一把(用 tour server)
项目根配置指向概念演示 Server(同时有 tools / resources / prompts):
{"mcpServers":{"tour":{"command":"node","args":["examples/mcp-tour-server/server.js"]}}}# 可选:先确认 Server 本身nodeexamples/mcp-tour-server/smoke.mjsnodeexamples/mcp-tour-server/how-to-host.mjs# 接进 Agentcp(或编辑).mcp.json → 如上 bun run devREPL 里:
/help # 应看到 /tour:plan_trip (MCP) … /tour:plan_trip 巴黎 3 # 提示:已挂载 MCP Resource ×1(server=tour) # 因为 prompt 里写了 @tour:docs://handbook,只挂这一本手册 # 模型按手册 + 开场白开始规划 # 普通消息也可以直接 @ 引用(不必走 slash): 根据 @tour:docs://handbook ,帮我列三条差旅注意点 # 提示:已挂载 MCP Resource ×1 # 材料先进入上下文,再处理你的这句话 # 或让模型自己拉材料: 列出 MCP 资源,并读取 docs://handbook只用计算器 Server(无 resources/prompts)时:没有 List/Read 资源工具,也没有 MCP slash——行为与 Tools 接线篇一致。
和主循环的关系
L1 CLI / REPL → 加载 commands、clients;slash / 普通输入 / headless 解析 @server:uri L2 query() → 不变(看到的仍是 messages + tools) L3 runToolUse → List/ReadMcpResource 只是多两个只读 Tool L4 services/mcp → fetch / promptSlash / resource 工具Resources / Prompts 不改 ReAct 循环:一个变工具表,一个变「本轮开头注入的 meta 消息」。
和 Skills(目录摘要 + Skill 工具)、项目上下文(systemPrompt)是同一家族的「把外部材料喂给模型」,只是协议与触发方式不同。
刻意没做什么?
| 没做 | 意味着什么 |
|---|---|
| Sampling / Roots / Elicitation | Client 侧三大能力仍留空 |
resources/subscribe、SSE/HTTP | 仍仅 stdio;资源一次性 list/read |
| headless 自动跑 MCP slash | pipe/headless不执行/server:prompt;但会解析 prompt 里的@server:uri |
@自动补全 UI / 资源面板 | CLI 已能解析@server:uri,但没有输入时的补全面板 |
| 无 mention 时全量挂载 | 刻意不做;没有@就不自动塞材料 |
| 图片进模型上下文 | image/blob 占位,不塞 base64 |
完整产品往往会有资源面板和更重的远程传输;mini 验证的是:
capabilities 发现 → Resource 工具 + Prompt slash → slash / 普通输入 / headless 共用 @server:uri 按需挂材料 → 无引用不自动挂 → 先材料、后正文 → query 零感知系列拼图(MCP 三连)
| 篇 | 内容 |
|---|---|
| 概念 | 六大能力 + 怎么用 |
| Tools 接线 | stdio + 适配器 + 门卫 |
| 本篇 | Resources 工具 + Prompts slash +@server:uri(slash / 普通消息 / headless) |
再到整条 Agent 系列:循环 → 工具 → 会话 → 上下文 → Skills → 权限 → Bash → compact →MCP 从 Tools 扩到材料与开场,再收成显式引用。
你可以从这里带走什么?
- Resources 可以有两条路:模型调 List/Read 工具,或 Host 按文本里的
@server:uri自动挂材料。 - Prompts ≠ Skills:用户点模板 vs 模型读说明书;触发面不同。
@server:uri不只服务 slash:REPL 普通输入和 headless prompt 也会解析;材料在前,用户原文在后。- 无引用就不自动挂:Host 不做全量兜底;需要材料就写
@,或让模型走 List/Read。 injectBefore+ meta:不改query(),只改「本轮消息从哪来」。- 无 capability 则零开销:没有 resources/prompts 的 server,行为与早期 Tools-only 一致。
仓库与相关文档
- GitHub:react-agent-mini
- MCP 概念 · MCP Tools 接线 · compact 2.0
- tour Server:examples/mcp-tour-server
- 术语表:src/services/mcp/CONTEXT.md
- Resource 工具:src/tools/McpResourceTools.ts
欢迎 Star、Issue 和 PR。
本文基于 react-agent-mini 变更v4-mcp-capabilities(Resources 工具 + Prompts slash)与v4-mcp-resource-refs(@server:uri按需挂载;覆盖 slash / 普通消息 / headless;无引用不自动挂)撰写。