# https://github.com/yusong652/yade-mcp 项目说明书

生成时间：2026-06-24 14:52:03 UTC

## 目录

- [概览与系统架构](#page-1)
- [MCP Server、工具与知识库](#page-2)
- [Bridge 运行时、执行与任务生命周期](#page-3)
- [部署、运维与 Showcase 示例](#page-4)

<a id='page-1'></a>

## 概览与系统架构

### 相关页面

相关主题：[MCP Server、工具与知识库](#page-2), [Bridge 运行时、执行与任务生命周期](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/yusong652/yade-mcp/blob/main/README.md)
- [src/yade_mcp/tools/query_api.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/query_api.py)
- [src/yade_mcp/tools/browse_api.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/browse_api.py)
- [src/yade_mcp/tools/execute_code.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/execute_code.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/runtime/pyrunner.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/runtime/pyrunner.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/console/history.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/console/history.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/transport/server.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/transport/server.py)
- [src/yade_mcp/knowledge/resources/python_api_docs/runtime/MaterialContainer.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/MaterialContainer.json)
- [src/yade_mcp/knowledge/resources/python_api_docs/runtime/InteractionContainer.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/InteractionContainer.json)

</details>

# 概览与系统架构

## 1. 项目定位与设计目标

`yade-mcp` 是面向 [YADE](https://yade-dem.org/) 离散元仿真框架的 **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. 双端架构

系统呈典型的 **客户端—网关—宿主** 三段式结构：

```mermaid
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 发行说明](https://github.com/yusong652/yade-mcp/releases/tag/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 引入）——其状态机如下：

```mermaid
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 发行说明](https://github.com/yusong652/yade-mcp/releases/tag/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 发行说明](https://github.com/yusong652/yade-mcp/releases/tag/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 发行说明](https://github.com/yusong652/yade-mcp/releases/tag/bridge-v0.3.1)。
- 版本配套：MCP 端 v0.3.x 与 Bridge 端 v0.3.x 通过 WebSocket 元数据兼容；新引入的取消元数据（`terminated` vs `timeout`）需 Bridge 至少 v0.3.0 资料来源：[v0.3.0 发行说明](https://github.com/yusong652/yade-mcp/releases/tag/v0.3.0)。

---

## See Also

- 工具参考：`yade_query_api` / `yade_browse_api` / `yade_execute_code`
- Bridge 运行时：`PyRunner` 注入与自愈机制
- 数据持久化：Console JSONL 历史与任务日志分页
- 社区讨论：YADE `__main__` 命名空间在 `%run` 下的行为（bridge-v0.2.2）

---

<a id='page-2'></a>

## MCP Server、工具与知识库

### 相关页面

相关主题：[概览与系统架构](#page-1), [Bridge 运行时、执行与任务生命周期](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/yade_mcp/tools/__init__.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/__init__.py)
- [src/yade_mcp/tools/browse_api.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/browse_api.py)
- [src/yade_mcp/tools/query_api.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/query_api.py)
- [src/yade_mcp/tools/execute_code.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/execute_code.py)
- [src/yade_mcp/tools/execute_task.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/execute_task.py)
- [src/yade_mcp/tools/check_task_status.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/check_task_status.py)
- [src/yade_mcp/tools/list_tasks.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/list_tasks.py)
- [src/yade_mcp/tools/interrupt_task.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/interrupt_task.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/handlers/tasks.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/handlers/tasks.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/handlers/__init__.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/handlers/__init__.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/runtime/pyrunner.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/runtime/pyrunner.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/transport/server.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/transport/server.py)
- [README.md](https://github.com/yusong652/yade-mcp/blob/main/README.md)
</details>

# MCP Server、工具与知识库

## 架构概览

`yade-mcp` 项目由两个协同工作的 Python 包组成：`yade-mcp`（MCP Server 端，基于 [FastMCP](https://github.com/jlowin/fastmcp) 暴露工具资源）和 `yade-mcp-bridge`（运行在 YADE 进程内的 WebSocket 桥接服务）。MCP Server 负责把工具调用翻译为 JSON-RPC 消息，桥接服务则负责在 YADE 的 Python 命名空间里执行真实操作，二者通过 WebSocket 在 `ws://<host>:<port>` 上通信 [README.md:1-13](https://github.com/yusong652/yade-mcp/blob/main/README.md)。在桥接侧，所有消息分发由 `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](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/handlers/__init__.py)。

```mermaid
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](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/__init__.py)。整套工具围绕三大职能展开：知识库导航、YADE 进程内执行、任务生命周期管理。

### 知识库浏览与查询

- `yade_browse_api`：按 YADE 原生类树浏览文档。路径是点号分隔的层级（如 `engine.GlobalEngine.NewtonIntegrator`），未指定路径时返回顶层类别，导航完全沿父类链进行 [src/yade_mcp/tools/browse_api.py:30-50](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/browse_api.py)。
- `yade_query_api`：按关键字做相关性搜索（类似 grep），返回按相关度排序的类/函数列表，适用于只知道关键词而不知道准确类名的场景 [src/yade_mcp/tools/query_api.py:14-37](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/query_api.py)。

### 代码与任务执行

- `yade_execute_code`：在 YADE 进程中**同步**执行一段 Python 代码并立即返回 stdout。即便有任务在运行也能响应，因此常被用作实时 REPL 检查 `O.bodies`、`O.engines`、应力张量等状态 [src/yade_mcp/tools/execute_code.py:16-32](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/execute_code.py)。
- `yade_execute_task`：以**异步**方式提交本地脚本文件路径，桥接服务为它分配一个 6 位 `task_id` 并立即返回；脚本在后台由 `_make_pyrunner` 创建的 PyRunner 引擎驱动执行 [src/yade_mcp/tools/execute_task.py:19-37](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/execute_task.py)。

### 任务生命周期管理

- `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](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/check_task_status.py)。
- `yade_list_tasks`：列出所有被追踪任务，支持 `skip_newest` / `limit` 翻页 [src/yade_mcp/tools/list_tasks.py:17-30](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/list_tasks.py)。
- `yade_interrupt_task`：通过 `flag_only` 与 `flag_and_async_exc` 两条路径协同工作，可在不重启桥接的情况下打断 `O.run` 任务或纯 Python 死循环，并保留 YADE `__main__` 命名空间的状态 [src/yade_mcp/tools/interrupt_task.py:1-30](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/interrupt_task.py)。

| 工具 | 同步/异步 | 主要用途 | 关键参数 |
|------|-----------|----------|----------|
| `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](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/MaterialContainer.json)、[src/yade_mcp/knowledge/resources/python_api_docs/runtime/InteractionContainer.json:1-40](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/InteractionContainer.json)。

## 桥接服务与运行时集成

桥接服务在 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](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/runtime/pyrunner.py)。WebSocket 服务由 `BridgeServer` 提供，`create_server` 默认绑定 `localhost:9002`，可通过 `host` / `port` 参数调整 [yade-mcp-bridge/src/yade_mcp_bridge/transport/server.py:1-20](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/transport/server.py)。

任务执行处理器在 `handlers/tasks.py` 中实现：默认页大小 `_DEFAULT_LIMIT = 64`，调用方未传 `limit` 时只会获得有界页码而非全量历史；分页元数据由 `pagination.total_count` 告知剩余条目数 [yade-mcp-bridge/src/yade_mcp_bridge/handlers/tasks.py:13-40](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/handlers/tasks.py)。路径信息在返回给 LLM 前会通过 `path_to_llm_format` 统一替换为正斜杠格式，避免在 Windows 主机上产生歧义 [yade-mcp-bridge/src/yade_mcp_bridge/utils/path_utils.py:1-6](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/utils/path_utils.py)。

## 常见失效模式

- **`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 重新抓取。

## 另请参阅

- [README.md](https://github.com/yusong652/yade-mcp/blob/main/README.md) — 项目总览与安装方式
- [yade-mcp 工具实现目录](https://github.com/yusong652/yade-mcp/tree/main/src/yade_mcp/tools)
- [yade-mcp-bridge 处理器目录](https://github.com/yusong652/yade-mcp/tree/main/yade-mcp-bridge/src/yade_mcp_bridge/handlers)
- [v0.2.2 — runtime-driven API doc refresh](https://github.com/yusong652/yade-mcp/releases/tag/v0.2.2)
- [bridge-v0.3.0 — Deadloop self-recovery](https://github.com/yusong652/yade-mcp/releases/tag/bridge-v0.3.0)

---

<a id='page-3'></a>

## Bridge 运行时、执行与任务生命周期

### 相关页面

相关主题：[概览与系统架构](#page-1), [MCP Server、工具与知识库](#page-2)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [yade-mcp-bridge/src/yade_mcp_bridge/handlers/tasks.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/handlers/tasks.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/console/history.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/console/history.py)
- [src/yade_mcp/tools/execute_task.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/execute_task.py)
- [src/yade_mcp/tools/check_task_status.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/check_task_status.py)
- [src/yade_mcp/tools/list_tasks.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/list_tasks.py)
- [src/yade_mcp/tools/interrupt_task.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/interrupt_task.py)
- [src/yade_mcp/tools/execute_code.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/execute_code.py)
- [src/yade_mcp/bridge/context.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/bridge/context.py)
- [README.md](https://github.com/yusong652/yade-mcp/blob/main/README.md)
</details>

# Bridge 运行时、执行与任务生命周期

## 概述与作用域

`yade-mcp-bridge` 是连接 [YADE](https://yade-dem.org) 进程与外部 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 的核心职责可以归纳为三层：

1. **运行时分发**：将接收到的消息按 `type` 字段路由到对应的 handler；任务型消息交给 `handle_execute_task` / `handle_check_task_status` / `handle_list_tasks` / `handle_interrupt_task`，REPL 型消息交给 `handle_execute_code`。
2. **执行与回收**：启动 YADE 任务线程、调度 REPL 代码、捕获 stdout/stderr、写入日志文件，并在结束时统一构造响应数据。
3. **生命周期管理**：维护任务从 `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-N `boost::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]()）。

```mermaid
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]()）：

1. **`flag_only`** —— 设置一个全局中断标志，YADE `PyRunner` 的 `tick` 在每次仿真迭代之间检查该标志，从而在 `O.run` 路径上优雅退出。
2. **`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 知识库与查询工具](./api-knowledge-and-query.md)
- [MCP 工具注册与响应契约](./mcp-tool-registration-and-contracts.md)
- [Bridge 传输协议与 WebSocket 帧格式](./bridge-transport-and-websocket.md)
- [历史 Release Notes（GitHub）](https://github.com/yusong652/yade-mcp/releases)

---

<a id='page-4'></a>

## 部署、运维与 Showcase 示例

### 相关页面

相关主题：[概览与系统架构](#page-1), [Bridge 运行时、执行与任务生命周期](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [docs/agentic/yade-mcp-bootstrap.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap.md)
- [docs/agentic/yade-mcp-bootstrap-claude.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-claude.md)
- [docs/agentic/yade-mcp-bootstrap-codex.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-codex.md)
- [docs/agentic/yade-mcp-bootstrap-copilot.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-copilot.md)
- [docs/agentic/yade-mcp-bootstrap-gemini.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-gemini.md)
- [docs/agentic/yade-mcp-bootstrap-opencode.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-opencode.md)
- [README.md](https://github.com/yusong652/yade-mcp/blob/main/README.md)
- [src/yade_mcp/tools/execute_code.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/execute_code.py)
- [src/yade_mcp/tools/browse_api.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/browse_api.py)
- [src/yade_mcp/tools/query_api.py](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/tools/query_api.py)
- [yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py](https://github.com/yusong652/yade-mcp/blob/main/yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py)
- [src/yade_mcp/knowledge/resources/python_api_docs/runtime/TriaxialTest.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/TriaxialTest.json)
- [src/yade_mcp/knowledge/resources/python_api_docs/runtime/SimpleShear.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/SimpleShear.json)
- [src/yade_mcp/knowledge/resources/python_api_docs/runtime/MaterialContainer.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/MaterialContainer.json)
- [src/yade_mcp/knowledge/resources/python_api_docs/runtime/BodyContainer.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/BodyContainer.json)
- [src/yade_mcp/knowledge/resources/python_api_docs/runtime/InteractionContainer.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/InteractionContainer.json)
- [src/yade_mcp/knowledge/resources/python_api_docs/runtime/FileGenerator.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/FileGenerator.json)
</details>

# 部署、运维与 Showcase 示例

`yade-mcp` 是一套将 AI Agent 接入到离散元仿真框架 [YADE](https://yade-dem.org/) 的 Model Context Protocol（MCP）双向桥接系统。它的工程结构由两个互相独立、版本号分别管理的 Python 包组成：

- **yade-mcp**（MCP 端）：在 Agent 一侧提供 FastMCP 工具集，对外发布到 PyPI（[README.md](https://github.com/yusong652/yade-mcp/blob/main/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](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap.md) | 通用 Agentic 工作流 | 顶层入口 |
| [yade-mcp-bootstrap-claude.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-claude.md) | Claude / Claude Code | Claude 客户端注册 |
| [yade-mcp-bootstrap-codex.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-codex.md) | Codex | Codex 客户端注册 |
| [yade-mcp-bootstrap-copilot.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-copilot.md) | GitHub Copilot | Copilot 客户端注册 |
| [yade-mcp-bootstrap-gemini.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-gemini.md) | Gemini | Gemini 客户端注册 |
| [yade-mcp-bootstrap-opencode.md](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap-opencode.md) | OpenCode | OpenCode 客户端注册 |

部署顺序通常为：

1. **安装 Bridge**：在 YADE 的 Python 环境中 `pip install yade-mcp-bridge`。
2. **启动 Bridge**：在 YADE IPython 控制台中执行 `start()`，Bridge 会打印形如 `YADE MCP Bridge on ws://<host>:<port>, log: <path>` 的单行横幅（[bridge-v0.3.1](https://github.com/yusong652/yade-mcp/releases/tag/bridge-v0.3.1)），并以**守护线程**形式运行任务泵，不会阻塞交互提示符（[bridge-v0.2.0](https://github.com/yusong652/yade-mcp/releases/tag/yade-mcp-bridge-v0.2.0)）。
3. **安装 MCP 端**：`pip install yade-mcp`，并按对应 `yade-mcp-bootstrap-*.md` 的说明把 MCP server 注册到目标 Agent。
4. **校验连通性**：通过 Agent 调用任意一个 `yade_query_api` / `yade_browse_api` 工具，若返回 `ok=true` 且 payload 非空，表明两端握手成功。

## 运维要点

### 日志与会话输出

`bridge-v0.3.1` 之后，初始化阶段的 INFO 级日志被重定向到 `bridge.log` 文件，stdout 只保留 WARNING 级别，交互提示符保持干净（[bridge-v0.3.1](https://github.com/yusong652/yade-mcp/releases/tag/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](https://github.com/yusong652/yade-mcp/releases/tag/bridge-v0.2.2)）。

### 取消与超时语义

`yade_execute_code` 在超时时返回的错误码 `error.code` 区分三种状态（[src/yade_mcp/tools/execute_code.py](https://github.com/yusong652/yade-mcp/blob/main/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](https://github.com/yusong652/yade-mcp/releases/tag/v0.3.0)）。

### 任务生命周期

对于长任务，必须使用 `yade_execute_task` 而不是 `yade_execute_code`，原因是 `bridge-v0.2.4` 修复了 `O.run(N, wait=False)` 导致的"假成功 / 孤儿循环"问题——任务可能在毫秒级完成而后台循环仍在跑，进而吃掉后续的 cycling 异常（[bridge-v0.2.4](https://github.com/yusong652/yade-mcp/releases/tag/bridge-v0.2.4)）。任务响应体中任务级状态（`pending / running / completed / failed / interrupted`）刻意放在 `data` 字段下，而不是顶层的 `ok` 旁（[yade-mcp-bridge/src/yade_mcp_bridge/utils/response.py](https://github.com/yusong652/yade-mcp/blob/main/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](https://github.com/yusong652/yade-mcp/releases/tag/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](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/TriaxialTest.json)。该类继承自 `FileGenerator`（[FileGenerator.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/FileGenerator.json)），典型属性包括 `sigmaIsoCompaction`、`sphereFrictionDeg`、`compactionFrictionDeg` 等。检索由 [src/yade_mcp/tools/query_api.py](https://github.com/yusong652/yade-mcp/blob/main/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](https://github.com/yusong652/yade-mcp/blob/main/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](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/SimpleShear.json)）。若 Agent 需要在脚本里给材料加标签，应使用 `O.materials.append(mat)`，返回值为新 `id`；按 label 访问可使用 `O.materials['steel']`（[MaterialContainer.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/MaterialContainer.json)），迭代接触则通过 `O.interactions[23,65]` 或 `O.interactions` 迭代器（[InteractionContainer.json](https://github.com/yusong652/yade-mcp/blob/main/src/yade_mcp/knowledge/resources/python_api_docs/runtime/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](https://github.com/yusong652/yade-mcp/releases/tag/v0.2.1)），MCP 端不再做"读窗口内再翻页"的脆弱近似。

## See Also

- [快速开始与 Bridge 启动](https://github.com/yusong652/yade-mcp/blob/main/docs/agentic/yade-mcp-bootstrap.md)
- [核心架构与协议]()
- [API 检索与浏览工具参考]()
- [任务调度与取消语义]()

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：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

<!-- canonical_name: yusong652/yade-mcp; human_manual_source: deepwiki_human_wiki -->
