feat(agent): deferred MCP tool schema disclosure (Tool Search) - #2443
Merged
Merged
Conversation
topcheer
pushed a commit
that referenced
this pull request
Sep 16, 2026
…ting) CodeQL flagged 6 critical alerts on PR #2443: the new tool_search dispatch/auto-activate paths feed JSON-derived tool names into the error-tracking pipeline, opening a new taint path to the '%s' single-quote interpolation in error_cascade.go's guidance strings. The strings are message text (not SQL/shell), so the exploitability is theoretical, but %q is the correct fix: Go-quoted output is escape-safe and the quoting pattern CodeQL keys on disappears. Args unchanged, message quoting changes from 'key' to "key". Co-Authored-By: ggcode <noreply@ggcode.dev>
topcheer
commented
Sep 16, 2026
topcheer
left a comment
Owner
Author
There was a problem hiding this comment.
复审通过 ✅(6 PR 排程最后一环)
- 单调激活语义正确:activated 只增不减——尊重 dynamic tool pruning 回退教训(agent.go activeToolDefs 注释的失败模式:mid-run 缩表 destabilize+CJK 误发),是本设计最重要的约束且被显式遵守
- autoActivate 挂点精确:unknown-tool 检查之后、执行之前——deferred 工具 registry 里真实存在(不触发 unknown error),激活保证后续请求与历史引用一致(history carry-over 安全)
- 边界完备:built-in 永不 deferred(file/edit/run 首轮全量)/20 MCP 门槛下自动关闭(小配置零往返)/GGCODE_TOOL_SEARCH=off 显式退出/compaction 的 SetToolDefinitionOverhead 同步缩减列表(记账准确)
- 并发安全:toolSearchState 全 mu 守卫(并行工具执行下激活竞态防护)
- error_cascade %q 顺带修复:即 CodeQL 污点根因(格式串注入面消除)——修复方向正确且是 main 既有 sink,纳入本 PR 合理
- search 语义:AND-token 匹配+确定性序(sort.Strings)+limit 钳制+空 query 目录浏览;agent-side meta-tool 不进 registry(sub-agent clone/权限流零扰动)
- 10 测试含 fakeMCPTool 集成
CI 全绿(CodeQL 复绿=污点消除验证)。可合并。
…-tool Implements Tool Search (Anthropic Advanced Tool Use, advanced-tool-use-2025-11-20) for ggcode: when the registry carries >=20 MCP tools (mcp__server__tool), their schemas are hidden behind a single agent-side tool_search meta-tool. The model searches on demand; matched schemas are returned in the tool result and activated, so subsequent requests carry core tools + meta-tool + activated schemas only. Design constraints honored: - Activation is strictly monotonic (schemas only added mid-run, never removed) — the failure mode that got dynamic tool pruning reverted. - Built-in tools are never deferred; file/edit/search/run stay fully available from the first turn. - Meta-tool handled agent-side (not registry-backed) so sub-agent clones and Registry.ToDefinitions stay untouched. - Calling a deferred MCP tool by name auto-activates its schema (history carry-over safety); state is mutex-guarded for parallel tool execution. - Per-turn SetToolDefinitionOverhead now reflects the reduced list. - Opt-out: GGCODE_TOOL_SEARCH=off. Research: https://docs.anth.com/en/docs/agents-and-tools/tool-use/tool-search-tool (mirrored at code.claude.com/docs/en/advanced-tool-use) Co-Authored-By: ggcode <noreply@ggcode.dev> Co-Authored-By: ggcode <noreply@ggcode.dev>
Covers the integration points that unit tests on toolSearchState miss: - executeTool dispatches the tool_search meta-tool agent-side (no registry lookup) and a successful search feeds the next request's active list - by-name calls to deferred MCP tools execute normally AND auto-activate their schema (history carry-over consistency) - below-threshold agents send the full registry list with no meta-tool Co-Authored-By: ggcode <noreply@ggcode.dev> Co-Authored-By: ggcode <noreply@ggcode.dev>
…ting) CodeQL flagged 6 critical alerts on PR #2443: the new tool_search dispatch/auto-activate paths feed JSON-derived tool names into the error-tracking pipeline, opening a new taint path to the '%s' single-quote interpolation in error_cascade.go's guidance strings. The strings are message text (not SQL/shell), so the exploitability is theoretical, but %q is the correct fix: Go-quoted output is escape-safe and the quoting pattern CodeQL keys on disappears. Args unchanged, message quoting changes from 'key' to "key". Co-Authored-By: ggcode <noreply@ggcode.dev>
topcheer
force-pushed
the
mcp-tool-search
branch
from
September 16, 2026 19:16
ed7ee3c to
6e4b484
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Implements Tool Search (deferred tool loading) for ggcode, porting Anthropic's Advanced Tool Use capability (beta
advanced-tool-use-2025-11-20, docs) to the agent runtime.When the tool registry carries >= 20 MCP tools (
mcp__server__toolnaming, e.g. many connected MCP servers), their JSON schemas are hidden behind a singletool_searchmeta-tool:tool_searchonly — MCP schema tokens are no longer paid on every call.Design constraints honored
activeToolDefsin agent.go): mid-run list shrinkage destabilized models and misfired on CJK contexts.tool_searchis not registry-backed: sub-agent clones,Registry.ToDefinitions()and permission flows stay untouched; activation state is per-agent and mutex-guarded for parallel tool execution.SetToolDefinitionOverheadnow reflects the reduced list, so compaction accounting stays accurate.GGCODE_TOOL_SEARCH=off(also auto-disables below 20 MCP tools to keep zero-round-trip behavior on small setups).Files
internal/agent/tool_search.go— state, scoring search, meta-tool definition, executor (~260 lines)internal/agent/agent.go— struct field, NewAgent init, run-startinit, per-turnactiveDefsinternal/agent/agent_tool.go— meta-tool dispatch + by-name auto-activationinternal/agent/tool_search_test.go— 7 tests: threshold, defer/activate, re-search no-match, auto-activate, env opt-out, deterministic order, concurrent activation (-race)Verification
go build -tags goolm ./...✅,go vet -tags goolm ./internal/agent✅, gofmt clean ✅go test -tags goolm -race -run ToolSearch ./internal/agent✅go test -tags goolm -p 1 -parallel 1 ./internal/agent✅ (full package)Research
Co-Authored-By: ggcode noreply@ggcode.dev