MCP区分资源读取与工具调用的实现方法
在 MCP(Model Context Protocol)服务里,最容易混淆的是 Resource 和 Tool:前者负责把上下文交给客户端读取,后者负责让模型请求一次明确的动作。判断标准很简单:如果对象的核心价值是“这里有一份可定位的数据”,优先建成 Resource;如果需要传入参数并触碰查询、计算、写入或外部系统,就应该建成 Tool。两者都可以返回文本或结构化内容,但发现方式、权限模型和错误处理不能混为一谈。
- Resource 用唯一 URI 表示可读取的数据,典型调用是
resources/read。 - Tool 用名称和 JSON Schema 描述可执行能力,典型调用是
tools/call。 - 只读上下文、可变动作、协议错误和业务失败要分别建模,权限与审计也要分层。
先把 Resource 和 Tool 的职责边界摆正
Resource 更像“可被引用的上下文入口”。规范示例中的文件、数据库 Schema、应用资料都可以通过 URI 唯一定位,客户端用 resources/list 发现它们,再用 resources/read 读取内容。Resource 是否自动进入模型上下文,由 Host 应用决定,协议本身不强制某一种界面或选择方式。
Tool 则是“可请求执行的能力”。服务端通过 tools/list 公布名称、描述和 inputSchema,客户端在确认用户意图和权限后,用 tools/call 传入 arguments。查询天气、执行数据库查询、创建工单或调用内部 API,都属于 Tool 的典型边界。即便工具返回一段文档,也不能因为结果是文本就把它建模成 Resource。
| 判断点 | Resource | Tool |
|---|---|---|
| 核心语义 | 读取一份有 URI 的上下文 | 执行一次有名称的能力 |
| 发现方法 | resources/list | tools/list |
| 执行/读取方法 | resources/read | tools/call |
| 关键输入 | URI,可选模板参数 | arguments 与 JSON Schema |
| 主要风险 | 越权读取、URI 穿越、过期内容 | 误操作、参数注入、数据外发 |

资源读取用 URI 链路,工具调用用名称和参数
实现时先声明 capability,再按对象的协议消息设计路由。Resource 至少要让客户端知道可用 URI、名称、描述和 MIME 类型;动态数据可以用 Resource Template 表达参数化 URI,并按需支持订阅或列表变更通知。Tool 至少要给出稳定名称、可读描述和严格的输入 Schema;如果返回对象需要稳定解析,再补充 outputSchema。
{
"jsonrpc": "2.0",
"id": 21,
"method": "resources/read",
"params": {"uri": "memo://project/alpha/architecture"}
}
{
"jsonrpc": "2.0",
"id": 22,
"method": "tools/call",
"params": {
"name": "search_project",
"arguments": {"project": "alpha", "query": "鉴权边界"}
}
}
上面两条消息看起来都像“向服务端取信息”,但语义不同:第一条是按 URI 取已经定义好的资源;第二条是要求服务端执行一次搜索动作。伪代码中也应保留这个分支,避免把所有请求都塞进一个万能 Tool:
type Request =
| { method: "resources/read"; params: { uri: string } }
| { method: "tools/call"; params: { name: string; arguments: Record } };
function dispatch(request: Request) {
if (request.method === "resources/read") {
// 资源先校验 URI 和读取权限,再返回文本或二进制内容。
return readResource(request.params.uri);
}
// 工具先校验参数、确认敏感动作,再进入业务执行和审计记录。
return callTool(request.params.name, request.params.arguments);
}
这里的 readResource 和 callTool 是服务端内部实现接口,不是 MCP 新增的方法名。真正对外暴露的仍是 JSON-RPC 消息。资源读取失败应返回资源不存在等协议错误;工具如果名称未知或参数不符合 Schema,属于协议层错误;外部服务超时、库存不足或业务拒绝,则应在工具结果中明确 isError: true,让客户端知道“调用到了,但执行没有成功”。

生产环境按权限、审计和错误分层
Resource 的安全重点是“能否读到这份数据”。服务端要校验 URI,限制可访问的资源范围,并在资源包含敏感信息时绑定用户、租户或工作区权限。不要把文件路径直接拼接成 URI 后无条件读取,也不要把一次性授权信息写进可长期复用的资源描述。
Tool 的安全重点是“这次动作能造成什么影响”。输入要按 Schema 和业务规则双重校验;写入、删除、发送消息、付费或导出等动作应设置人工确认、超时、限流和审计日志。工具注解只能作为提示,客户端不应把不受信任服务端的注解当成安全证明。
- Resource:校验 URI、访问主体、数据范围和内容新鲜度。
- Tool:校验名称、参数、权限、幂等性、超时和副作用。
- 两者共用:记录 request id、耗时、结果类型和脱敏后的失败原因。
最后做一次建模检查:没有副作用、需要被客户端选择或订阅、并且能用稳定 URI 表达的对象,通常适合 Resource;需要模型决定参数、触发查询或改变外部状态的对象,通常适合 Tool。若一个对象同时具备两种特征,可以让 Resource 提供只读上下文,再让 Tool 提供明确动作,避免用一个接口承担两套权限语义。
相关问题
Resource 能不能接收参数?
可以用 Resource Template 表达参数化 URI,并通过模板补全参数;但它仍然表示“按地址读取资源”,不要借此隐藏写入或执行动作。
Tool 返回文件时还算 Tool 吗?
算。判断依据是请求是否触发了一次能力调用,而不是结果是文本、图片还是文件。Tool 也可以返回 Resource Link 或嵌入式 Resource,供客户端继续读取。
工具失败应该返回 JSON-RPC error 吗?
未知工具、非法参数等协议问题用 JSON-RPC error;工具已经被正确调用但业务执行失败,应返回工具结果并设置 isError: true,两者不要混用。
Go archive/zip写入 Zip 时处理重复条目的实现方法
- 上一篇
- Go archive/zip写入 Zip 时处理重复条目的实现方法
- 下一篇
- PHP attributes用 Reflection 读取自定义属性的实现方法
-
- 科技周边 · 人工智能 | 5小时前 | 错误处理 · 参数校验 · agent · openai api · AI工程 · Tool calling · 函数调用 业务错误 JSON Schema Tool calling strict 工具参数校验 模型错误
- Tool calling校验工具参数并区分模型与业务错误的实现方法
- 380浏览 收藏
-
- 科技周边 · 人工智能 | 6小时前 | openai api · 结构化输出 · AI工程 · Pydantic JSON Schema Structured Outputs
- Structured Outputs让模型结果贴合 JSON Schema的实现方法
- 191浏览 收藏
-
- 科技周边 · 人工智能 | 8小时前 | 人工智能 · 结构化输出 · JSON解析 · 模型输出 · 接口容错 · 大模型结构化输出 模型输出JSON缺字段 JSON兜底解析 JSON Schema校验 AI接口异常处理
- 模型输出 JSON 缺字段时如何设计兜底解析
- 272浏览 收藏
-
- 科技周边 · 人工智能 | 10小时前 | 人工智能 · 显存管理 · 推理优化 · 本地推理 KV Cache batch size
- 本地推理 KV cache 和 batch size 如何做取舍
- 251浏览 收藏
-
- 科技周边 · 人工智能 | 11小时前 | API · 性能优化 · ai · AI 提示词缓存 Responses API Prompt Caching
- AI 提示词缓存如何按稳定前缀组织请求
- 357浏览 收藏
-
- 科技周边 · 人工智能 | 12小时前 |
- 分类评测集不均衡时如何比较 macro 与 micro 指标
- 473浏览 收藏
-
- 科技周边 · 人工智能 | 14小时前 |
- Agent 工具返回文件路径时如何限制工作区范围
- 381浏览 收藏
-
- 科技周边 · 人工智能 | 15小时前 |
- AI 流式响应中的 finish_reason 如何决定持久化时机
- 195浏览 收藏
-
- 科技周边 · 人工智能 | 17小时前 |
- LoRA adapter 合并后 tokenizer 配置如何核对
- 162浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 43次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 140次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 77次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 45次使用
-
- CMMLU
- 深入了解CMMLU中文评估基准,涵盖67个学科主题,提供数据集下载、Zero-shot/Five-shot评估方法及排行榜,助力优化中文语言模型性能。
- 27次使用
-
- 本地大模型反复输出同一句话怎么调整生成参数
- 2026-09-06 501浏览
-
- Python 调用大模型时如何用结构化输出校验 JSON:从解析失败到可重试
- 2026-08-29 501浏览
-
- AI写作工具免费版安装教程(含豆包Clawdbot)
- 2026-05-30 501浏览
-
- WPS AI能自动生成PPT吗?输入主题一键制作演示文稿
- 2026-05-27 501浏览
-
- Canva手机闪退解决方法及适配指南
- 2026-05-25 501浏览

