Claude Agent SDK Python: Build Agentic Workflows with Claude Code

Oct 10, 2025

Introduction

Claude Agent SDK Python (repository: anthropics/claude-agent-sdk-python) is the official Python SDK for building agents on top of Claude Code.

In this post, we’ll dive deep into the capabilities, installation, usage patterns, code samples, and how you can contribute or extend the SDK to build powerful, autonomous agents in Python.

Here is some metadata at a glance:

  • Project Name: anthropics/claude-agent-sdk-python
  • Description: Python SDK for Claude Agent (Claude Code)
  • Stars / Forks: ~ (not displayed on landing, but repository listing shows “Star / Fork” UI)
  • License: MIT
  • Primary Language: Python (>= 3.10)
  • Tags / Topics: agent, SDK, Claude, Python, AI agent, tool integration
  • Owner / Organization: anthropics (Anthropic)
  • Latest Release: v0.0.23 (released Sep 17, 2025)

Key Features

Here are the standout features of Claude Agent SDK Python:

  • Async streaming API via query(), returning an AsyncIterator of messages.
  • Session client support via ClaudeSDKClient for interactive, multi-turn conversations.
  • Support for custom tools and Model Context Protocol (MCP) servers (defining Python functions as callable tools).
  • Fine-grained control over allowed tools, permission modes, and hooks (pre/post tool invocation).
  • Automatic context compaction and prompt caching to manage token budgets.
  • Production-ready features: error handling, session controls, monitoring, and extensibility.
  • Migration path from the deprecated claude-code-sdk to claude-agent-sdk.

Installation Guide

To install and setup Claude Agent SDK for Python, follow these steps:

Prerequisites

  • Python 3.10 or newer
  • Node.js (for Claude Code CLI / backend interoperability)
  • Claude Code command-line tool: npm install -g @anthropic-ai/claude-code

Install via pip

pip install claude-agent-sdk

Note: The older claude-code-sdk package is deprecated; migration documentation is available.

Environment Setup

Be sure to set your Anthropic API key as an environment variable:

export ANTHROPIC_API_KEY="your_api_key_here"

Optionally, for Bedrock/Vertex integration, set environment flags: CLAUDE_CODE_USE_BEDROCK or CLAUDE_CODE_USE_VERTEX.

How to Use

Below are typical patterns and workflows when working with the SDK.

Using query() (stateless, streaming)

import anyio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock

async def ask(prompt: str):
async for message in query(prompt=prompt):
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text)

anyio.run(ask("Hello Claude"))

Using ClaudeSDKClient for sessions

from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions

client = ClaudeSDKClient()
options = ClaudeAgentOptions(system_prompt="You are a helpful assistant.")

await client.start(prompt="Hi Claude", options=options)
response = await client.send("Tell me a joke")
print(response)

Defining custom tools (MCP servers)

from claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeAgentOptions

@tool("add", "Add two numbers", {"a": float, "b": float})
async def add_tool(args):
return {"content": [{"type": "text", "text": f"Sum: {args['a'] + args['b']}"}]}

mcp = create_sdk_mcp_server(name="calc", version="1.0.0", tools=[add_tool])
options = ClaudeAgentOptions(mcp_servers={"calc": mcp}, allowed_tools=["mcp__calc__add"])

async for msg in query(prompt="What is 3 + 5?", options=options):
print(msg)

These patterns—one-shot streaming, session-based chat, and tool-enabled agents—give you a versatile base for agentic applications.

Code Examples

Here are additional code snippets illustrating useful workflows:

  • Interactive conversation loop:
    async def chat_loop():
    client = ClaudeSDKClient()
    await client.start(prompt="You are Claude assistant.")
    while True:
    user = input("You: ")
    resp = await client.send(user)
    print("Claude:", resp)
    
  • Executing shell commands via tool usage:
    @tool("bash", "Execute bash commands", {"cmd": str})
    async def bash_tool(args):
    import subprocess
    out = subprocess.run(args["cmd"], shell=True, capture_output=True, text=True)
    return {"content": [{"type": "text", "text": out.stdout or out.stderr}]}
    
    options = ClaudeAgentOptions(allowed_tools=["mcp__bash__bash"], mcp_servers={"bash": bash_mcp})
    
    and then query with a prompt that triggers tool invocation
    
  • Mixing streaming and tool hooks:
    async for msg in query(prompt="List files and count lines", options=options):
    # within streaming, inspect tool use events or partial results
    print(msg)
    

Contribution Guide

Want to contribute? The repository includes standard contributor resources:

  • CONTRIBUTING.md: guidelines on how to propose changes, style, testing, and PR workflow (present in repo)
  • LICENSE: MIT license automatically included enabling open contributions.
  • CHANGELOG / Release notes: each release tag includes notes (e.g. v0.0.23)
  • Issue tracker: open issues for bugs, enhancements, and feature requests.
  • Code reviews & CI: use GitHub Actions workflows to validate incoming PRs.

When proposing contributions, ensure tests pass, include documentation, add examples if you introduce new APIs, and follow the coding conventions already in place.

Community & Support

Places to engage or get help:

  • GitHub Issues / Discussions: ask questions or report bugs via the repository interface.
  • Anthropic engineering blog: articles about developing agents with Claude Agent SDK.
  • Docs & API Reference: official Claude Agent SDK documentation on Claude’s site.
  • Community Posts / Blogs: tutorial writeups like Jimmy Song’s overview, Eesel’s guide, PromptLayer blogs.

Conclusion

The Claude Agent SDK Python presents a robust, production-ready foundation for integrating agentic capabilities into Python projects. Whether you’re exploring one-shot queries or building multi-turn agents with custom tools, the SDK offers a flexible, streaming-first API with support for tool invocation, session control, and context management.

As the AI agent ecosystem continues to evolve, this SDK will likely serve as a core building block for developer-facing AI workflows in Python.

What is the difference between query() and ClaudeSDKClient?

The query() function initiates a one-shot, stateless streaming exchange: each call is independent. The ClaudeSDKClient supports session continuity, reusing context across multiple messages, supporting interactive multi-turn conversations with tool hooks.

How do I define and register a custom tool?

Use the @tool decorator to define an async function with a name, description, and an input schema. Then wrap it in a MCP server using create_sdk_mcp_server, and include that server in your ClaudeAgentOptions configuration under mcp_servers and allowed_tools.

How to migrate from the deprecated claude-code-sdk?

Uninstall the old claude-code-sdk package, install claude-agent-sdk, update imports from claude_code_sdk to claude_agent_sdk, and rename types like ClaudeCodeOptionsClaudeAgentOptions. See the migration guide for breaking changes.

Can I use the SDK with Bedrock or Vertex AI?

Yes—by setting env flags CLAUDE_CODE_USE_BEDROCK=1 or CLAUDE_CODE_USE_VERTEX=1 and configuring credentials, the SDK can route requests via Amazon Bedrock or Google Vertex AI as a backend.

Is streaming supported over long-running sessions?

Yes — both query() and ClaudeSDKClient support streaming responses. The session client lets you stream partial results in multi-turn conversations and manage interrupts or cancellations.