445 async def set_model(self, model: str | None = None) -> None445 async def set_model(self, model: str | None = None) -> None
446 async def rewind_files(self, user_message_id: str) -> None446 async def rewind_files(self, user_message_id: str) -> None
447 async def get_mcp_status(self) -> McpStatusResponse447 async def get_mcp_status(self) -> McpStatusResponse
448 async def get_context_usage(self) -> ContextUsageResponse
448 async def reconnect_mcp_server(self, server_name: str) -> None449 async def reconnect_mcp_server(self, server_name: str) -> None
449 async def toggle_mcp_server(self, server_name: str, enabled: bool) -> None450 async def toggle_mcp_server(self, server_name: str, enabled: bool) -> None
450 async def stop_task(self, task_id: str) -> None451 async def stop_task(self, task_id: str) -> None
466| `set_model(model)` | Change the model for the current session. Pass `None` to reset to [Claude Code's default model](/docs/en/model-config) |467| `set_model(model)` | Change the model for the current session. Pass `None` to reset to [Claude Code's default model](/docs/en/model-config) |
467| `rewind_files(user_message_id)` | Restore files to their state at the specified user message. Requires `enable_file_checkpointing=True`. See [File checkpointing](/docs/en/agent-sdk/file-checkpointing) |468| `rewind_files(user_message_id)` | Restore files to their state at the specified user message. Requires `enable_file_checkpointing=True`. See [File checkpointing](/docs/en/agent-sdk/file-checkpointing) |
468| `get_mcp_status()` | Get the status of all configured MCP servers. Returns [`McpStatusResponse`](#mcpstatusresponse) |469| `get_mcp_status()` | Get the status of all configured MCP servers. Returns [`McpStatusResponse`](#mcpstatusresponse) |
470| `get_context_usage()` | Get a breakdown of context window usage by category, skill, and tool. The same data `/context` shows in an interactive session. Returns [`ContextUsageResponse`](#contextusageresponse). To compute the breakdown, Claude Code makes several token-counting API requests that don't appear in the message stream; see [how these requests are handled](#contextusageresponse) |
469| `reconnect_mcp_server(server_name)` | Retry connecting to an MCP server that failed or was disconnected |471| `reconnect_mcp_server(server_name)` | Retry connecting to an MCP server that failed or was disconnected |
470| `toggle_mcp_server(server_name, enabled)` | Enable or disable an MCP server mid-session. Disabling removes its tools |472| `toggle_mcp_server(server_name, enabled)` | Enable or disable an MCP server mid-session. Disabling a stdio, SSE, or HTTP server removes its tools |
471| `stop_task(task_id)` | Stop a running background task. A [`TaskNotificationMessage`](#tasknotificationmessage) with status `"stopped"` follows in the message stream |473| `stop_task(task_id)` | Stop a running background task. A [`TaskNotificationMessage`](#tasknotificationmessage) with status `"stopped"` follows in the message stream |
472| `get_server_info()` | Get the server's initialization info, including available commands and output styles |474| `get_server_info()` | Get the server's initialization info, including available commands and output styles |
473| `disconnect()` | Disconnect from Claude |475| `disconnect()` | Disconnect from Claude |
536 538
537#### Example - Streaming input with ClaudeSDKClient539#### Example - Streaming input with ClaudeSDKClient
538 540
541`query()` also accepts an async iterable of user message dicts, so you can assemble the prompt at send time or include content blocks such as images. Claude Code starts responding to the first yielded message as soon as it arrives, without waiting for the iterable to finish, and `receive_response()` stops at the `ResultMessage` that ends that response. Put everything Claude should read before answering into one message, as this generator does, and pair each `query()` call with its own `receive_response()` loop.
542
539```python theme={null}543```python theme={null}
540import asyncio544import asyncio
541from claude_agent_sdk import ClaudeSDKClient545from claude_agent_sdk import ClaudeSDKClient
542 546
543 547
544async def message_stream():548async def message_stream():
545 """Generate messages dynamically."""549 """Assemble the prompt at send time and yield it as one user message."""
546 yield {550 readings = {"Temperature": "25°C", "Humidity": "60%"}
547 "type": "user",551 data = ", ".join(f"{name}: {value}" for name, value in readings.items())
548 "message": {"role": "user", "content": "Analyze the following data:"},
549 }
550 await asyncio.sleep(0.5)
551 yield {
552 "type": "user",
553 "message": {"role": "user", "content": "Temperature: 25°C, Humidity: 60%"},
554 }
555 await asyncio.sleep(0.5)
556 yield {552 yield {
557 "type": "user",553 "type": "user",
558 "message": {"role": "user", "content": "What patterns do you see?"},554 "message": {
555 "role": "user",
556 "content": f"Analyze the following sensor data and describe any patterns you see: {data}",
557 },
559 }558 }
560 559
561 560
1453| `scope` | `str` (optional) | Configuration scope |1452| `scope` | `str` (optional) | Configuration scope |
1454| `tools` | `list` (optional) | Tools provided by this server, each with `name`, `description`, and `annotations` fields |1453| `tools` | `list` (optional) | Tools provided by this server, each with `name`, `description`, and `annotations` fields |
1455 1454
1455### `ContextUsageResponse`
1456
1457Response from [`ClaudeSDKClient.get_context_usage()`](#methods). This is the same payload Claude Code renders for the `/context` command in an interactive session, so alongside the token counts it carries display fields such as `color` and `gridRows` that Claude Code uses to draw the `/context` usage grid.
1458
1459Claude Code builds this payload by sending several requests to the [token-counting](https://platform.claude.com/docs/en/build-with-claude/token-counting) API. These requests don't appear in the message stream, so cost tracking that reads the stream won't see them. On the Anthropic API, token counting isn't billed.
1460
1461```python theme={null}
1462class ContextUsageResponse(TypedDict):
1463 categories: list[ContextUsageCategory]
1464 totalTokens: int
1465 maxTokens: int
1466 rawMaxTokens: int
1467 percentage: float
1468 model: str
1469 isAutoCompactEnabled: bool
1470 memoryFiles: list[dict[str, Any]]
1471 mcpTools: list[dict[str, Any]]
1472 agents: list[dict[str, Any]]
1473 gridRows: list[list[dict[str, Any]]]
1474 autoCompactThreshold: NotRequired[int]
1475 deferredBuiltinTools: NotRequired[list[dict[str, Any]]]
1476 systemTools: NotRequired[list[dict[str, Any]]]
1477 systemPromptSections: NotRequired[list[dict[str, Any]]]
1478 slashCommands: NotRequired[dict[str, Any]]
1479 skills: NotRequired[dict[str, Any]] # skill usage with frontmatter breakdown
1480 messageBreakdown: NotRequired[dict[str, Any]] # message tokens by type
1481 apiUsage: NotRequired[dict[str, Any] | None]
1482```
1483
1484Each `ContextUsageCategory` entry carries `name`, `tokens`, `color`, and an optional `isDeferred` flag. `totalTokens` is the session's current context usage, and `maxTokens` is the window that usage is measured against. That window is the model's context window, or the lower auto-compaction window when one applies, and `rawMaxTokens` carries the same value as `maxTokens`. `apiUsage` holds the usage from the latest API response, not a running total for the session. Claude Code leaves the optional `deferredBuiltinTools`, `systemTools`, and `systemPromptSections` keys unset, so expect them to be absent even though the type declares them.
1485
1456### `SdkPluginConfig`1486### `SdkPluginConfig`
1457 1487
1458Configuration for loading plugins in the SDK.1488Configuration for loading plugins in the SDK.
2454 2484
2455Documentation of input/output schemas for all built-in Claude Code tools. While the Python SDK doesn't export these as types, they represent the structure of tool inputs and outputs in messages.2485Documentation of input/output schemas for all built-in Claude Code tools. While the Python SDK doesn't export these as types, they represent the structure of tool inputs and outputs in messages.
2456 2486
2487Each output shown is the value you read from [`UserMessage.tool_use_result`](#usermessage) for that tool. Key names appear exactly as Claude Code emits them. A key annotated `| None` with a "present when" or "optional" comment is omitted when it doesn't apply.
2488
2457### Agent2489### Agent
2458 2490
2459**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.2491**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.
2621 2653
2622**Tool name:** `Bash`2654**Tool name:** `Bash`
2623 2655
2624For what sets the foreground ceiling, see [Timeout and output limits](/docs/en/tools-reference#timeout-and-output-limits). For the background time limit, see [Background commands](/docs/en/tools-reference#background-commands).2656For what sets the foreground ceiling, see [Timeout and output limits](/docs/en/tools-reference#timeout-and-output-limits). For the background time limit, see [Time limit for background commands](/docs/en/tools-reference#time-limit-for-background-commands).
2625 2657
2626**Input:**2658**Input:**
2627 2659
2694 2726
2695```python theme={null}2727```python theme={null}
2696{2728{
2697 "message": str, # Confirmation message2729 "filePath": str, # The file that was edited
2698 "replacements": int, # Number of replacements made2730 "oldString": str, # The text that was replaced
2699 "file_path": str, # File path that was edited2731 "newString": str, # The text that replaced it
2732 "originalFile": str | None, # File contents before the edit
2733 "structuredPatch": [ # Diff hunks for the change
2734 {
2735 "oldStart": int,
2736 "oldLines": int,
2737 "newStart": int,
2738 "newLines": int,
2739 "lines": list[str],
2740 }
2741 ],
2742 "userModified": bool, # Whether the user changed the proposed edit before accepting it
2743 "replaceAll": bool, # Whether all occurrences were replaced
2744 "gitDiff": { # Optional git diff summary for the file
2745 "filename": str,
2746 "status": "modified" | "added",
2747 "additions": int,
2748 "deletions": int,
2749 "changes": int,
2750 "patch": str,
2751 "repository": str | None, # GitHub owner/repo when available
2752 } | None,
2700}2753}
2701```2754```
2702 2755
2714}2767}
2715```2768```
2716 2769
2717**Output (Text files):**2770The output takes one of the following shapes depending on what Claude read. Check the `type` key to tell them apart.
2771
2772**Output (type: `"text"`):**
2773
2774```python theme={null}
2775{
2776 "type": "text",
2777 "file": {
2778 "filePath": str, # The file that was read
2779 "content": str, # The returned content
2780 "numLines": int, # Number of lines in the returned content
2781 "startLine": int, # Line number the content starts at
2782 "totalLines": int, # Total number of lines in the file
2783 "truncatedByTokenCap": bool | None, # Present and True when a whole-file read exceeded the token cap and content is the first page
2784 },
2785}
2786```
2787
2788**Output (type: `"image"`):**
2789
2790```python theme={null}
2791{
2792 "type": "image",
2793 "file": {
2794 "base64": str, # Base64-encoded image data
2795 "type": "image/jpeg" | "image/png" | "image/gif" | "image/webp", # Image MIME type
2796 "originalSize": int, # Original file size in bytes
2797 "dimensions": { # Optional sizing info for coordinate mapping
2798 "originalWidth": int | None, # Optional; original width in pixels
2799 "originalHeight": int | None, # Optional; original height in pixels
2800 "displayWidth": int | None, # Optional; width after resizing
2801 "displayHeight": int | None, # Optional; height after resizing
2802 } | None,
2803 },
2804}
2805```
2806
2807**Output (type: `"notebook"`):**
2718 2808
2719```python theme={null}2809```python theme={null}
2720{2810{
2721 "content": str, # File contents with line numbers2811 "type": "notebook",
2722 "total_lines": int, # Total number of lines in file2812 "file": {
2723 "lines_returned": int, # Lines actually returned2813 "filePath": str, # The notebook that was read
2814 "cells": list, # Notebook cells
2815 },
2724}2816}
2725```2817```
2726 2818
2727**Output (Images):**2819**Output (type: `"pdf"`):**
2728 2820
2729```python theme={null}2821```python theme={null}
2730{2822{
2731 "image": str, # Base64 encoded image data2823 "type": "pdf",
2732 "mime_type": str, # Image MIME type2824 "file": {
2733 "file_size": int, # File size in bytes2825 "filePath": str, # The PDF that was read
2826 "base64": str, # Base64-encoded PDF data
2827 "originalSize": int, # File size in bytes
2828 },
2829}
2830```
2831
2832**Output (type: `"parts"`):**
2833
2834```python theme={null}
2835{
2836 "type": "parts",
2837 "file": {
2838 "filePath": str, # The PDF that was read
2839 "originalSize": int, # File size in bytes
2840 "count": int, # Number of pages extracted as images
2841 "outputDir": str, # Directory containing the extracted page images
2842 },
2843 "firstPage": int | None, # Optional document page number of the first extracted page
2844}
2845```
2846
2847**Output (type: `"file_unchanged"`):**
2848
2849```python theme={null}
2850{
2851 "type": "file_unchanged", # The file is unchanged since Claude last read it in this session, so the content isn't repeated
2852 "file": {
2853 "filePath": str,
2854 },
2855 "source": "seeded" | None, # Present when the earlier copy came from a CLAUDE.md or memory file loaded at startup rather than a Read call
2734}2856}
2735```2857```
2736 2858
2751 2873
2752```python theme={null}2874```python theme={null}
2753{2875{
2754 "message": str, # Success message2876 "type": "create" | "update", # Whether the write created a new file or overwrote an existing one
2755 "bytes_written": int, # Number of bytes written2877 "filePath": str, # The file that was written
2756 "file_path": str, # File path that was written2878 "content": str, # The content that was written
2879 "structuredPatch": [ # Diff hunks; empty for a new file, when nothing changed, or when Claude Code skipped the diff
2880 {
2881 "oldStart": int,
2882 "oldLines": int,
2883 "newStart": int,
2884 "newLines": int,
2885 "lines": list[str],
2886 }
2887 ],
2888 "originalFile": str | None, # Previous content; None for a new file or when the previous content was too large to include
2889 "gitDiff": { # Optional git diff summary for the file
2890 "filename": str,
2891 "status": "modified" | "added",
2892 "additions": int,
2893 "deletions": int,
2894 "changes": int,
2895 "patch": str,
2896 "repository": str | None, # GitHub owner/repo when available
2897 } | None,
2898 "userModified": bool | None, # Optional; whether the user edited the proposed content before accepting it
2757}2899}
2758```2900```
2759 2901
2774 2916
2775```python theme={null}2917```python theme={null}
2776{2918{
2777 "matches": list[str], # Array of matching file paths2919 "durationMs": int, # Time taken to run the search, in milliseconds
2778 "count": int, # Number of matches found2920 "numFiles": int, # Number of paths returned, after any truncation
2779 "search_path": str, # Search directory used2921 "filenames": list[str], # Matching file paths
2922 "truncated": bool, # Whether the results were truncated at the 100-file limit
2923 "totalMatches": int | None, # Optional total number of matching files before truncation; a lower bound when countIsComplete is False
2924 "countIsComplete": bool | None, # Optional; whether totalMatches is exact
2780}2925}
2781```2926```
2782 2927
2928`totalMatches` and `countIsComplete` require Claude Code v2.1.191 or later.
2929
2783### Grep2930### Grep
2784 2931
2785**Tool name:** `Grep`2932**Tool name:** `Grep`
2798 "-B": int | None, # Lines to show before each match2945 "-B": int | None, # Lines to show before each match
2799 "-A": int | None, # Lines to show after each match2946 "-A": int | None, # Lines to show after each match
2800 "-C": int | None, # Lines to show before and after2947 "-C": int | None, # Lines to show before and after
2948 "context": int | None, # Lines to show before and after; -C is an alias
2949 "-o": bool | None, # Print only the matched parts of each line
2801 "head_limit": int | None, # Limit output to first N lines/entries2950 "head_limit": int | None, # Limit output to first N lines/entries
2951 "offset": int | None, # Skip first N lines/entries before applying head_limit
2802 "multiline": bool | None, # Enable multiline mode2952 "multiline": bool | None, # Enable multiline mode
2803}2953}
2804```2954```
2805 2955
2806**Output (content mode):**2956**Output:**
2807 2957
2808```python theme={null}2958```python theme={null}
2809{2959{
2810 "matches": [2960 "mode": "content" | "files_with_matches" | "count" | None, # The output mode that was used
2811 {2961 "numFiles": int, # Number of files in the result; always 0 in content mode
2812 "file": str,2962 "filenames": list[str], # Matching files in files_with_matches mode; empty in the other modes
2813 "line_number": int | None,2963 "content": str | None, # Matching lines in content mode, or per-file counts in count mode
2814 "line": str,2964 "numLines": int | None, # Number of lines in content, present in content mode
2815 "before_context": list[str] | None,2965 "numMatches": int | None, # Total match count, present in count mode
2816 "after_context": list[str] | None,2966 "totalFiles": int | None, # Optional total before head_limit and offset, in files_with_matches mode
2817 }2967 "totalLines": int | None, # Optional total before head_limit and offset, in content mode
2818 ],2968 "appliedLimit": int | None, # Present when head_limit truncated the result
2819 "total_matches": int,2969 "appliedOffset": int | None, # Present when an offset was applied
2820}2970}
2821```2971```
2822 2972
2823**Output (files\_with\_matches mode):**2973Grep returns this dict shape in each output mode. Which optional keys are present depends on `output_mode`.
2824 2974
2825```python theme={null}2975`totalFiles` requires Claude Code v2.1.208 or later. `totalLines` requires Claude Code v2.1.210 or later.
2826{
2827 "files": list[str], # Files containing matches
2828 "count": int, # Number of files with matches
2829}
2830```
2831 2976
2832### NotebookEdit2977### NotebookEdit
2833 2978
2849 2994
2850```python theme={null}2995```python theme={null}
2851{2996{
2852 "message": str, # Success message2997 "new_source": str, # The source written to the cell
2853 "edit_type": "replaced" | "inserted" | "deleted", # Type of edit performed2998 "old_source": str | None, # Previous cell source, present for replace and delete
2854 "cell_id": str | None, # Cell ID that was affected2999 "cell_id": str | None, # ID of the edited cell, when available
2855 "total_cells": int, # Total cells in notebook after edit3000 "cell_type": "code" | "markdown", # The cell type
3001 "language": str, # The notebook's programming language
3002 "edit_mode": str, # The edit mode that was used
3003 "error": str | None, # Error message when the operation failed
3004 "notebook_path": str, # The notebook file
3005 "original_file": str, # Notebook content before the edit
3006 "updated_file": str, # Notebook content after the edit
2856}3007}
2857```3008```
2858 3009
2944 3095
2945```python theme={null}3096```python theme={null}
2946{3097{
2947 "message": str, # Success message3098 "oldTodos": [ # The todo list before the update
2948 "stats": {"total": int, "pending": int, "in_progress": int, "completed": int},3099 {
3100 "content": str,
3101 "status": "pending" | "in_progress" | "completed",
3102 "activeForm": str,
3103 }
3104 ],
3105 "newTodos": [ # The todo list after the update
3106 {
3107 "content": str,
3108 "status": "pending" | "in_progress" | "completed",
3109 "activeForm": str,
3110 }
3111 ],
2949}3112}
2950```3113```
2951 3114
3103 3266
3104```python theme={null}3267```python theme={null}
3105{3268{
3106 "message": str, # Confirmation message3269 "plan": str | None, # The plan that was presented to the user
3107 "approved": bool | None, # Whether user approved the plan3270 "isAgent": bool, # True when a subagent called the tool
3271 "filePath": str | None, # Present when the plan was saved to a file
3272 "hasTaskTool": bool | None, # Optional; whether the Agent tool is available in the current context
3273 "planWasEdited": bool | None, # Present and True when the user edited the plan before approving
3274 "awaitingLeaderApproval": bool | None, # Present and True when a teammate sent the plan to the team lead for approval
3275 "requestId": str | None, # Optional ID of that approval request
3108}3276}
3109```3277```
3110 3278
3120}3288}
3121```3289```
3122 3290
3291The result is a list rather than a dict, so `tool_use_result` holds a `list` for this tool.
3292
3123**Output:**3293**Output:**
3124 3294
3125```python theme={null}3295```python theme={null}
3126{3296[ # One entry per resource
3127 "resources": [
3128 {3297 {
3129 "uri": str,3298 "uri": str, # Resource URI
3130 "name": str,3299 "name": str, # Resource name
3131 "description": str | None,3300 "mimeType": str | None, # Optional MIME type
3132 "mimeType": str | None,3301 "description": str | None, # Optional description
3133 "server": str,3302 "server": str, # Server that provides this resource
3134 }3303 }
3135 ],3304]
3136 "total": int,
3137}
3138```3305```
3139 3306
3140### ReadMcpResource3307### ReadMcpResource
3155```python theme={null}3322```python theme={null}
3156{3323{
3157 "contents": [3324 "contents": [
3158 {"uri": str, "mimeType": str | None, "text": str | None, "blob": str | None}3325 {
3326 "uri": str, # Resource URI
3327 "mimeType": str | None, # Optional MIME type
3328 "text": str | None, # Text content, or a note about the binary content
3329 "blobSavedTo": str | None, # Present when Claude Code saved binary content to disk; path of the saved file
3330 }
3159 ],3331 ],
3160 "server": str,3332 "error": str | None, # Present when the server couldn't read the resource
3161}3333}
3162```3334```
3163 3335