Skip to content

Make invoke_tool self-correcting on argument mismatch#29

Merged
rockfordlhotka merged 1 commit into
mainfrom
fix/invoke-tool-self-correcting-args
Jun 3, 2026
Merged

Make invoke_tool self-correcting on argument mismatch#29
rockfordlhotka merged 1 commit into
mainfrom
fix/invoke-tool-self-correcting-args

Conversation

@rockfordlhotka

Copy link
Copy Markdown
Member

Problem

Claude Desktop (via this aggregator) repeatedly failed calling the downstream csla-mcp search/fetch tools with missing required parameter 'message' / 'fileName'. The downstream server, its API key, and its embedding model were all healthy — a direct tools/call with the correct keys works.

Root cause: list_services returns only each tool's name + description, not its inputSchema (ServiceIndex.ToolSummary). When a consumer invokes off list_services alone, it guesses parameter names from the description prose (e.g. csla-mcp's message parameter is described with the word "query," steering the guess to query/name). The downstream SDK then sanitizes the binding error to a generic "An error occurred invoking '<tool>'", so the model has no way to recover without separately calling get_service_details.

Fix

ToolProxyHandler.InvokeAsync is now self-correcting. When a downstream call returns an error, it compares the supplied arguments against the tool's cached input schema and — only when there's a real mismatch (missing required or unknown keys) — appends a corrective block to the error result naming the specific bad keys and the full schema. The model can then retry correctly without a separate get_service_details round-trip.

  • Genuine tool-side errors on schema-valid arguments are left untouched (no noise).
  • Schema lookup reuses the ToolIndex cache and is fully guarded, so it can never break the proxy.

Example of the enriched error a caller now receives:

Argument mismatch for tool 'search' on 'csla-mcp'. Missing required parameter(s): [message]. Unrecognized argument key(s): [query]. You sent: [query]. Re-invoke with arguments matching this input schema: {…"required":["message"]…}

Verification

  • dotnet build clean (0 warnings/errors); SDK types matched.
  • 88/89 tests pass; the one failure is the pre-existing flaky JsonFilePersistence parallel-IO test, which passes in isolation and is unrelated to this change.

Version bumped 0.3.00.3.1.

Follow-up (not in this PR)

Optionally add compact param hints (required parameter names) to list_services itself, so the wrong guess is prevented at the source as well.

🤖 Generated with Claude Code

When a consumer invokes a downstream tool off list_services alone (which
returns only tool name + description, not inputSchema), it can guess wrong
parameter names from the description prose. Downstream SDKs sanitize the
binding error to a generic message, so the model had no way to recover
without a separate get_service_details call.

ToolProxyHandler now checks the supplied arguments against the downstream
tool's cached input schema when a call returns an error, and appends a
corrective hint (naming the missing/unknown keys and the full schema) only
when there is an actual mismatch. Schema-valid calls that fail for genuine
tool-side reasons are left untouched, and schema lookup is guarded so it can
never break the proxy.

Bump version to 0.3.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rockfordlhotka
rockfordlhotka merged commit cfa955f into main Jun 3, 2026
1 check passed
@rockfordlhotka
rockfordlhotka deleted the fix/invoke-tool-self-correcting-args branch June 3, 2026 10:11
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