Skip to content

[Grok/dsh 72] 插件 MCP 贡献接入 #204

Closed

Description

@Blackman99

Parent

#132

Ticket: 72

Status: ready-for-agent

User Stories: 39, 41(见父规格)

What to build

用户启用含 MCP 配置的插件后可以实际发现并调用工具,停用或卸载时对应连接和授权状态正确撤回。

Acceptance criteria

  • 插件提供的 MCP 配置进入同一连接和工具执行路径,不另造 MCP 客户端或权限机制。
  • 来源冲突、启停、插件更新及缺依赖导致的部分失败在扩展视图和实际工具目录一致。
  • 插件安装不授予 MCP 执行权限;撤回后不能通过旧目录或缓存继续调用已撤销工具。
  • 用真实插件加测试 MCP 进程验证完整生命周期,直接配置 MCP 不依赖本票。

Blocked by

Delivery contract

用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。

Activity

  1. Blackman99 commented on Sep 25, 2026

    @Blackman99
    OwnerAuthor

    已完成,提交:99ebc6a (已推送到 rewrite/grok-dsh-20260920,已 rebase 到 #186 与 #196 之后,双方新增内容均保留)。

    实现

    • 插件 MCP 走同一条路径:已启用且受信任插件的 .mcp.json / 清单 mcpServers(路径、路径列表或内联表)作为 Source::Plugin 进入 mcp::discover,再经同一个计划文件、dsh MCP 客户端和审批门挂载;没有新增 MCP 客户端或权限机制。插件来源优先级最低(同名的用户/项目/导入服务器胜出,插件之间按名称先到先得,被遮蔽的记录在 Discovery.shadowed)。相对 command/cwd 在插件目录内解析,越出目录则该服务器无效;进程环境与 ${...} 展开提供 GROK_PLUGIN_ROOT/DATA 与 CLAUDE_PLUGIN_* 别名。
    • 一致性:plugin list --json(contributions.mcpServers)、/plugins 展开行、mcp list、/mcps 使用同一份发现结果,标注 plugin: <名称>;状态包括 ready、failed(缺少程序,属部分失败,不影响其他服务器与会话)、shadowed、invalid、disabled 或插件自身状态;TUI 中显示实时 connected (N tools) / “下一次提示时撤回”。mcp enable|disable 认得插件服务器名;mcp remove 对插件服务器给出提示。
    • 权限与撤回:安装/启用不授予任何执行权限。每个会改变插件状态的 plugin 命令前后对“插件胜出的服务器”做指纹(插件、revision、传输);停用、更新、卸载或名称被其他插件接管时,忘记该服务器 server__* 的已记住批准(拒绝保留);mcp remove 使名称落到插件服务器时同样忘记旧批准。AcpClient 记录会话实际挂载的计划;TUI 在下一次提示前替换 dsh 子进程,编辑器服务器(agent stdio/serve)在空闲会话的下一次提示前于新 dsh 中恢复同一会话,过期的预热运行时被丢弃,因此旧目录/缓存中的工具无法再调用(实测返回 unknown tool / Unknown MCP tool)。

    验证(真实数字)

    • cargo test --locked --workspace --offline --no-fail-fast:1695 通过 / 2 失败 / 2 忽略;2 个失败为既有的 filesystem_sandbox(与本单无关,此前已记录;此前间歇失败的 voice/privacy 本次通过)。新增 plugin 单元测试 4 个(信任/启用门控、遮蔽、变量展开、越界命令、清单形式、损坏文件隔离、批准撤回、挂载计划比较与 live 注解)。
    • TMPDIR=/tmp pnpm test:102 个文件,2547 通过 / 3 失败 / 15 跳过;失败为高负载下的 reference-evidence(既有 5s 超时)、reference-inventory(5s 超时)和 rust-plan(等待超时),后两者单独重跑 174/174 通过。
    • 新增 scripts/rust-plugin-mcp.spec.mjs(2 个用例,真实 dsh + 插件自带的无密钥 fixture MCP 进程):未信任安装被拒、安装未启用不挂载、启用后工具可见、无规则的 headless 调用与 ACP 拒绝无副作用、批准后副作用写入插件数据目录恰好一次、已记住批准在新会话生效、停用后批准被忘记且已打开的 ACP 会话在下一提示前失去工具、重新启用会再次询问、卸载移除;用户服务器胜出、缺少程序的部分失败在 plugin list --json 与工具列表中一致、mcp disable|enable、名称回到插件、plugin update 重新挂载新定义。
    • 新增 PTY scripts/rust-plugin-mcp-pty-test.py(已加入 test:rust:pty):Linux 通过;rust-plugin-content-pty-test.py 通过;rust-plugin-pty-test.py 需要 macOS,未运行。
    • pnpm run typecheck 通过;cargo fmt --check 通过;cargo clippy ... -D warnings 仅有既有的 2 处(tail_marker 未使用、filesystem_sandbox.rs 多余 return),排除这 2 项后无告警。

    未验证

    • macOS / Windows 未运行;真实模型提供方与付费/远程 MCP 服务未使用(全部为本地 fixture 与无密钥 mock);参考二进制未运行,对照依据为固定源码版本 e8563f8。
    • 手工编辑 config.toml 删除同名服务器(不经 mcp remove)时不会自动撤回旧批准。
    • 托管的 MCP allow/deny(allowedMcpServers / deniedMcpServers / allow_managed_mcp_servers_only)不在本单验收内,之前的负责工单也未实现,需要另行指定负责人。

    范围

    后续

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions