Doramagic 项目包 · 项目说明书
yade-mcp 项目
连接 AI 智能体与 YADE 的 MCP 服务器,通过自然对话运行 DEM 离散元仿真。
概览与系统架构
yade-mcp 是面向 YADE 离散元仿真框架的 Model Context Protocol (MCP) 适配器,使 AI 智能体能够以工具调用的方式直接驱动 YADE 的 Python 运行时。项目仓库由两个并列的发行包组成:yade-mcp(MCP 客户端/服务端库)和 yade-mcp-bridge(运行在 YADE 进程内的代理)。README 开头点明 "O...
继续阅读本节完整说明和来源证据。
1. 项目定位与设计目标
yade-mcp 是面向 YADE 离散元仿真框架的 Model Context Protocol (MCP) 适配器,使 AI 智能体能够以工具调用的方式直接驱动 YADE 的 Python 运行时。项目仓库由两个并列的发行包组成:yade-mcp(MCP 客户端/服务端库)和 yade-mcp-bridge(运行在 YADE 进程内的代理)。README 开头点明 "O.engines += [LLM()] # yet another engine.",表明其目标是把 LLM 当作 YADE 中的一个引擎来使用 资料来源:README.md:1-25。
整个系统被刻意拆成两端,原因是 YADE 自身占据 GIL 并大量使用 C++ 扩展,把网络层直接塞进 YADE 解释器内部会引发稳定性问题;引入独立 Bridge 进程则让 AI 工具栈与仿真主循环解耦。Bridge 端用 PyRunner 周期回调维持心跳,MCP 端用 FastMCP 暴露工具 资料来源:yade-mcp-bridge/src/yade_mcp_bridge/runtime/pyrunner.py:1-30、资料来源:src/yade_mcp/tools/query_api.py:8-12。
2. 双端架构
系统呈典型的 客户端—网关—宿主 三段式结构:
flowchart LR A[AI Agent / MCP Client] -->|stdio / MCP protocol| B[yade-mcp Server] B -->|WebSocket| C[yade-mcp-bridge] C -->|PyRunner tick| D[YADE Runtime / O.engines] D -->|console I/O + state| C C -->|events| B B -->|tool response| A
- AI Agent:通过标准 MCP 协议调用工具,例如
yade_query_api、yade_browse_api、yade_execute_code资料来源:src/yade_mcp/tools/query_api.py:12-40、资料来源:src/yade_mcp/tools/browse_api.py:10-44。 - yade-mcp Server:负责 API 文档检索、调用编码以及响应包络的构造。所有响应统一经过
build_ok()包装并注入_context.user_console上下文 资料来源:src/yade_mcp/contracts(按 yade-mcp v0.2.0 发行说明)。 - yade-mcp-bridge:在 YADE 进程内启动一个 WebSocket 服务(默认
ws://localhost:9002),由BridgeServer管理连接、由TaskDataBuilder构造统一响应 资料来源:yade-mcp-bridge/src/yade_mcp_bridge/transport/server.py、资料来源:yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py:7-46。 - YADE Runtime:Bridge 通过注入到
O.engines[0]的PyRunner周期回调(命令字符串固定为_mcp_pyrunner_tick() # yade-mcp-bridge: DO NOT MODIFY)与主循环同步 资料来源:yade-mcp-bridge/src/yade_mcp_bridge/runtime/pyrunner.py:10-25。
3. 核心组件
| 组件 | 所在包 | 职责 |
|---|---|---|
APISearch / APILoader | yade_mcp.knowledge.search、yade_mcp.knowledge.loader | 基于 371 份 YADE 类 JSON 做关键词检索与类树浏览 |
yade_query_api / yade_browse_api | yade_mcp.tools | 提供按关键字或按类路径(engine.GlobalEngine.NewtonIntegrator)的 API 查询 |
yade_execute_code | yade_mcp.tools.execute_code | 把一段 Python 直接送入 Bridge 执行,区分 interrupted / terminated / timeout 三种失败形态 |
TaskDataBuilder | yade_mcp_bridge.utils.response | 统一任务响应字典的拼装,状态字段(pending / running / completed / failed / interrupted)落在 data 内 |
ConsoleHistory | yade_mcp_bridge.console.history | 以 JSONL 形式持久化 IPython 输入输出,并维护投递游标 _last_delivered_id |
BridgeServer | yade_mcp_bridge.transport.server | HTTP/WS 宿主,负责多客户端路由与优雅停机 |
API 文档以离线 JSON 形式随包发布,例如 MaterialContainer.json 描述了 append/index 方法 资料来源:src/yade_mcp/knowledge/resources/python_api_docs/runtime/MaterialContainer.json:1-25,InteractionContainer.json 描述了 has/countReal/nth 等方法 资料来源:src/yade_mcp/knowledge/resources/python_api_docs/runtime/InteractionContainer.json:1-30,便于 LLM 在不连 Bridge 的情况下也能静态检索类层次。
4. 通信协议与生命周期
Bridge 与 MCP 之间采用 WebSocket 长连接。Bridge 端 start() 启动一个后台守护线程承担任务泵,使 YADE 交互控制台保持可用(非阻塞模式,v0.2.0 引入)——其状态机如下:
stateDiagram-v2 [*] --> idle idle --> running: 收到 execute_code / execute_task running --> interrupted: O.run 周期边界暂停 running --> terminated: async 异常注入成功 running --> timeout: C 扩展卡死,泵仍阻塞 running --> completed: 任务正常结束 completed --> idle terminated --> idle interrupted --> idle timeout --> [*]: 需要 Bridge 重启
历史日志通过 ConsoleHistory 持久化到 DATA_DIR/console_history.jsonl,游标写入 console_cursor.json,因此 MCP 客户端可随时 consume() 拉取新增条目而无状态负担 资料来源:yade-mcp-bridge/src/yade_mcp_bridge/console/history.py:23-58。任务输出分页(skip_newest / limit / filter_text)自 v0.2.1 起完全在 Bridge 端对原始日志进行,响应中显式返回 total_lines / line_range / has_older / has_newer 资料来源:yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py:7-46(参见 bridge-v0.2.1 发行说明)。
常见失效模式:当用户在 Bridge 启动后于 YADE IPython 中执行%run script.py,YADE 的PyRunner会用py::exec(cmd, __main__.__dict__)重新解析sys.modules['__main__'],造成NameError: name '_mcp_pyrunner_tick' is not defined—— v0.2.2 修复方案要求_make_pyrunner在__main__命名空间中注册符号 资料来源:yade-mcp-bridge/src/yade_mcp_bridge/runtime/pyrunner.py:10-30(参见 bridge-v0.2.2 发行说明)。
5. 启动与版本配套
- MCP 端:
pip install yade-mcp,使用yade-mcp命令启动 stdio 服务 资料来源:README.md:1-25。 - Bridge 端:在 YADE 的 IPython 中
import yade_mcp_bridge; yade_mcp_bridge.start(),启动横幅简化为单行YADE MCP Bridge on ws://<host>:<port>, log: <path>,初始化日志降至 WARNING 级别并写入bridge.log,避免污染交互提示符 资料来源:bridge-v0.3.1 发行说明。 - 版本配套:MCP 端 v0.3.x 与 Bridge 端 v0.3.x 通过 WebSocket 元数据兼容;新引入的取消元数据(
terminatedvstimeout)需 Bridge 至少 v0.3.0 资料来源:v0.3.0 发行说明。
来源:https://github.com/yusong652/yade-mcp / 项目说明书
MCP Server、工具与知识库
yade-mcp 项目由两个协同工作的 Python 包组成:yade-mcp(MCP Server 端,基于 FastMCP 暴露工具资源)和 yade-mcp-bridge(运行在 YADE 进程内的 WebSocket 桥接服务)。MCP Server 负责把工具调用翻译为 JSON-RPC 消息,桥接服务则负责在 YADE 的 Python 命名空间里执行真实操作,...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
架构概览
yade-mcp 项目由两个协同工作的 Python 包组成:yade-mcp(MCP Server 端,基于 FastMCP 暴露工具资源)和 yade-mcp-bridge(运行在 YADE 进程内的 WebSocket 桥接服务)。MCP Server 负责把工具调用翻译为 JSON-RPC 消息,桥接服务则负责在 YADE 的 Python 命名空间里执行真实操作,二者通过 WebSocket 在 ws://<host>:<port> 上通信 README.md:1-13。在桥接侧,所有消息分发由 handlers 包统一暴露,包括任务类(handle_execute_task、handle_check_task_status、handle_list_tasks、handle_interrupt_task)和控制台类(handle_execute_code、handle_console_history)处理器 yade-mcp-bridge/src/yade_mcp_bridge/handlers/__init__.py:1-28。
graph LR
Agent[AI Agent / MCP Client] -->|tools/call| Server[yade-mcp Server]
Server -->|JSON-RPC over WS| Bridge[yade-mcp-bridge]
Bridge -->|PyRunner tick| Yade[YADE __main__ namespace]
Yade -->|stdout / log| Bridge
Bridge -->|result| Server
Server -->|response| Agent
Server -.读取.-> KB[(knowledge/resources/python_api_docs)]MCP 工具集
工具注册入口位于 src/yade_mcp/tools/__init__.py,所有工具都通过 register(mcp: FastMCP) 挂载到 Server 上 src/yade_mcp/tools/__init__.py:1-22。整套工具围绕三大职能展开:知识库导航、YADE 进程内执行、任务生命周期管理。
知识库浏览与查询
yade_browse_api:按 YADE 原生类树浏览文档。路径是点号分隔的层级(如engine.GlobalEngine.NewtonIntegrator),未指定路径时返回顶层类别,导航完全沿父类链进行 src/yade_mcp/tools/browse_api.py:30-50。yade_query_api:按关键字做相关性搜索(类似 grep),返回按相关度排序的类/函数列表,适用于只知道关键词而不知道准确类名的场景 src/yade_mcp/tools/query_api.py:14-37。
代码与任务执行
yade_execute_code:在 YADE 进程中同步执行一段 Python 代码并立即返回 stdout。即便有任务在运行也能响应,因此常被用作实时 REPL 检查O.bodies、O.engines、应力张量等状态 src/yade_mcp/tools/execute_code.py:16-32。yade_execute_task:以异步方式提交本地脚本文件路径,桥接服务为它分配一个 6 位task_id并立即返回;脚本在后台由_make_pyrunner创建的 PyRunner 引擎驱动执行 src/yade_mcp/tools/execute_task.py:19-37。
任务生命周期管理
yade_check_task_status:支持skip_newest/limit/filter三个分页/过滤参数,桥接侧读取完整日志文件并返回显式分页字典(total_lines、line_range、has_older、has_newer),同时向下兼容旧版顶层status字段 src/yade_mcp/tools/check_task_status.py:1-44。yade_list_tasks:列出所有被追踪任务,支持skip_newest/limit翻页 src/yade_mcp/tools/list_tasks.py:17-30。yade_interrupt_task:通过flag_only与flag_and_async_exc两条路径协同工作,可在不重启桥接的情况下打断O.run任务或纯 Python 死循环,并保留 YADE__main__命名空间的状态 src/yade_mcp/tools/interrupt_task.py:1-30。
| 工具 | 同步/异步 | 主要用途 | 关键参数 |
|---|---|---|---|
yade_browse_api | async | 知识库类树浏览 | path |
yade_query_api | async | 关键字搜索 API | query, limit |
yade_execute_code | async(调用后阻塞等待 stdout) | 实时 REPL | code, timeout |
yade_execute_task | async(立即返回 task_id) | 提交后台脚本 | script_path, description |
yade_check_task_status | async | 轮询任务状态与输出 | task_id, skip_newest, limit, filter, wait_seconds |
yade_list_tasks | async | 浏览任务历史 | skip_newest, limit |
yade_interrupt_task | async | 取消运行中任务 | task_id |
知识库结构
知识库以 src/yade_mcp/knowledge/resources/python_api_docs/runtime/ 下的 371 份 JSON 文件为载体,每份对应一个 YADE 类,记录 name、category、parent、属性列表与方法签名(包含 args / returns / description)。例如 MaterialContainer.json 描述了 engines 类别下 append / index 等方法,InteractionContainer.json 描述 bodies 类别下 has / countReal / nth 的用法,TriaxialTest.json 则给出三轴试验预处理器各阶段的标准加载路径。v0.2.2 版本对全部 371 个运行时可内省的类进行了重新生成(基于真实 YADE 运行时反射),不涉及 API 行为变更 src/yade_mcp/knowledge/resources/python_api_docs/runtime/MaterialContainer.json:1-30、src/yade_mcp/knowledge/resources/python_api_docs/runtime/InteractionContainer.json:1-40。
桥接服务与运行时集成
桥接服务在 YADE 进程内启动后,会通过 _normalize_pyrunner 把一个标记为 yade-mcp-bridge: DO NOT MODIFY 的 PyRunner 强制放置在 O.engines[0],并以 iterPeriod 周期驱动 _mcp_pyrunner_tick 消息泵 yade-mcp-bridge/src/yade_mcp_bridge/runtime/pyrunner.py:1-30。WebSocket 服务由 BridgeServer 提供,create_server 默认绑定 localhost:9002,可通过 host / port 参数调整 yade-mcp-bridge/src/yade_mcp_bridge/transport/server.py:1-20。
任务执行处理器在 handlers/tasks.py 中实现:默认页大小 _DEFAULT_LIMIT = 64,调用方未传 limit 时只会获得有界页码而非全量历史;分页元数据由 pagination.total_count 告知剩余条目数 yade-mcp-bridge/src/yade_mcp_bridge/handlers/tasks.py:13-40。路径信息在返回给 LLM 前会通过 path_to_llm_format 统一替换为正斜杠格式,避免在 Windows 主机上产生歧义 yade-mcp-bridge/src/yade_mcp_bridge/utils/path_utils.py:1-6。
常见失效模式
NameError: name '_mcp_pyrunner_tick' is not defined:在 YADE IPython 控制台执行%run script.py时可能触发;pyrunner.py已将执行命名空间指向sys.modules['__main__'].__dict__修复该问题。O.run(N, wait=False)产生静默成功:v0.2.4 起任务生命周期与循环生命周期对齐,循环后台运行时若发生错误会冒泡上报。- API 文档与运行时不一致:v0.2.2 已对全部 371 份 JSON 重新生成;如发现新增类无文档,可通过知识库 scraper 重新抓取。
另请参阅
来源:https://github.com/yusong652/yade-mcp / 项目说明书
Bridge 运行时、执行与任务生命周期
yade-mcp-bridge 是连接 YADE 进程与外部 AI Agent 的运行时中继。它以 WebSocket 服务形式运行在 YADE Python/IPython 控制台之中,把 AI Agent 通过 Model Context Protocol (MCP) 提交的操作(执行脚本、执行代码片段、查询状态、中断任务、列举任务等)翻译成对 YADE 全局对象 O、...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述与作用域
yade-mcp-bridge 是连接 YADE 进程与外部 AI Agent 的运行时中继。它以 WebSocket 服务形式运行在 YADE Python/IPython 控制台之中,把 AI Agent 通过 Model Context Protocol (MCP) 提交的操作(执行脚本、执行代码片段、查询状态、中断任务、列举任务等)翻译成对 YADE 全局对象 O、O.engines、O.bodies 的实际调用,并通过 JSON 信封返回结果。yade-mcp(MCP Server)则把 FastMCP 工具与 Bridge 的 WebSocket 客户端桥接起来,二者共同构成端到端的"AI ↔ YADE"通道。
Bridge 的核心职责可以归纳为三层:
- 运行时分发:将接收到的消息按
type字段路由到对应的 handler;任务型消息交给handle_execute_task/handle_check_task_status/handle_list_tasks/handle_interrupt_task,REPL 型消息交给handle_execute_code。 - 执行与回收:启动 YADE 任务线程、调度 REPL 代码、捕获 stdout/stderr、写入日志文件,并在结束时统一构造响应数据。
- 生命周期管理:维护任务从
pending→running→completed | failed | interrupted的状态机,并向上层暴露查询、列举和中断能力。
yade-mcp-bridge v0.3.1 简化了启动横幅为单行输出 YADE MCP Bridge on ws://<host>:<port>, log: <path>,并将 stdout 日志级别收敛至 WARNING,避免在交互提示符上刷屏 —— 这是社区最关心的"清洁控制台"体验的来源(README.md:1-31)。
执行路径:REPL 与后台任务
Bridge 同时支持两种执行模式,对应 MCP 层的两类工具。
`yade_execute_code` —— 同步 REPL
execute_code 是一条同步阻塞的请求-响应链路:MCP 工具 yade_execute_code 把 Python 片段透传到 Bridge 的 handle_execute_code,Bridge 在 YADE 线程中执行该代码、把 stdout 捕获并返回。timeout 参数用于控制最长等待秒数。代码片段中可访问到 YADE 的全部命名空间(O、utils、bodies、materials 等),副作用会保留在 __main__ 中。
自 bridge-v0.3.0 起,timeout 被细分为两种结果状态:
terminated—— 异步异常(TaskInterrupt)注入成功,pump 已释放,YADE 状态可能已经被中断。这是"干净"的中断结果。timeout—— 异步异常注入失败(例如目标线程处于 Dummy-Nboost::python帧内),pump 可能仍然被占用,需要进一步干预。
社区 release notes 指出,这一拆分使得 Agent 能够区分"已确认的取消"与"未确认的强制超时",从而避免对已损坏的 YADE 状态做错误假设(src/yade_mcp/tools/execute_code.py:1-49)。
`yade_execute_task` —— 异步任务
execute_task 用于提交较长的脚本(如多分钟以上的 O.run 循环),由 Bridge 的 ScriptRunner 在独立线程中运行。MCP 层在调用 client.execute_task 时立即返回生成的 task_id(UUID 6 位前缀),Agent 用 yade_check_task_status 轮询、用 yade_interrupt_task 取消、用 yade_list_tasks 浏览历史。
bridge-v0.2.4 修复了 O.run(N, wait=False) 引起的"静默成功"问题:当脚本以 wait=False 提交 O.run 后,任务可能毫秒级返回成功,而 YADE 仍在后台迭代。此前的实现在这种场景下会出现脚本提前结束、但 cycling 错误无人捕获的孤儿任务。修复后任务生命周期与 cycling 生命周期对齐,错误能被正确回传到日志(src/yade_mcp/tools/execute_task.py:1-49)。
flowchart LR
A[Agent MCP 工具调用] --> B{yade-mcp Server}
B -->|yade_execute_code| C[handle_execute_code]
B -->|yade_execute_task| D[handle_execute_task]
C --> E[YADE __main__ 同步执行]
D --> F[ScriptRunner 后台线程]
F --> G[任务日志 JSONL]
E --> H[响应 envelope]
G --> H
H --> I[Agent 收到结果]任务生命周期与状态机
Bridge 中的任务对象由 TaskDataBuilder 构造,所有任务相关字段都被嵌套到 data 内,例如 data.task_id、data.task_type、data.script_path、data.status、data.start_time、data.elapsed_time 等。这种"信封 + 数据"的分层结构在 TaskDataBuilder 中显式建模:with_status / with_timing / with_pagination 等链式调用明确把生命周期状态写在 data.status 中,而不是 envelope 顶层(yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py:1-49)。
任务状态机有五种取值:
| 状态 | 含义 | 触发路径 |
|---|---|---|
pending | 任务已提交但尚未启动 | ScriptRunner.run 入队 |
running | 任务线程已开始执行 | 调度器取出任务 |
completed | 任务成功结束 | 脚本正常 return |
failed | 任务抛出未捕获异常 | 异常被 ScriptRunner 捕获 |
interrupted | 任务被显式中断 | handle_interrupt_task 触发 |
中断语义(`yade_interrupt_task`)
interrupt_task 在 Bridge 端同时施加两条取消路径(src/yade_mcp/tools/interrupt_task.py:1-49):
flag_only—— 设置一个全局中断标志,YADEPyRunner的tick在每次仿真迭代之间检查该标志,从而在O.run路径上优雅退出。flag_and_async_exc—— 在flag_only基础上,向脚本线程注入TaskInterrupt异常,使纯 Python 死循环(无O.run在栈上)也能被强制中止。
响应里通过 method 字段报告实际生效的路径。若异步异常被拒绝(例如目标线程处于 boost::python Dummy-N 帧),async_exc_skipped_reason 字段给出原因。
v0.3.0 在 MCP 层将这一语义向前透传:Agent 现在能区分优雅取消(terminated)与强制杀死(timeout),并确认 YADE __main__ 命名空间在中断后仍然存活(已赋值的 O 状态、变量无需重跑)。
输出分页(`yade_check_task_status`)
bridge-v0.2.1 将任务输出分页从 MCP 层下沉到 Bridge 层。handle_check_task_status 接收 skip_newest、limit、filter_text 三个参数,对完整日志文件进行分页,并把分页元数据(total_lines、line_range、has_older、has_newer)显式返回。MCP 不再对可能的截断输出做猜测式分页(yade-mcp-bridge/src/yade_mcp_bridge/handlers/tasks.py:1-49)。
yade_list_tasks 用类似的 skip_newest + limit 接口翻页任务列表,默认每页 32 条。
运行时上下文注入
yade-mcp v0.2.0 引入了 User Console Context Awareness 特性。MCP 工具响应在构造阶段会通过 with_context 装饰器异步拉取 Bridge 的 user_console 上下文,该上下文来自 ConsoleHistory —— 一个以 JSONL 持久化的 IPython 输入/输出缓冲(yade-mcp-bridge/src/yade_mcp_bridge/console/history.py:1-49)。
ConsoleHistory 维护一个磁盘游标(console_cursor.json),使得:
- Bridge 崩溃后新条目不会丢失;
- MCP 客户端可以断开重连后继续消费增量历史;
- 每条 entry 自增 ID,
on_new_entry回调可触发推送通知。
with_context 装饰器在工具边界上同时覆盖成功与失败两条分支,把 _context.user_console 注入到响应 envelope 中(src/yade_mcp/bridge/context.py:1-49)。这一机制让 Agent 在调用 yade_execute_code 或 yade_execute_task 时,能看到用户最近在 YADE 控制台亲自键入的命令,从而理解 Agent 视角之外的现场活动。
build_ok() 自 v0.2.0 起变为异步方法,正是为了在构造响应前 await 这一上下文拉取动作。
常见失效模式与排障指引
| 现象 | 可能原因 | 应对 |
|---|---|---|
yade_execute_code 报 terminated 但 YADE 状态似乎异常 | TaskInterrupt 已注入,部分语句未执行 | 重新发起一次只读查询确认 O 状态 |
yade_execute_code 报 timeout | 目标线程处于 boost::python Dummy-N 帧 | 重启 Bridge,或先停止当前仿真 |
NameError: _mcp_pyrunner_tick 在 %run script.py 后出现 | YADE 的 PyRunner 在 py::exec 时重新解析 sys.modules['__main__'],IPython %run 临时覆盖了模块 | bridge-v0.2.2 已修复 |
任务长时间 running 但无新日志 | O.run(N, wait=False) 触发孤儿 cycling | bridge-v0.2.4 已修复,旧版本需要重启 |
| 控制台交互提示被刷屏 | Bridge 启动时输出大量 INFO 日志 | bridge-v0.3.1 已将 stdout 收敛至 WARNING 级别 |
Console capture not installed 误报 | 启动日志中的虚假告警 | bridge-v0.3.1 已修复 |
See Also
- yade-mcp API 知识库与查询工具
- MCP 工具注册与响应契约
- Bridge 传输协议与 WebSocket 帧格式
- 历史 Release Notes(GitHub)
来源:https://github.com/yusong652/yade-mcp / 项目说明书
部署、运维与 Showcase 示例
yade-mcp 是一套将 AI Agent 接入到离散元仿真框架 YADE 的 Model Context Protocol(MCP)双向桥接系统。它的工程结构由两个互相独立、版本号分别管理的 Python 包组成:
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
- yade-mcp(MCP 端):在 Agent 一侧提供 FastMCP 工具集,对外发布到 PyPI(README.md)。
- yade-mcp-bridge(YADE 端):在 YADE Python 控制台内启动一个 WebSocket 服务,作为 MCP 工具调用进入仿真进程的反向通道,版本以
bridge-vX.Y.Z形式单独打 tag。
部署时必须保证两侧协同启动,否则 MCP 工具调用会因找不到 ws://host:port 而失败。
部署方式
引导文档矩阵
仓库根目录的 docs/agentic/ 子目录为不同 Agent 客户端各提供一份专用引导文档,不依赖通用 README,因为每个 Agent 的 MCP 客户端配置语法不同:
| 引导文件 | 适配 Agent | 用途 |
|---|---|---|
| yade-mcp-bootstrap.md | 通用 Agentic 工作流 | 顶层入口 |
| yade-mcp-bootstrap-claude.md | Claude / Claude Code | Claude 客户端注册 |
| yade-mcp-bootstrap-codex.md | Codex | Codex 客户端注册 |
| yade-mcp-bootstrap-copilot.md | GitHub Copilot | Copilot 客户端注册 |
| yade-mcp-bootstrap-gemini.md | Gemini | Gemini 客户端注册 |
| yade-mcp-bootstrap-opencode.md | OpenCode | OpenCode 客户端注册 |
部署顺序通常为:
- 安装 Bridge:在 YADE 的 Python 环境中
pip install yade-mcp-bridge。 - 启动 Bridge:在 YADE IPython 控制台中执行
start(),Bridge 会打印形如YADE MCP Bridge on ws://<host>:<port>, log: <path>的单行横幅(bridge-v0.3.1),并以守护线程形式运行任务泵,不会阻塞交互提示符(bridge-v0.2.0)。 - 安装 MCP 端:
pip install yade-mcp,并按对应yade-mcp-bootstrap-*.md的说明把 MCP server 注册到目标 Agent。 - 校验连通性:通过 Agent 调用任意一个
yade_query_api/yade_browse_api工具,若返回ok=true且 payload 非空,表明两端握手成功。
运维要点
日志与会话输出
bridge-v0.3.1 之后,初始化阶段的 INFO 级日志被重定向到 bridge.log 文件,stdout 只保留 WARNING 级别,交互提示符保持干净(bridge-v0.3.1)。若用户在控制台手动运行 %run script.py,需要关注 bridge-v0.2.2 修复的 NameError: name '_mcp_pyrunner_tick' is not defined 问题——它源于 IPython 的 %run 临时替换 sys.modules['__main__'],导致 YADE PyRunner 注入的 tick 函数解析失败(bridge-v0.2.2)。
取消与超时语义
yade_execute_code 在超时时返回的错误码 error.code 区分三种状态(src/yade_mcp/tools/execute_code.py):
error.code | 含义 | 后续动作 |
|---|---|---|
interrupted | 仿真在 O.run 迭代边界被干净暂停 | 改用 yade_execute_task + yade_interrupt_task |
terminated | 异步异常注入成功,泵线程已释放 | 检查 YADE 状态后再重试 |
timeout | abort 失败,可能仍阻塞 | 必要时重启 Bridge |
v0.3.0 进一步将 terminated 与 timeout 拆分,让 Agent 能够区分"被优雅取消"和"被强制杀死"(v0.3.0)。
任务生命周期
对于长任务,必须使用 yade_execute_task 而不是 yade_execute_code,原因是 bridge-v0.2.4 修复了 O.run(N, wait=False) 导致的"假成功 / 孤儿循环"问题——任务可能在毫秒级完成而后台循环仍在跑,进而吃掉后续的 cycling 异常(bridge-v0.2.4)。任务响应体中任务级状态(pending / running / completed / failed / interrupted)刻意放在 data 字段下,而不是顶层的 ok 旁(yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py)。
上下文注入
yade-mcp v0.2.0 起 build_ok() 被改为 async,并在所有工具响应中自动注入 _context.user_console,让 Agent 看到用户在 YADE 控制台的最近活动(v0.2.0)。
Showcase 示例
仓库在 src/yade_mcp/knowledge/resources/python_api_docs/runtime/ 下保存了 371 个由运行时 introspect 得到的 YADE 类 JSON,可作为"知识检索 → 编码 → 提交"的最小 Showcase 模板。
示例 1:检索三轴试验类
调用 yade_query_api(query="triaxial stress", limit=5) 即可命中 TriaxialTest.json。该类继承自 FileGenerator(FileGenerator.json),典型属性包括 sigmaIsoCompaction、sphereFrictionDeg、compactionFrictionDeg 等。检索由 src/yade_mcp/tools/query_api.py 内的 APISearch.search 完成,结果通过 build_docs_data(source="python_api", action="query", …) 统一封装。
示例 2:浏览 API 树
yade_browse_api 沿 YADE 原生继承树导航,例如 path="engine.GlobalEngine.NewtonIntegrator" 即可获得 NewtonIntegrator 的完整文档(src/yade_mcp/tools/browse_api.py)。
示例 3:组合构造场景
在拿到 TriaxialTest / SimpleShear 这类 FileGenerator 之后,可通过 yade_execute_code 在 YADE 内联调用 TriaxialTest().generate() 生成场景;SimpleShear 场景在初始松散堆积后默认做 2 MPa 的等向压缩,再切换到 KinemCNDEngine / KinemCNSEngine / KinemCNLEngine 完成常法向位移 / 刚度 / 应力路径(SimpleShear.json)。若 Agent 需要在脚本里给材料加标签,应使用 O.materials.append(mat),返回值为新 id;按 label 访问可使用 O.materials['steel'](MaterialContainer.json),迭代接触则通过 O.interactions[23,65] 或 O.interactions 迭代器(InteractionContainer.json)。
示例 4:分页读取任务输出
长任务运行中可调用 yade_check_task_status(task_id, skip_newest=0, limit=200, filter_text="error") 拿到 total_lines / line_range / has_older / has_newer 元数据;分页完全在 Bridge 侧基于完整日志文件计算(v0.2.1),MCP 端不再做"读窗口内再翻页"的脆弱近似。
See Also
- 快速开始与 Bridge 启动
- 核心架构与协议
- API 检索与浏览工具参考
- 任务调度与取消语义
来源:https://github.com/yusong652/yade-mcp / 项目说明书
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
风险会影响是否适合普通用户安装。
Pitfall Log / 踩坑日志
项目:yusong652/yade-mcp
摘要:发现 7 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:配置坑 - 可能修改宿主 AI 配置。
1. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 证据:capability.host_targets | https://github.com/yusong652/yade-mcp | host_targets=mcp_host, claude, claude_code, gemini_cli, codex
2. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://github.com/yusong652/yade-mcp | README/documentation is current enough for a first validation pass.
3. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://github.com/yusong652/yade-mcp | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://github.com/yusong652/yade-mcp | no_demo; severity=medium
5. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://github.com/yusong652/yade-mcp | no_demo; severity=medium
6. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://github.com/yusong652/yade-mcp | issue_or_pr_quality=unknown
7. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://github.com/yusong652/yade-mcp | release_recency=unknown
来源:Doramagic 发现、验证与编译记录