Skip to content

Fix mcp_invoke_tool flat-args self-healing#445

Merged
rockfordlhotka merged 2 commits into
mainfrom
fix/mcp-flat-args-self-heal
May 23, 2026
Merged

Fix mcp_invoke_tool flat-args self-healing#445
rockfordlhotka merged 2 commits into
mainfrom
fix/mcp-flat-args-self-heal

Conversation

@rockfordlhotka
Copy link
Copy Markdown
Member

Summary

  • Bug: When the LLM dropped the arguments wrapper on mcp_invoke_tool and inlined inner-tool fields at the top level (e.g. server_name, tool_name, accountId, query all as siblings), McpManagementExecutor.InvokeToolAsync dispatched the call with no inner args. The MCP server rejected with "X is required", and recovery's enricher surfaced a missing-field error to the LLM — even though the LLM had supplied the field, just one level up. Spotted in the live cluster log when the agent looped on search_emails and move_email.
  • Fix 1 (McpManagementExecutor): Added the missing third branch. When there's no nested arguments/params/args wrapper but there ARE non-reserved top-level keys, promote them into a synthetic arguments object before dispatch. Reserved wrapper keys are excluded so they don't leak into the inner call.
  • Fix 2 (WispExecutor.TryAutoCorrectMcpParamsAsync): When the step has empty params AND no enriched recovery context, decline auto-correction up-front instead of asking the cheap-tier LLM to invent values. In practice it ignored NO_CORRECTION and emitted things like {"query":"*"} or {"query":""} — schema-clean but semantically empty — causing downstream archive steps to fail without any signal the search itself was bogus.
  • Bumped version 0.12.22 → 0.12.23.

Test plan

  • Unit tests: 5 new tests covering both fixes (InvokeTool_FlatTopLevelFields_PromotedIntoArguments, InvokeTool_NestedArgsTakePrecedenceOverFlatFields, ValidationFailure_EmptyParamsAndNoEnrichedContext_LlmNotCalled, ValidationFailure_EmptyParamsButEnrichedContextPresent_LlmStillCalled, IsEffectivelyEmptyParams_RecognizesEmptyShapes)
  • Full RockBot.Tools.Tests suite green (193/193)
  • Full RockBot.Wisp.Tests suite green (132/132)
  • Built + pushed rockylhotka/rockbot-agent:0.12.23 and helm-upgraded; pod healthy, agent boots clean
  • CLI smoke test against live cluster: email search via mcp_invoke_tool round-trips successfully (proper-shape happy path)
  • Not yet observed live: the new promoted N flat top-level field(s) log line — depends on the LLM emitting the broken shape again, which is intermittent

🤖 Generated with Claude Code

rockfordlhotka and others added 2 commits May 23, 2026 13:10
The agent intermittently dropped the `arguments` wrapper on mcp_invoke_tool
calls, inlining inner-tool fields at the top level (e.g. server_name,
tool_name, accountId, query as siblings). McpManagementExecutor handled
the nested-wrapper case and the empty-args case but not this third shape —
so the call dispatched with no inner args and the MCP server rejected with
"X is required." Recovery's enricher then surfaced a missing-field error
to the LLM even though the LLM had passed the field one level up.

Add a third branch that promotes every non-reserved top-level key into a
synthetic `arguments` object before dispatch, so the call still works.

Also tighten the wisp auto-corrector: when the step has empty params AND
no enriched recovery context, decline up-front rather than asking the
cheap-tier LLM to invent values. In practice it ignored the NO_CORRECTION
instruction and emitted things like {"query":"*"} or {"query":""} —
schema-clean but semantically empty — which caused downstream archive
steps to fail without any signal that the search itself was bogus.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rockfordlhotka rockfordlhotka merged commit a32b380 into main May 23, 2026
1 check passed
@rockfordlhotka rockfordlhotka deleted the fix/mcp-flat-args-self-heal branch May 23, 2026 18:32
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.

1 participant