[DOCS] Python SDK reference incorrectly states query() does not support custom tools

Resolved 💬 3 comments Opened Jan 26, 2026 by coygeek Closed Feb 28, 2026

Documentation Type

Incorrect/outdated documentation

Documentation Location

https://platform.claude.com/docs/en/agent-sdk/python

Section/Topic

"Choosing Between query() and ClaudeSDKClient" - Quick Comparison table

Current Documentation

The comparison table states:

| Feature | query() | ClaudeSDKClient |
| :------------------ | :---------------------------- | :--------------------------------- |
| Custom Tools | ❌ Not supported | ✅ Supported |

The SDK README also states: "Unlike query(), ClaudeSDKClient additionally enables custom tools and hooks, both of which can be defined as Python functions."

What's Wrong or Missing?

The documentation indicates that query() does not support custom tools (implemented via MCP servers). However, the code shows:

  1. ClaudeAgentOptions includes an mcp_servers field for custom tools
  2. query() accepts ClaudeAgentOptions
  3. The internal process_query() function processes mcp_servers from options regardless of whether called from query() or ClaudeSDKClient

SDK Evidence:

# From types.py - ClaudeAgentOptions includes mcp_servers
@dataclass
class ClaudeAgentOptions:
"""Query options for Claude SDK."""
mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
# ... other fields

# From client.py - process_query() handles mcp_servers for both query() and ClaudeSDKClient
async def process_query(
self,
prompt: str | AsyncIterable[dict[str, Any]],
options: ClaudeAgentOptions,
transport: Transport | None = None,
) -> AsyncIterator[Message]:
# ...
# Extract SDK MCP servers from configured options
sdk_mcp_servers = {}
if configured_options.mcp_servers and isinstance(
configured_options.mcp_servers, dict
):
for name, config in configured_options.mcp_servers.items():
if isinstance(config, dict) and config.get("type") == "sdk":
sdk_mcp_servers[name] = config["instance"]

Both query() and ClaudeSDKClient internally call process_query(), which handles MCP servers the same way.

Suggested Improvement

Option 1: Update the table to show query() supports custom tools:

| Feature | query() | ClaudeSDKClient |
| :------------------ | :---------------------------- | :--------------------------------- |
| Custom Tools | ✅ Supported | ✅ Supported |

Option 2: If there are actual limitations (e.g., in-process SDK MCP servers require streaming mode), clarify the specific limitation:

| Feature | query() | ClaudeSDKClient |
| :------------------ | :---------------------------- | :--------------------------------- |
| Custom Tools | ⚠️ External MCP only | ✅ Full support (SDK + external) |

Also update the SDK README section that claims query() doesn't support custom tools.

Impact

High - Prevents users from using a feature

Additional Context

Verification Method: Cross-referenced against Python Agent SDK source code (claude-agent-sdk-python)
SDK Files:

  • types.py - ClaudeAgentOptions class definition with mcp_servers field
  • client.py - process_query() function that handles mcp_servers for both interfaces

Related Issue: This is the same root cause as the hooks support discrepancy - the comparison table appears to incorrectly differentiate query() and ClaudeSDKClient capabilities when both use the same underlying process_query() implementation.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗