From 6c0c63b679ef6cd3ec2a56e723a2edfb76250754 Mon Sep 17 00:00:00 2001 From: azmym Date: Mon, 1 Jun 2026 14:46:18 +0200 Subject: [PATCH] fix: teach agents the ToolSearch deferred-tool step for heavy-MCP sessions In sessions with many MCP servers connected, Claude Code defers MCP tools: the tool name is shown but its schema is not loaded, and a direct call fails until the caller materializes it via ToolSearch. The five Gemini agents told themselves to "use the gemini_search_grounded tool" but never mentioned ToolSearch, so a subagent in a heavy-MCP session could not find a directly callable Gemini tool, burned its turn budget hunting for the name, and ended mid-investigation without emitting its JSON. The orchestrator then fell back to plain web search. Intermittent because a light session loads the tools directly and a capable model sometimes rediscovers ToolSearch unaided. Distinct from the v0.4.1 tools:-allowlist bug and from the stale-session case gemini-doctor covers. - Add a "Deferred tools (do this FIRST)" step to each agent's Tool availability section: ToolSearch with a namespace-agnostic keyword query, then call the exact tool name returned; treat as missing only after ToolSearch returns no match. - gemini-consult skill documents the path and points to gemini-doctor. - tests/mcp-namespace.bats asserts every agent documents the ToolSearch step via a keyword query (not a hardcoded mcp__ path). 83 tests pass. - Bump to 0.5.1; CHANGELOG updated. --- .claude-plugin/plugin.json | 2 +- CHANGELOG.md | 11 +++++++++++ agents/gemini-challenger.md | 2 ++ agents/gemini-researcher.md | 2 ++ agents/gemini-reviewer.md | 2 ++ agents/gemini-summarizer.md | 2 ++ agents/gemini-validator.md | 2 ++ skills/gemini-consult/SKILL.md | 13 +++++++++++++ tests/mcp-namespace.bats | 25 +++++++++++++++++++++++++ 9 files changed, 60 insertions(+), 1 deletion(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 50ea335..65ee941 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "gemini-plugin", "displayName": "Gemini Plugin", - "version": "0.5.0", + "version": "0.5.1", "description": "Wraps gemini-mcp into a Claude Code plugin so Gemini acts as a second opinion: validator/challenger/researcher/summarizer/reviewer subagents, auto-trigger hooks, and 9 task-oriented skills.", "author": { "name": "azmym" }, "homepage": "https://github.com/azmym/gemini-plugin", diff --git a/CHANGELOG.md b/CHANGELOG.md index 59031be..ff6e667 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to gemini-plugin are documented here. The format follows [Ke ## [Unreleased] +## [0.5.1] - 2026-06-01 + +### Fixed + +- **Agents stalled "hunting for the tool name" in sessions with many MCP servers.** When numerous MCP servers are connected, Claude Code switches MCP tools into *deferred* mode: the tool name is shown in a system reminder but its schema is not loaded, so a direct call fails until the caller materializes it via `ToolSearch`. The five agents told themselves to "use the gemini_search_grounded tool" but never mentioned `ToolSearch`, so a subagent in a heavy-MCP session could not find a directly-callable Gemini tool, burned its turn budget hunting for the name, and ended mid-investigation without emitting its JSON, after which the orchestrator fell back to plain web search. This was intermittent because a light session loads the tools directly and a capable model sometimes rediscovers `ToolSearch` unaided. Distinct from the v0.4.1 `tools:`-allowlist bug and from the stale-session case `gemini-doctor` covers. Fixed by adding a "Deferred tools (do this FIRST)" step to each agent's "Tool availability" section: call `ToolSearch` with a namespace-agnostic keyword query (e.g. `gemini search grounded`) to load the schema, then call the exact tool name returned; treat the tool as missing only after `ToolSearch` returns no match. + +### Changed + +- `gemini-consult` skill documents the deferred-tool path and points to `/gemini-plugin:gemini-doctor` when an agent returns `unavailable`/`unknown` with a missing-tool error. +- `tests/mcp-namespace.bats` now asserts every agent documents the `ToolSearch` deferred-tool step using a keyword query (not a hardcoded `mcp__` path). + ## [0.5.0] - 2026-05-29 ### Added diff --git a/agents/gemini-challenger.md b/agents/gemini-challenger.md index de8fcdd..b3efc89 100644 --- a/agents/gemini-challenger.md +++ b/agents/gemini-challenger.md @@ -27,6 +27,8 @@ You are gemini-challenger, a constructive devil's advocate powered by Claude Son Your challenge capability uses Gemini MCP tools inherited from the session (gemini_generate, gemini_chat). The registered name may be namespaced by the install (the manual-install namespace for a manual install, the plugin-install namespace for the plugin install); use whichever the session exposes. +**Deferred tools (do this FIRST).** In a session with many MCP servers connected, your Gemini tools are often *deferred*: the tool name appears in a system reminder but its schema is NOT loaded, and calling it directly fails with an input-validation error. Do not hunt for the exact tool name and do not give up. Before your first Gemini call, run the `ToolSearch` tool with a keyword query such as `gemini generate` (or `gemini chat`) to materialize the schema, then call the exact tool name `ToolSearch` returns. If `ToolSearch` is not in your toolset, the Gemini tools are already loaded directly, so call them by name. Treat the tool as missing ONLY after `ToolSearch` returns no Gemini match. + If NO Gemini tool is available, do NOT invent alternatives from training knowledge. Emit `verdict: "pass"` (non-blocking) with a single `must_address` entry "Gemini was unavailable; challenge not performed" and an `error` field naming the missing tool. A loud failure is correct; a fabricated challenge is a defect. ## Verdict Rules diff --git a/agents/gemini-researcher.md b/agents/gemini-researcher.md index 1cf0928..85b3079 100644 --- a/agents/gemini-researcher.md +++ b/agents/gemini-researcher.md @@ -24,6 +24,8 @@ Never opine without a citation. Every claim in your answer must be traceable to Your search capability comes from a Gemini MCP tool inherited from the session (gemini_search_grounded, gemini_start_research, gemini_get_research_report). The registered name may be namespaced by the install (the manual-install namespace for a manual install, the plugin-install namespace for the plugin install); use whichever the session exposes. +**Deferred tools (do this FIRST).** In a session with many MCP servers connected, your Gemini tools are often *deferred*: the tool name appears in a system reminder but its schema is NOT loaded, and calling it directly fails with an input-validation error. Do not hunt for the exact tool name and do not give up. Before your first Gemini call, run the `ToolSearch` tool with a keyword query such as `gemini search grounded` (or `gemini start research`) to materialize the schema, then call the exact tool name `ToolSearch` returns. If `ToolSearch` is not in your toolset, the Gemini tools are already loaded directly, so call them by name. Treat the tool as missing ONLY after `ToolSearch` returns no Gemini match. + If NO Gemini search tool is available in this session, do NOT answer from your own training knowledge. Emit the JSON with `confidence: "unavailable"`, `citations: []`, and an `error` field naming the missing tool, for example: "gemini_search_grounded not available in session". A loud failure is correct; a confident-looking fabricated answer is a defect. ## Workflow diff --git a/agents/gemini-reviewer.md b/agents/gemini-reviewer.md index 5ecbb59..df016b3 100644 --- a/agents/gemini-reviewer.md +++ b/agents/gemini-reviewer.md @@ -43,6 +43,8 @@ You have 10 turns. Budget them: Your review capability uses Gemini MCP tools inherited from the session (gemini_chat, gemini_search_grounded). The registered name may be namespaced by the install (the manual-install namespace for a manual install, the plugin-install namespace for the plugin install); use whichever the session exposes. +**Deferred tools (do this FIRST).** In a session with many MCP servers connected, your Gemini tools are often *deferred*: the tool name appears in a system reminder but its schema is NOT loaded, and calling it directly fails with an input-validation error. Do not hunt for the exact tool name and do not give up. Before your first Gemini call, run the `ToolSearch` tool with a keyword query such as `gemini chat` (or `gemini search grounded`) to materialize the schema, then call the exact tool name `ToolSearch` returns. If `ToolSearch` is not in your toolset, the Gemini tools are already loaded directly, so call them by name. Treat the tool as missing ONLY after `ToolSearch` returns no Gemini match. + If NO Gemini tool is available, do NOT review from training knowledge alone. Emit `verdict: "unknown"` with an `error` field naming the missing tool, for example: "gemini_chat not available in session". A loud failure is correct; a fabricated review is a defect. ## What you are NOT diff --git a/agents/gemini-summarizer.md b/agents/gemini-summarizer.md index 0434f05..ca928c7 100644 --- a/agents/gemini-summarizer.md +++ b/agents/gemini-summarizer.md @@ -20,6 +20,8 @@ You are gemini-summarizer, a session compression and risk analysis agent powered Your synthesis uses the gemini_generate MCP tool inherited from the session. The registered name may be namespaced by the install (the manual-install namespace for a manual install, the plugin-install namespace for the plugin install); use whichever the session exposes. +**Deferred tools (do this FIRST).** In a session with many MCP servers connected, your Gemini tool is often *deferred*: the tool name appears in a system reminder but its schema is NOT loaded, and calling it directly fails with an input-validation error. Do not hunt for the exact tool name and do not give up. Before your Gemini call, run the `ToolSearch` tool with a keyword query such as `gemini generate` to materialize the schema, then call the exact tool name `ToolSearch` returns. If `ToolSearch` is not in your toolset, the Gemini tool is already loaded directly, so call it by name. Treat the tool as missing ONLY after `ToolSearch` returns no Gemini match. + If NO Gemini tool is available, do NOT synthesize from training knowledge alone. Emit your JSON document with an "error" field naming the missing tool, for example: "gemini_generate not available in session", and include only what you can derive directly from the inputs you read. A loud failure is correct; a fabricated summary is a defect. ## Two Modes diff --git a/agents/gemini-validator.md b/agents/gemini-validator.md index 1ed983a..3326eb4 100644 --- a/agents/gemini-validator.md +++ b/agents/gemini-validator.md @@ -28,6 +28,8 @@ You are gemini-validator, a precise skeptical reviewer powered by Google Gemini. Your validation capability uses Gemini MCP tools inherited from the session (gemini_generate, gemini_search_grounded). The registered name may be namespaced by the install (the manual-install namespace for a manual install, the plugin-install namespace for the plugin install); use whichever the session exposes. +**Deferred tools (do this FIRST).** In a session with many MCP servers connected, your Gemini tools are often *deferred*: the tool name appears in a system reminder but its schema is NOT loaded, and calling it directly fails with an input-validation error. Do not hunt for the exact tool name and do not give up. Before your first Gemini call, run the `ToolSearch` tool with a keyword query such as `gemini generate` (or `gemini search grounded`) to materialize the schema, then call the exact tool name `ToolSearch` returns. If `ToolSearch` is not in your toolset, the Gemini tools are already loaded directly, so call them by name. Treat the tool as missing ONLY after `ToolSearch` returns no Gemini match. + If NO Gemini tool is available, do NOT validate from training knowledge alone. Emit `verdict: "unknown"` with an `error` field naming the missing tool, for example: "gemini_generate not available in session". A loud failure is correct; a confident fabricated verdict is a defect. ## Validation Rules diff --git a/skills/gemini-consult/SKILL.md b/skills/gemini-consult/SKILL.md index e0ce382..cd07f0a 100644 --- a/skills/gemini-consult/SKILL.md +++ b/skills/gemini-consult/SKILL.md @@ -40,6 +40,19 @@ Dispatch a Gemini agent when ANY of these is true: Agents do not call each other (subagents cannot spawn subagents). You are the router: pick the one agent that matches and dispatch it. +## Deferred Gemini tools in heavy-MCP sessions + +When many MCP servers are connected, Claude Code *defers* MCP tools: the Gemini +tool names appear in a system reminder, but their schemas are not loaded and a +direct call fails. An agent must call `ToolSearch` (keyword query such as +`gemini search grounded`) to materialize the schema before invoking the tool. +The five agents already document this step in their own "Tool availability" +section, so dispatch them normally. But if an agent's JSON comes back with +`confidence: "unavailable"` / `verdict: "unknown"` and an `error` mentioning a +missing Gemini tool, do NOT assume the server is down: first run +`/gemini-plugin:gemini-doctor`. If doctor's check 2 passes but check 3 fails, +the session is stale (restart Claude Code); if both pass, retry the dispatch. + ## The one-consult-per-turn cap At most ONE manual, rule-driven Gemini consult per turn, across all five agents. diff --git a/tests/mcp-namespace.bats b/tests/mcp-namespace.bats index 3662697..c580a8f 100644 --- a/tests/mcp-namespace.bats +++ b/tests/mcp-namespace.bats @@ -46,3 +46,28 @@ AGENTS=(gemini-validator gemini-challenger gemini-researcher gemini-summarizer g fi done } + +@test "every agent documents the deferred-tool ToolSearch step" { + # In heavy-MCP sessions the Gemini tools are deferred (schema not loaded); + # an agent must call ToolSearch before invoking them or it stalls hunting + # for the tool name. Each agent MUST teach this in its system prompt. + for agent in "${AGENTS[@]}"; do + if ! grep -q "ToolSearch" "$AGENTS_DIR/${agent}.md"; then + echo "FAIL: $agent does not mention ToolSearch (deferred-tool path missing)" + return 1 + fi + done +} + +@test "the deferred-tool note uses keyword queries, not a hardcoded mcp__ path" { + # The ToolSearch guidance must rely on namespace-agnostic keyword queries so + # it works for both the plugin and manual installs (and keeps the no-mcp__ + # rule above green). + for agent in "${AGENTS[@]}"; do + if grep -q "ToolSearch" "$AGENTS_DIR/${agent}.md" \ + && ! grep -qiE "keyword query" "$AGENTS_DIR/${agent}.md"; then + echo "FAIL: $agent mentions ToolSearch but not the keyword-query approach" + return 1 + fi + done +}