Agent SDK reference - Python changedagent-sdk/python
Nearest release: v2.1.286, published 10 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 1 Oct 2026 03:48 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 1 Oct 2026 04:07 UTC.
Upstream edited
Recorded here
Lines+244added
Lines−105removed
From line
532
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits39to this page, all time
The whole hunk
from line 532, old and new numbered
/
from line 532
532532
533533#### Example - Streaming input with ClaudeSDKClient
534534
535`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.
536
535537```python theme={null}
536538import asyncio
537539from claude_agent_sdk import ClaudeSDKClient
from line 540
538540
539541
540542async def message_stream():
541 """Generate messages dynamically."""
543 """Assemble the prompt at send time and yield it as one user message."""
544 readings = {"Temperature": "25°C", "Humidity": "60%"}
545 data = ", ".join(f"{name}: {value}" for name, value in readings.items())
542546 yield {
543547 "type": "user",
544 "message": {"role": "user", "content": "Analyze the following data:"},
548 "message": {
549 "role": "user",
550 "content": f"Analyze the following sensor data and describe any patterns you see: {data}",
551 },
545552 }
546 await asyncio.sleep(0.5)
547 yield {
548 "type": "user",
549 "message": {"role": "user", "content": "Temperature: 25°C, Humidity: 60%"},
550 }
551 await asyncio.sleep(0.5)
552 yield {
553 "type": "user",
554 "message": {"role": "user", "content": "What patterns do you see?"},
555 }
556553
557554
558555async def main():
from line 2447
24502447
24512448Documentation 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.
24522449
2450Each 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.
2451
24532452### Agent
24542453
24552454**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.
from line 2689
26902689
26912690```python theme={null}
26922691{
2693 "message": str, # Confirmation message
2694 "replacements": int, # Number of replacements made
2695 "file_path": str, # File path that was edited
2692 "filePath": str, # The file that was edited
2693 "oldString": str, # The text that was replaced
2694 "newString": str, # The text that replaced it
2695 "originalFile": str | None, # File contents before the edit
2696 "structuredPatch": [ # Diff hunks for the change
2697 {
2698 "oldStart": int,
2699 "oldLines": int,
2700 "newStart": int,
2701 "newLines": int,
2702 "lines": list[str],
2703 }
2704 ],
2705 "userModified": bool, # Whether the user changed the proposed edit before accepting it
2706 "replaceAll": bool, # Whether all occurrences were replaced
2707 "gitDiff": { # Optional git diff summary for the file
2708 "filename": str,
2709 "status": "modified" | "added",
2710 "additions": int,
2711 "deletions": int,
2712 "changes": int,
2713 "patch": str,
2714 "repository": str | None, # GitHub owner/repo when available
2715 } | None,
26962716}
26972717```
26982718
from line 2730
27102730}
27112731```
27122732
2713**Output (Text files):**
2733The output takes one of the following shapes depending on what Claude read. Check the `type` key to tell them apart.
27142734
2735**Output (type: `"text"`):**
2736
27152737```python theme={null}
27162738{
2717 "content": str, # File contents with line numbers
2718 "total_lines": int, # Total number of lines in file
2719 "lines_returned": int, # Lines actually returned
2739 "type": "text",
2740 "file": {
2741 "filePath": str, # The file that was read
2742 "content": str, # The returned content
2743 "numLines": int, # Number of lines in the returned content
2744 "startLine": int, # Line number the content starts at
2745 "totalLines": int, # Total number of lines in the file
2746 "truncatedByTokenCap": bool | None, # Present and True when a whole-file read exceeded the token cap and content is the first page
2747 },
27202748}
27212749```
27222750
2723**Output (Images):**
2751**Output (type: `"image"`):**
27242752
27252753```python theme={null}
27262754{
2727 "image": str, # Base64 encoded image data
2728 "mime_type": str, # Image MIME type
2729 "file_size": int, # File size in bytes
2755 "type": "image",
2756 "file": {
2757 "base64": str, # Base64-encoded image data
2758 "type": "image/jpeg" | "image/png" | "image/gif" | "image/webp", # Image MIME type
2759 "originalSize": int, # Original file size in bytes
2760 "dimensions": { # Optional sizing info for coordinate mapping
2761 "originalWidth": int | None, # Optional; original width in pixels
2762 "originalHeight": int | None, # Optional; original height in pixels
2763 "displayWidth": int | None, # Optional; width after resizing
2764 "displayHeight": int | None, # Optional; height after resizing
2765 } | None,
2766 },
27302767}
27312768```
27322769
2770**Output (type: `"notebook"`):**
2771
2772```python theme={null}
2773{
2774 "type": "notebook",
2775 "file": {
2776 "filePath": str, # The notebook that was read
2777 "cells": list, # Notebook cells
2778 },
2779}
2780```
2781
2782**Output (type: `"pdf"`):**
2783
2784```python theme={null}
2785{
2786 "type": "pdf",
2787 "file": {
2788 "filePath": str, # The PDF that was read
2789 "base64": str, # Base64-encoded PDF data
2790 "originalSize": int, # File size in bytes
2791 },
2792}
2793```
2794
2795**Output (type: `"parts"`):**
2796
2797```python theme={null}
2798{
2799 "type": "parts",
2800 "file": {
2801 "filePath": str, # The PDF that was read
2802 "originalSize": int, # File size in bytes
2803 "count": int, # Number of pages extracted as images
2804 "outputDir": str, # Directory containing the extracted page images
2805 },
2806 "firstPage": int | None, # Optional document page number of the first extracted page
2807}
2808```
2809
2810**Output (type: `"file_unchanged"`):**
2811
2812```python theme={null}
2813{
2814 "type": "file_unchanged", # The file is unchanged since Claude last read it in this session, so the content isn't repeated
2815 "file": {
2816 "filePath": str,
2817 },
2818 "source": "seeded" | None, # Present when the earlier copy came from a CLAUDE.md or memory file loaded at startup rather than a Read call
2819}
2820```
2821
27332822### Write
27342823
27352824**Tool name:** `Write`
from line 2836
27472836
27482837```python theme={null}
27492838{
2750 "message": str, # Success message
2751 "bytes_written": int, # Number of bytes written
2752 "file_path": str, # File path that was written
2839 "type": "create" | "update", # Whether the write created a new file or overwrote an existing one
2840 "filePath": str, # The file that was written
2841 "content": str, # The content that was written
2842 "structuredPatch": [ # Diff hunks; empty for a new file, when nothing changed, or when Claude Code skipped the diff
2843 {
2844 "oldStart": int,
2845 "oldLines": int,
2846 "newStart": int,
2847 "newLines": int,
2848 "lines": list[str],
2849 }
2850 ],
2851 "originalFile": str | None, # Previous content; None for a new file or when the previous content was too large to include
2852 "gitDiff": { # Optional git diff summary for the file
2853 "filename": str,
2854 "status": "modified" | "added",
2855 "additions": int,
2856 "deletions": int,
2857 "changes": int,
2858 "patch": str,
2859 "repository": str | None, # GitHub owner/repo when available
2860 } | None,
2861 "userModified": bool | None, # Optional; whether the user edited the proposed content before accepting it
27532862}
27542863```
27552864
from line 2879
27702879
27712880```python theme={null}
27722881{
2773 "matches": list[str], # Array of matching file paths
2774 "count": int, # Number of matches found
2775 "search_path": str, # Search directory used
2882 "durationMs": int, # Time taken to run the search, in milliseconds
2883 "numFiles": int, # Number of paths returned, after any truncation
2884 "filenames": list[str], # Matching file paths
2885 "truncated": bool, # Whether the results were truncated at the 100-file limit
2886 "totalMatches": int | None, # Optional total number of matching files before truncation; a lower bound when countIsComplete is False
2887 "countIsComplete": bool | None, # Optional; whether totalMatches is exact
27762888}
27772889```
27782890
2891`totalMatches` and `countIsComplete` require Claude Code v2.1.191 or later.
2892
27792893### Grep
27802894
27812895**Tool name:** `Grep`
from line 2908
27942908 "-B": int | None, # Lines to show before each match
27952909 "-A": int | None, # Lines to show after each match
27962910 "-C": int | None, # Lines to show before and after
2911 "context": int | None, # Lines to show before and after; -C is an alias
2912 "-o": bool | None, # Print only the matched parts of each line
27972913 "head_limit": int | None, # Limit output to first N lines/entries
2914 "offset": int | None, # Skip first N lines/entries before applying head_limit
27982915 "multiline": bool | None, # Enable multiline mode
27992916}
28002917```
28012918
2802**Output (content mode):**
2919**Output:**
28032920
28042921```python theme={null}
28052922{
2806 "matches": [
2807 {
2808 "file": str,
2809 "line_number": int | None,
2810 "line": str,
2811 "before_context": list[str] | None,
2812 "after_context": list[str] | None,
2813 }
2814 ],
2815 "total_matches": int,
2923 "mode": "content" | "files_with_matches" | "count" | None, # The output mode that was used
2924 "numFiles": int, # Number of files in the result; always 0 in content mode
2925 "filenames": list[str], # Matching files in files_with_matches mode; empty in the other modes
2926 "content": str | None, # Matching lines in content mode, or per-file counts in count mode
2927 "numLines": int | None, # Number of lines in content, present in content mode
2928 "numMatches": int | None, # Total match count, present in count mode
2929 "totalFiles": int | None, # Optional total before head_limit and offset, in files_with_matches mode
2930 "totalLines": int | None, # Optional total before head_limit and offset, in content mode
2931 "appliedLimit": int | None, # Present when head_limit truncated the result
2932 "appliedOffset": int | None, # Present when an offset was applied
28162933}
28172934```
28182935
2819**Output (files\_with\_matches mode):**
2936Grep returns this dict shape in each output mode. Which optional keys are present depends on `output_mode`.
28202937
2821```python theme={null}
2822{
2823 "files": list[str], # Files containing matches
2824 "count": int, # Number of files with matches
2825}
2826```
2938`totalFiles` requires Claude Code v2.1.208 or later. `totalLines` requires Claude Code v2.1.210 or later.
28272939
28282940### NotebookEdit
28292941
from line 2957
28452957
28462958```python theme={null}
28472959{
2848 "message": str, # Success message
2849 "edit_type": "replaced" | "inserted" | "deleted", # Type of edit performed
2850 "cell_id": str | None, # Cell ID that was affected
2851 "total_cells": int, # Total cells in notebook after edit
2960 "new_source": str, # The source written to the cell
2961 "old_source": str | None, # Previous cell source, present for replace and delete
2962 "cell_id": str | None, # ID of the edited cell, when available
2963 "cell_type": "code" | "markdown", # The cell type
2964 "language": str, # The notebook's programming language
2965 "edit_mode": str, # The edit mode that was used
2966 "error": str | None, # Error message when the operation failed
2967 "notebook_path": str, # The notebook file
2968 "original_file": str, # Notebook content before the edit
2969 "updated_file": str, # Notebook content after the edit
28522970}
28532971```
28542972
from line 3058
29403058
29413059```python theme={null}
29423060{
2943 "message": str, # Success message
2944 "stats": {"total": int, "pending": int, "in_progress": int, "completed": int},
3061 "oldTodos": [ # The todo list before the update
3062 {
3063 "content": str,
3064 "status": "pending" | "in_progress" | "completed",
3065 "activeForm": str,
3066 }
3067 ],
3068 "newTodos": [ # The todo list after the update
3069 {
3070 "content": str,
3071 "status": "pending" | "in_progress" | "completed",
3072 "activeForm": str,
3073 }
3074 ],
29453075}
29463076```
29473077
from line 3229
30993229
31003230```python theme={null}
31013231{
3102 "message": str, # Confirmation message
3103 "approved": bool | None, # Whether user approved the plan
3232 "plan": str | None, # The plan that was presented to the user
3233 "isAgent": bool, # True when a subagent called the tool
3234 "filePath": str | None, # Present when the plan was saved to a file
3235 "hasTaskTool": bool | None, # Optional; whether the Agent tool is available in the current context
3236 "planWasEdited": bool | None, # Present and True when the user edited the plan before approving
3237 "awaitingLeaderApproval": bool | None, # Present and True when a teammate sent the plan to the team lead for approval
3238 "requestId": str | None, # Optional ID of that approval request
31043239}
31053240```
31063241
from line 3251
31163251}
31173252```
31183253
3254The result is a list rather than a dict, so `tool_use_result` holds a `list` for this tool.
3255
31193256**Output:**
31203257
31213258```python theme={null}
3122{
3123 "resources": [
3124 {
3125 "uri": str,
3126 "name": str,
3127 "description": str | None,
3128 "mimeType": str | None,
3129 "server": str,
3130 }
3131 ],
3132 "total": int,
3133}
3259[ # One entry per resource
3260 {
3261 "uri": str, # Resource URI
3262 "name": str, # Resource name
3263 "mimeType": str | None, # Optional MIME type
3264 "description": str | None, # Optional description
3265 "server": str, # Server that provides this resource
3266 }
3267]
31343268```
31353269
31363270### ReadMcpResource
from line 3285
31513285```python theme={null}
31523286{
31533287 "contents": [
3154 {"uri": str, "mimeType": str | None, "text": str | None, "blob": str | None}
3288 {
3289 "uri": str, # Resource URI
3290 "mimeType": str | None, # Optional MIME type
3291 "text": str | None, # Text content, or a note about the binary content
3292 "blobSavedTo": str | None, # Present when Claude Code saved binary content to disk; path of the saved file
3293 }
31553294 ],
3156 "server": str,
3295 "error": str | None, # Present when the server couldn't read the resource
31573296}
31583297```
31593298
No line in this hunk matches that.