Skip to content

Commit f5823c6

Browse files
authored
feat: add public get_mcp_status() method to ClaudeSDKClient (#516)
## Motivation The Claude Investigator app, which uses the python claude agent SDK, needs to query MCP server connection status (example [here](https://github.com/anthropics/anthropic/blob/948dc8cc4a739b7d026d54e8da2e175cd1659340/ts-threat-intel/ts_threat_intel/claude_investigator/services/client_actor.py#L554-L557)). Currently it does this by reaching into private SDK internals: ```python if client._query and hasattr(client._query, "_send_control_request"): mcp_status_response = await client._query._send_control_request( {"subtype": "mcp_status"} ) ``` This is fragile — any SDK refactor silently breaks the caller, and the `hasattr` guard means failures degrade silently to no MCP status reporting. ## Changes Add a public `get_mcp_status()` method following the exact same pattern as `interrupt()`, `set_permission_mode()`, `set_model()`, and `rewind_files()`: - **`Query.get_mcp_status()`** — sends `{"subtype": "mcp_status"}` control request via `_send_control_request` - **`ClaudeSDKClient.get_mcp_status()`** — public wrapper with connection check, docstring with Returns and Example sections Callers can now simply do: ```python mcp_status_response = await client.get_mcp_status() ``` ## Testing The method delegates entirely to the existing `_send_control_request` infrastructure which is already tested. The new code is a 3-line wrapper with no branching logic.
1 parent 6a0140a commit f5823c6

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

src/claude_agent_sdk/_internal/query.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,10 @@ async def _handle_sdk_mcp_request(
517517
"error": {"code": -32603, "message": str(e)},
518518
}
519519

520+
async def get_mcp_status(self) -> dict[str, Any]:
521+
"""Get current MCP server connection status."""
522+
return await self._send_control_request({"subtype": "mcp_status"})
523+
520524
async def interrupt(self) -> None:
521525
"""Send interrupt control request."""
522526
await self._send_control_request({"subtype": "interrupt"})

src/claude_agent_sdk/client.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,32 @@ async def rewind_files(self, user_message_id: str) -> None:
293293
raise CLIConnectionError("Not connected. Call connect() first.")
294294
await self._query.rewind_files(user_message_id)
295295

296+
async def get_mcp_status(self) -> dict[str, Any]:
297+
"""Get current MCP server connection status (only works with streaming mode).
298+
299+
Queries the Claude Code CLI for the live connection status of all
300+
configured MCP servers.
301+
302+
Returns:
303+
Dictionary with MCP server status information. Contains a
304+
'mcpServers' key with a list of server status objects, each having:
305+
- 'name': Server name (str)
306+
- 'status': Connection status ('connected', 'pending', 'failed',
307+
'needs-auth', 'disabled')
308+
309+
Example:
310+
```python
311+
async with ClaudeSDKClient(options) as client:
312+
status = await client.get_mcp_status()
313+
for server in status.get("mcpServers", []):
314+
print(f"{server['name']}: {server['status']}")
315+
```
316+
"""
317+
if not self._query:
318+
raise CLIConnectionError("Not connected. Call connect() first.")
319+
result: dict[str, Any] = await self._query.get_mcp_status()
320+
return result
321+
296322
async def get_server_info(self) -> dict[str, Any] | None:
297323
"""Get server initialization info including available commands and output styles.
298324

0 commit comments

Comments
 (0)