当前位置: 首页 > news >正文

第3篇:原生SDK极简入门

这篇只做一件事:把第2篇里的一个 FastMCP 工具,改写为原生SDK版本。

1. 你需要先知道的 JSON-RPC

工具调用时,客户端发这样的请求:

{"jsonrpc": "2.0","id": 1,"method": "tools/call","params": {"name": "search_recipes_by_ingredient","arguments": { "ingredient": "番茄" }}
}

服务器要回这样的响应(内容放在 result.content[0].text 里,通常是字符串化的 JSON):

{"jsonrpc": "2.0","id": 1,"result": {"content": [{ "type": "text", "text": "{\"success\": true, \"recipes\": [], \"count\": 0}" }]}
}

记住两点:

  • 参数来自 request.params.arguments
  • 返回值需要构造成 CallToolResult(content=[TextContent(...)])

2. 只改一个工具:FastMCP → 原生SDK

沿用第2篇的内部函数(在 app/models.py):

  • _search_recipes_by_ingredient(ingredient: str) -> Dict

FastMCP 版本(第2篇)

@mcp.tool()
def search_recipes_by_ingredient(ingredient: str) -> Dict:"""根据食材查询食谱"""return _search_recipes_by_ingredient(ingredient)

原生SDK 版本(极简)

# 需要:pip install mcp
import json
from mcp.server.models import CallToolRequest, CallToolResult
from mcp.types import TextContentfrom .models import _search_recipes_by_ingredient  # 直接复用第2篇内部函数class SearchRecipesTool:async def handle(self, request: CallToolRequest) -> CallToolResult:# 1) 手动取参数ingredient = (request.params.arguments or {}).get("ingredient", "").strip()# 2) 最小的参数校验if not ingredient:return CallToolResult(content=[TextContent(type="text", text=json.dumps({"success": False, "error": "缺少食材参数"}, ensure_ascii=False))])# 3) 业务逻辑:复用第2篇函数result = _search_recipes_by_ingredient(ingredient)# 4) 按MCP要求封装响应return CallToolResult(content=[TextContent(type="text", text=json.dumps(result, ensure_ascii=False))])

就这么简单:手动取参、调用旧逻辑、封装标准返回。

3. 为什么原生SDK要"这么写"

显式参数:你清楚看到参数来自哪里,怎么校验

  • FastMCP:def search(ingredient: str) - 魔法注入
  • 原生SDK:request.params.arguments.get("ingredient") - 明确来源

结构化返回:约束你把数据放进 content,和客户端约定一致

  • FastMCP:return {"success": True} - 直接返回
  • 原生SDK:CallToolResult(content=[TextContent(...)]) - 标准封装

错误可控:返回结构里能带上错误信息,前后端更稳

  • FastMCP:异常或None可能导致不明确的错误
  • 原生SDK:统一的错误格式 {"success": False, "error": "..."}

适用场景对比表

场景FastMCP原生SDK
快速原型推荐过度
高性能需求一般推荐
定制协议不支持推荐

总结

原生SDK的本质就是:显式控制每个细节,换取更多的灵活性


文章转载自:

http://gYbjDP0X.wrtxk.cn
http://zZKCpvNK.wrtxk.cn
http://u9uwYOFC.wrtxk.cn
http://UIBI6Dpv.wrtxk.cn
http://gPP9Xtol.wrtxk.cn
http://gIwyZwTr.wrtxk.cn
http://gjeuNqwl.wrtxk.cn
http://FRTz7mEu.wrtxk.cn
http://DsKIrar0.wrtxk.cn
http://5nBu5Pz4.wrtxk.cn
http://1vuzx4Rp.wrtxk.cn
http://YUcefxIy.wrtxk.cn
http://qXGLuUhB.wrtxk.cn
http://7WRp59bE.wrtxk.cn
http://ndF58lqD.wrtxk.cn
http://oN8QuJDq.wrtxk.cn
http://TlyS7qbW.wrtxk.cn
http://3H2EWvze.wrtxk.cn
http://qH0C1t18.wrtxk.cn
http://lm5QIqoh.wrtxk.cn
http://hHyubYFK.wrtxk.cn
http://jWTZ5Zn9.wrtxk.cn
http://Sx8JtEMN.wrtxk.cn
http://G99UM42I.wrtxk.cn
http://lEbWTEJf.wrtxk.cn
http://5wa2T8CX.wrtxk.cn
http://dDnTdAJC.wrtxk.cn
http://MuMWGaon.wrtxk.cn
http://B3qUuTE5.wrtxk.cn
http://GkrA1s2C.wrtxk.cn
http://www.dtcms.com/a/381154.html

相关文章:

  • RAG技术的构建、搭建与企业应用
  • LeaferJS好用的 Canvas 引擎
  • Hadoop集群格式化操作
  • 鸿蒙app日志存储
  • 2025年精品课怎么录制?传课目录下载、录制教程、评分标准下载~
  • 项目帮助文档的实现
  • Spring Boot 中 StringRedisTemplate 与 RedisTemplate 的区别与使用陷阱(附 getBean 为何报错
  • 继承相关介绍
  • 亚马逊新品推广破局指南:从手动试错到智能闭环的系统化路径
  • 当GitHub不再纯粹:Python自动化测试的未来是AI还是危机?
  • 【C语言】“栈”顶到底是上面还是下面?高地址还是低地址?
  • 3种光伏设计方式,哪个最适合你?
  • 移动考勤软件如何选?GPS和离线打卡两大功能解析
  • 代码随想录学习摘抄day8(二叉树21-31)
  • 0~1构建一个mini blot.new(无AI版本)
  • Nuitka 将 Python 脚本封装为 .pyd 或 .so 文件
  • 解决Arthas 端口冲突问题
  • linux执行systemctl enable xxxxx 报 Failed to execute operation: Bad message
  • linux C 语言开发 (八) 进程基础
  • Oracle SQL调优技巧实战指南
  • B1013 PAT乙级JAVA题解 数素数
  • oracle字符转time
  • 阿里巴巴开放开放平台商品详情接口技术实现:详情数据深度解析方案
  • python使用pip安装的包与卸载
  • 题目:快乐数
  • Leecode hot100 - 287. 寻找重复数
  • SQL优化分析学习
  • Thinking Machines的博客
  • Linux命令行的核心理念与实用指南
  • 单板挑战4路YOLOv8!米尔瑞芯微RK3576开发板性能实测