Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/anthropics/claude-agent-sdk-python/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Content blocks represent different types of content within messages. They are used in both UserMessage and AssistantMessage content.
ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock

TextBlock

Represents plain text content.
@dataclass
class TextBlock:
    text: str
text
str
required
The text content.

Example

async for message in client:
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, TextBlock):
                print(f"Claude says: {block.text}")

ThinkingBlock

Represents Claude’s internal reasoning (extended thinking).
@dataclass
class ThinkingBlock:
    thinking: str
    signature: str
thinking
str
required
The thinking content showing Claude’s reasoning process.
signature
str
required
Cryptographic signature verifying the thinking content.

Example

async for message in client:
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, ThinkingBlock):
                print(f"Claude's reasoning: {block.thinking}")
                print(f"Verified: {block.signature}")
Thinking blocks are only present when extended thinking is enabled via the thinking option in ClaudeAgentOptions.

ToolUseBlock

Represents Claude’s intent to use a tool.
@dataclass
class ToolUseBlock:
    id: str
    name: str
    input: dict[str, Any]
id
str
required
Unique identifier for this tool use (e.g., "toolu_01ABC123").
name
str
required
Name of the tool being invoked (e.g., "Bash", "Read", "Write").
input
dict[str, Any]
required
Tool input parameters as a dictionary.

Example

async for message in client:
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, ToolUseBlock):
                print(f"Tool: {block.name}")
                print(f"ID: {block.id}")
                print(f"Input: {block.input}")
                
                # Example tool use
                if block.name == "Bash":
                    print(f"Command: {block.input.get('command')}")
                elif block.name == "Write":
                    print(f"File: {block.input.get('filePath')}")

Common Tool Input Schemas

ToolResultBlock

Represents the result of a tool execution.
@dataclass
class ToolResultBlock:
    tool_use_id: str
    content: str | list[dict[str, Any]] | None = None
    is_error: bool | None = None
tool_use_id
str
required
ID of the tool use this result corresponds to (matches ToolUseBlock.id).
content
str | list[dict[str, Any]] | None
Tool output content. Can be:
  • A string for simple text output
  • A list of content blocks for structured output
  • None if the tool had no output
is_error
bool | None
Whether the tool execution resulted in an error.

Example

async for message in client:
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, ToolResultBlock):
                print(f"Tool result for: {block.tool_use_id}")
                if block.is_error:
                    print(f"Error: {block.content}")
                else:
                    print(f"Output: {block.content}")
Tool result blocks are typically generated internally by the SDK and CLI. You usually don’t need to create them manually unless implementing custom tool execution.

Pattern Matching Example

Python 3.10+ pattern matching makes it easy to handle different content block types:
async for message in client:
    if isinstance(message, AssistantMessage):
        for block in message.content:
            match block:
                case TextBlock(text=text):
                    print(f"Text: {text}")
                
                case ThinkingBlock(thinking=thinking):
                    print(f"Thinking: {thinking}")
                
                case ToolUseBlock(id=tool_id, name=name, input=input):
                    print(f"Tool {name} ({tool_id}): {input}")
                
                case ToolResultBlock(tool_use_id=tool_id, content=content, is_error=is_error):
                    status = "error" if is_error else "success"
                    print(f"Result for {tool_id} ({status}): {content}")

Type Guards

For older Python versions or more explicit type checking:
from claude_agent_sdk.types import (
    TextBlock,
    ThinkingBlock,
    ToolUseBlock,
    ToolResultBlock,
)

async for message in client:
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, TextBlock):
                print(f"Text: {block.text}")
            elif isinstance(block, ThinkingBlock):
                print(f"Thinking: {block.thinking}")
            elif isinstance(block, ToolUseBlock):
                print(f"Tool: {block.name}")
            elif isinstance(block, ToolResultBlock):
                print(f"Result: {block.content}")

Build docs developers (and LLMs) love