☰
从 MCP 协议到工程落地:一次工具调用如何变成一版路书
2026/10/30 5:06:11 网站建设 项目流程

本文分两部分。第一部分是 MCP 的通用知识(第 1–8 节),只在少数地方用 Roadbook 举例;第二部分以 Roadbook(github.com/devgxy/roadbook)为例,讲工程落地(第 9–18 节)。两部分可以分开读:只关心协议的人读完第一部分即可;从第 9 节开始的人,可以回第 1–4 节补 Host/Client/Server 与传输的定义。

全文速览:

  • MCP 是连接层,不是编排层:它规定工具怎么接、怎么调、怎么回,不规定谁来决定调用。
  • 本地 MCP 与远程 MCP 的差别,主要在信任边界:密钥归谁、用户是谁、失败怎么发生。
  • 这个项目把「取事实」交给 MCP,把「下结论」交给规则,模型只做参数抽取和可选精修。

目录

第一部分 · 知识

  1. MCP 解决什么问题
  2. Host、Client、Server
  3. tools、resources、prompts
  4. 传输:stdio 与 Streamable HTTP
  5. 生命周期与一次调用
  6. 工具契约
  7. 安全边界
  8. 编排:Agent 与管线

第二部分 · 工程

  1. 项目全貌
  2. 本地 MCP 接入
  3. 高德 MCP 实战
  4. 12306 MCP 实战
  5. 一次规划的流程
  6. 模型的两个位置
  7. 故障与边界
  8. 上远程 MCP 要补什么
  9. 代码地图
  10. 决策清单

第一部分 · 知识

1. MCP 解决什么问题

一句话:Model Context Protocol(MCP)把 N 个客户端 × M 个工具的适配,变成 N + M 次实现。

在没有协议之前,每个模型客户端要接每个工具,都得写一套私有集成:鉴权、参数格式、错误处理、结果解析各写一遍。客户端有 N 个、工具 M 个,工作量是乘法。

MCP 把中间抽成一层协议:客户端侧实现一次 Client,工具侧实现一次 Server,两边按同一套 JSON-RPC(基于 JSON 的远程调用格式)消息说话。工作量变成加法。

图 1:MCP 把 N×M 套适配变成 N+M 次实现

这件事和 LSP 很像:编辑器不再为每个语言写补全,语言不再为每个编辑器写插件,中间是一套 Language Server Protocol。MCP 是模型工具领域的同一种思路。

需要说清的是,MCP 标准化的核心是「接入」:

  • 它解决的:工具怎么被发现、怎么被调用、结果怎么回传、连接怎么建立和关闭、远程怎么鉴权。
  • 它不解决的:什么时候该调工具、调哪个、调几次、结果可不可信、失败怎么降级、多个工具怎么编排。

后面这些属于 Host 的编排策略;这也是为什么同一个 Server,既可以是 agent 手里的工具,也可以是确定性管线里的一个依赖。要理解这套协议怎么落地,先看三个角色。

2. Host、Client、Server

一句话:Host 管决策,Client 管连接,Server 管执行;模型不直接连 Server。

三个角色:

  • Host(宿主应用):持有模型、用户界面和上下文。它决定「现在需不需要工具」,也负责把模型的选择翻译成协议调用。典型例子是聊天客户端、IDE、桌面助手。
  • Client(协议客户端):Host 内部的连接器。一个 Client 对应一个 Server 连接,负责握手、列工具、发调用、收结果、处理通知。
  • Server(MCP Server,工具服务):对外暴露能力。它可以是本地子进程,也可以是远端服务;它不知道对面是哪个模型,也不需要知道。

关系是 1 个 Host 带 N 个 Client,1 个 Client 连 1 个 Server:

图 2:Host、Client、Server 的连接关系

职责可以再拆细一点:

角色负责不负责
Host持有模型、决定调用时机、维护上下文、做权限策略协议消息的编解码
Client握手、能力协商、请求/响应、通知、重连决定调什么工具
Server执行工具、返回内容、报告错误理解模型、维护对话

「模型不直接连 Server」是理解 MCP 的关键。模型看到的是 Host 转述的工具描述,模型输出的调用也由 Host 转成tools/call。所以鉴权、限流、审计这些事都发生在 Host 与 Server 之间,不发生在模型与 Server 之间;本地 MCP 通常没有协议级鉴权,密钥由 Host 注入。

映射到这个项目:

角色实现
Hostagent.py的 qwen_agent 助手;或 Web 服务travel_app.py
Clientmcp_client.py的会话封装;agent 侧由 qwen_agent 管理
Servernpx拉起的@amap/amap-maps-mcp-server、12306-mcp,以及自写的desktop_txt_mcp.py

3. tools、resources、prompts

一句话:三种能力对应三种控制权——tools 偏模型,resources 偏应用,prompts 偏用户。

Server 可以暴露三类能力:

能力是什么谁决定使用例子
tools可调用的函数,有参数 schema 和返回内容模型(经 Host)或代码查坐标、查车次
resources按 URI 读取的上下文数据应用文件内容、数据库记录
prompts可复用的提示词模板,带参数用户「按这个格式写周报」

这个划分很重要:不是所有能力都该做成「工具」。只读的上下文更适合 resources,固定模板更适合 prompts;把它们全塞进 tools,会让模型的选择空间变大、准确率变低。

工具是三者中唯一可能带副作用的类别,所以协议给了它最严格的契约:名字、描述、JSON Schema 参数、返回内容块、错误标记。资源是只读的,提示词是给用户选的,风险和工具不在一个量级。

Roadbook 只用了 tools 这一类:查坐标、查路线、查天气、搜 POI、查车次。没有 resources,也没有 prompts。

三类能力最终都要经过传输层,下一节看它是怎么走的。

4. 传输:stdio 与 Streamable HTTP

一句话:本地走 stdio,远程走 Streamable HTTP;差别不只在地址,而在信任边界和生命周期。

规范定义了两类传输。

stdio(本地):Host 启动一个子进程,双方在 stdin/stdout 上跑 JSON-RPC,一行一条消息;日志走 stderr,不污染协议通道。子进程的生命周期跟 Host 绑定,Host 退出,Server 也就结束。

Streamable HTTP(远程):Client 向一个 HTTP 端点 POST 消息,服务端可以用 SSE(Server-Sent Events,服务器推送)流回传;会话通过Mcp-Session-Id维持。规范为 HTTP 传输定义了基于 OAuth 2.1 的授权。更早的 HTTP+SSE 方案已经被它取代。

图 3:本地 stdio 与远程 Streamable HTTP

维度本地 stdio远程 Streamable HTTP
启动方式Host 拉起子进程Host 连接 URL
密钥环境变量,留在本机OAuth / Token,留在服务端
用户模型单机单用户多租户,需要隔离
失败模式冷启动、进程崩溃网络、鉴权、限流
升级跟 Host 走服务端独立升级
观测本机日志集中追踪与审计

这个项目的 MCP 全部是本地进程:它是桌面/单机应用,API Key 是用户自己的,放进子进程环境变量最直接。唯一的例外是配图:主路径直接调 Tavily 的 REST 接口,没有走 MCP。协议不是强制项——一个只用来补图、不需要被模型发现、也没有多工具复用价值的接口,直接 HTTP 更简单。

5. 生命周期与一次调用

一句话:连接建立一次,之后是「列工具 → 调用 → 收结果」;协议错误和工具错误要分开处理。

一次完整的 MCP 会话大致是这样:

图 4:一次 MCP 调用的生命周期

几个细节值得单独说:

  • 版本协商:initialize里带protocolVersion,Server 回它支持的版本;不兼容时 Client 应当断开,而不是硬连。
  • 能力协商:双方在initialize里声明自己支持什么,比如 Server 是否有 tools、Client 是否支持 sampling 或 roots。
  • 分页:tools/list可能带cursor,工具多的时候要翻页。
  • 进度:tools/call可以带progressToken,Server 用notifications/progress回报。
  • 取消:Client 发notifications/cancelled,但取消是「请求停止」,不是「保证已经停止」——已经产生的副作用不会回滚。
  • 两类错误:协议层错误走 JSON-RPC 的error;工具执行失败走正常结果里的isError: true,附带错误文本。前者是「消息没走通」,后者是「工具跑了但失败了」,处理方式不同。

tools/call是一条 JSON-RPC 消息:

{"jsonrpc":"2.0","id":7,"method":"tools/call","params":{"name":"maps_geo","arguments":{"address":"北京"}}}

返回不是「一个结构化对象」,而是 content blocks(下面是一段示意):

{"jsonrpc":"2.0","id":7,"result":{"content":[{"type":"text","text":"{\"geocodes\":[{\"location\":\"116.40,39.90\"}]}"}],"isError":false}}

这就是为什么调用方通常要做两件事:先把 blocks 拼成文本,再按业务格式解析。协议保证传得到,不保证字段稳定。

流程走通只是开始,可靠性由契约决定。

6. 工具契约

一句话:工具名和描述是给模型看的,参数 schema 是给双方校验的,返回内容块是给调用方解析的。

一个 tool 定义通常包含四类信息:

字段作用谁在用
name唯一标识模型、Client、Server
description说明「什么时候该用它」模型
inputSchema参数的 JSON Schema模型生成参数、Server 校验
annotations可选;只读、破坏性、幂等、开放世界等提示Host 做策略

annotations是提示,不是强制约束。比如readOnlyHint: true表示「这个工具不该改数据」,Host 可以据此决定要不要弹确认,但 Server 仍然可能改——安全不能只靠注解。

返回侧,content blocks 支持文本、图片、音频、内嵌资源;较新的规范版本还引入了structuredContent,让工具既能给模型看文本,也能给程序看结构。这个项目锁的是mcp==1.7.1,主路径仍按 content blocks 处理。

工具设计里最容易踩的三个坑:

  1. 参数类型含糊。路径规划要的是坐标,不是城市名。如果描述没写清,模型就会拿地名去调,然后失败。这个项目因此把流程拆成「先maps_geo换坐标,再maps_direction_driving」。
  2. 描述写的是「做什么」,不是「什么时候用」。模型靠描述选工具;maps_text_search和maps_geo都能处理地名,描述不区分,模型就会选错。
  3. 不要默认工具是幂等的。协议不提供幂等键,重试是否安全由工具设计决定。查天气可以重试,下单不能。

契约解决的是单次调用,信任问题在调用之外。

7. 安全边界

一句话:本地 MCP 的风险是「以你的权限运行」,远程 MCP 的风险是「以别人的身份访问」。

本地 Server 以当前用户权限运行,能读文件、能发网络请求、能拿环境变量里的 Key。风险包括:

  • 工具输出是不可信输入。Server 返回的文本会进入模型上下文,可能包含提示注入。Host 要限制长度、隔离来源,不能把工具输出当系统指令。
  • Key 在环境变量里。只要 Server 进程或日志泄露,Key 就泄露;不要把 Key 放进模型上下文,也不要写进错误信息。
  • 权限过大。一个只该读文件的 Server,不应该有网络权限;一个只该查天气的工具,不应该能删数据。

远程 Server 多了一层身份问题。当前规范为 HTTP 传输定义了基于 OAuth 2.1 的授权,强调几件事:

  • 不要 token passthrough:Client 不能把用户 token 原样转给下游服务,必须做 audience 校验。
  • 资源指示器:请求里声明目标资源,防止 token 被拿去访问别的服务。
  • 租户隔离:一个 Server 服务多个用户时,工具调用必须带用户上下文,不能共享缓存或会话。
  • SSRF 与参数注入:工具参数里出现 URL、路径、SQL 时,Server 侧必须校验,不能直接拼。

一句话:本地 MCP 的信任边界是「这台机器」,远程 MCP 的信任边界是「这个租户」。换传输,安全模型要跟着换。

边界之外,最后一个知识问题是编排。

8. 编排:Agent 与管线

一句话:MCP 决定「能调什么」,编排决定「谁来调、按什么顺序调」。

同一个 Server,可以有两种完全不同的用法。

Agent 循环:模型看上下文,选工具和参数;Host 执行;结果回填;模型继续,直到它认为可以回答。

图 5:Agent 循环:模型决定下一步调用

管线:代码写死调用顺序,模型不参与调度。

图 6:管线:代码决定调用顺序

维度Agent管线
谁决定下一步模型代码
工具选择描述 + 上下文写死的顺序
优点开放、可组合、能处理没预演过的任务可测试、可复现、延迟可控
代价不确定、难审计、成本高覆盖面有限、改流程要改代码
适合开放式任务、工具集经常变强合规、强审计、结果要可复算

还有中间形态:路由(先用小模型选一类工具,再交给管线)、规划-执行(模型只出计划,执行由代码做)、人在环(关键步骤等确认)。选哪种,取决于你对「不确定」的容忍度。

第一部分小结:MCP 定义的是连接与调用,不是编排;Host 决定谁选工具;工具契约决定可靠性;安全模型随传输方式变化。下面进入工程。


第二部分 · 工程

9. 项目全貌

一句话:一个 Starlette 服务,一条规则规划管线,MCP 只出现在取事实的那一段。

Roadbook 做的事很窄:把一句口语收成几天自驾路书。它的工程结构比功能看起来简单:

图 7:Roadbook 的工程结构

几个关键决定:

  • 规划不用 agent 框架。调用顺序是代码写死的,模型只在两个受控节点出现。
  • MCP 全部是本地进程。高德、12306 用npx起子进程;自写的桌面工具用 Python 起。
  • 配图不走 MCP。直接调 Tavily REST,原因见第 4 节。
  • 结果流式输出。POST /api/plan用 SSE 把工具进度推给前端。

还有一条支线:agent.py用 qwen_agent 把同一份 MCP 配置挂给模型,做一个「模型自己选工具」的桌面助手。它和 Web 主路径共用配置,但不共用编排。

先看配置和会话,再看两个具体的 Server。

10. 本地 MCP 接入

一句话:一份配置、一个会话池、两层锁,解决「怎么起、怎么复用、怎么不互相拖死」。

配置

配置是「服务名 → 启动命令」:

{"amap-maps":{"command":"npx","args":["-y","@amap/amap-maps-mcp-server"],"env":{"AMAP_MAPS_API_KEY":"..."}},"12306-mcp":{"command":"npx","args":["-y","12306-mcp"]}}

这是_build_servers()的形状;交给 qwen_agent 时,外面再包一层{"mcpServers": ...}。这里省略了desktop-txt和 Tavily。

实际代码里,高德和 Tavily 有 Key 才注册,12306 和desktop-txt无条件注册。缺 Key 时服务不出现,进程照常启动;但缺高德 Key,规划请求本身会失败——「进程能起来」和「功能可用」是两件事。

自写 Server

自己写一个本地 Server 也不复杂。desktop_txt_mcp.py用 FastMCP(MCP 的 Python 服务端框架)把两个普通函数暴露成工具:

frommcp.server.fastmcpimportFastMCP mcp=FastMCP("桌面 TXT 文件统计器")@mcp.tool()defcount_desktop_txt_files()->int:"""统计桌面上 .txt 文件的数量"""...

函数名就是工具名,docstring 就是工具描述。

会话与超时

会话管理解决三个问题:

  • 冷启动:npx起一个子进程要几秒,不能每次请求都起。会话池把子进程留下,initialize()之后复用。
  • 互相拖死:每个 Server 一把创建锁,一个 Server 启动卡住,不会阻塞其他 Server。
  • 失败自愈:会话在上下文边界抛异常时,从池里摘掉,下次重建。

调用侧还有一把会话内锁:同一个 Server 的call_tool串行执行;高德另外限制调用起始间隔(0.36 秒),遇到 QPS 超限退避重试。这些是实现策略,不是 MCP 协议的要求。

超时是另一组必须写清的数字:

位置超时说明
Server 启动30 秒包含启动、建会话、initialize()
12306 工具默认 14 秒整次调用,含冷启动和等锁
12306 部分核验8 秒站名解析、途经核验
规划精修7 秒只包住模型合成

启动时预热高德和 Tavily;12306 不预热。原因写在代码注释里:它一启动就请求官网,网络抖动会让进程直接退出。预热失败也不影响启动,只是第一次查班次要把冷启动时间算进去。

11. 高德 MCP 实战

一句话:先把地名换成坐标,再拿坐标查路线;返回是文本,解析要兜底。

这个项目用了高德的四个工具:

工具参数返回
maps_geoaddress地理编码,含location(lng,lat)
maps_direction_drivingorigin、destination(坐标)路线paths[0]:distance、duration、steps[].polyline
maps_weathercityforecasts[].casts或lives
maps_text_searchkeywords、cityPOI 列表:名称、地址、照片

调用参数长这样:

[{"name":"maps_geo","arguments":{"address":"北京"}},{"name":"maps_direction_driving","arguments":{"origin":"116.40,39.90","destination":"104.06,30.67"}},{"name":"maps_weather","arguments":{"city":"成都"}},{"name":"maps_text_search","arguments":{"keywords":"成都 景点","city":"成都"}}]

流程上有两个约束:

  • 地理编码要先做。路径规划只认坐标;拿地名直接调,会得到失败或空结果。坐标有缓存时跳过这一步。
  • 解析必须兜底。结果文本里可能是 JSON,也可能是被包装过的文本;代码要能从geocodes、return、pois里挑location,从route.paths[0]取距离时长,从forecasts或casts取天气序列。解析失败时退回正则。

高德对频率敏感:同一个会话的调用串行,起始间隔 0.36 秒,QPS 超限退避重试。这也是为什么「四个查询并发提交」不等于「四个请求同时发出」——它们只是同时进入队列。

规划里最容易被忽略的降级是路线失败:拿不到驾车结果时,用球面距离估算路网里程,避免整份行程退化成「目的地游」。天气拿不到时写「天气信息暂缺」;POI 不够时用内置的县域候选补足。

12. 12306 MCP 实战

一句话:先城市换站点码,再按站点查车次;查不到就用静态参考班次兜底。

12306 的工具更贴近业务:

工具参数用途
get-current-date无取当前日期
get-station-code-of-cityscitys: "北京|上海"城市 → 站点码
get-station-code-by-namesstationNames: "北京南|上海虹桥"站名 → 站点码
get-ticketsdate、fromStation、toStation、format、trainFilterFlags、limitedNum查车次

一次高铁方案大致是:如果没传出行日期,先取日期;再把城市转成站点码,然后用站点码查get-tickets,最后把班次附到行程里。它只在「高铁 + 到站租车」模式下触发,普通自驾不会调 12306。

12306 的失败并不罕见:官网限流、网络抖动、车次查不到,代码都按失败处理——查不到就退回内置的静态参考班次,并在结果里标明来源。静态班次不保证准确,但能保证页面不空;这是工程取舍。

两个 Server 都拿到了,下一节把它们串成一次规划。

13. 一次规划的流程

一句话:先取事实,再跑规则,边算边推;模型不在工具与规则的主链路上。

图 8:一次路书规划的完整时序

三个设计点:

1. 先事实,后规则。MCP 只把坐标、路线、天气、POI 取回来;逐日安排、预算、清单、适合谁,全部由规则函数从事实拼出来。这样数字可复算,改路时才能算清「多开了多少公里」。

2. 流式暴露过程。工具调用要几秒,页面不能白等。骨架先出,geo、route、weather、palette、itinerary依次推给前端。冷路径里route会推两次(取回路线后一次,规则算完里程后一次),itinerary通常两次(规则版、附加信息后的最终版),开启精修时再多一次。命中缓存时事件更少,palette会先于geo。

3. 缓存的是整份 trip。相同参数命中内存缓存时,工具调用全部跳过,只把缓存的阶段重放一遍。缓存没有持久化,进程重启即失效。

流程里模型只出现在两个位置,下一节展开。

14. 模型的两个位置

一句话:模型只做「把非结构化输入变成结构」,以及「可选地重写一版」;默认路径不参与算数字,精修是例外。

规划模块里,模型只有两个入口:

一、参数抽取。出发地或目的地缺失、且有一句话可解析时,才调模型从句子中抽origin、destination、days,要求只输出 JSON。字段齐了就直接用表单,不调模型。

二、可选精修。ROADBOOK_LLM_REFINE=1时,规则路书先生成、先推送,然后最多等 7 秒让模型合成一版;超时或异常就保留规则版。

第二点有个值得记住的教训:让模型输出结构化数据时,输出契约必须和消费方一致。精修提示词要的是完整行程 JSON,但里面没有budget、fit_verdict、checklist、pitfalls这些字段,代码也没有把模型结果和规则版合并。结果不是「文案变差」,而是数据缺字段——预算、必知、清单各自以占位、回退或残留旧状态的方式表现出来。同时,精修版里的distance、drive_hours也可能来自模型,不再是规则算出的值。

对话改路是另一个对照:意图解析不调模型,用正则识别天数、起终点、途经城、节奏、预算,城市拿CITY_COORDS校验。普通局部改动走规则;改起终点会重新进入规划流程,开启精修且未命中缓存时,仍可能调模型。

一句话总结:模型适合把非结构化输入变成结构,不适合生成你可以算出来的数字。

这些位置也带来新的故障模式。

15. 故障与边界

一句话:工程里的失败大多出在进程、超时、会话和契约上,而不是模型本身。

故障现象现有处理边界
子进程冷启动第一次调用慢几秒启动时预热高德/Tavily12306 不预热,首次查班次慢
会话异常某个 Server 一直失败异常穿过上下文时摘除重建被吞掉的错误不会触发淘汰
超时页面等不到结果精修 7 秒回退;12306 工具 14 秒后返回空超时不等于取消,后台请求可能还在跑
旧响应旧路书覆盖新结果改路用请求序号(epoch),新规划用 AbortController都在前端,服务端无幂等键
限流请求被拒分钟限流、并发闸门、日配额单进程内存计数,多实例不共享
契约漂移精修后字段缺失规则版兜底没有 schema 校验与合并

本地跑通之后,才谈得上换远程。

16. 上远程 MCP 要补什么

一句话:本地换远程,第一件事不是改协议,而是补身份、密钥、隔离和运维。

要补的本地 stdio远程 Streamable HTTP
鉴权无协议级鉴权;密钥经环境变量注入OAuth / Token
密钥位置本机 Server 进程服务端,模型不可见
多用户不涉及租户隔离与配额
失败处理冷启动、进程崩溃网络超时、限流、重试
版本升级跟 Host 走独立部署,schema 要兼容
数据合规本机数据驻留与审计

什么时候该上远程:工具要共享、密钥要集中、用户跨设备、需要统一审计。什么时候本地就够:桌面应用、用户自己的 Key、需要读本机文件、追求低延迟。

这个项目选本地,是因为它本来就是单机应用:高德的 Key 应该在用户自己手里,放进 Server 子进程的环境变量,模型永远看不到。换成远程,第一件事是加一个代理,把密钥和多租户挡在模型之外。

最后是代码地图和决策清单。

17. 代码地图

文件管什么先看
agent.py模型决定调用的 agentinit_agent_service
mcp_client.pyClient 侧:注册、会话、预热_build_servers、open_server_session
desktop_txt_mcp.py30 行的自写 Server(见第 10 节)count_desktop_txt_files
travel_app.pyHost:路由与 SSEplan_stream、routes
trip_planner.py管线:工具调用与规则_gather_amap_staged、_build_fast_itinerary
rail_hsr.py12306 工具与班次attach_hsr_rental_to_trip、fetch_hsr_trains
static/js/roadbook-ui.js前端:SSE、地图、海报startPlan、handleStage

阅读顺序

想跟一次完整调用,按这条线读:startPlan→/api/plan→plan_trip_async→_gather_amap_staged→open_server_session/call_tool→_build_fast_itinerary→handleStage。

本地运行

本地运行需要 Python 3.11+ 和可执行的npx:

gitclone https://github.com/devgxy/roadbook.gitcdroadbook python3-mvenv .venv&&source.venv/bin/activate pipinstall-rrequirements.txtcp.env.example .env# 至少填 AMAP_MAPS_API_KEYpython travel_app.py

浏览器打开http://127.0.0.1:7861。算路要AMAP_MAPS_API_KEY,配图要TAVILY_API_KEY,参数抽取、可选精修和桌面助手要DASHSCOPE_API_KEY。

产品侧的说明在 product-design.md、roadbook-spec.md、interaction-ui.md。

18. 决策清单

全文小结:六个问题:

  1. 接工具用 MCP 还是直接 API?工具会被多个 Host 复用、需要标准发现与鉴权,选 MCP;一次性、无状态、只服务一个应用,直接 API 更简单。
  2. 本地还是远程?密钥属于用户、需要读本机文件、单机应用,选本地;要共享、要集中鉴权、要跨设备,选远程。
  3. Agent 还是管线?任务开放、工具集会变,选 agent;结果要可复算、要审计、流程固定,选管线。
  4. 模型还是规则?把非结构化输入变成结构,用模型;能从字段算出来的数字,用规则。
  5. 流式还是批量?工具耗时明显、用户需要感知进度,用 SSE;一次调用就返回,普通 JSON 即可。
  6. 模型输出怎么校验?结构必须和消费方一致;宁可回退规则版,也不要让缺字段的数据流进界面。

MCP 标准化了「工具怎么接」;但决定「谁来选工具、结果怎么用」的,始终是 Host 里的那套编排。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询