Skip to content

feat(tools/mcp): 为 MCP specs 暴露链路接入过滤器#242

Merged
phantom5099 merged 3 commits into
1024XEngineer:mainfrom
Cai-Tang-www:main
Apr 12, 2026
Merged

feat(tools/mcp): 为 MCP specs 暴露链路接入过滤器#242
phantom5099 merged 3 commits into
1024XEngineer:mainfrom
Cai-Tang-www:main

Conversation

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator

关联

背景

当前 ListAvailableSpecs 会把所有 MCP tools 全量暴露给模型,带来两个问题:

  • 无法按 server 状态、策略或 agent 角色裁剪 MCP 工具可见性
  • MCP schema 全量注入 prompt,增加无关工具干扰与上下文负担

本次改动

  • internal/tools/mcp 新增 ExposureFilter 抽象与默认实现
  • internal/tools/registryListAvailableSpecs 末端接入 MCP 暴露过滤
  • 过滤维度支持:
    • server status
    • allowlist / denylist
    • agent role
  • 过滤执行基于 mcp.Registry.Snapshot() 的不可变快照
  • 过滤异常时按 fail-closed 处理:不暴露 MCP tools,但不影响 built-in tools
  • 为后续 query-aware 过滤预留 SpecListInput.Query
  • config / bootstrap 接入 tools.mcp.exposure 配置装配链路
  • 保持 MCP 实际执行链路与 spec 暴露链路解耦,避免执行错误依赖过滤上下文

审计与行为

  • 新增过滤原因:
    • offline
    • policy_deny
    • agent_mismatch
    • allowlist_miss
    • filter_error
  • 可通过 registry 读取最近一次 MCP 暴露过滤审计快照

测试

  • 新增 MCP exposure filter 单测
  • 补齐 registry / adapter / config / bootstrap 相关测试
  • 已执行:go test ./...

@codecov

codecov Bot commented Apr 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.44156% with 51 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/tools/registry.go 72.04% 13 Missing and 13 partials ⚠️
internal/tools/mcp/exposure_filter.go 88.37% 7 Missing and 8 partials ⚠️
internal/config/model.go 87.69% 4 Missing and 4 partials ⚠️
internal/tools/mcp/adapter.go 66.66% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

整体实现方向清晰,测试覆盖也比较完整;但我这边确认有 3 个值得尽快处理的问题,其中 2 个是高优先级行为/安全风险。

Comment thread internal/tools/registry.go Outdated
Comment thread internal/tools/registry.go
Comment thread internal/tools/registry.go
@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

/code -codex 修复你所提到的review问题

@fennoai

fennoai Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

已完成

已按你这条指令修复我此前提出的 3 个 review 问题,并推送到当前 PR 分支。

具体修复

  • 执行链路补上策略门控:resolveMCPAdapter 在解析前会检查 policy_deny,命中后直接拒绝执行(返回 tool: not found),避免“spec 不可见但可猜名调用”。
  • 过滤错误语义修复:filterMCPSnapshots 遇到 context.Canceled / context.DeadlineExceeded 现在原样透传,不再被 fail-closed 吞掉。
  • Agent 为空回退策略:DefaultExposureFilterAgent 为空时跳过 agent 维度过滤,避免 runtime 当前默认调用场景下 MCP specs 被全量过滤。

测试

  • 新增/更新测试:
    • TestRegistryExecuteRejectsPolicyDeniedMCPTool
    • TestRegistryListAvailableSpecsReturnsContextErrorFromExposureFilter
    • TestDefaultExposureFilterSkipsAgentFilterWhenAgentIsEmpty
  • 本地执行:
    • go test ./internal/tools/... 通过
    • go test ./... 未全绿(internal/appTestBuildToolRegistryAppliesMCPExposureConfig 依赖 mock 可执行文件,当前环境缺失)

提交信息

View job run

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot review

@fennoai

fennoai Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Review Findings

  1. High tools.mcp.exposure.agents 在当前 runtime 主链路下会把 MCP specs 全量过滤掉。

    • 位置:internal/runtime/runtime.go:262internal/tools/mcp/exposure_filter.go:81-90internal/tools/mcp/exposure_filter.go:122-127
    • 问题:runtime 调用 ListAvailableSpecs 仅传 SessionIDAgent 为空;一旦配置了 Agents 规则,agentRule == nil 分支会将所有 MCP 工具标记为 agent_mismatch 并拒绝暴露。
    • 影响:开启 agent 维度配置后,模型在真实运行中看不到任何 MCP 工具。
  2. High MCP 暴露过滤仅作用于 spec 展示,执行链路可绕过策略直接调用被隐藏工具。

    • 位置:internal/tools/registry.go:167-177internal/tools/registry.go:255-279
    • 问题:Execute -> resolveMCPAdapter 直接扫描 mcp.Registry.Snapshot() 找工具,未复用/校验 policy_denyallowlistagentstatus 过滤结果。
    • 影响:只要模型或提示词猜到完整名(如 mcp.admin.secret),仍可能调用“不可见” MCP 工具,策略边界被绕过。
  3. Medium 过滤器上下文取消错误被吞掉,导致取消信号失效。

    • 位置:internal/tools/registry.go:298-303
    • 问题:filter.Filter(...) 返回任意错误都会被 fail-closed 吞掉并返回 nil error;其中包含 context.Canceled/context.DeadlineExceeded
    • 影响:请求在取消后仍可能继续向后执行,造成额外开销和语义不一致。

Verification Notes

  • 已基于 origin/main...HEAD 审阅变更。
  • 本地执行 go test ./...:失败于 internal/appmock 可执行文件缺失),其余包通过。

View job run

fix(tools): 修复 MCP 暴露过滤 review 问题
@phantom5099 phantom5099 merged commit 2079c91 into 1024XEngineer:main Apr 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(tools/mcp): 工具暴露过滤(避免全量 schema 注入)

3 participants