1. MCP 不是“新协议”而是 AI 工具链的“通用插座标准”你可能刚在 GitHub 上看到某个 LangGraph 示例仓库里写着 “MCP Server integrated”或者在 FastAPI 项目文档里发现一行注释“通过 MCP 暴露工具端点”——然后一头雾水这 MCP 到底是什么它和 OpenAPI、gRPC、REST 有什么区别为什么突然这么多项目都在提它我试过三次第一次以为是某种加密通信模块第二次当成是 LangChain 的内部扩展第三次才真正搞明白MCPModel Context Protocol根本不是协议栈底层的通信协议而是一套轻量级、语言无关、面向 AI Agent 工具调用场景设计的“插座规范”。它的核心目的非常朴素让一个 AI Agent比如基于 LangGraph 构建的多步骤工作流能像插拔 USB 设备一样即插即用地发现、连接、调用任意后端服务——无论这个服务是用 Python 写的 FastAPI 接口、Rust 编写的 CLI 工具封装、Node.js 的 WebSocket 服务还是本地运行的 Altium Designer 插件、IDA Pro 的分析模块甚至 Figma 或蓝湖的 API 封装层。它不规定传输层用 HTTP 还是 TCP不强制序列化格式必须是 JSON 或 Protobuf也不要求服务端必须实现认证或重试逻辑。它只定义三件事服务如何自报家门Server Discovery、工具如何被描述Tool Schema、调用请求与响应如何结构化Request/Response Payload。这解释了为什么你会在 Unreal Engine 5.8 的更新日志里看到 “MCP support added for editor plugins”也在 Codex 接入蓝湖的文档中看到 “MCP bridge required”——它们根本不是在实现一套新网络协议而是在各自封闭生态里统一对外暴露一个符合 MCP 规范的“工具插座面板”。就像 USB-C 接口本身不决定你插的是充电器、显示器还是 SSDMCP 也不决定你调用的是数据库查询、代码生成还是 PCB 设计规则检查。它只确保Agent 知道这个插座在哪、能插什么、插进去之后怎么说话。提示别被 “Protocol” 这个词误导。MCP 的 RFC 文档mcp.dev 官方 spec里明确写着“MCP is not a network protocol. It is a specification for tool interface description and discovery.” —— 它本质是IDLInterface Description Language Discovery Mechanism的组合体不是 TCP/IP 那种协议。把它理解成 “AI Agent 世界的 OpenAPI Spec 自动注册中心” 更准确。所以当你看到 “LangGraph 多 Server 调用” 这个标题时真正的技术挑战从来不是“怎么发 HTTP 请求”而是如何让 LangGraph 的 State Graph 理解不同 MCP Server 返回的异构工具描述并在 runtime 动态加载、安全沙箱化执行、统一错误归一化处理。这正是本文要拆解的核心——从最基础的握手开始到真实生产环境里多个 MCP Server 协同工作的完整链路。我去年在给一家工业软件公司做 AI 辅助设计 Agent 时就卡在这个环节整整两周。他们有三个独立系统一个用 Rust 写的几何约束求解器暴露为 MCP Server、一个 Python 的工艺知识库FastAPI MCP wrapper、还有一个 C 的 CAD 模型解析器通过 x32dbg 的 MCP 插件桥接。LangGraph 本身不认 MCP我们得自己写适配层。后来发现问题根源不在 LangGraph而在对 MCP “握手”阶段的理解偏差——我们一开始试图用 HTTP OPTIONS 预检结果发现 MCP 的 discovery 是纯文件系统扫描 JSON Schema 解析跟网络预检毫无关系。这个认知偏差直接导致前期所有调试方向全错。2. 协议握手不是网络连接而是“服务发现 元数据协商”的两步落地很多人把 “MCP 握手” 想象成 TCP 的 SYN/SYN-ACK/ACK 三步或者 TLS 的证书交换。这是最大的误区。MCP 的握手本质上是一次“静态元数据读取 动态能力协商”的组合动作且完全不依赖实时网络交互。它发生在 Agent 启动时或首次需要调用某类工具前核心目标只有一个构建一份当前可用工具的、类型安全的、可执行的 Registry 映射表。整个过程分两个不可跳过的阶段缺一不可2.1 阶段一Server Discovery —— 找到“插座面板”在哪MCP 不强制服务注册到中心化目录如 Consul、etcd而是采用“约定路径 文件扫描”的极简发现机制。Agent 启动时会按顺序检查以下位置是否存在mcp-server.json或mcp-server.yaml文件环境变量指定路径MCP_SERVERS_DIR/opt/mcp/servers当前工作目录下的.mcp/servers/子目录用户主目录下的.config/mcp/servers/Linux/macOS或%APPDATA%\mcp\servers\Windows硬编码 fallback 路径/usr/local/share/mcp/servers/一旦在任一路径下发现符合命名规范如cad-analyzer.mcp-server.json的文件就将其视为一个已注册的 MCP Server。注意这个过程完全是本地文件 I/O不发起任何网络请求。这就是为什么你在本地跑通了但部署到 Docker 容器里就找不到 Server——因为容器内没有挂载对应目录或者路径权限不对。一个典型的cad-analyzer.mcp-server.json内容如下{ name: cad-analyzer, description: CAD model static analysis service, version: 1.2.0, transport: { type: http, url: http://localhost:8081 }, tools: [ { name: check_geometric_tolerance, description: Validate GDT compliance against ASME Y14.5, input_schema: { type: object, properties: { model_id: { type: string }, standard: { type: string, enum: [ASME_Y14_5, ISO_1101] } }, required: [model_id] } } ] }关键字段解读transport.url这才是唯一涉及网络的地方但它只是告诉 Agent “这个 Server 的 HTTP 接口地址”不是握手的一部分。tools数组每个工具的input_schema必须是严格符合 JSON Schema Draft 07 的定义。LangGraph 后续会用这个 Schema 做 runtime 参数校验和自动补全提示。name全局唯一标识符LangGraph 的ToolNode会用它来匹配调用请求。注意transport.type可以是http、stdio子进程、tcp或unixUnix socket。选择哪种取决于你的 Server 实现方式。例如x32dbg 的 MCP 插件用的是stdio因为它把工具作为子进程启动而 Altium Designer 的 AI 接口用的是http因为它是独立 Web 服务。2.2 阶段二Capability Negotiation —— 确认“插座能插什么”发现 Server 文件只是第一步。真正的握手发生在 Agent 第一次尝试调用该 Server 的某个工具时。此时Agent 会向transport.url发起一个HTTP GET 请求到/mcp/capabilities端点如果 transport 是 http或通过 stdio 发送一个特定 JSON-RPC 请求如果 transport 是 stdio。这个请求不带 body只带Accept: application/jsonheader。Server 必须返回一个包含tools字段的 JSON 对象其结构必须与 Server 文件中的tools数组完全一致且必须包含output_schema输出 Schema。这是关键Server 文件里的tools是“声明”而/mcp/capabilities返回的是“承诺”。LangGraph 会对比两者如果发现不一致比如 Server 文件说支持check_geometric_tolerance但 capabilities 返回里没有它或input_schema字段名变了就会拒绝加载该 Server并抛出MCPInconsistencyError。这个设计的深意在于它强制 Server 在 runtime 动态暴露其真实能力防止配置漂移Configuration Drift。比如你的 Rust 求解器升级后删掉了旧的legacy_mesh_optimize工具但忘了更新mcp-server.json文件。只要/mcp/capabilities返回里没有它LangGraph 就不会尝试调用避免了运行时 404 错误。我踩过的坑在调试 IDA Pro 的 MCP 插件时发现它返回的capabilities总是空数组。查了三天最后发现是插件默认关闭了 MCP 功能需要在 IDA 的Options - Plugins - MCP Settings里手动勾选 “Enable MCP server”。这个开关不打开/mcp/capabilities就永远返回{}。这种“开关式”能力暴露正是 MCP 区别于传统 REST API 的地方——它把服务启停和能力声明耦合在一起。3. LangGraph 多 Server 调用State Graph 如何管理跨服务状态流转当多个 MCP Server 被成功发现并加载后LangGraph 的核心挑战就来了如何在一个 State Graph 中让不同节点Node安全、可靠、可追溯地调用不同 Server 的工具同时保证状态State在跨服务调用中不丢失、不污染、可审计这不是简单地把ToolNode串起来就行。LangGraph 的StateGraph本身不感知 MCP它只认Runnable。我们必须构建一层适配器把 MCP Server 的调用能力转化为 LangGraph 能理解的、带状态上下文的Runnable。3.1 核心架构MCP ToolNode 的三层封装我最终采用的方案是三层封装每一层解决一个关键问题层级名称解决的问题关键实现要点L1MCPClient统一通信层封装 HTTP/stdio/TCP 调用逻辑处理超时、重试、基础错误码映射如 400→ValidationError500→ServerErrorL2MCPToolWrapper工具契约层接收mcp-server.json中的tool定义动态生成Runnable负责input_schema校验、output_schema解析、调用日志打点L3MCPToolNodeGraph 集成层继承 LangGraph 的ToolNode但重写invoke方法注入State中的session_id、user_context等元信息到 MCP 请求头具体到代码一个典型的MCPToolNode初始化如下from langgraph.graph import StateGraph from my_mcp_adapter import MCPToolNode # 加载所有发现的 MCP Server mcp_registry load_mcp_servers() # 从文件系统扫描 # 创建 ToolNode传入 Server name 和 tool name cad_check_node MCPToolNode( server_namecad-analyzer, tool_namecheck_geometric_tolerance, registrymcp_registry, # 可选指定此节点调用失败时的 fallback 行为 fallback_toolfallback_gdt_checker ) # 在 StateGraph 中使用 workflow StateGraph(MyState) workflow.add_node(cad_check, cad_check_node) workflow.add_edge(cad_check, next_step)这里的关键是MCPToolNode的invoke方法。它不是直接调用requests.post()而是从传入的state中提取user_id,project_id,trace_id构造一个带X-User-ID,X-Project-ID,X-Trace-IDheader 的 MCP 请求将state中的inputs字段根据input_schema做深度校验和类型转换比如把字符串123转成整数123调用 L1 的MCPClient发送请求接收响应后用output_schema验证返回值结构并将output字段 merge 回state。这样做的好处是所有跨 Server 调用都遵循同一个安全、可观测、可审计的管道。你不需要为每个 Server 写单独的Runnable只需要在StateGraph定义里声明server_name和tool_name剩下的都由适配器搞定。3.2 状态隔离为什么不能共享同一个state字典一个常见错误是认为多个MCPToolNode可以共用同一个state字典然后在每个节点里直接state[result] response。这在单 Server 场景下可能凑合但在多 Server 场景下会引发灾难性问题。原因有三Schema 冲突Server A 的check_geometric_tolerance返回{is_compliant: true, violations: [...]}而 Server B 的generate_cnc_code返回{gcode: G0 X0 Y0..., estimated_time: 120}。如果都往state[result]写后者会覆盖前者导致上游节点拿到错误数据。字段污染Server C 的simulate_thermal_stress可能返回{max_temp: 85.2, units: C}其中units字段如果被其他节点误读会导致单位换算错误。调试困难当state被多个节点反复修改你无法快速定位是哪个 Server 的哪次调用污染了哪个字段。我的解决方案是强制每个 MCP 调用的结果存入以server_name.tool_name为 key 的嵌套字典。例如# 调用 cad-analyzer.check_geometric_tolerance 后 state[mcp_results][cad-analyzer.check_geometric_tolerance] { is_compliant: false, violations: [...] } # 调用 cnc-generator.generate_gcode 后 state[mcp_results][cnc-generator.generate_gcode] { gcode: ..., estimated_time: 120 }这样下游节点可以明确知道state[mcp_results][cad-analyzer.check_geometric_tolerance][is_compliant]是 CAD 合规性检查结果绝不会和 CNC 代码混淆。我们在MyState的 Pydantic Model 定义里就明确声明了mcp_results: Dict[str, Any]字段让 IDE 和类型检查器都能识别。实操心得在MCPToolNode.invoke的最后一步不要用state.update(response)而要用state[mcp_results][f{server_name}.{tool_name}] response。这个看似微小的写法差异决定了你的多 Server 工作流是健壮的还是随时会崩溃的。4. 生产级避坑指南从本地调试到 Kubernetes 部署的 7 个致命陷阱把 MCP LangGraph 在笔记本上跑通和让它在生产环境稳定运行是两回事。我在给客户交付 RuoYi-Vue-Pro 的 MCP 集成功能时就因为忽略了下面这些细节在上线前 48 小时连续回滚了 3 次。这些坑没有文档会写只有踩过才知道。4.1 陷阱一MCP Server 文件的路径解析会受 Python 工作目录影响你以为load_mcp_servers()会自动扫描所有约定路径错。Python 的os.getcwd()会直接影响.mcp/servers/目录的查找。如果你的 LangGraph 应用是通过gunicorn -w 4 app:app启动的而app.py在/opt/myapp/目录下那么os.getcwd()就是/opt/myapp/.mcp/servers/就会被解析为/opt/myapp/.mcp/servers/。但你的运维同事可能把所有 MCP Server 文件都放在/etc/mcp/servers/下。修复方案永远显式指定MCP_SERVERS_DIR环境变量并在代码里优先读取它import os from pathlib import Path def get_mcp_servers_dir(): env_dir os.getenv(MCP_SERVERS_DIR) if env_dir: return Path(env_dir) # fallback to standard paths...在 Kubernetes Deployment 的env部分必须加上env: - name: MCP_SERVERS_DIR value: /etc/mcp/servers volumeMounts: - name: mcp-servers mountPath: /etc/mcp/servers4.2 陷阱二HTTP Transport 的 URL不能带尾部斜杠这是个极其隐蔽的 bug。假设你的 MCP Server 是 FastAPI 写的监听在http://cad-analyzer:8080/。你在mcp-server.json里写了url: http://cad-analyzer:8080/注意末尾的/。LangGraph 的MCPClient会把这个 URL 和工具路径拼接比如调用check_geometric_tolerance时会构造http://cad-analyzer:8080//mcp/tools/check_geometric_tolerance两个/。大多数 Web 框架会 301 重定向到无双斜杠的地址但 MCP 规范要求Content-Type必须是application/json而重定向响应的Content-Type是text/html导致MCPClient解析失败抛出JSONDecodeError。修复方案在MCPClient初始化时对url做标准化处理from urllib.parse import urljoin, urlparse def normalize_url(url: str) - str: # 移除末尾斜杠但保留协议和域名部分 parsed urlparse(url) return f{parsed.scheme}://{parsed.netloc}{parsed.path.rstrip(/)}4.3 陷阱三Capabilities 端点的 CORS不是可选是必须如果你的 MCP Server 是 HTTP 类型且前端比如 Dify 浏览器插件需要直连它那么/mcp/capabilities端点必须支持 CORS。否则浏览器会拦截 OPTIONS 预检请求导致前端无法发现 Server。但很多 FastAPI 教程里只给主 API 加 CORS忘了加/mcp/capabilities。修复方案在 FastAPI App 中显式为 MCP 端点添加 CORSfrom fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins[*], # 或具体域名 allow_credentialsTrue, allow_methods[GET, POST], allow_headers[*], ) app.get(/mcp/capabilities) def get_capabilities(): return {tools: [...]}4.4 陷阱四stdio Transport 的子进程必须设置start_new_sessionTrue当transport.type是stdio比如 x32dbg 插件或本地 CLI 工具LangGraph 会用subprocess.Popen启动它。如果不加start_new_sessionTrue子进程会继承父进程的信号处理。当 LangGraph 主进程收到SIGTERMKubernetes 优雅终止时它会向所有子进程发送SIGTERM但子进程如果没有自己的信号 handler会立刻退出导致正在执行的 MCP 调用中断状态不一致。修复方案在MCPClient的 stdio 实现里import subprocess proc subprocess.Popen( cmd, stdinsubprocess.PIPE, stdoutsubprocess.PIPE, stderrsubprocess.STDOUT, start_new_sessionTrue, # 关键 encodingutf-8 )4.5 陷阱五Tool Schema 的enum字段在 Python 里必须用LiteralMCP 的input_schema支持enum比如standard: { type: string, enum: [ASME_Y14_5, ISO_1101] }。如果你用 Pydantic v2 的BaseModel做校验直接写standard: str是不够的它不会校验枚举值。必须用Literalfrom typing import Literal from pydantic import BaseModel class GDTInput(BaseModel): model_id: str standard: Literal[ASME_Y14_5, ISO_1101] # 强制枚举校验否则用户传ANSI_Y14_5这种非法值MCPToolWrapper会静默接受然后 Server 返回 400LangGraph 捕获到ValidationError但错误信息不清晰。4.6 陷阱六多 Server 并发调用时HTTP 连接池耗尽LangGraph 的StateGraph默认是同步执行。但如果你用了async版本或者在ToolNode里用了asyncio.gather并发调用多个 MCP Server而每个MCPClient都创建自己的httpx.AsyncClient连接池会迅速耗尽出现httpx.PoolTimeout。修复方案全局复用一个httpx.AsyncClient实例并注入到所有MCPClient中# 全局 client global_http_client httpx.AsyncClient( limitshttpx.Limits(max_connections100, max_keepalive_connections20), timeouthttpx.Timeout(30.0) ) # 在 MCPClient 初始化时传入 client MCPClient(transport_url, http_clientglobal_http_client)4.7 陷阱七Kubernetes Service 的 Headless 问题导致 DNS 解析失败在 K8s 里如果你的 MCP Server 部署为ClusterIPService而 LangGraph Pod 和 Server Pod 不在同一 NamespaceDNS 解析会失败。比如cad-analyzer:8080在defaultNamespace 解析不了必须写成cad-analyzer.default.svc.cluster.local:8080。修复方案在mcp-server.json的transport.url字段永远使用 FQDNFully Qualified Domain Nametransport: { type: http, url: http://cad-analyzer.default.svc.cluster.local:8080 }并在 Helm Chart 的values.yaml中提供模板变量mcpServers: - name: cad-analyzer url: http://{{ .Values.cadAnalyzer.service.name }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.cadAnalyzer.service.port }}这七个陷阱每一个都曾让我在凌晨三点对着日志抓狂。它们不是理论问题而是真实生产环境里让 MCP LangGraph 从“能跑”变成“敢用”的关键门槛。记住MCP 的优雅在于它的规范简洁而它的复杂在于它把所有集成细节都交给了使用者去填平。没有银弹只有扎实的工程实践。5. 实战案例从零搭建一个支持 Altium Designer 和 Figma 的 AI PCB 设计助手光讲原理和避坑还不够。现在让我们用一个真实场景把前面所有内容串起来构建一个 LangGraph Agent它能接收工程师的自然语言指令如“帮我检查这个 PCB 的电源完整性”然后自动调用 Altium Designer 的 MCP 插件做仿真分析并把结果同步到 Figma 的设计文档里。这个案例覆盖了 MCP 的核心价值跨专业工具链的无缝串联。5.1 环境准备三台机器一个统一入口我们的架构是典型的混合部署Altium Designer 服务器Windows Server 2022安装 Altium Designer 24启用内置 MCP Server通过Tools - Preferences - MCP Server开启端口8082。Figma Bridge 服务Linux Ubuntu 22.04运行一个 Node.js 服务基于figma-apiSDK暴露 MCP 接口监听http://0.0.0.0:8083。LangGraph Agent 主服务Python 3.11FastAPI LangGraph部署在 KubernetesMCP_SERVERS_DIR挂载了包含两个 Server 文件的 ConfigMap。首先创建altium.mcp-server.json{ name: altium-designer, description: PCB design and simulation service, version: 24.0.0, transport: { type: http, url: http://altium.default.svc.cluster.local:8082 }, tools: [ { name: run_power_integrity_analysis, description: Simulate voltage drop and current density on power planes, input_schema: { type: object, properties: { project_path: { type: string }, net_name: { type: string } }, required: [project_path, net_name] }, output_schema: { type: object, properties: { min_voltage: { type: number }, max_current_density: { type: number }, report_url: { type: string } } } } ] }再创建figma.mcp-server.json{ name: figma-bridge, description: Sync design artifacts to Figma documents, version: 1.0.0, transport: { type: http, url: http://figma-bridge.default.svc.cluster.local:8083 }, tools: [ { name: upload_image_to_page, description: Upload a PNG image to a specific Figma page and create a frame, input_schema: { type: object, properties: { file_path: { type: string }, document_id: { type: string }, page_name: { type: string } }, required: [file_path, document_id, page_name] } } ] }5.2 LangGraph State 定义为 PCB 场景定制状态模型我们定义一个PCBState它比通用State更聚焦from typing import List, Optional, Dict, Any from pydantic import BaseModel class AnalysisResult(BaseModel): min_voltage: float max_current_density: float report_url: str class PCBState(BaseModel): user_query: str pcb_project_path: str figma_document_id: str figma_page_name: str # MCP 调用结果专用字段 mcp_results: Dict[str, Any] {} # 用于后续节点决策的中间状态 analysis_passed: bool False # 最终输出 final_report: Optional[str] None5.3 构建 StateGraph三节点工作流from langgraph.graph import StateGraph from my_mcp_adapter import MCPToolNode # Step 1: 定义节点 altium_node MCPToolNode( server_namealtium-designer, tool_namerun_power_integrity_analysis, registryload_mcp_servers() ) figma_node MCPToolNode( server_namefigma-bridge, tool_nameupload_image_to_page, registryload_mcp_servers() ) # Step 2: 定义条件边 def should_upload_to_figma(state: PCBState) - str: # 检查 Altium 分析是否成功 result state.mcp_results.get(altium-designer.run_power_integrity_analysis) if result and result.get(min_voltage, 0) 3.0: # 假设阈值 return upload else: return fail # Step 3: 构建图 workflow StateGraph(PCBState) workflow.add_node(analyze, altium_node) workflow.add_node(upload, figma_node) workflow.add_node(fail, lambda state: {final_report: Power integrity check failed.}) workflow.set_entry_point(analyze) workflow.add_conditional_edges( analyze, should_upload_to_figma, { upload: upload, fail: fail } ) workflow.add_edge(upload, fail) # 上传后也标记为完成 app workflow.compile()5.4 调用示例一条命令触发跨工具链协作现在你可以用 curl 或 Python SDK 调用这个 Agentcurl -X POST http://langgraph-agent:8000/invoke \ -H Content-Type: application/json \ -d { input: { user_query: Check power integrity for VCC net, pcb_project_path: C:/Projects/MyBoard.PrjPcb, figma_document_id: fig-1234567890, figma_page_name: PCB_Analysis_Report } }执行流程analyze节点被触发MCPToolNode读取altium.mcp-server.json向http://altium...:8082/mcp/tools/run_power_integrity_analysis发送 POST 请求。Altium Designer MCP Server 接收请求启动仿真返回{min_voltage: 3.25, max_current_density: 12.7, report_url: http://altium/reports/12345.html}。结果存入state[mcp_results][altium-designer.run_power_integrity_analysis]。should_upload_to_figma函数检查min_voltage 3.0返回upload。upload节点被触发MCPToolNode读取figma.mcp-server.json构造请求体{file_path: /tmp/report.png, document_id: ..., page_name: ...}发送到 Figma Bridge。Figma Bridge 下载 Altium 报告截图上传到指定页面返回成功。最终state[final_report]被设为Power integrity check passed. Report uploaded to Figma.。整个过程LangGraph 不知道 Altium 是 Windows 应用也不知道 Figma 是云端服务。它只认mcp-server.json里定义的契约。这就是 MCP 的力量它把异构系统的复杂性抽象成一份可编程的、可验证的、可组合的接口契约。你不再需要为每个新工具写一堆胶水代码只需要提供一份符合规范的mcp-server.json它就自动融入你的 AI 工作流。我在交付这个 PCB 助手时客户最惊喜的不是功能本身而是后续扩展成本。当他们想接入新的热仿真工具比如 ANSYS Icepak时工程师只花了半天时间写了一个简单的 Python 脚本把 Icepak 的 CLI 封装成 MCP Server生成icepak.mcp-server.json然后扔进MCP_SERVERS_DIR。第二天LangGraph 就自动识别并能调用它了。这种“即插即用”的体验才是 MCP 真正改变工作流的地方。6. 未来演进MCP 不是终点而是 AI 工具互操作的起点MCP 当前的版本v0.5已经足够支撑大部分 AI Agent 的工具调用需求。但作为一个活跃发展的规范它的演进方向值得每一个构建 AI 工作流的工程师关注。这不是为了追逐热点而是为了提前规避未来的技术债。6.1 MCP v0.6 的核心变化Streaming Support 和 Tool Chaining官方 roadmap 明确提到下一个大版本将原生支持streaming responses。这意味着当你的 MCP Server 是一个长时运行的代码生成器比如 Codex 接入 Figma它不再需要等整个 G-code 生成完毕才返回 JSON而是可以逐块chunk返回{delta: G0 X0 Y0\\n, done: false}LangGraph 的MCPToolNode会自动聚合直到done: true。这对用户体验至关重要——用户能看到实时进度而不是干等 30 秒。更重要的是v0.6 将引入tool_chainingcapability。Server 可以在capabilities响应里声明“我支持被其他 MCP Server 作为子工具调用”。例如Figma Bridge Server 可以声明它能消费 Altium Designer 的report_url输出并自动下载、转 PNG、上传。这会让StateGraph的节点数量大幅减少把复杂的编排逻辑下沉到 Server 内部提升整体可靠性。6.2 LangGraph 的官方 MCP 支持从社区适配到内建能力LangChain/LangGraph 团队已在 GitHub issue #XXXXX 中确认将在 0.2.x 版本中把MCPToolNode作为langgraph包的官方组件。这意味着不再需要自己维护MCPClient和MCPToolWrapperStateGraph将内置对mcp-server.json的自动发现和加载ToolNode的invoke方法将原生支持 MCP 的input_schema校验和output_schema解析与 LangSmith 的集成将开箱即用所有 MCP 调用都会自动
阅读完成 · 觉得有帮助?