anthropics / anthropics/claude-code
[BUG] ToolSearch returns stub schemas (no parameter properties) for third-party MCP connector tools, causing typed-parameter calls to fail
- Langage dominant
- Python
- Étoiles
- 145k
- Forks
- 23.1k
- Métriques de merge des PR
- Métriques de PR en attente
Description
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
### What's Wrong?
Summary
When a deferred MCP connector tool is loaded via ToolSearch, the returned schema has a generic description (just the bare tool name, not the server's actual description) and parameters: {"type": "object"} with no properties defined — even though the underlying MCP server clearly has a full JSON Schema (confirmed by the server's own runtime validation errors, which cite real field names and types). Because the harness never sees the real schema, it can't coerce non-string parameter values before sending them to the tool, so every argument is forwarded as a literal string. The MCP server then rejects any parameter that isn't itself typed as a string.
Environment
Claude Code desktop app, Windows 11
Model: Sonnet 5 (claude-sonnet-5)
Affected MCP servers (all reproduced independently): a HubSpot CRM connector, Vercel, Gmail, Google Calendar, Todoist, and an SEO/analytics connector (OpenSEO). Not affected: Claude Code's own built-in deferred tools (e.g. WebSearch, Monitor), which resolve with full, correct schemas via the same ToolSearch mechanism.
Steps to reproduce
In a session with a HubSpot MCP connector attached, wait for its tools to appear in the deferred-tools list (unloaded).
Call ToolSearch with query: "select:__search_crm_objects".
Observe the returned function definition: "description": "Searches and retrieves CRM records..." is actually present in this one case, but parameters.properties includes fields like limit (declared "type": "integer") and properties/filterGroups (declared "type": "array") — this part looks correct in isolation.
Call the tool: search_crm_objects({ objectType: "contacts", limit: 10 }).
Observe the error: [limit] Expected a number (int) but received String — despite ToolSearch having reported limit as type: integer moments earlier, and despite passing a numeric literal in the tool call.
Repeat with properties: ["email", "firstname"] (an array): [properties] Expected an Array but received String.
For several other MCP connector tools (Vercel list_projects, Gmail search_threads, Calendar list_events, Todoist find-tasks), ToolSearch returns an even more degraded stub: description equal to the literal tool name, and parameters: {"type": "object"} with no properties key at all — so there is no way to know a parameter's expected type before calling it.
Expected behavior
ToolSearch should return the MCP server's actual advertised JSON Schema for each tool (name, description, and full parameters including nested types), and the harness should coerce/validate arguments against that schema before dispatching the call — consistent with how built-in Claude Code tools (WebSearch, Monitor, etc.) already behave when loaded the same way.
Actual behavior
For some connector tools, ToolSearch returns a correctly-typed schema, but the invocation layer still serializes every argument as a string regardless of the declared type, causing the MCP server's own validator to reject non-string fields.
For other connector tools, ToolSearch doesn't even surface a real schema — every field collapses to an empty {"type": "object"}, with the tool's actual name substituted in as its description. There is no way to discover valid parameters short of trial-and-error against the server's error messages.
Impact
Any MCP connector tool with a non-string parameter (number, array, or nested object) is effectively unusable unless the server happens to expose an alternate string-only interface. In our case, the HubSpot connector has a fallback SQL-style tool (query_crm_data, single sql: string param) that works around this — the primary search_crm_objects/get_crm_objects/discover_hubspot_schema tools do not. Connectors without such a fallback have no workaround at all.
Additional notes
The bug reproduces consistently across multiple unrelated MCP servers, and across multiple sessions over several days, so it doesn't look like a transient/network issue.
Happy to provide the exact ToolSearch outputs and error strings from a live session if useful.
### What Should Happen?
ToolSearch should return the MCP server's actual advertised JSON Schema for each tool (name, description, and full parameters including nested types), and the harness should coerce/validate arguments against that schema before dispatching the call — consistent with how built-in Claude Code tools (WebSearch, Monitor, etc.) already behave when loaded the same way.
### Error Messages/Logs
```shell
```
### Steps to Reproduce
In a session with a HubSpot MCP connector attached, wait for its tools to appear in the deferred-tools list (unloaded).
Call ToolSearch with query: "select:__search_crm_objects".
Observe the returned function definition: "description": "Searches and retrieves CRM records..." is actually present in this one case, but parameters.properties includes fields like limit (declared "type": "integer") and properties/filterGroups (declared "type": "array") — this part looks correct in isolation.
Call the tool: search_crm_objects({ objectType: "contacts", limit: 10 }).
Observe the error: [limit] Expected a number (int) but received String — despite ToolSearch having reported limit as type: integer moments earlier, and despite passing a numeric literal in the tool call.
Repeat with properties: ["email", "firstname"] (an array): [properties] Expected an Array but received String.
For several other MCP connector tools (Vercel list_projects, Gmail search_threads, Calendar list_events, Todoist find-tasks), ToolSearch returns an even more degraded stub: description equal to the literal tool name, and parameters: {"type": "object"} with no properties key at all — so there is no way to know a parameter's expected type before calling it.
### Claude Model
None
### Is this a regression?
Yes, this worked in a previous version
### Last Working Version
_No response_
### Claude Code Version
2.1.220
### Platform
Anthropic API
### Operating System
Windows
### Terminal/Shell
Windows Terminal
### Additional Information
_No response_
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Piste de recherche
Start by reproducing with Claude Code 2.1.220 and a third-party MCP connector, using ToolSearch for search_crm_objects and then calling it with numeric or array parameters. Compare the returned schema and dispatch behavior for connector tools versus built-in deferred tools like WebSearch or Monitor. Done means ToolSearch exposes the connector's real JSON Schema and non-string arguments reach the MCP server with the expected types.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- json
- Domaine
- ai-infra-agents, api, tooling
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 45/100