agent-sdk-python

Implements production-ready AI agents using the official Python SDK for autonomous workflows. Use when implementing agent workflows, SDK integration, one-shot queries, interactive conversations, custom MCP tools, permission control, CLAUDE.md context loading, error handling, hooks, or agent delegation. Works with .py files and agent architectures. Trigger terms: "Agent SDK", "query()", "ClaudeSDKClient", "@tool decorator", "setting_sources", "agent permissions", "SDK hooks".

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "agent-sdk-python" with this command: npx skills add dawiddutoit/custom-claude/dawiddutoit-custom-claude-agent-sdk-python

Agent SDK Integration

Purpose

Build production-ready AI agents using the Agent SDK for Python. This skill provides hands-on workflows for implementing agent features including simple queries, interactive conversations, custom MCP tools, permission control, context loading, and error handling.

Quick Start

Simple one-shot query:

from claude_agent_sdk import query

async for message in query(prompt="What is the capital of France?"):
    print(message)

Interactive conversation:

from claude_agent_sdk import ClaudeSDKClient

async with ClaudeSDKClient() as client:
    await client.query("Hello!")
    async for msg in client.receive_response():
        print(msg)

When to Use This Skill

Explicit Triggers:

  • "build agent with SDK"
  • "use query() function"
  • "create ClaudeSDKClient"
  • "implement agent workflows"
  • "add custom MCP tools"
  • "configure agent permissions"
  • "load CLAUDE.md context"
  • "implement agent hooks"

Implicit Triggers:

  • Implementing autonomous agent behavior
  • Creating interactive chat agents
  • Building batch processing workflows
  • Adding custom tools to agents
  • Managing agent permissions
  • Integrating project context into agents

Debugging Scenarios:

  • Agent not connecting to CLI
  • Tools not available to agent
  • Permission denied errors
  • Context not loading correctly
  • Hooks not executing

Instructions

Step 1: Choose the Right API Mode

Use query() for:

  • Simple one-shot questions
  • Batch processing of independent tasks
  • Stateless operations
  • When all inputs are known upfront
  • CI/CD automation scripts

Use ClaudeSDKClient for:

  • Interactive conversations with follow-ups
  • Chat applications or REPL interfaces
  • When you need to send messages based on responses
  • Long-running sessions with state management
  • Interrupt capabilities

Step 2: Build Simple Agent (query() Function)

Basic implementation:

from claude_agent_sdk import query, ClaudeAgentOptions

async for message in query(
    prompt="Analyze this code for security issues",
    options=ClaudeAgentOptions(
        system_prompt="You are a security expert",
        cwd="/path/to/project",
        permission_mode="default"
    )
):
    if hasattr(message, 'content'):
        print(message.content)

Key configuration options:

  • system_prompt: Define agent expertise
  • cwd: Set working directory
  • permission_mode: Control tool execution ("default", "acceptEdits", "bypassPermissions")
  • model: Choose model ("claude-sonnet-4", "claude-opus-4")

Step 3: Build Interactive Agent (ClaudeSDKClient)

Full conversation example:

from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions

async with ClaudeSDKClient(
    options=ClaudeAgentOptions(
        system_prompt="You are a helpful coding assistant",
        permission_mode="acceptEdits"
    )
) as client:
    # Send initial message
    await client.query("Help me write a Python web server")

    # Process response
    async for msg in client.receive_response():
        print(msg)

    # Follow-up question
    await client.query("Can you add error handling?")
    async for msg in client.receive_response():
        print(msg)

See references/implementation-guide.md for detailed patterns.

Step 4: Create Custom MCP Tools

Define tools with @tool decorator:

from claude_agent_sdk import tool, create_sdk_mcp_server

@tool("greet", "Greet a user by name", {"name": str})
async def greet(args):
    return {
        "content": [{"type": "text", "text": f"Hello, {args['name']}!"}]
    }

# Create MCP server
calculator = create_sdk_mcp_server(
    name="calculator",
    version="1.0.0",
    tools=[greet]
)

# Use with agent
options = ClaudeAgentOptions(
    mcp_servers={"calc": calculator},
    allowed_tools=["greet"]
)

See references/implementation-guide.md for error handling and advanced patterns.

Step 5: Configure Permissions and Tool Access

Fine-grained tool restrictions:

options = ClaudeAgentOptions(
    # Allow only specific tools
    allowed_tools=["Read", "Grep", "search_code"],

    # Block dangerous tools
    disallowed_tools=["Bash", "Write"],

    # Permission mode
    permission_mode="default"
)

Dynamic permission callback:

from claude_agent_sdk import PermissionResultAllow, PermissionResultDeny

async def can_use_tool(tool_name, tool_input, context):
    if tool_name in ["Read", "Grep", "Glob"]:
        return PermissionResultAllow()

    if tool_name == "Bash" and "rm" in str(tool_input):
        return PermissionResultDeny(
            message="Destructive bash commands are not allowed",
            interrupt=True
        )

    return PermissionResultAllow()

options = ClaudeAgentOptions(can_use_tool=can_use_tool)

See references/implementation-guide.md for complete examples.

Step 6: Load CLAUDE.md Context (setting_sources)

Load project and user instructions:

options = ClaudeAgentOptions(
    # Load CLAUDE.md files
    setting_sources=["user", "project"],

    # user: ~/.claude/CLAUDE.md (user-level instructions)
    # project: ./CLAUDE.md or ./.claude/CLAUDE.md (project-level)

    cwd="/path/to/project"
)

async for message in query(
    prompt="Review this code following project standards",
    options=options
):
    print(message)

When to use which source:

  • "user": Personal preferences, global workflows
  • "project": Team standards, project architecture
  • "local": Machine-specific settings
  • Best practice: Use ["user", "project"] for most workflows

Step 7: Implement Error Handling

Try/catch with specific exceptions:

from claude_agent_sdk import (
    ClaudeSDKError,
    CLIConnectionError,
    CLINotFoundError,
    ProcessError
)

try:
    async for message in query(prompt="Hello"):
        print(message)

except CLINotFoundError:
    print("Install CLI: npm install -g claude-code")

except CLIConnectionError as e:
    print(f"Connection failed: {e}")

except ProcessError as e:
    print(f"Process error (exit {e.exit_code}): {e.stderr}")

See references/implementation-guide.md for retry patterns.

Step 8: Add Hooks for Event-Driven Automation

PreToolUse hook:

from claude_agent_sdk import HookMatcher

async def log_tool_use(input_data, tool_use_id, context):
    tool_name = input_data.get("tool", {}).get("name")
    print(f"About to use tool: {tool_name}")
    return {}  # Empty = allow

options = ClaudeAgentOptions(
    hooks={
        "PreToolUse": [
            HookMatcher(matcher="Bash|Write", hooks=[log_tool_use])
        ]
    }
)

See references/implementation-guide.md for PostToolUse and blocking patterns.

Step 9: Implement Agent Delegation

Define custom agents:

from claude_agent_sdk import AgentDefinition

options = ClaudeAgentOptions(
    agents={
        "python-expert": AgentDefinition(
            description="Python code expert",
            prompt="Expert Python developer",
            tools=["Read", "Write"],
            model="opus"
        )
    }
)

async for message in query(
    prompt="@python-expert Review this code",
    options=options
):
    print(message)

See references/implementation-guide.md for multi-agent patterns.

Supporting Files

References

Scripts

Expected Outcomes

Successful Agent Implementation:

✅ Agent created with proper configuration
✅ Tools accessible and executing correctly
✅ Permissions enforced as expected
✅ Context loaded from CLAUDE.md files
✅ Error handling captures all exceptions
✅ Hooks executing at correct lifecycle points

Common Issues:

  • CLI not found: Install with npm install -g claude-code
  • Permission denied: Check permission_mode and allowed_tools
  • Tools unavailable: Verify mcp_servers configuration
  • Context not loading: Check setting_sources and cwd path

Requirements

Python Dependencies:

pip install claude-agent-sdk
# or
uv pip install claude-agent-sdk

System Requirements:

# Claude CLI
npm install -g claude-code

# Verify installation
claude-code --version

Environment Variables:

# API Key (default)
export ANTHROPIC_API_KEY=your_key

# OR Amazon Bedrock
export CLAUDE_CODE_USE_BEDROCK=1
export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret
export AWS_REGION=us-east-1

# OR Google Vertex AI
export CLAUDE_CODE_USE_VERTEX=1
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json

Integration Points

With Project Patterns

ServiceResult Pattern:

from domain.value_objects import ServiceResult

async def agent_query_service(prompt: str) -> ServiceResult[list]:
    try:
        messages = []
        async for message in query(prompt=prompt):
            messages.append(message)
        return ServiceResult.success(messages)
    except ClaudeSDKError as e:
        return ServiceResult.failure(f"Agent query failed: {e}")

Fail-Fast Imports:

# ✅ CORRECT - Fail fast
from claude_agent_sdk import query, ClaudeAgentOptions

# ❌ WRONG - Optional dependency
try:
    from claude_agent_sdk import query
except ImportError:
    query = None

See references/implementation-guide.md for dependency injection patterns.

Common Patterns

Code Review Agent

async def code_review_agent(file_path: str):
    async for message in query(
        prompt=f"Review {file_path} for code quality",
        options=ClaudeAgentOptions(
            system_prompt="Senior code reviewer",
            setting_sources=["project"],
            allowed_tools=["Read", "Grep"]
        )
    ):
        yield message

Batch Processing

async def batch_analyze(files: list[str]):
    results = {}
    for file_path in files:
        messages = []
        async for msg in query(
            prompt=f"Analyze {file_path}",
            options=ClaudeAgentOptions(allowed_tools=["Read"])
        ):
            messages.append(msg)
        results[file_path] = messages
    return results

See references/implementation-guide.md for interactive debugging and production patterns.

Red Flags to Avoid

  • Using optional imports instead of fail-fast (violates project standards)
  • Not handling CLINotFoundError (users get cryptic errors)
  • Skipping permission configuration (security risk)
  • Not loading project context with setting_sources (ignores team standards)
  • Using bypassPermissions in production (dangerous)
  • Not implementing error handling (unreliable agents)
  • Hardcoding paths instead of using cwd parameter
  • Not testing hooks before deployment
  • Mixing query() and ClaudeSDKClient in same workflow (confusion)
  • Not cleaning up client connections (resource leaks)

Notes

  • API Mode Choice: Use query() for one-shot, ClaudeSDKClient for interactive
  • Permission Modes: "default" = ask user, "acceptEdits" = auto-accept, "bypassPermissions" = no checks
  • Context Loading: Always use ["user", "project"] for team workflows
  • Error Handling: Always catch CLINotFoundError and CLIConnectionError
  • Hook Matchers: Use regex patterns or None for all tools
  • Tool Restrictions: Prefer allowed_tools over disallowed_tools for security
  • Agent Delegation: Use @agent-name syntax in prompts
  • Production: Always implement permission callbacks and logging hooks

See Also

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

uv-python-version-management

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-best-practices-fail-fast-imports

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-best-practices-async-context-manager

No summary provided by upstream source.

Repository SourceNeeds Review
agent-sdk-python | V50.AI