docs(extension): 补充阶段C MCP开发说明

This commit is contained in:
2026-09-01 11:32:47 +08:00
parent fc4b7b9495
commit aedb1c1267
13 changed files with 328 additions and 28 deletions
+2 -1
View File
@@ -118,7 +118,7 @@ cd frontend
pnpm test pnpm test
``` ```
当前回归基线为后端 81 项测试、前端 27 项测试,且生产构建通过。测试数量会随功能增长,以本地实际输出和 CI 为准。 当前回归基线为后端 87 项测试、前端 27 项测试,且生产构建通过。测试数量会随功能增长,以本地实际输出和 CI 为准。
构建产物位于 `frontend/dist`,该目录不提交到 Git。 构建产物位于 `frontend/dist`,该目录不提交到 Git。
@@ -132,6 +132,7 @@ pnpm test
| [后端接口契约](docs/contracts/后端接口契约-开发版.md) | HTTP/SSE 接口、错误和当前实现状态 | | [后端接口契约](docs/contracts/后端接口契约-开发版.md) | HTTP/SSE 接口、错误和当前实现状态 |
| [第二阶段接口契约](docs/contracts/第二阶段接口契约-开发版.md) | 第二阶段公共 DTO、计划接口、SSE、错误码与联调顺序 | | [第二阶段接口契约](docs/contracts/第二阶段接口契约-开发版.md) | 第二阶段公共 DTO、计划接口、SSE、错误码与联调顺序 |
| [AI Core 与 Agent Core](docs/development/AI-Core与Agent-Core开发说明.md) | Provider、Agent、Tool、Permission 与 Extension Core | | [AI Core 与 Agent Core](docs/development/AI-Core与Agent-Core开发说明.md) | Provider、Agent、Tool、Permission 与 Extension Core |
| [MCP Bridge 与 Plugin Host](docs/development/MCP-Bridge与Plugin-Host开发说明.md) | stdio MCP、隔离进程、Tool 映射、状态与错误边界 |
| [Git 使用细则](docs/guides/Git使用细则-团队开发版.md) | 分支、提交、PR、Review 与合并流程 | | [Git 使用细则](docs/guides/Git使用细则-团队开发版.md) | 分支、提交、PR、Review 与合并流程 |
| [CI/CD 细则](docs/guides/CI-CD细则-团队开发版.md) | Gitea 流水线、质量门禁、产物、发布与回滚规则 | | [CI/CD 细则](docs/guides/CI-CD细则-团队开发版.md) | Gitea 流水线、质量门禁、产物、发布与回滚规则 |
| [Agent Trace 复盘](docs/retrospectives/Agent-Core第二阶段问题与修复复盘.md) | Agent 持久化、SSE 恢复、事件契约与脱敏问题复盘 | | [Agent Trace 复盘](docs/retrospectives/Agent-Core第二阶段问题与修复复盘.md) | Agent 持久化、SSE 恢复、事件契约与脱敏问题复盘 |
+1 -1
View File
@@ -23,7 +23,7 @@ uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
uv run pytest uv run pytest
``` ```
当前基线为 81 项测试通过。Provider API Key 可通过前端设置页写入,也可用 `OPENAI_API_KEY``DEEPSEEK_API_KEY``AINOTE_CREDENTIAL_<ID>` 注入;不要把真实密钥写入仓库。 当前基线为 87 项测试通过。Provider API Key 可通过前端设置页写入,也可用 `OPENAI_API_KEY``DEEPSEEK_API_KEY``AINOTE_CREDENTIAL_<ID>` 注入;不要把真实密钥写入仓库。
团队接口清单见 `../docs/contracts/后端接口契约-开发版.md`,机器可读契约以运行时的 `/openapi.json` 为准。 团队接口清单见 `../docs/contracts/后端接口契约-开发版.md`,机器可读契约以运行时的 `/openapi.json` 为准。
+1
View File
@@ -31,6 +31,7 @@
- [AI Core 与 Agent Core 开发说明](development/AI-Core与Agent-Core开发说明.md) - [AI Core 与 Agent Core 开发说明](development/AI-Core与Agent-Core开发说明.md)
- [Knowledge 与 Retrieval Core 开发说明](development/Knowledge与Retrieval-Core开发说明.md) - [Knowledge 与 Retrieval Core 开发说明](development/Knowledge与Retrieval-Core开发说明.md)
- [模型提供商与模型发现开发说明](development/模型提供商与模型发现开发说明.md) - [模型提供商与模型发现开发说明](development/模型提供商与模型发现开发说明.md)
- [MCP Bridge 与 Plugin Host 开发说明](development/MCP-Bridge与Plugin-Host开发说明.md)
- [前端壳子与接口层开发说明](development/前端壳子与接口层开发说明.md) - [前端壳子与接口层开发说明](development/前端壳子与接口层开发说明.md)
- [前端写作体验优化开发说明](development/前端写作体验优化开发说明.md) - [前端写作体验优化开发说明](development/前端写作体验优化开发说明.md)
- [前端视觉与轻量动效优化开发说明](development/前端视觉与轻量动效优化开发说明.md) - [前端视觉与轻量动效优化开发说明](development/前端视觉与轻量动效优化开发说明.md)
@@ -5,7 +5,7 @@
> 适用范围:桌面客户端、本地知识库、RAG、Agent、Skill、多模型接入、多模态处理与可选云同步 > 适用范围:桌面客户端、本地知识库、RAG、Agent、Skill、多模型接入、多模态处理与可选云同步
> 目标读者:前端、Rust 桌面端、Python AI Core、算法、测试与后续接手项目的开发成员 > 目标读者:前端、Rust 桌面端、Python AI Core、算法、测试与后续接手项目的开发成员
> 实施状态更新:2026-09-01。本文同时包含目标架构、当前实现和第二阶段接口基线。第一阶段已完成 Vue Web 联调前端、FastAPI、Knowledge/Retrieval、Agent/Tool/Permission、Skill/Plugin 声明式运行时、Mock/OpenAI-Compatible/Ollama Provider、DeepSeek/OpenAI 预设、模型发现及开发阶段 Fernet 凭据存储。Web Workspace 已通过 FastAPI 接入后端配置的真实单 Vault第二阶段 Agent Trace 持久化、分页快照可恢复 SSE 已完成。后续继续接入真实音频处理、MCP、Plugin Command/Settings、Provider 协议增强、Benchmark、文档导出、主题包、Trace 可视化、Mermaid 和函数图像。Tauri/Rust Host、Stronghold、原生多 Vault 文件系统和 Sync Server 仍未实现。 > 实施状态更新:2026-09-01。本文同时包含目标架构、当前实现和第二阶段接口基线。第一阶段已完成 Vue Web 联调前端、FastAPI、Knowledge/Retrieval、Agent/Tool/Permission、Skill/Plugin 声明式运行时、Mock/OpenAI-Compatible/Ollama Provider、DeepSeek/OpenAI 预设、模型发现及开发阶段 Fernet 凭据存储。Web Workspace 已通过 FastAPI 接入后端配置的真实单 Vault第二阶段 Agent Trace 持久化、分页快照可恢复 SSE、stdio MCP Bridge 与隔离 Plugin Host 已完成。后续继续接入真实音频处理、Plugin Command/Settings、Provider 协议增强、Benchmark、文档导出、主题包、Trace 可视化、Mermaid 和函数图像。Tauri/Rust Host、Stronghold、原生多 Vault 文件系统和 Sync Server 仍未实现。
--- ---
@@ -1044,6 +1044,8 @@ Plugin Host 负责:
MCP Bridge 用于接入具有 MCP Server 接口的插件或外部工具服务。 MCP Bridge 用于接入具有 MCP Server 接口的插件或外部工具服务。
当前已实现本地 stdio 首版:Plugin Runtime 在授权后的启用阶段启动独立 Server 进程,完成 `initialize`、capability negotiation、分页 `tools/list`、`tools/call`、取消、超时、异常退出和 Host Restart。实现接受 `2025-11-25`、`2025-06-18`、`2025-03-26` 与 `2024-11-05` 协议版本;Streamable HTTP、Resource、Prompt、Sampling 与操作系统级沙箱仍属于后续范围。
MCP Tool 进入系统后的调用路径为: MCP Tool 进入系统后的调用路径为:
```text ```text
@@ -1062,7 +1064,7 @@ Tool Registry 仍使用项目自己的 `ToolDefinition` 和 `ToolResult`。MCP B
MCP 能力首先用于 Tool 和 Resource 类扩展。需要复杂 UI 的插件通过 Frontend Extension Slot 单独处理。 MCP 能力首先用于 Tool 和 Resource 类扩展。需要复杂 UI 的插件通过 Frontend Extension Slot 单独处理。
第二阶段 MCP Bridge 至少覆盖以下协议边界: 当前 stdio MCP Bridge 覆盖以下协议边界:
```text ```text
Server Process / Connection Lifecycle Server Process / Connection Lifecycle
@@ -1074,7 +1076,7 @@ tools/call 与 ToolResult 映射
健康检查与 Tool 注销 健康检查与 Tool 注销
``` ```
首个宿主实现优先支持本地 `stdio` 传输;其他传输在兼容性测试后增加。外部 Server 的 Tool 名称进入项目注册表前添加 Plugin 命名空间,并校验 JSON Schema、权限重复 ID。MCP 内容不得绕过项目自己的 Permission、超时、日志净化和结果大小限制 首个宿主实现支持本地 `stdio` 传输;其他传输在兼容性测试后增加。外部 Server 的 Tool 名称进入项目注册表前添加 Plugin 命名空间,并校验 JSON Schema、权限重复 ID 及其与 Manifest Contribution 的一致性。MCP 调用复用项目自己的 Permission、超时、Agent Trace、日志净化和结果大小限制;子进程环境按白名单裁剪,不传入 Provider Key、Vault 或数据库路径
### 12.6 Frontend Extension Slot ### 12.6 Frontend Extension Slot
@@ -2321,7 +2323,7 @@ Markdown Workspace
第一阶段 Plugin Runtime 已完成安装、启用、停用、权限和声明式 Tool 注册,建立 Skill 调用 Plugin Tool 的基础链路。Command、Settings 和 MCP 执行不计入第一阶段完成项。 第一阶段 Plugin Runtime 已完成安装、启用、停用、权限和声明式 Tool 注册,建立 Skill 调用 Plugin Tool 的基础链路。Command、Settings 和 MCP 执行不计入第一阶段完成项。
截至 2026-09-01,上述第一阶段后端链路和 Web 联调前端均已完成第二阶段前置的 Workspace 去 Mock 联调Agent Trace 持久化/恢复接口也已完成。当前验证基线为后端 81 项测试、前端 27 项测试及生产构建通过。向量链路当前使用 `HashEmbeddingProvider` 验证工程正确性,真实 Embedding 召回质量不属于该测试结论。 截至 2026-09-01,上述第一阶段后端链路和 Web 联调前端均已完成第二阶段前置的 Workspace 去 Mock 联调Agent Trace 持久化/恢复接口以及 stdio MCP Bridge / Plugin Host 也已完成。当前验证基线为后端 87 项测试、前端 27 项测试及生产构建通过。向量链路当前使用 `HashEmbeddingProvider` 验证工程正确性,真实 Embedding 召回质量不属于该测试结论。
第二阶段在既有 Contract 上接入: 第二阶段在既有 Contract 上接入:
@@ -2331,7 +2333,7 @@ Multimodal
└── pyannote.audio └── pyannote.audio
Extension / Model Extension / Model
├── MCP Bridge ├── MCP Bridgestdio 首版已实现)
├── Plugin Command Contribution ├── Plugin Command Contribution
├── Plugin Settings Contribution ├── Plugin Settings Contribution
└── Provider Streaming / Tool Calling / Error Mapping 增强 └── Provider Streaming / Tool Calling / Error Mapping 增强
@@ -2353,7 +2355,7 @@ Frontend Extension
└── Plugin Settings UI └── Plugin Settings UI
``` ```
上述列表描述第二阶段技术范围,不表示能力已经实现。每项功能必须继续经过现有 Service、Contract、Permission 和 Adapter 边界,不因 Demo 需要在 Vue 组件、Router 或 Agent Runtime 中直接绑定第三方协议。 上述列表描述第二阶段技术范围,其中 stdio MCP Bridge 已实现,其余能力以各自开发说明的状态为准。每项功能必须继续经过现有 Service、Contract、Permission 和 Adapter 边界,不因 Demo 需要在 Vue 组件、Router 或 Agent Runtime 中直接绑定第三方协议。
第三阶段处理: 第三阶段处理:
@@ -2409,7 +2411,7 @@ Sync Server 按独立服务开发和部署,不进入桌面客户端核心启
Python AI Core 未来作为 Tauri Sidecar 运行,当前由开发命令独立启动,FastAPI 提供本地接口。Knowledge Core 管理笔记结构;Retrieval Core 当前通过 FTS5、`HashEmbeddingProvider`、sqlite-vec、RRF 和轻量 Reranker 跑通混合检索,真实 Embedding 与正式 Benchmark 在第二阶段接入;Agent Runtime 使用 Tool Registry 操作知识库和任务,并将扩展 Agent Trace Contract 供可视化和 Benchmark 共用;Skill Runtime 将提示词、工具、权限和检索参数组装为可复用 Agent 配置。 Python AI Core 未来作为 Tauri Sidecar 运行,当前由开发命令独立启动,FastAPI 提供本地接口。Knowledge Core 管理笔记结构;Retrieval Core 当前通过 FTS5、`HashEmbeddingProvider`、sqlite-vec、RRF 和轻量 Reranker 跑通混合检索,真实 Embedding 与正式 Benchmark 在第二阶段接入;Agent Runtime 使用 Tool Registry 操作知识库和任务,并将扩展 Agent Trace Contract 供可视化和 Benchmark 共用;Skill Runtime 将提示词、工具、权限和检索参数组装为可复用 Agent 配置。
当前 Plugin Runtime 支持 Manifest、生命周期和声明式白名单 Tool Contribution;第二阶段通过 MCP Bridge 接入隔离 Tool,并增加 Command 与 Settings Contribution。Provider Adapter 当前实现 Mock、OpenAI Chat/OpenAI-Compatible 与 Ollama,第二阶段按统一行为测试完善 OpenAI Responses、Anthropic Messages 等协议。多模态目标方案使用 faster-whisper、pyannote.audio 和可选 emotion2vec;当前只读取 Host 预生成 transcript。 当前 Plugin Runtime 支持 Manifest、生命周期和声明式白名单 Tool Contribution,并已通过 stdio MCP Bridge 接入独立进程 Tool、Host 状态与重启接口;Command 与 Settings Contribution 尚待后续阶段实现。Provider Adapter 当前实现 Mock、OpenAI Chat/OpenAI-Compatible 与 Ollama,第二阶段按统一行为测试完善 OpenAI Responses、Anthropic Messages 等协议。多模态目标方案使用 faster-whisper、pyannote.audio 和可选 emotion2vec;当前只读取 Host 预生成 transcript。
第二阶段内容输出以 Document AST、Exporter Adapter、Mermaid Renderer 和 Function Plot Renderer 为共同边界,支持 HTML、PDF、DOCX 与静态图导出。Theme Package 使用 Manifest、Design Token 和受限 CSS 实现本地导入;联网主题市场不属于本阶段核心依赖。API Key 在 Web 联调期由 Fernet 开发存储加密保存,桌面版迁移到 Tauri Stronghold。多设备同步的目标方案为独立、可自托管的 Sync Server,目前尚未实现;本地核心功能不依赖 Sync Server。 第二阶段内容输出以 Document AST、Exporter Adapter、Mermaid Renderer 和 Function Plot Renderer 为共同边界,支持 HTML、PDF、DOCX 与静态图导出。Theme Package 使用 Manifest、Design Token 和受限 CSS 实现本地导入;联网主题市场不属于本阶段核心依赖。API Key 在 Web 联调期由 Fernet 开发存储加密保存,桌面版迁移到 Tauri Stronghold。多设备同步的目标方案为独立、可自托管的 Sync Server,目前尚未实现;本地核心功能不依赖 Sync Server。
@@ -746,8 +746,8 @@ Markdown
- [ ] faster-whisper 能完成真实音频转写; - [ ] faster-whisper 能完成真实音频转写;
- [ ] pyannote.audio 能生成说话人分段; - [ ] pyannote.audio 能生成说话人分段;
- [ ] 两者能组合生成带时间戳和 Speaker 的 Transcript - [ ] 两者能组合生成带时间戳和 Speaker 的 Transcript
- [ ] MCP Server 能通过 MCP Bridge 注册 Tool - [x] MCP Server 能通过 MCP Bridge 注册 Tool
- [ ] Agent 能调用 MCP Tool - [x] Agent 能调用 MCP Tool
- [ ] Plugin Command Contribution 后端可注册; - [ ] Plugin Command Contribution 后端可注册;
- [ ] Plugin Settings Contribution 后端可解析; - [ ] Plugin Settings Contribution 后端可解析;
- [ ] Provider Adapter 的 Streaming / Tool Calling / Error Mapping 稳定; - [ ] Provider Adapter 的 Streaming / Tool Calling / Error Mapping 稳定;
@@ -1,6 +1,6 @@
# 后端接口契约(开发版) # 后端接口契约(开发版)
> 更新日期:2026-08-31。本文档记录当前前后端联调使用的已实现接口;机器可读字段、校验规则和响应模型以 FastAPI 运行时生成的 OpenAPI 为准。第二阶段尚未实现的规划接口见 `第二阶段接口契约-开发版.md`,不要将规划路径视为当前服务能力。 > 更新日期:2026-09-01。本文档记录当前前后端联调使用的已实现接口;机器可读字段、校验规则和响应模型以 FastAPI 运行时生成的 OpenAPI 为准。第二阶段尚未实现的规划接口见 `第二阶段接口契约-开发版.md`,不要将规划路径视为当前服务能力。
## 契约入口 ## 契约入口
@@ -76,6 +76,8 @@ Web 联调阶段只暴露后端通过 `APP_VAULT_PATH` 配置的单一 Vault
| POST | `/api/plugins/{plugin_id}/enable` | 启用 Plugin | | POST | `/api/plugins/{plugin_id}/enable` | 启用 Plugin |
| POST | `/api/plugins/{plugin_id}/disable` | 停用 Plugin | | POST | `/api/plugins/{plugin_id}/disable` | 停用 Plugin |
| PUT | `/api/plugins/{plugin_id}/permissions` | 设置 Plugin 已授权权限 | | PUT | `/api/plugins/{plugin_id}/permissions` | 设置 Plugin 已授权权限 |
| GET | `/api/plugins/{plugin_id}/host` | 获取隔离 MCP Host 状态、工具数和协商信息 |
| POST | `/api/plugins/{plugin_id}/host/restart` | 重启 MCP Host 并重新发现、校验和注册 Tool |
| DELETE | `/api/plugins/{plugin_id}` | 卸载 Plugin | | DELETE | `/api/plugins/{plugin_id}` | 卸载 Plugin |
### Provider ### Provider
@@ -174,7 +176,7 @@ RunCancelled
## 当前实现状态 ## 当前实现状态
更新至 2026-09-01:后端 81 项回归测试通过。 更新至 2026-09-01:后端 87 项回归测试通过。
- Chat、Agent Run、Agent Events、Tool 列表、Provider 配置生命周期、模型列表和连接测试已经接入 AI Core。 - Chat、Agent Run、Agent Events、Tool 列表、Provider 配置生命周期、模型列表和连接测试已经接入 AI Core。
- Agent Run/Event 已持久化到 SQLiteSSE 帧携带 sequence `id`,断线后可以回放缺失事件。Trace API 与 Benchmark 共用同一事件事实,并在入库前执行 Secret 脱敏和结果限长。 - Agent Run/Event 已持久化到 SQLiteSSE 帧携带 sequence `id`,断线后可以回放缺失事件。Trace API 与 Benchmark 共用同一事件事实,并在入库前执行 Secret 脱敏和结果限长。
@@ -183,6 +185,7 @@ RunCancelled
- Workspace 已接入后端配置的真实 Vault;文件树、笔记读写、文件/目录新建、重命名和删除不再使用前端 Mock Fallback。 - Workspace 已接入后端配置的真实 Vault;文件树、笔记读写、文件/目录新建、重命名和删除不再使用前端 Mock Fallback。
- Note Move 保留 `note_id`;Citation 的字符偏移统一使用 UTF-16 code unit,供浏览器编辑器直接定位。 - Note Move 保留 `note_id`;Citation 的字符偏移统一使用 UTF-16 code unit,供浏览器编辑器直接定位。
- Plugin 启用前必须通过权限接口记录授权,未知权限默认拒绝。 - Plugin 启用前必须通过权限接口记录授权,未知权限默认拒绝。
- 本地 stdio MCP Server 已通过独立子进程接入 Plugin RuntimeAgent 只消费内部 Tool Contract。Host 支持 initialize、分页发现、调用、超时取消、状态查询、重启和异常退出后的 Tool 注销。
- Attachment Tool 读取 Host 管理的 `attachments` 目录;音频接口读取 Host 生成的转写文本,真实本地语音模型在第二阶段接入。 - Attachment Tool 读取 Host 管理的 `attachments` 目录;音频接口读取 Host 生成的转写文本,真实本地语音模型在第二阶段接入。
- 接入业务模块时保持当前路径和 Contract,不在 Router 中直接实现数据库、Provider 或 Agent 逻辑。 - 接入业务模块时保持当前路径和 Contract,不在 Router 中直接实现数据库、Provider 或 Agent 逻辑。
@@ -2,7 +2,7 @@
> 文档状态:接口冻结草案 > 文档状态:接口冻结草案
> >
> 更新日期:2026-08-31 > 更新日期:2026-09-01
> >
> 依据:`../architecture/第二阶段团队分工表.md`、`../architecture/AI笔记软件技术栈说明-团队版-v2.3.md`、`后端接口契约-开发版.md` > 依据:`../architecture/第二阶段团队分工表.md`、`../architecture/AI笔记软件技术栈说明-团队版-v2.3.md`、`后端接口契约-开发版.md`
@@ -45,8 +45,8 @@
| Transcription | POST | `/api/media/transcriptions/{job_id}/notes` | 计划新增 | 将 Transcript 写入 Knowledge Core | | Transcription | POST | `/api/media/transcriptions/{job_id}/notes` | 计划新增 | 将 Transcript 写入 Knowledge Core |
| Agent Trace | GET | `/api/agent/runs/{run_id}/events` | 已实现 | 支持游标恢复并增加模型与权限事件 | | Agent Trace | GET | `/api/agent/runs/{run_id}/events` | 已实现 | 支持游标恢复并增加模型与权限事件 |
| Agent Trace | GET | `/api/agent/runs/{run_id}/trace` | 已实现 | 分页读取可回放 Trace 快照 | | Agent Trace | GET | `/api/agent/runs/{run_id}/trace` | 已实现 | 分页读取可回放 Trace 快照 |
| Plugin Host | GET | `/api/plugins/{plugin_id}/host` | 计划新增 | 获取 MCP Host 健康状态 | | Plugin Host | GET | `/api/plugins/{plugin_id}/host` | 已实现 | 获取 MCP Host 健康状态 |
| Plugin Host | POST | `/api/plugins/{plugin_id}/host/restart` | 计划新增 | 重启异常 Host 并重新发现 Tool | | Plugin Host | POST | `/api/plugins/{plugin_id}/host/restart` | 已实现 | 重启异常 Host 并重新发现 Tool |
| Plugin Command | GET | `/api/plugin-contributions/commands` | 计划新增 | 获取前端可展示的 Command | | Plugin Command | GET | `/api/plugin-contributions/commands` | 计划新增 | 获取前端可展示的 Command |
| Plugin Command | POST | `/api/plugin-contributions/commands/{command_id}/execute` | 计划新增 | 受控执行 Command | | Plugin Command | POST | `/api/plugin-contributions/commands/{command_id}/execute` | 计划新增 | 受控执行 Command |
| Plugin Settings | GET | `/api/plugins/{plugin_id}/settings` | 计划新增 | 获取 Schema 与非敏感配置 | | Plugin Settings | GET | `/api/plugins/{plugin_id}/settings` | 计划新增 | 获取 Schema 与非敏感配置 |
@@ -427,7 +427,29 @@ class McpBridge(Protocol):
async def stop(self, plugin_id: str) -> None: ... async def stop(self, plugin_id: str) -> None: ...
``` ```
首个实现支持本地 `stdio`。Host 负责 initialize、capability negotiation、进程生命周期、超时取消、stderr 隔离和异常退出后的 Tool 注销。 首个实现支持本地 `stdio`,按 MCP `2025-11-25` 发起 initialize,并兼容 `2025-06-18``2025-03-26``2024-11-05` 协商结果。Host 负责 capability negotiation、分页 `tools/list`进程生命周期、超时取消、stderr 隔离和异常退出后的 Tool 注销。stdio 消息使用 UTF-8 单行 JSON-RPC;当前不实现 Streamable HTTP。
MCP Plugin 的 `backend` 增加:
```yaml
backend:
type: mcp
transport: stdio
command: python
args: [server.py]
startup_timeout_seconds: 5
tool_timeout_seconds: 30
```
命令通过参数数组直接启动,不经过 Shell。带路径的 executable 必须位于 Plugin 包内;PATH 中的命令可以按名称引用。子进程只继承运行所需的系统环境变量,不继承 `OPENAI_API_KEY``APP_DB_PATH`、Vault 路径等宿主状态。Secret 注入留给阶段 D 的专用引用接口。
远端 Tool 的可选项目权限放在 MCP `_meta`
```json
{ "_meta": { "notesagent/permission": "notes.read" } }
```
该权限必须属于项目已知权限并同时出现在 Plugin Manifest 中。发现结果必须与 `contributes.tools` 的命名空间 ID 完全一致;校验全部成功后才一次性发布到 Tool Registry。
当前 Web 开发接口 `POST /api/plugins/install` 使用 `package_path`。桌面 Host 接入后,`ExtensionInstallRequest` 增加 `package_id`,由文件选择器产生临时包句柄;`package_path` 只在明确的 development 环境保留并标记 deprecated,生产构建拒绝任意前端路径。 当前 Web 开发接口 `POST /api/plugins/install` 使用 `package_path`。桌面 Host 接入后,`ExtensionInstallRequest` 增加 `package_id`,由文件选择器产生临时包句柄;`package_path` 只在明确的 development 环境保留并标记 deprecated,生产构建拒绝任意前端路径。
@@ -460,6 +482,8 @@ error
`POST /api/plugins/{plugin_id}/host/restart` 返回 `202 OperationResponse`。重启期间先注销旧 Tool,发现和校验全部成功后再一次性发布新 Tool 集合,避免半注册状态。 `POST /api/plugins/{plugin_id}/host/restart` 返回 `202 OperationResponse`。重启期间先注销旧 Tool,发现和校验全部成功后再一次性发布新 Tool 集合,避免半注册状态。
当前实现还返回协商后的 `protocol_version``server_name``server_version`。单条协议消息上限为 2 MiB,单次 Tool Result 上限为 256 KiB;超限分别按 Host/Result 错误处理。Server 异常退出或发送无效 stdout 消息时,Host 进入 `unhealthy`Plugin 进入 `error`,相关 Tool 立即注销。
### 7.3 Command Contribution 列表 ### 7.3 Command Contribution 列表
`GET /api/plugin-contributions/commands?location=command_palette` `GET /api/plugin-contributions/commands?location=command_palette`
@@ -2,7 +2,7 @@
> 本文档用于团队开发和模块联调,记录当前已经落地的核心边界与使用方式。 > 本文档用于团队开发和模块联调,记录当前已经落地的核心边界与使用方式。
> 更新日期:2026-09-01。第一阶段 AI Core、Agent Core、Extension Core 和 Model Core 主链路已经完成;第二阶段 Agent Trace 持久化可恢复 SSE 已落地,后端当前回归基线为 81 项测试通过。 > 更新日期:2026-09-01。第一阶段 AI Core、Agent Core、Extension Core 和 Model Core 主链路已经完成;第二阶段 Agent Trace 持久化可恢复 SSE、stdio MCP Bridge 与隔离 Plugin Host 已落地,后端当前回归基线为 87 项测试通过。
## 当前实现 ## 当前实现
@@ -33,12 +33,14 @@ backend/app/
│ ├── permissions.py 权限策略、确认请求和会话授权 │ ├── permissions.py 权限策略、确认请求和会话授权
│ └── builtin_tools.py 无副作用的内置开发 Tool │ └── builtin_tools.py 无副作用的内置开发 Tool
├── extensions/ ├── extensions/
── runtime.py Skill/Plugin Manifest、生命周期、依赖与 Tool Contribution ── runtime.py Skill/Plugin Manifest、生命周期、依赖与 Tool Contribution
│ └── mcp.py stdio JSON-RPC、MCP 生命周期、发现、调用与 Host 隔离
└── container.py AI Core 依赖组装 └── container.py AI Core 依赖组装
backend/extensions/ backend/extensions/
├── skills/knowledge-assistant/ 内置知识库 Skill ├── skills/knowledge-assistant/ 内置知识库 Skill
── plugins/text-tools/ 内置示例 Plugin ── plugins/text-tools/ 内置声明式 Plugin
└── fixtures/mcp-echo/ 离线 MCP Server 联调 Fixture
``` ```
Router 只负责 HTTP/SSE 与错误转换,不实现 Agent、Tool 或 Provider 业务逻辑。 Router 只负责 HTTP/SSE 与错误转换,不实现 Agent、Tool 或 Provider 业务逻辑。
@@ -57,6 +59,7 @@ Router 只负责 HTTP/SSE 与错误转换,不实现 Agent、Tool 或 Provider
- SQLite Trace、分页快照与可恢复 SSE; - SQLite Trace、分页快照与可恢复 SSE;
- Skill Manifest、Prompt、Tool/Permission/模型能力解析; - Skill Manifest、Prompt、Tool/Permission/模型能力解析;
- Plugin Manifest、生命周期和 Tool Contribution - Plugin Manifest、生命周期和 Tool Contribution
- stdio MCP Bridge、隔离进程生命周期、Tool 映射与 Host 健康状态;
- Skill 调用内置 Tool 与 Plugin Tool - Skill 调用内置 Tool 与 Plugin Tool
- 公共 Contract 和 API 接入。 - 公共 Contract 和 API 接入。
@@ -65,7 +68,7 @@ Router 只负责 HTTP/SSE 与错误转换,不实现 Agent、Tool 或 Provider
- Note、NoteBlock、Markdown Parser:由 Knowledge Core 提供; - Note、NoteBlock、Markdown Parser:由 Knowledge Core 提供;
- FTS5、Vector、RRF、Reranker、Citation:由 Retrieval Core 提供; - FTS5、Vector、RRF、Reranker、Citation:由 Retrieval Core 提供;
- 文件系统和 API Key 明文读取:由 Rust Host 提供; - 文件系统和 API Key 明文读取:由 Rust Host 提供;
- MCP Plugin Host、Frontend Extension Slot:按技术基线放在第二阶段实现。 - Frontend Extension Slot 与 Plugin Command/Settings:按第二阶段后续阶段实现。
## Provider ## Provider
@@ -302,7 +305,7 @@ DELETE /api/skills/{skill_id}
### Plugin Runtime ### Plugin Runtime
第一阶段 Plugin Runtime 完成 Manifest 校验、安装、启用、停用、卸载和 Tool Contribution。第三方代码不会直接 import 到 AI Core;当前 Declarative Plugin Host 只执行宿主实现的白名单 handler,MCP Host 留到第二阶段 第一阶段 Plugin Runtime 完成 Manifest 校验、安装、启用、停用、卸载和声明式 Tool Contribution。阶段 C 增加 stdio MCP Bridge第三方代码不会直接 import 到 AI Core,而由独立子进程运行,通过换行分隔 JSON-RPC 完成 initialize、Tool 发现和调用
启用 Plugin 时将 Tool 注册到统一 Tool Registry,并标记 `source=plugin`;停用或异常时注销 Tool。启用中的 Skill 依赖某 Plugin Tool 时,Plugin 不能直接卸载。 启用 Plugin 时将 Tool 注册到统一 Tool Registry,并标记 `source=plugin`;停用或异常时注销 Tool。启用中的 Skill 依赖某 Plugin Tool 时,Plugin 不能直接卸载。
@@ -315,11 +318,15 @@ GET /api/plugins/{plugin_id}
POST /api/plugins/{plugin_id}/enable POST /api/plugins/{plugin_id}/enable
POST /api/plugins/{plugin_id}/disable POST /api/plugins/{plugin_id}/disable
PUT /api/plugins/{plugin_id}/permissions PUT /api/plugins/{plugin_id}/permissions
GET /api/plugins/{plugin_id}/host
POST /api/plugins/{plugin_id}/host/restart
DELETE /api/plugins/{plugin_id} DELETE /api/plugins/{plugin_id}
``` ```
Plugin Manifest 中的权限只是声明,不代表已经授权。带权限的 Plugin 安装后进入 `permission_required`,Host 必须通过权限接口记录用户授权,之后才能启用。JSON Schema 在安装阶段校验,Tool 调用时再次校验实际参数。 Plugin Manifest 中的权限只是声明,不代表已经授权。带权限的 Plugin 安装后进入 `permission_required`,Host 必须通过权限接口记录用户授权,之后才能启用。JSON Schema 在安装阶段校验,Tool 调用时再次校验实际参数。
MCP Tool 进入 Registry 前统一增加 `<plugin_id>.<remote_name>` 命名空间。Server 声明的 `notesagent/permission` 必须属于已知权限并出现在 Plugin Manifest;发现集合还必须与 Manifest Contribution 完全一致。启用失败会回滚全部 Tool 并关闭子进程,异常退出会把 Plugin 标记为 `error` 并立即注销对应 Tool。详细实现和 Fixture 操作见 [MCP Bridge 与 Plugin Host 开发说明](MCP-Bridge与Plugin-Host开发说明.md)。
内置示例 `text-tools` 注册 `text.uppercase`。内置 `knowledge-assistant` Skill 同时声明 `notes.search``text.uppercase`,用于验证完整链路: 内置示例 `text-tools` 注册 `text.uppercase`。内置 `knowledge-assistant` Skill 同时声明 `notes.search``text.uppercase`,用于验证完整链路:
```text ```text
@@ -342,4 +349,4 @@ Skill Manifest
- Task 已持久化到 SQLiteAttachment Tool 读取 Host 管理目录中的 UTF-8 文件。 - Task 已持久化到 SQLiteAttachment Tool 读取 Host 管理目录中的 UTF-8 文件。
- `audio.transcribe` 当前消费 Host 预生成的 transcriptfaster-whisper 与说话人分离仍按技术基线在第二阶段接入。 - `audio.transcribe` 当前消费 Host 预生成的 transcriptfaster-whisper 与说话人分离仍按技术基线在第二阶段接入。
- Extension 安装记录暂存内存;后续接入持久化 Registry 与版本升级流程。 - Extension 安装记录暂存内存;后续接入持久化 Registry 与版本升级流程。
- 当前 Plugin Host 支持内置声明式白名单 handler;MCP Bridge、独立进程健康检查与 UI Contribution 在第二阶段实现 - 当前 Plugin Host 支持内置声明式 handler 和本地 stdio MCP ServerStreamable HTTP、OS 级沙箱、Plugin Command/Settings 与 UI Contribution 留在后续阶段
@@ -3,7 +3,7 @@
> 本文档用于团队开发和模块联调,记录 Knowledge Core / Retrieval Core 已经落地的 > 本文档用于团队开发和模块联调,记录 Knowledge Core / Retrieval Core 已经落地的
> 模块边界、数据模型、接口与使用方式,对应分工表中的杨星萱。 > 模块边界、数据模型、接口与使用方式,对应分工表中的杨星萱。
> 更新日期:2026-09-01。第一阶段 Knowledge/Retrieval 主链路已经完成,并已接入 Agent Tool Registry;完整后端回归基线为 81 项测试通过。 > 更新日期:2026-09-01。第一阶段 Knowledge/Retrieval 主链路已经完成,并已接入 Agent Tool Registry;完整后端回归基线为 87 项测试通过。
## 当前实现 ## 当前实现
@@ -0,0 +1,262 @@
# MCP Bridge 与 Plugin Host 开发说明
> 更新日期:2026-09-01。本文记录第二阶段阶段 C 已实现的本地 stdio MCP Bridge、隔离 Plugin Host、Tool Contract 转换和离线测试方式。Plugin Command 与 Settings 属于阶段 D,不在本文实现范围内。
## 1. 目标与实现状态
阶段 C 的目标是让外部 MCP Server 进入既有 Plugin、Tool、Permission、Agent 和 Trace 链路,同时避免 Agent Runtime、前端或 Benchmark 直接依赖 MCP 原始消息。
当前链路:
```text
Plugin Manifest
→ Plugin Runtime
→ 独立 stdio MCP Server 进程
→ initialize / capability negotiation
→ tools/list 分页发现与校验
→ NotesAgent ToolDefinition
→ Tool Registry / Permission Manager
→ Agent Runtime / Agent Trace
```
已经实现:
- 本地 stdio 子进程启动、关闭和异常退出检测;
- UTF-8、换行分隔的 JSON-RPC 2.0 消息;
- initialize、协议版本与 tools capability 协商;
- `notifications/initialized`
- 分页 `tools/list`
- `tools/call`、业务错误与 JSON-RPC 错误转换;
- 超时和 `notifications/cancelled`
- Tool 命名空间、JSON Schema、权限和 Manifest 集合校验;
- Host 状态查询、重启和异常后的 Tool 自动注销;
- stderr 隔离、环境变量裁剪、消息及结果大小限制;
- 无网络、无密钥的确定性 MCP Fixture。
实现依据为 MCP 官方 [Lifecycle 2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle)、[Transports 2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports) 和 [Tools 2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25/server/tools)。
## 2. 代码位置
```text
backend/app/extensions/mcp.py
stdio 进程、JSON-RPC、MCP 生命周期、发现、调用和 Host 状态
backend/app/extensions/runtime.py
Plugin Manifest、权限、MCP Tool 批量注册/回滚和生命周期集成
backend/app/agent/tools.py
内部 Tool 参数校验、结构化执行错误和线程安全 Registry
backend/extensions/fixtures/mcp-echo/
确定性 stdio MCP Server 与 Plugin Manifest
```
## 3. Plugin Manifest
MCP Plugin 的后端配置示例:
```yaml
id: example-mcp
name: Example MCP
version: 1.0.0
permissions:
- notes.read
contributes:
tools:
- example-mcp.search
backend:
type: mcp
transport: stdio
command: python
args: [server.py]
startup_timeout_seconds: 5
tool_timeout_seconds: 30
```
约束:
- 阶段 C 只接受 `type: mcp``transport: stdio`
- 命令和参数通过数组直接传给 `subprocess.Popen`,不经过 Shell
- PATH 中的 executable 使用名称,例如 `python``node`
- manifest 中带目录的 executable 必须解析到 Plugin 包内部;
- `contributes.tools` 使用 `<plugin_id>.<remote_name>`
- 安装阶段只读 Manifest,不启动第三方进程;
- 完成用户授权后,`enable` 才启动 Host。
## 4. 生命周期
### 4.1 启动
启用 MCP Plugin 时依次执行:
1. 检查 Plugin 声明权限是否全部获得授权;
2. 检查 Manifest 声明的 Tool ID 是否与现有 Registry 冲突;
3. 启动独立 stdio Server
4. 发送 `initialize`
5. 校验协商版本和 `tools` capability
6. 发送 `notifications/initialized`
7. 分页读取 `tools/list`
8. 校验全部 Tool
9. 确认发现集合与 Manifest 完全一致;
10. 将完整集合注册到 Tool Registry
11. Plugin 和 Host 进入 `ready`
任何步骤失败都会注销本轮已注册 Tool、关闭子进程并把 Plugin 标记为 `error`,不会留下半启用状态。
### 4.2 停止与异常退出
停用、卸载或应用关闭时,先注销 Tool,再关闭 stdin,等待 Server 正常退出。超时后依次 terminate 和 kill。
Server 异常退出、stdout 出现非 JSON-RPC 内容或发送超大协议消息时:
- 未完成请求返回 `PLUGIN_HOST_UNAVAILABLE`
- Host 进入 `unhealthy`
- Plugin 进入 `error`
- 对应 Tool 从 Registry 中立即注销;
- 用户可以调用 Host Restart 接口重新协商和发现。
Server 发送 `notifications/tools/list_changed` 时不会直接信任新集合。当前实现先把 Host 标记为不健康并注销旧 Tool,要求通过 Restart 重新执行完整发现与校验。
## 5. Tool Contract 转换
MCP Tool
```json
{
"name": "search",
"description": "Search notes",
"inputSchema": { "type": "object", "properties": {} },
"_meta": { "notesagent/permission": "notes.read" }
}
```
进入系统后转换为:
```json
{
"name": "example-mcp.search",
"description": "Search notes",
"parameters": { "type": "object", "properties": {} },
"permission": "notes.read",
"source": "plugin"
}
```
转换规则:
- 远端名称必须能转换为合法且稳定的项目 Tool ID;
- `inputSchema` 必须是有效的 object JSON Schema
- `_meta.notesagent/permission` 必须属于项目已知权限;
- Tool 权限必须同时出现在 Plugin Manifest 中;
- Agent 仍通过 Tool Registry 执行参数校验、Permission、超时和 Trace
- MCP `structuredContent` 存在时映射为内部 output;否则保留为受控 `content` 数组;
- MCP `isError: true` 映射为 `MCP_TOOL_CALL_FAILED`
- 结果超过 256 KiB 映射为 `MCP_TOOL_RESULT_TOO_LARGE`
## 6. 隔离与安全边界
当前隔离是“独立进程 + 协议边界”,不是完整的操作系统沙箱。
已经执行的保护:
- 第三方模块不 import 到 AI Core
- 子进程 `cwd` 固定为 Plugin 包目录;
- 不使用 Shell 拼接命令;
- 不把 Provider API Key、`APP_DB_PATH`、Vault 路径和其他宿主环境变量传入子进程;
- stderr 与 JSON-RPC stdout 分离,stderr 不进入 API 和 Agent Trace
- stdout 只能发送合法 MCP JSON-RPC
- 单条协议消息上限 2 MiB
- 单次 Tool Result 上限 256 KiB
- MCP Tool 不绕过 Permission Manager 和 Agent Tool Timeout。
当前尚未提供容器、受限系统账户、seccomp、Windows AppContainer 或 macOS Sandbox,因此 Plugin 进程仍具有当前操作系统用户授予的一般文件访问能力。正式社区插件分发前必须继续增加包签名、来源验证和平台级沙箱;不得把当前进程隔离描述为完全安全执行任意不可信代码。
## 7. Host API
```http
GET /api/plugins/{plugin_id}/host
POST /api/plugins/{plugin_id}/host/restart
```
状态响应包含:
```text
plugin_id
backend_type / transport
status
tools_count
started_at / last_seen_at
protocol_version
server_name / server_version
error
```
状态值:
```text
stopped
starting
ready
unhealthy
error
```
Restart 返回 `202 OperationResponse`。接口返回前已完成本地 Host 重启和 Tool 重新发现;`message` 中给出最终 Host 状态。
## 8. 离线 Fixture
Fixture 位于:
```text
backend/extensions/fixtures/mcp-echo
```
它提供:
- `mcp-fixture.echo`:返回 structuredContent
- `mcp-fixture.fail`:返回 `isError: true`
- `mcp-fixture.sleep`:验证超时和取消;
- `mcp-fixture.large`:验证结果大小上限;
- `mcp-fixture.environment`:验证宿主 Secret/路径没有进入子进程;
- `mcp-fixture.exit`:验证异常退出、Tool 注销和 Restart。
Fixture 的 `tools/list` 使用两页响应,用于覆盖分页发现。测试还会启动缺少 tools capability 和返回无效 Schema 的变体。
## 9. 验证
```powershell
cd backend
uv run python -m compileall -q app
uv run pytest
cd ../frontend
pnpm test
pnpm type-check
pnpm build
```
阶段 C 新增测试覆盖:
- initialize、版本和 capability negotiation
- 分页 `tools/list` 与命名空间映射;
- Permission、JSON Schema 与 Contribution 集合;
- Tool 成功、业务错误、结果过大和超时;
- Agent Runtime 调用 MCP Tool 并写入正式 Trace
- Secret/Vault 环境隔离;
- Server 异常退出、Tool 注销和 Host Restart
- 缺少 capability 与无效 MCP Schema
- OpenAPI 发布 Host 状态和重启路径。
## 10. 当前边界与后续阶段
阶段 C 不包含:
- Streamable HTTP MCP transport
- Resources、Prompts、Sampling、Elicitation 和 MCP Tasks
- Plugin Command 与 Settings Contribution
- Secret Reference 注入;
- Plugin Registry 持久化、签名与社区来源校验;
- 操作系统级沙箱;
- Tool 列表热更新的无中断替换。
阶段 D 将在当前 Plugin Runtime 上继续增加 Command、Settings、Secret Contract 和命名空间 Storage,不修改 Agent 使用内部 Tool Contract 的原则。
@@ -187,12 +187,12 @@ pnpm build
```text ```text
pnpm build passed pnpm build passed
pnpm test 27 passed pnpm test 27 passed
uv run pytest 81 passed uv run pytest 87 passed
preview smoke HTTP 200 preview smoke HTTP 200
git diff --check passed git diff --check passed
``` ```
当前前端使用 Vitest 执行 Store、Workspace API Adapter、SSE 恢复游标、文件树、编辑器组件、智能体标签、轻量动效约束、Markdown 对比度 Token、scoped CSS 选择器约束和 Shiki GitHub 双主题测试;`pnpm build` 同时执行 `vue-tsc -b` 与 Vite 生产构建。后端测试出现过 `.pytest_cache` 无法写入的 Windows 权限警告,不影响 81 项测试结果,也不涉及产品代码。 当前前端使用 Vitest 执行 Store、Workspace API Adapter、SSE 恢复游标、文件树、编辑器组件、智能体标签、轻量动效约束、Markdown 对比度 Token、scoped CSS 选择器约束和 Shiki GitHub 双主题测试;`pnpm build` 同时执行 `vue-tsc -b` 与 Vite 生产构建。后端测试出现过 `.pytest_cache` 无法写入的 Windows 权限警告,不影响 87 项测试结果,也不涉及产品代码。
Vite 当前会提示 Chat 与 Workspace 的部分异步 Chunk 超过 500 kB,这是 Milkdown、CodeMirror、KaTeX 和 Shiki 等编辑/渲染依赖带来的性能优化项,不影响构建成功或功能正确性;进入桌面打包前应通过手动分包或更细粒度动态加载继续优化。 Vite 当前会提示 Chat 与 Workspace 的部分异步 Chunk 超过 500 kB,这是 Milkdown、CodeMirror、KaTeX 和 Shiki 等编辑/渲染依赖带来的性能优化项,不影响构建成功或功能正确性;进入桌面打包前应通过手动分包或更细粒度动态加载继续优化。
@@ -104,4 +104,4 @@ pnpm build
自动化验证覆盖 Provider 预设、OpenAI-Compatible `/models` 请求与鉴权头、模型映射、前端自动刷新、排序去重及按 Provider 隔离错误。生产构建同时执行 Vue 和 TypeScript 类型检查。 自动化验证覆盖 Provider 预设、OpenAI-Compatible `/models` 请求与鉴权头、模型映射、前端自动刷新、排序去重及按 Provider 隔离错误。生产构建同时执行 Vue 和 TypeScript 类型检查。
当前完整回归基线:后端 81 项测试、前端 27 项测试通过,前端类型检查和生产构建通过。Provider 配置目前仍保存在内存 Registry,AI Core 重启后需要重新创建;凭据密文会保留。OpenAI Responses 与 Anthropic Messages Adapter 尚未实现,设置页正式预设不会使用这两种协议。 当前完整回归基线:后端 87 项测试、前端 27 项测试通过,前端类型检查和生产构建通过。Provider 配置目前仍保存在内存 Registry,AI Core 重启后需要重新创建;凭据密文会保留。OpenAI Responses 与 Anthropic Messages Adapter 尚未实现,设置页正式预设不会使用这两种协议。
@@ -4,7 +4,7 @@
> 审阅范围:FastAPI、Knowledge / Retrieval Core、Agent Core、Extension Core、Provider Adapter、公共接口和后端开发文档。 > 审阅范围:FastAPI、Knowledge / Retrieval Core、Agent Core、Extension Core、Provider Adapter、公共接口和后端开发文档。
> 文档用途:记录问题形成原因、实际影响、修复判断和落地方案,供后续开发文档、比赛材料与技术博客使用。 > 文档用途:记录问题形成原因、实际影响、修复判断和落地方案,供后续开发文档、比赛材料与技术博客使用。
> 2026-09-01 状态补充:本文记录的缺陷均保持修复。此后又加入 Provider 预设、模型发现、DeepSeek/OpenAI 凭据解析、Fernet 加密存储Agent Trace 持久化,当前完整后端回归基线为 81 项测试通过。 > 2026-09-01 状态补充:本文记录的缺陷均保持修复。此后又加入 Provider 预设、模型发现、DeepSeek/OpenAI 凭据解析、Fernet 加密存储Agent Trace 持久化和 stdio MCP Plugin Host,当前完整后端回归基线为 87 项测试通过。
## 1. 审阅结论 ## 1. 审阅结论