57 57
58## Functions58## Functions
59 59
60<Note>Signature blocks and bare `async for` / `async with` fragments on this page are illustrative. To run them, wrap the body in `async def main(): ...` and call `asyncio.run(main())`.</Note>
61
60### `query()`62### `query()`
61 63
62Creates a new session for each interaction with Claude Code by default. Returns an async iterator that yields messages as they arrive. Each call to `query()` starts fresh with no memory of previous interactions unless you pass `continue_conversation=True` or `resume` in [`ClaudeAgentOptions`](#claudeagentoptions). See [Sessions](/en/agent-sdk/sessions).64Creates a new session for each interaction with Claude Code by default. Returns an async iterator that yields messages as they arrive. Each call to `query()` starts fresh with no memory of previous interactions unless you pass `continue_conversation=True` or `resume` in [`ClaudeAgentOptions`](#claudeagentoptions). See [Sessions](/en/agent-sdk/sessions).
93 options = ClaudeAgentOptions(95 options = ClaudeAgentOptions(
94 system_prompt="You are an expert Python developer",96 system_prompt="You are an expert Python developer",
95 permission_mode="acceptEdits",97 permission_mode="acceptEdits",
96 cwd="/home/user/project",
97 )98 )
98 99
99 async for message in query(prompt="Create a Python web server", options=options):100 async for message in query(prompt="Create a Python web server", options=options):
215#### Example216#### Example
216 217
217```python theme={null}218```python theme={null}
218from claude_agent_sdk import tool, create_sdk_mcp_server219from claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeAgentOptions
219 220
220 221
221@tool("add", "Add two numbers", {"a": float, "b": float})222@tool("add", "Add two numbers", {"a": float, "b": float})
428```python theme={null}429```python theme={null}
429from claude_agent_sdk import list_sessions, tag_session430from claude_agent_sdk import list_sessions, tag_session
430 431
431# Tag a session432# Tag the most recent session
432tag_session("550e8400-e29b-41d4-a716-446655440000", "needs-review")433sessions = list_sessions(directory="/path/to/project", limit=1)
434if sessions:
435 tag_session(sessions[0].session_id, "needs-review")
433 436
434# Later: find all sessions with that tag437# Later: find all sessions with that tag
435for session in list_sessions(directory="/path/to/project"):438for session in list_sessions(directory="/path/to/project"):
496The client can be used as an async context manager for automatic connection management:499The client can be used as an async context manager for automatic connection management:
497 500
498```python theme={null}501```python theme={null}
499async with ClaudeSDKClient() as client:502import asyncio
503from claude_agent_sdk import ClaudeSDKClient
504
505
506async def main():
507 async with ClaudeSDKClient() as client:
500 await client.query("Hello Claude")508 await client.query("Hello Claude")
501 async for message in client.receive_response():509 async for message in client.receive_response():
502 print(message)510 print(message)
511
512
513asyncio.run(main())
503```514```
504 515
505> **Important:** When iterating over messages, avoid using `break` to exit early as this can cause asyncio cleanup issues. Instead, let the iteration complete naturally or use flags to track when you've found what you need.516> **Important:** When iterating over messages, avoid using `break` to exit early as this can cause asyncio cleanup issues. Instead, let the iteration complete naturally or use flags to track when you've found what you need.
635#### Example - Advanced permission control646#### Example - Advanced permission control
636 647
637```python theme={null}648```python theme={null}
649import asyncio
638from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions650from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
639from claude_agent_sdk.types import (651from claude_agent_sdk.types import (
640 PermissionResultAllow,652 PermissionResultAllow,
768 permission_mode: PermissionMode | None = None780 permission_mode: PermissionMode | None = None
769 continue_conversation: bool = False781 continue_conversation: bool = False
770 resume: str | None = None782 resume: str | None = None
783 session_id: str | None = None
771 max_turns: int | None = None784 max_turns: int | None = None
772 max_budget_usd: float | None = None785 max_budget_usd: float | None = None
773 disallowed_tools: list[str] = field(default_factory=list)786 disallowed_tools: list[str] = field(default_factory=list)
802 enable_file_checkpointing: bool = False815 enable_file_checkpointing: bool = False
803 session_store: SessionStore | None = None816 session_store: SessionStore | None = None
804 session_store_flush: SessionStoreFlushMode = "batched"817 session_store_flush: SessionStoreFlushMode = "batched"
818 load_timeout_ms: int = 60_000
819 task_budget: TaskBudget | None = None
805```820```
806 821
807| Property | Type | Default | Description |822| Property | Type | Default | Description |
814| `permission_mode` | `PermissionMode \| None` | `None` | Permission mode for tool usage |829| `permission_mode` | `PermissionMode \| None` | `None` | Permission mode for tool usage |
815| `continue_conversation` | `bool` | `False` | Continue the most recent conversation |830| `continue_conversation` | `bool` | `False` | Continue the most recent conversation |
816| `resume` | `str \| None` | `None` | Session ID to resume |831| `resume` | `str \| None` | `None` | Session ID to resume |
832| `session_id` | `str \| None` | `None` | Use a specific session ID instead of an auto-generated one. Must be a valid UUID. Can't be combined with `continue_conversation` or `resume` unless `fork_session` is also set |
817| `max_turns` | `int \| None` | `None` | Maximum agentic turns (tool-use round trips) |833| `max_turns` | `int \| None` | `None` | Maximum agentic turns (tool-use round trips) |
818| `max_budget_usd` | `float \| None` | `None` | Stop the query when the client-side cost estimate reaches this USD value. Compared against the same estimate as `total_cost_usd`; see [Track cost and usage](/en/agent-sdk/cost-tracking) for accuracy caveats |834| `max_budget_usd` | `float \| None` | `None` | Stop the query when the client-side cost estimate reaches this USD value. Compared against the same estimate as `total_cost_usd`; see [Track cost and usage](/en/agent-sdk/cost-tracking) for accuracy caveats |
819| `disallowed_tools` | `list[str]` | `[]` | Tools to deny. A bare name such as `"Bash"` removes the tool from Claude's context. A scoped rule such as `"Bash(rm *)"` leaves the tool available and denies matching calls in every permission mode, including `bypassPermissions`. See [Permissions](/en/agent-sdk/permissions#allow-and-deny-rules) |835| `disallowed_tools` | `list[str]` | `[]` | Tools to deny. A bare name such as `"Bash"` removes the tool from Claude's context. A scoped rule such as `"Bash(rm *)"` leaves the tool available and denies matching calls in every permission mode, including `bypassPermissions`. See [Permissions](/en/agent-sdk/permissions#allow-and-deny-rules) |
848| `effort` | [`EffortLevel`](#effortlevel) ` \| None` | `None` | Effort level for thinking depth. See [adjust the effort level](/en/model-config#adjust-effort-level) |864| `effort` | [`EffortLevel`](#effortlevel) ` \| None` | `None` | Effort level for thinking depth. See [adjust the effort level](/en/model-config#adjust-effort-level) |
849| `session_store` | [`SessionStore`](/en/agent-sdk/session-storage#the-sessionstore-interface) ` \| None` | `None` | Mirror session transcripts to an external backend so any host can resume them. See [Persist sessions to external storage](/en/agent-sdk/session-storage) |865| `session_store` | [`SessionStore`](/en/agent-sdk/session-storage#the-sessionstore-interface) ` \| None` | `None` | Mirror session transcripts to an external backend so any host can resume them. See [Persist sessions to external storage](/en/agent-sdk/session-storage) |
850| `session_store_flush` | `Literal["batched", "eager"]` | `"batched"` | When to flush mirrored transcript entries to `session_store`. `"batched"` flushes once per turn or when the buffer fills; `"eager"` triggers a background flush after every frame. Ignored when `session_store` is `None` |866| `session_store_flush` | `Literal["batched", "eager"]` | `"batched"` | When to flush mirrored transcript entries to `session_store`. `"batched"` flushes once per turn or when the buffer fills; `"eager"` triggers a background flush after every frame. Ignored when `session_store` is `None` |
867| `load_timeout_ms` | `int` | `60000` | Per-call timeout for `session_store.load()` and `list_subkeys()` during resume materialization, in milliseconds |
868| `task_budget` | `TaskBudget \| None` | `None` | API-side token budget. Sent as `output_config.task_budget` with the `task-budgets-2026-03-13` beta header. Pass `{"total": <int>}`. |
851 869
852#### Handle slow or stalled API responses870#### Handle slow or stalled API responses
853 871
854The CLI subprocess reads several environment variables that control API timeouts and stall detection. Pass them through `ClaudeAgentOptions.env`:872The CLI subprocess reads several environment variables that control API timeouts and stall detection. Pass them through `ClaudeAgentOptions.env`:
855 873
856```python theme={null}874```python theme={null}
875from claude_agent_sdk import ClaudeAgentOptions
876
857options = ClaudeAgentOptions(877options = ClaudeAgentOptions(
858 env={878 env={
859 "API_TIMEOUT_MS": "120000",879 "API_TIMEOUT_MS": "120000",
943 963
944```python theme={null}964```python theme={null}
945# Do not load user, project, or local settings from disk965# Do not load user, project, or local settings from disk
966import asyncio
946from claude_agent_sdk import query, ClaudeAgentOptions967from claude_agent_sdk import query, ClaudeAgentOptions
947 968
948async for message in query(969
970async def main():
971 async for message in query(
949 prompt="Analyze this code",972 prompt="Analyze this code",
950 options=ClaudeAgentOptions(973 options=ClaudeAgentOptions(
951 setting_sources=[]974 setting_sources=[]
952 ),975 ),
953):976 ):
954 print(message)977 print(message)
978
979
980asyncio.run(main())
955```981```
956 982
957<Note>983<Note>
961**Load all filesystem settings explicitly:**987**Load all filesystem settings explicitly:**
962 988
963```python theme={null}989```python theme={null}
990import asyncio
964from claude_agent_sdk import query, ClaudeAgentOptions991from claude_agent_sdk import query, ClaudeAgentOptions
965 992
966async for message in query(993
994async def main():
995 async for message in query(
967 prompt="Analyze this code",996 prompt="Analyze this code",
968 options=ClaudeAgentOptions(997 options=ClaudeAgentOptions(
969 setting_sources=["user", "project", "local"]998 setting_sources=["user", "project", "local"]
970 ),999 ),
971):1000 ):
972 print(message)1001 print(message)
1002
1003
1004asyncio.run(main())
973```1005```
974 1006
975**Load only specific setting sources:**1007**Load only specific setting sources:**
976 1008
977```python theme={null}1009```python theme={null}
978# Load only project settings, ignore user and local1010# Load only project settings, ignore user and local
979async for message in query(1011import asyncio
1012from claude_agent_sdk import query, ClaudeAgentOptions
1013
1014
1015async def main():
1016 async for message in query(
980 prompt="Run CI checks",1017 prompt="Run CI checks",
981 options=ClaudeAgentOptions(1018 options=ClaudeAgentOptions(
982 setting_sources=["project"] # Only .claude/settings.json1019 setting_sources=["project"] # Only .claude/settings.json
983 ),1020 ),
984):1021 ):
985 print(message)1022 print(message)
1023
1024
1025asyncio.run(main())
986```1026```
987 1027
988**Testing and CI environments:**1028**Testing and CI environments:**
989 1029
990```python theme={null}1030```python theme={null}
991# Ensure consistent behavior in CI by excluding local settings1031# Ensure consistent behavior in CI by excluding local settings
992async for message in query(1032import asyncio
1033from claude_agent_sdk import query, ClaudeAgentOptions
1034
1035
1036async def main():
1037 async for message in query(
993 prompt="Run tests",1038 prompt="Run tests",
994 options=ClaudeAgentOptions(1039 options=ClaudeAgentOptions(
995 setting_sources=["project"], # Only team-shared settings1040 setting_sources=["project"], # Only team-shared settings
996 permission_mode="bypassPermissions",1041 permission_mode="bypassPermissions",
997 ),1042 ),
998):1043 ):
999 print(message)1044 print(message)
1045
1046
1047asyncio.run(main())
1000```1048```
1001 1049
1002**SDK-only applications:**1050**SDK-only applications:**
1004```python theme={null}1052```python theme={null}
1005# Define everything programmatically.1053# Define everything programmatically.
1006# Pass [] to opt out of filesystem setting sources.1054# Pass [] to opt out of filesystem setting sources.
1007async for message in query(1055import asyncio
1056from claude_agent_sdk import AgentDefinition, ClaudeAgentOptions, query
1057
1058
1059async def main():
1060 async for message in query(
1008 prompt="Review this PR",1061 prompt="Review this PR",
1009 options=ClaudeAgentOptions(1062 options=ClaudeAgentOptions(
1010 setting_sources=[],1063 setting_sources=[],
1011 agents={...},1064 agents={
1012 mcp_servers={...},1065 "code-reviewer": AgentDefinition(
1066 description="Reviews code changes",
1067 prompt="You are a code reviewer. Report issues in the diff.",
1068 ),
1069 },
1013 allowed_tools=["Read", "Grep", "Glob"],1070 allowed_tools=["Read", "Grep", "Glob"],
1014 ),1071 ),
1015):1072 ):
1016 print(message)1073 print(message)
1074
1075
1076asyncio.run(main())
1017```1077```
1018 1078
1019**Loading CLAUDE.md project instructions:**1079**Loading CLAUDE.md project instructions:**
1020 1080
1021```python theme={null}1081```python theme={null}
1022# Load project settings to include CLAUDE.md files1082# Load project settings to include CLAUDE.md files
1023async for message in query(1083import asyncio
1084from claude_agent_sdk import query, ClaudeAgentOptions
1085
1086
1087async def main():
1088 async for message in query(
1024 prompt="Add a new feature following project conventions",1089 prompt="Add a new feature following project conventions",
1025 options=ClaudeAgentOptions(1090 options=ClaudeAgentOptions(
1026 system_prompt={1091 system_prompt={
1030 setting_sources=["project"], # Loads CLAUDE.md from project1095 setting_sources=["project"], # Loads CLAUDE.md from project
1031 allowed_tools=["Read", "Write", "Edit"],1096 allowed_tools=["Read", "Write", "Edit"],
1032 ),1097 ),
1033):1098 ):
1034 print(message)1099 print(message)
1100
1101
1102asyncio.run(main())
1035```1103```
1036 1104
1037#### Settings precedence1105#### Settings precedence
1097 "plan", # Planning mode - explore without editing1165 "plan", # Planning mode - explore without editing
1098 "dontAsk", # Deny anything not pre-approved instead of prompting1166 "dontAsk", # Deny anything not pre-approved instead of prompting
1099 "bypassPermissions", # Bypass permission checks; explicit ask rules still prompt (use with caution)1167 "bypassPermissions", # Bypass permission checks; explicit ask rules still prompt (use with caution)
1100 "auto", # A model classifier approves or denies each tool call1168 "auto", # Model classifier approves or denies permission prompts
1101]1169]
1102```1170```
1103 1171
1146class ToolPermissionContext:1214class ToolPermissionContext:
1147 signal: Any | None = None # Future: abort signal support1215 signal: Any | None = None # Future: abort signal support
1148 suggestions: list[PermissionUpdate] = field(default_factory=list)1216 suggestions: list[PermissionUpdate] = field(default_factory=list)
1217 tool_use_id: str | None = None
1218 agent_id: str | None = None
1149 blocked_path: str | None = None1219 blocked_path: str | None = None
1150 decision_reason: str | None = None1220 decision_reason: str | None = None
1151 title: str | None = None1221 title: str | None = None
1157| :---------------- | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |1227| :---------------- | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
1158| `signal` | `Any \| None` | Reserved for future abort signal support |1228| `signal` | `Any \| None` | Reserved for future abort signal support |
1159| `suggestions` | `list[PermissionUpdate]` | Permission update suggestions from the CLI. Bash prompts include a suggestion with the `localSettings` destination, so returning it in `updated_permissions` writes the rule to `.claude/settings.local.json` and persists across sessions. |1229| `suggestions` | `list[PermissionUpdate]` | Permission update suggestions from the CLI. Bash prompts include a suggestion with the `localSettings` destination, so returning it in `updated_permissions` writes the rule to `.claude/settings.local.json` and persists across sessions. |
1230| `tool_use_id` | `str \| None` | Identifier of the specific tool call this prompt is for. Always populated when delivered to `can_use_tool` |
1231| `agent_id` | `str \| None` | Sub-agent ID when the call originates from a subagent; `None` for the main agent |
1160| `blocked_path` | `str \| None` | File path that triggered the permission request, when applicable. For example, when a Bash command tries to access a path outside allowed directories |1232| `blocked_path` | `str \| None` | File path that triggered the permission request, when applicable. For example, when a Bash command tries to access a path outside allowed directories |
1161| `decision_reason` | `str \| None` | Reason this permission request was triggered. Forwarded from a PreToolUse hook's `permissionDecisionReason` when the hook returned `"ask"` |1233| `decision_reason` | `str \| None` | Reason this permission request was triggered. Forwarded from a PreToolUse hook's `permissionDecisionReason` when the hook returned `"ask"` |
1162| `title` | `str \| None` | Full permission prompt sentence, such as `Claude wants to read foo.txt`. Use as the primary prompt text when present |1234| `title` | `str \| None` | Full permission prompt sentence, such as `Claude wants to read foo.txt`. Use as the primary prompt text when present |
1309# config.budget_tokens would raise AttributeError1381# config.budget_tokens would raise AttributeError
1310```1382```
1311 1383
1384### `TaskBudget`
1385
1386API-side task budget in tokens, used with the `task_budget` field in `ClaudeAgentOptions`.
1387
1388```python theme={null}
1389class TaskBudget(TypedDict):
1390 total: int
1391```
1392
1393| Field | Type | Description |
1394| :------ | :---- | :------------------------------ |
1395| `total` | `int` | Total token budget for the task |
1396
1397Because this is a `TypedDict`, pass it as a plain dict, such as `ClaudeAgentOptions(task_budget={"total": 50000})`.
1398
1312### `SdkBeta`1399### `SdkBeta`
1313 1400
1314Literal type for SDK beta features.1401Literal type for SDK beta features.
1498 error: AssistantMessageError | None = None1585 error: AssistantMessageError | None = None
1499 usage: dict[str, Any] | None = None1586 usage: dict[str, Any] | None = None
1500 message_id: str | None = None1587 message_id: str | None = None
1588 stop_reason: str | None = None
1589 session_id: str | None = None
1590 uuid: str | None = None
1501```1591```
1502 1592
1503| Field | Type | Description |1593| Field | Type | Description |
1508| `error` | [`AssistantMessageError`](#assistantmessageerror) ` \| None` | Error type if the response encountered an error |1598| `error` | [`AssistantMessageError`](#assistantmessageerror) ` \| None` | Error type if the response encountered an error |
1509| `usage` | `dict[str, Any] \| None` | Per-message token usage (same keys as [`ResultMessage.usage`](#resultmessage)) |1599| `usage` | `dict[str, Any] \| None` | Per-message token usage (same keys as [`ResultMessage.usage`](#resultmessage)) |
1510| `message_id` | `str \| None` | API message ID. Multiple messages from one turn share the same ID |1600| `message_id` | `str \| None` | API message ID. Multiple messages from one turn share the same ID |
1601| `stop_reason` | `str \| None` | Stop reason from the API (e.g. `end_turn`, `tool_use`) |
1602| `session_id` | `str \| None` | ID of the session this message belongs to |
1603| `uuid` | `str \| None` | Unique message identifier within the session transcript |
1511 1604
1512### `AssistantMessageError`1605### `AssistantMessageError`
1513 1606
1898```1991```
1899 1992
1900<Note>1993<Note>
1901 The TypeScript SDK supports additional hook events not yet available in Python: `SessionStart`, `SessionEnd`, `Setup`, `TeammateIdle`, `TaskCompleted`, `ConfigChange`, `WorktreeCreate`, `WorktreeRemove`, `PostToolBatch`, and `MessageDisplay`.1994 The TypeScript SDK supports additional hook events not yet available in Python. See the [hook availability table](/en/agent-sdk/hooks#available-hooks) for per-SDK support.
1902</Note>1995</Note>
1903 1996
1904### `HookCallback`1997### `HookCallback`
1944 default_factory=list2037 default_factory=list
1945 ) # List of callbacks to execute2038 ) # List of callbacks to execute
1946 timeout: float | None = (2039 timeout: float | None = (
1947 None # Timeout in seconds for all hooks in this matcher (default: 60)2040 None # Timeout in seconds. When omitted, the per-event default applies
1948 )2041 )
1949```2042```
1950 2043
2297This example registers two hooks: one that blocks dangerous bash commands like `rm -rf /`, and another that logs all tool usage for auditing. The security hook only runs on Bash commands (via the `matcher`), while the logging hook runs on all tools.2390This example registers two hooks: one that blocks dangerous bash commands like `rm -rf /`, and another that logs all tool usage for auditing. The security hook only runs on Bash commands (via the `matcher`), while the logging hook runs on all tools.
2298 2391
2299```python theme={null}2392```python theme={null}
2393import asyncio
2300from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, HookContext2394from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, HookContext
2301from typing import Any2395from typing import Any
2302 2396
2334 ), # 2 min for validation2428 ), # 2 min for validation
2335 HookMatcher(2429 HookMatcher(
2336 hooks=[log_tool_use]2430 hooks=[log_tool_use]
2337 ), # Applies to all tools (default 60s timeout)2431 ), # Applies to all tools (per-event default timeout)
2338 ],2432 ],
2339 "PostToolUse": [HookMatcher(hooks=[log_tool_use])],2433 "PostToolUse": [HookMatcher(hooks=[log_tool_use])],
2340 }2434 }
2341)2435)
2342 2436
2343async for message in query(prompt="Analyze this codebase", options=options):2437async def main():
2438 async for message in query(prompt="Analyze this codebase", options=options):
2344 print(message)2439 print(message)
2440
2441
2442asyncio.run(main())
2345```2443```
2346 2444
2347## Tool Input/Output Types2445## Tool Input/Output Types
2350 2448
2351### Agent2449### Agent
2352 2450
2353**Tool name:** `Agent` (previously `Task`, which is still accepted as an alias)2451**Tool name:** `Agent`. The previous name `Task` is still accepted as an alias, and the `tools` list in the init [`SystemMessage`](#systemmessage) reports this tool as `Task` for backward compatibility.
2354 2452
2355**Input:**2453**Input:**
2356 2454
2358{2456{
2359 "description": str, # A short (3-5 word) description of the task2457 "description": str, # A short (3-5 word) description of the task
2360 "prompt": str, # The task for the agent to perform2458 "prompt": str, # The task for the agent to perform
2361 "subagent_type": str, # The type of specialized agent to use2459 "subagent_type": str | None, # The type of specialized agent to use
2460 "model": "sonnet" | "opus" | "haiku" | "fable" | None, # Model override for this agent
2461 "run_in_background": bool | None, # Launch the agent in the background
2462 "name": str | None, # Name for the spawned agent
2463 "mode": "acceptEdits" | "auto" | "bypassPermissions" | "default" | "dontAsk" | "plan" | None, # Permission mode for the agent
2464 "isolation": "worktree" | "remote" | None, # Isolation mode for the agent's changes
2362}2465}
2363```2466```
2364 2467
2365**Output:**2468Launches a new agent to handle complex, multi-step tasks autonomously.
2469
2470**Output (status: `"completed"`):**
2366 2471
2367```python theme={null}2472```python theme={null}
2368{2473{
2369 "result": str, # Final result from the subagent2474 "status": "completed",
2370 "usage": dict | None, # Token usage statistics2475 "agentId": str, # ID of the agent that ran
2371 "total_cost_usd": float | None, # Estimated total cost in USD2476 "agentType": str | None, # The subagent type that handled the task
2372 "duration_ms": int | None, # Execution duration in milliseconds2477 "content": [ # Result content blocks
2478 {
2479 "type": "text",
2480 "text": str,
2481 "citations": list | None,
2482 }
2483 ],
2484 "resolvedModel": str | None, # Model the subagent actually ran on
2485 "totalToolUseCount": int, # Number of tool calls the agent made
2486 "totalDurationMs": int, # Execution duration in milliseconds
2487 "totalTokens": int, # Total tokens used
2488 "usage": { # Token usage statistics
2489 "input_tokens": int,
2490 "output_tokens": int,
2491 "cache_creation_input_tokens": int | None,
2492 "cache_read_input_tokens": int | None,
2493 "server_tool_use": {"web_search_requests": int, "web_fetch_requests": int} | None,
2494 "service_tier": str | None,
2495 "cache_creation": {"ephemeral_1h_input_tokens": int, "ephemeral_5m_input_tokens": int} | None,
2496 "inference_geo": str | None,
2497 "speed": str | None,
2498 "iterations": Any | None,
2499 },
2500 "toolStats": { # Aggregate tool activity for the run
2501 "readCount": int,
2502 "searchCount": int,
2503 "bashCount": int,
2504 "editFileCount": int,
2505 "linesAdded": int,
2506 "linesRemoved": int,
2507 "otherToolCount": int,
2508 "frameCount": int | None,
2509 } | None,
2510 "prompt": str, # The prompt the agent ran
2511 "worktreePath": str | None, # Present for worktree-isolated runs
2512 "worktreeBranch": str | None, # Present for worktree-isolated runs
2373}2513}
2374```2514```
2375 2515
2516**Output (status: `"async_launched"`):**
2517
2518```python theme={null}
2519{
2520 "status": "async_launched",
2521 "isAsync": bool | None, # True on background launches
2522 "agentId": str, # ID of the launched agent
2523 "description": str, # The task description
2524 "resolvedModel": str | None, # Model the subagent runs on
2525 "prompt": str, # The prompt the agent runs
2526 "outputFile": str, # File path where the agent's output is written
2527 "canReadOutputFile": bool | None, # Whether the output file can be read directly
2528}
2529```
2530
2531**Output (status: `"remote_launched"`):**
2532
2533```python theme={null}
2534{
2535 "status": "remote_launched",
2536 "taskId": str, # ID of the remote task
2537 "sessionUrl": str, # Link to the remote cloud session
2538 "description": str, # The task description
2539 "prompt": str, # The prompt the agent runs
2540 "outputFile": str, # File path where the agent's output is written
2541}
2542```
2543
2544Returns the result from the subagent. The output is discriminated on the `status` field: `"completed"` for finished tasks, `"async_launched"` for background tasks, and `"remote_launched"` for tasks Claude Code dispatched to a remote cloud session, where `sessionUrl` links to that session and `taskId` identifies it. Worktree-isolated runs include `worktreePath` and `worktreeBranch` on the `completed` variant.
2545
2546The `resolvedModel` field on the `completed` and `async_launched` variants names the model the subagent actually ran on, which can differ from the requested `model` input when [`availableModels`](/en/model-config#restrict-model-selection) or another override applies. {/* min-version: 2.1.174 */}This field requires Claude Code v2.1.174 or later.
2547
2376### AskUserQuestion2548### AskUserQuestion
2377 2549
2378**Tool name:** `AskUserQuestion`2550**Tool name:** `AskUserQuestion`
2396 "multiSelect": bool, # Set to true to allow multiple selections2568 "multiSelect": bool, # Set to true to allow multiple selections
2397 }2569 }
2398 ],2570 ],
2399 "answers": dict[str, str | list[str]] | None,2571 "answers": dict[str, str] | None,
2400 # User answers populated by the permission system. Multi-select2572 # User answers populated by the permission system. Multi-select
2401 # answers may be a list of labels or a comma-joined string2573 # answers are a comma-joined string of the selected labels; a
2574 # list of labels is accepted on input and coerced to that form
2402}2575}
2403```2576```
2404 2577
2845}3018}
2846```3019```
2847 3020
2848### BashOutput3021### TaskOutput
3022
3023**Tool name:** `TaskOutput`. The previous name `BashOutput` is still accepted as an alias.
2849 3024
2850**Tool name:** `BashOutput`3025<Note>`TaskOutput` is deprecated; prefer `Read` on the task's output file path. {/* min-version: 2.1.83 */}Deprecated since Claude Code v2.1.83. The schemas below remain valid for hooks and permission handlers that encounter the tool.</Note>
2851 3026
2852**Input:**3027**Input:**
2853 3028
2854```python theme={null}3029```python theme={null}
2855{3030{
2856 "bash_id": str, # The ID of the background shell3031 "task_id": str, # The task ID to get output from
2857 "filter": str | None, # Optional regex to filter output lines3032 "block": bool, # Whether to wait for completion (default True)
3033 "timeout": int, # Max wait time in ms (default 30000)
2858}3034}
2859```3035```
2860 3036
2862 3038
2863```python theme={null}3039```python theme={null}
2864{3040{
2865 "output": str, # New output since last check3041 "retrieval_status": "success" | "timeout" | "not_ready", # Whether the output was retrieved
2866 "status": "running" | "completed" | "failed", # Current shell status3042 "task": dict | None, # Task details: task_id, task_type, status, description, output, plus type-specific fields such as exitCode
2867 "exitCode": int | None, # Exit code when completed
2868}3043}
2869```3044```
2870 3045
2871### KillBash3046### TaskStop
2872 3047
2873**Tool name:** `KillBash`3048**Tool name:** `TaskStop`. The previous names `KillShell` and `KillBash` are still accepted as aliases.
2874 3049
2875**Input:**3050**Input:**
2876 3051
2877```python theme={null}3052```python theme={null}
2878{3053{
2879 "shell_id": str # The ID of the background shell to kill3054 "task_id": str | None, # The ID of the background task to stop
3055 "shell_id": str | None, # Deprecated: use task_id instead
2880}3056}
2881```3057```
2882 3058
2884 3060
2885```python theme={null}3061```python theme={null}
2886{3062{
2887 "message": str, # Success message3063 "message": str, # Status message about the operation
2888 "shell_id": str, # ID of the killed shell3064 "task_id": str, # The ID of the task that was stopped
3065 "task_type": str, # The type of the task that was stopped
3066 "command": str | None, # The command or description of the stopped task
2889}3067}
2890```3068```
2891 3069
3182 options = ClaudeAgentOptions(3360 options = ClaudeAgentOptions(
3183 allowed_tools=["Read", "Write", "Bash"],3361 allowed_tools=["Read", "Write", "Bash"],
3184 permission_mode="acceptEdits",3362 permission_mode="acceptEdits",
3185 cwd="/home/user/project",
3186 )3363 )
3187 3364
3188 async for message in query(3365 async for message in query(
3448</Note>3625</Note>
3449 3626
3450```python theme={null}3627```python theme={null}
3628import asyncio
3451from claude_agent_sdk import (3629from claude_agent_sdk import (
3452 query,3630 query,
3453 ClaudeAgentOptions,3631 ClaudeAgentOptions,
3458)3636)
3459 3637
3460 3638
3639def is_command_authorized(command: str | None) -> bool:
3640 # Replace with your own authorization logic
3641 return False
3642
3643
3644
3461async def can_use_tool(3645async def can_use_tool(
3462 tool: str, input: dict, context: ToolPermissionContext3646 tool: str, input: dict, context: ToolPermissionContext
3463) -> PermissionResultAllow | PermissionResultDeny:3647) -> PermissionResultAllow | PermissionResultDeny:
3500 ),3684 ),
3501 ):3685 ):
3502 print(message)3686 print(message)
3687
3688
3689asyncio.run(main())
3503```3690```
3504 3691
3505This pattern enables you to:3692This pattern enables you to: