SpyBara
Go Premium

agent-sdk/python.md 2026-05-05 23:00 UTC to 2026-05-07 22:59 UTC

46 added, 7 removed.

2026
Sun 31 06:39 Sat 30 06:23 Fri 29 06:38 Thu 28 06:37 Wed 27 06:42 Tue 26 06:33 Sun 24 06:25 Sat 23 06:18 Fri 22 06:33 Thu 21 06:36 Wed 20 06:35 Tue 19 06:34 Mon 18 23:59 Sun 17 01:01 Fri 15 22:58 Thu 14 17:02 Wed 13 23:01 Tue 12 22:57 Mon 11 23:00 Sun 10 23:03 Sat 9 04:57 Fri 8 22:00 Thu 7 22:59 Tue 5 23:00 Mon 4 22:58 Sat 2 18:14 Fri 1 18:19

Referensi Agent SDK - Python

Referensi API lengkap untuk Python Agent SDK, termasuk semua fungsi, tipe, dan kelas.

Instalasi

pip install claude-agent-sdk

Memilih antara query() dan ClaudeSDKClient

Python SDK menyediakan dua cara untuk berinteraksi dengan Claude Code:

Perbandingan cepat

Fitur query() ClaudeSDKClient
Sesi Membuat sesi baru setiap kali Menggunakan kembali sesi yang sama
Percakapan Pertukaran tunggal Beberapa pertukaran dalam konteks yang sama
Koneksi Dikelola secara otomatis Kontrol manual
Streaming Input ✅ Didukung ✅ Didukung
Interrupts ❌ Tidak didukung ✅ Didukung
Hooks ✅ Didukung ✅ Didukung
Custom Tools ✅ Didukung ✅ Didukung
Continue Chat ❌ Sesi baru setiap kali ✅ Mempertahankan percakapan
Use Case Tugas sekali jalan Percakapan berkelanjutan

Kapan menggunakan query() (sesi baru setiap kali)

Terbaik untuk:

  • Pertanyaan sekali jalan di mana Anda tidak memerlukan riwayat percakapan
  • Tugas independen yang tidak memerlukan konteks dari pertukaran sebelumnya
  • Skrip otomasi sederhana
  • Ketika Anda menginginkan awal yang segar setiap kali

Kapan menggunakan ClaudeSDKClient (percakapan berkelanjutan)

Terbaik untuk:

  • Melanjutkan percakapan - Ketika Anda memerlukan Claude untuk mengingat konteks
  • Pertanyaan lanjutan - Membangun berdasarkan respons sebelumnya
  • Aplikasi interaktif - Antarmuka obrolan, REPL
  • Logika berbasis respons - Ketika tindakan berikutnya bergantung pada respons Claude
  • Kontrol sesi - Mengelola siklus hidup percakapan secara eksplisit

Fungsi

query()

Membuat sesi baru untuk setiap interaksi dengan Claude Code. Mengembalikan async iterator yang menghasilkan pesan saat tiba. Setiap panggilan ke query() dimulai segar tanpa memori interaksi sebelumnya.

async def query(
    *,
    prompt: str | AsyncIterable[dict[str, Any]],
    options: ClaudeAgentOptions | None = None,
    transport: Transport | None = None
) -> AsyncIterator[Message]

Parameter

Parameter Tipe Deskripsi
prompt str | AsyncIterable[dict] Prompt input sebagai string atau async iterable untuk mode streaming
options ClaudeAgentOptions | None Objek konfigurasi opsional (default ke ClaudeAgentOptions() jika None)
transport Transport | None Transport kustom opsional untuk berkomunikasi dengan proses CLI

Pengembalian

Mengembalikan AsyncIterator[Message] yang menghasilkan pesan dari percakapan.

Contoh - Dengan opsi

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions


async def main():
    options = ClaudeAgentOptions(
        system_prompt="You are an expert Python developer",
        permission_mode="acceptEdits",
        cwd="/home/user/project",
    )

    async for message in query(prompt="Create a Python web server", options=options):
        print(message)


asyncio.run(main())

tool()

Dekorator untuk mendefinisikan tools MCP dengan keamanan tipe.

def tool(
    name: str,
    description: str,
    input_schema: type | dict[str, Any],
    annotations: ToolAnnotations | None = None
) -> Callable[[Callable[[Any], Awaitable[dict[str, Any]]]], SdkMcpTool[Any]]

Parameter

Parameter Tipe Deskripsi
name str Pengenal unik untuk tool
description str Deskripsi yang dapat dibaca manusia tentang apa yang dilakukan tool
input_schema type | dict[str, Any] Skema yang mendefinisikan parameter input tool (lihat di bawah)
annotations ToolAnnotations | None Anotasi tool MCP opsional yang memberikan petunjuk perilaku kepada klien

Opsi skema input

  1. Pemetaan tipe sederhana (direkomendasikan):

    {"text": str, "count": int, "enabled": bool}
    
  2. Format JSON Schema (untuk validasi kompleks):

    {
        "type": "object",
        "properties": {
            "text": {"type": "string"},
            "count": {"type": "integer", "minimum": 0},
        },
        "required": ["text"],
    }
    

Pengembalian

Fungsi dekorator yang membungkus implementasi tool dan mengembalikan instance SdkMcpTool.

Contoh

from claude_agent_sdk import tool
from typing import Any


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

ToolAnnotations

Diimpor ulang dari mcp.types (juga tersedia sebagai from claude_agent_sdk import ToolAnnotations). Semua field adalah petunjuk opsional; klien tidak boleh mengandalkannya untuk keputusan keamanan.

Field Tipe Default Deskripsi
title str | None None Judul yang dapat dibaca manusia untuk tool
readOnlyHint bool | None False Jika True, tool tidak memodifikasi lingkungannya
destructiveHint bool | None True Jika True, tool dapat melakukan pembaruan destruktif (hanya bermakna ketika readOnlyHint adalah False)
idempotentHint bool | None False Jika True, panggilan berulang dengan argumen yang sama tidak memiliki efek tambahan (hanya bermakna ketika readOnlyHint adalah False)
openWorldHint bool | None True Jika True, tool berinteraksi dengan entitas eksternal (misalnya, pencarian web). Jika False, domain tool ditutup (misalnya, tool memori)
from claude_agent_sdk import tool, ToolAnnotations
from typing import Any


@tool(
    "search",
    "Search the web",
    {"query": str},
    annotations=ToolAnnotations(readOnlyHint=True, openWorldHint=True),
)
async def search(args: dict[str, Any]) -> dict[str, Any]:
    return {"content": [{"type": "text", "text": f"Results for: {args['query']}"}]}

create_sdk_mcp_server()

Buat server MCP dalam proses yang berjalan dalam aplikasi Python Anda.

def create_sdk_mcp_server(
    name: str,
    version: str = "1.0.0",
    tools: list[SdkMcpTool[Any]] | None = None
) -> McpSdkServerConfig

Parameter

Parameter Tipe Default Deskripsi
name str - Pengenal unik untuk server
version str "1.0.0" String versi server
tools list[SdkMcpTool[Any]] | None None Daftar fungsi tool yang dibuat dengan dekorator @tool

Pengembalian

Mengembalikan objek McpSdkServerConfig yang dapat diteruskan ke ClaudeAgentOptions.mcp_servers.

Contoh

from claude_agent_sdk import tool, create_sdk_mcp_server


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


@tool("multiply", "Multiply two numbers", {"a": float, "b": float})
async def multiply(args):
    return {"content": [{"type": "text", "text": f"Product: {args['a'] * args['b']}"}]}


calculator = create_sdk_mcp_server(
    name="calculator",
    version="2.0.0",
    tools=[add, multiply],  # Pass decorated functions
)

# Use with Claude
options = ClaudeAgentOptions(
    mcp_servers={"calc": calculator},
    allowed_tools=["mcp__calc__add", "mcp__calc__multiply"],
)

list_sessions()

Mencantumkan sesi masa lalu dengan metadata. Filter berdasarkan direktori proyek atau cantumkan sesi di semua proyek. Sinkron; mengembalikan segera.

def list_sessions(
    directory: str | None = None,
    limit: int | None = None,
    include_worktrees: bool = True
) -> list[SDKSessionInfo]

Parameter

Parameter Tipe Default Deskripsi
directory str | None None Direktori untuk mencantumkan sesi. Ketika dihilangkan, mengembalikan sesi di semua proyek
limit int | None None Jumlah maksimal sesi yang akan dikembalikan
include_worktrees bool True Ketika directory berada di dalam repositori git, sertakan sesi dari semua jalur worktree

Tipe pengembalian: SDKSessionInfo

Properti Tipe Deskripsi
session_id str Pengenal sesi unik
summary str Judul tampilan: judul kustom, ringkasan yang dihasilkan otomatis, atau prompt pertama
last_modified int Waktu modifikasi terakhir dalam milidetik sejak epoch
file_size int | None Ukuran file sesi dalam byte (None untuk backend penyimpanan jarak jauh)
custom_title str | None Judul sesi yang ditetapkan pengguna
first_prompt str | None Prompt pengguna bermakna pertama dalam sesi
git_branch str | None Cabang Git di akhir sesi
cwd str | None Direktori kerja untuk sesi
tag str | None Tag sesi yang ditetapkan pengguna (lihat tag_session())
created_at int | None Waktu pembuatan sesi dalam milidetik sejak epoch

Contoh

Cetak 10 sesi terbaru untuk proyek. Hasil diurutkan berdasarkan last_modified menurun, jadi item pertama adalah yang terbaru. Hilangkan directory untuk mencari di semua proyek.

from claude_agent_sdk import list_sessions

for session in list_sessions(directory="/path/to/project", limit=10):
    print(f"{session.summary} ({session.session_id})")

get_session_messages()

Mengambil pesan dari sesi masa lalu. Sinkron; mengembalikan segera.

def get_session_messages(
    session_id: str,
    directory: str | None = None,
    limit: int | None = None,
    offset: int = 0
) -> list[SessionMessage]

Parameter

Parameter Tipe Default Deskripsi
session_id str diperlukan ID sesi untuk mengambil pesan
directory str | None None Direktori proyek untuk dilihat. Ketika dihilangkan, mencari di semua proyek
limit int | None None Jumlah maksimal pesan yang akan dikembalikan
offset int 0 Jumlah pesan yang akan dilewati dari awal

Tipe pengembalian: SessionMessage

Properti Tipe Deskripsi
type Literal["user", "assistant"] Peran pesan
uuid str Pengenal pesan unik
session_id str Pengenal sesi
message Any Konten pesan mentah
parent_tool_use_id None Dicadangkan untuk penggunaan di masa depan

Contoh

from claude_agent_sdk import list_sessions, get_session_messages

sessions = list_sessions(limit=1)
if sessions:
    messages = get_session_messages(sessions[0].session_id)
    for msg in messages:
        print(f"[{msg.type}] {msg.uuid}")

get_session_info()

Membaca metadata untuk sesi tunggal berdasarkan ID tanpa memindai direktori proyek lengkap. Sinkron; mengembalikan segera.

def get_session_info(
    session_id: str,
    directory: str | None = None,
) -> SDKSessionInfo | None

Parameter

Parameter Tipe Default Deskripsi
session_id str diperlukan UUID sesi untuk dicari
directory str | None None Jalur direktori proyek. Ketika dihilangkan, mencari di semua direktori proyek

Mengembalikan SDKSessionInfo, atau None jika sesi tidak ditemukan.

Contoh

Cari metadata sesi tunggal tanpa memindai direktori proyek. Berguna ketika Anda sudah memiliki ID sesi dari run sebelumnya.

from claude_agent_sdk import get_session_info

info = get_session_info("550e8400-e29b-41d4-a716-446655440000")
if info:
    print(f"{info.summary} (branch: {info.git_branch}, tag: {info.tag})")

rename_session()

Mengganti nama sesi dengan menambahkan entri judul kustom. Panggilan berulang aman; judul terbaru menang. Sinkron.

def rename_session(
    session_id: str,
    title: str,
    directory: str | None = None,
) -> None

Parameter

Parameter Tipe Default Deskripsi
session_id str diperlukan UUID sesi untuk diganti nama
title str diperlukan Judul baru. Harus tidak kosong setelah menghapus spasi putih
directory str | None None Jalur direktori proyek. Ketika dihilangkan, mencari di semua direktori proyek

Menimbulkan ValueError jika session_id bukan UUID yang valid atau title kosong; FileNotFoundError jika sesi tidak dapat ditemukan.

Contoh

Ganti nama sesi terbaru sehingga lebih mudah ditemukan nanti. Judul baru muncul di SDKSessionInfo.custom_title pada pembacaan berikutnya.

from claude_agent_sdk import list_sessions, rename_session

sessions = list_sessions(directory="/path/to/project", limit=1)
if sessions:
    rename_session(sessions[0].session_id, "Refactor auth module")

tag_session()

Menandai sesi. Teruskan None untuk menghapus tag. Panggilan berulang aman; tag terbaru menang. Sinkron.

def tag_session(
    session_id: str,
    tag: str | None,
    directory: str | None = None,
) -> None

Parameter

Parameter Tipe Default Deskripsi
session_id str diperlukan UUID sesi untuk ditandai
tag str | None diperlukan String tag, atau None untuk menghapus. Disanitasi Unicode sebelum disimpan
directory str | None None Jalur direktori proyek. Ketika dihilangkan, mencari di semua direktori proyek

Menimbulkan ValueError jika session_id bukan UUID yang valid atau tag kosong setelah sanitasi; FileNotFoundError jika sesi tidak dapat ditemukan.

Contoh

Tandai sesi, kemudian filter berdasarkan tag itu pada pembacaan nanti. Teruskan None untuk menghapus tag yang ada.

from claude_agent_sdk import list_sessions, tag_session

# Tag a session
tag_session("550e8400-e29b-41d4-a716-446655440000", "needs-review")

# Later: find all sessions with that tag
for session in list_sessions(directory="/path/to/project"):
    if session.tag == "needs-review":
        print(session.summary)

Kelas

ClaudeSDKClient

Mempertahankan sesi percakapan di beberapa pertukaran. Ini adalah setara Python dari cara fungsi query() SDK TypeScript bekerja secara internal - ia membuat objek klien yang dapat melanjutkan percakapan.

Fitur Utama

  • Kontinuitas sesi: Mempertahankan konteks percakapan di beberapa panggilan query()
  • Percakapan yang sama: Sesi mempertahankan pesan sebelumnya
  • Dukungan interrupt: Dapat menghentikan eksekusi di tengah-tengah tugas
  • Siklus hidup eksplisit: Anda mengontrol kapan sesi dimulai dan berakhir
  • Alur berbasis respons: Dapat bereaksi terhadap respons dan mengirim tindak lanjut
  • Tools dan hooks kustom: Mendukung tools kustom (dibuat dengan dekorator @tool) dan hooks
class ClaudeSDKClient:
    def __init__(self, options: ClaudeAgentOptions | None = None, transport: Transport | None = None)
    async def connect(self, prompt: str | AsyncIterable[dict] | None = None) -> None
    async def query(self, prompt: str | AsyncIterable[dict], session_id: str = "default") -> None
    async def receive_messages(self) -> AsyncIterator[Message]
    async def receive_response(self) -> AsyncIterator[Message]
    async def interrupt(self) -> None
    async def set_permission_mode(self, mode: str) -> None
    async def set_model(self, model: str | None = None) -> None
    async def rewind_files(self, user_message_id: str) -> None
    async def get_mcp_status(self) -> McpStatusResponse
    async def reconnect_mcp_server(self, server_name: str) -> None
    async def toggle_mcp_server(self, server_name: str, enabled: bool) -> None
    async def stop_task(self, task_id: str) -> None
    async def get_server_info(self) -> dict[str, Any] | None
    async def disconnect(self) -> None

Metode

Metode Deskripsi
__init__(options) Inisialisasi klien dengan konfigurasi opsional
connect(prompt) Hubungkan ke Claude dengan prompt awal opsional atau aliran pesan
query(prompt, session_id) Kirim permintaan baru dalam mode streaming
receive_messages() Terima semua pesan dari Claude sebagai async iterator
receive_response() Terima pesan hingga dan termasuk ResultMessage
interrupt() Kirim sinyal interrupt (hanya bekerja dalam mode streaming)
set_permission_mode(mode) Ubah mode izin untuk sesi saat ini
set_model(model) Ubah model untuk sesi saat ini. Teruskan None untuk reset ke default
rewind_files(user_message_id) Pulihkan file ke keadaan mereka pada pesan pengguna yang ditentukan. Memerlukan enable_file_checkpointing=True. Lihat File checkpointing
get_mcp_status() Dapatkan status semua server MCP yang dikonfigurasi. Mengembalikan McpStatusResponse
reconnect_mcp_server(server_name) Coba lagi menghubungkan ke server MCP yang gagal atau terputus
toggle_mcp_server(server_name, enabled) Aktifkan atau nonaktifkan server MCP di tengah sesi. Menonaktifkan menghapus toolnya
stop_task(task_id) Hentikan tugas latar belakang yang sedang berjalan. TaskNotificationMessage dengan status "stopped" mengikuti dalam aliran pesan
get_server_info() Dapatkan informasi server termasuk ID sesi dan kemampuan
disconnect() Putuskan sambungan dari Claude

Dukungan Context Manager

Klien dapat digunakan sebagai async context manager untuk manajemen koneksi otomatis:

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

Penting: Saat mengulangi pesan, hindari menggunakan break untuk keluar lebih awal karena ini dapat menyebabkan masalah pembersihan asyncio. Sebaliknya, biarkan iterasi selesai secara alami atau gunakan flag untuk melacak kapan Anda menemukan apa yang Anda butuhkan.

Contoh - Melanjutkan percakapan

import asyncio
from claude_agent_sdk import ClaudeSDKClient, AssistantMessage, TextBlock, ResultMessage


async def main():
    async with ClaudeSDKClient() as client:
        # First question
        await client.query("What's the capital of France?")

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

        # Follow-up question - the session retains the previous context
        await client.query("What's the population of that city?")

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

        # Another follow-up - still in the same conversation
        await client.query("What are some famous landmarks there?")

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


asyncio.run(main())

Contoh - Streaming input dengan ClaudeSDKClient

import asyncio
from claude_agent_sdk import ClaudeSDKClient


async def message_stream():
    """Generate messages dynamically."""
    yield {
        "type": "user",
        "message": {"role": "user", "content": "Analyze the following data:"},
    }
    await asyncio.sleep(0.5)
    yield {
        "type": "user",
        "message": {"role": "user", "content": "Temperature: 25°C, Humidity: 60%"},
    }
    await asyncio.sleep(0.5)
    yield {
        "type": "user",
        "message": {"role": "user", "content": "What patterns do you see?"},
    }


async def main():
    async with ClaudeSDKClient() as client:
        # Stream input to Claude
        await client.query(message_stream())

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

        # Follow-up in same session
        await client.query("Should we be concerned about these readings?")

        async for message in client.receive_response():
            print(message)


asyncio.run(main())

Contoh - Menggunakan interrupts

import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, ResultMessage


async def interruptible_task():
    options = ClaudeAgentOptions(allowed_tools=["Bash"], permission_mode="acceptEdits")

    async with ClaudeSDKClient(options=options) as client:
        # Start a long-running task
        await client.query("Count from 1 to 100 slowly, using the bash sleep command")

        # Let it run for a bit
        await asyncio.sleep(2)

        # Interrupt the task
        await client.interrupt()
        print("Task interrupted!")

        # Drain the interrupted task's messages (including its ResultMessage)
        async for message in client.receive_response():
            if isinstance(message, ResultMessage):
                print(f"Interrupted task finished with subtype={message.subtype!r}")
                # subtype is "error_during_execution" for interrupted tasks

        # Send a new command
        await client.query("Just say hello instead")

        # Now receive the new response
        async for message in client.receive_response():
            if isinstance(message, ResultMessage) and message.subtype == "success":
                print(f"New result: {message.result}")


asyncio.run(interruptible_task())

Contoh - Kontrol izin lanjutan

from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
from claude_agent_sdk.types import (
    PermissionResultAllow,
    PermissionResultDeny,
    ToolPermissionContext,
)


async def custom_permission_handler(
    tool_name: str, input_data: dict, context: ToolPermissionContext
) -> PermissionResultAllow | PermissionResultDeny:
    """Custom logic for tool permissions."""

    # Block writes to system directories
    if tool_name == "Write" and input_data.get("file_path", "").startswith("/system/"):
        return PermissionResultDeny(
            message="System directory write not allowed", interrupt=True
        )

    # Redirect sensitive file operations
    if tool_name in ["Write", "Edit"] and "config" in input_data.get("file_path", ""):
        safe_path = f"./sandbox/{input_data['file_path']}"
        return PermissionResultAllow(
            updated_input={**input_data, "file_path": safe_path}
        )

    # Allow everything else
    return PermissionResultAllow(updated_input=input_data)


async def main():
    options = ClaudeAgentOptions(
        can_use_tool=custom_permission_handler, allowed_tools=["Read", "Write", "Edit"]
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query("Update the system config file")

        async for message in client.receive_response():
            # Will use sandbox path instead
            print(message)


asyncio.run(main())

Tipe

SdkMcpTool

Definisi untuk tool SDK MCP yang dibuat dengan dekorator @tool.

@dataclass
class SdkMcpTool(Generic[T]):
    name: str
    description: str
    input_schema: type[T] | dict[str, Any]
    handler: Callable[[T], Awaitable[dict[str, Any]]]
    annotations: ToolAnnotations | None = None
Properti Tipe Deskripsi
name str Pengenal unik untuk tool
description str Deskripsi yang dapat dibaca manusia
input_schema type[T] | dict[str, Any] Skema untuk validasi input
handler Callable[[T], Awaitable[dict[str, Any]]] Fungsi async yang menangani eksekusi tool
annotations ToolAnnotations | None Anotasi tool MCP opsional (misalnya, readOnlyHint, destructiveHint, openWorldHint). Dari mcp.types

Transport

Kelas dasar abstrak untuk implementasi transport kustom. Gunakan ini untuk berkomunikasi dengan proses Claude melalui saluran kustom (misalnya, koneksi jarak jauh alih-alih subprocess lokal).

from abc import ABC, abstractmethod
from collections.abc import AsyncIterator
from typing import Any


class Transport(ABC):
    @abstractmethod
    async def connect(self) -> None: ...

    @abstractmethod
    async def write(self, data: str) -> None: ...

    @abstractmethod
    def read_messages(self) -> AsyncIterator[dict[str, Any]]: ...

    @abstractmethod
    async def close(self) -> None: ...

    @abstractmethod
    def is_ready(self) -> bool: ...

    @abstractmethod
    async def end_input(self) -> None: ...
Metode Deskripsi
connect() Hubungkan transport dan siapkan untuk komunikasi
write(data) Tulis data mentah (JSON + newline) ke transport
read_messages() Async iterator yang menghasilkan pesan JSON yang diuraikan
close() Tutup koneksi dan bersihkan sumber daya
is_ready() Mengembalikan True jika transport dapat mengirim dan menerima
end_input() Tutup aliran input (misalnya, tutup stdin untuk transport subprocess)

Impor: from claude_agent_sdk import Transport

ClaudeAgentOptions

Dataclass konfigurasi untuk query Claude Code.

@dataclass
class ClaudeAgentOptions:
    tools: list[str] | ToolsPreset | None = None
    allowed_tools: list[str] = field(default_factory=list)
    system_prompt: str | SystemPromptPreset | None = None
    mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
    strict_mcp_config: bool = False
    permission_mode: PermissionMode | None = None
    continue_conversation: bool = False
    resume: str | None = None
    max_turns: int | None = None
    max_budget_usd: float | None = None
    disallowed_tools: list[str] = field(default_factory=list)
    model: str | None = None
    fallback_model: str | None = None
    betas: list[SdkBeta] = field(default_factory=list)
    output_format: dict[str, Any] | None = None
    permission_prompt_tool_name: str | None = None
    cwd: str | Path | None = None
    cli_path: str | Path | None = None
    settings: str | None = None
    add_dirs: list[str | Path] = field(default_factory=list)
    env: dict[str, str] = field(default_factory=dict)
    extra_args: dict[str, str | None] = field(default_factory=dict)
    max_buffer_size: int | None = None
    debug_stderr: Any = sys.stderr  # Deprecated
    stderr: Callable[[str], None] | None = None
    can_use_tool: CanUseTool | None = None
    hooks: dict[HookEvent, list[HookMatcher]] | None = None
    user: str | None = None
    include_partial_messages: bool = False
    include_hook_events: bool = False
    fork_session: bool = False
    agents: dict[str, AgentDefinition] | None = None
    setting_sources: list[SettingSource] | None = None
    sandbox: SandboxSettings | None = None
    plugins: list[SdkPluginConfig] = field(default_factory=list)
    max_thinking_tokens: int | None = None  # Deprecated: use thinking instead
    thinking: ThinkingConfig | None = None
    effort: Literal["low", "medium", "high", "xhigh", "max"] | None = None
    enable_file_checkpointing: bool = False
    session_store: SessionStore | None = None
    session_store_flush: SessionStoreFlushMode = "batched"
Properti Tipe Default Deskripsi
tools list[str] | ToolsPreset | None None Konfigurasi tools. Gunakan {"type": "preset", "preset": "claude_code"} untuk tools default Claude Code
allowed_tools list[str] [] Tools untuk auto-approve tanpa prompt. Ini tidak membatasi Claude hanya pada tools ini; tools yang tidak terdaftar jatuh ke permission_mode dan can_use_tool. Gunakan disallowed_tools untuk memblokir tools. Lihat Permissions
system_prompt str | SystemPromptPreset | None None Konfigurasi system prompt. Teruskan string untuk prompt kustom, atau gunakan {"type": "preset", "preset": "claude_code"} untuk system prompt Claude Code. Tambahkan "append" untuk memperluas preset
mcp_servers dict[str, McpServerConfig] | str | Path {} Konfigurasi server MCP atau jalur ke file konfigurasi
strict_mcp_config bool False Ketika True, gunakan hanya server yang diteruskan dalam mcp_servers dan abaikan .mcp.json proyek, pengaturan pengguna, dan server MCP yang disediakan plugin. Memetakan ke flag CLI --strict-mcp-config
permission_mode PermissionMode | None None Mode izin untuk penggunaan tool
continue_conversation bool False Lanjutkan percakapan terbaru
resume str | None None ID sesi untuk dilanjutkan
max_turns int | None None Jumlah maksimal putaran agentic (round trip penggunaan tool)
max_budget_usd float | None None Hentikan query ketika estimasi biaya sisi klien mencapai nilai USD ini. Dibandingkan dengan estimasi yang sama seperti total_cost_usd; lihat Track cost and usage untuk peringatan akurasi
disallowed_tools list[str] [] Tools untuk selalu ditolak. Aturan penolakan diperiksa terlebih dahulu dan mengganti allowed_tools dan permission_mode (termasuk bypassPermissions)
enable_file_checkpointing bool False Aktifkan pelacakan perubahan file untuk rewinding. Lihat File checkpointing
model str | None None Model Claude yang akan digunakan
fallback_model str | None None Model fallback yang akan digunakan jika model utama gagal
betas list[SdkBeta] [] Fitur beta untuk diaktifkan. Lihat SdkBeta untuk opsi yang tersedia
output_format dict[str, Any] | None None Format output untuk respons terstruktur (misalnya, {"type": "json_schema", "schema": {...}}). Lihat Structured outputs untuk detail
permission_prompt_tool_name str | None None Nama tool MCP untuk prompt izin
cwd str | Path | None None Direktori kerja saat ini
cli_path str | Path | None None Jalur kustom ke executable CLI Claude Code
settings str | None None Jalur ke file pengaturan
add_dirs list[str | Path] [] Direktori tambahan yang dapat diakses Claude
env dict[str, str] {} Variabel lingkungan yang digabungkan di atas lingkungan proses yang diwarisi. Lihat Environment variables untuk variabel yang dibaca CLI yang mendasar, dan Handle slow or stalled API responses untuk variabel terkait timeout
extra_args dict[str, str | None] {} Argumen CLI tambahan untuk diteruskan langsung ke CLI
max_buffer_size int | None None Byte maksimal saat membuffer stdout CLI
debug_stderr Any sys.stderr Deprecated - Objek seperti file untuk output debug. Gunakan callback stderr sebagai gantinya
stderr Callable[[str], None] | None None Fungsi callback untuk output stderr dari CLI
can_use_tool CanUseTool | None None Fungsi callback izin tool. Lihat Permission types untuk detail
hooks dict[HookEvent, list[HookMatcher]] | None None Konfigurasi hook untuk mengintersepsi event
user str | None None Pengenal pengguna
include_partial_messages bool False Sertakan event streaming pesan parsial. Ketika diaktifkan, pesan StreamEvent dihasilkan
include_hook_events bool False Sertakan event lifecycle hook dalam aliran pesan sebagai objek HookEventMessage
fork_session bool False Ketika melanjutkan dengan resume, fork ke ID sesi baru alih-alih melanjutkan sesi asli
agents dict[str, AgentDefinition] | None None Subagent yang didefinisikan secara programatis
plugins list[SdkPluginConfig] [] Muat plugin kustom dari jalur lokal. Lihat Plugins untuk detail
sandbox SandboxSettings | None None Konfigurasi perilaku sandbox secara programatis. Lihat Sandbox settings untuk detail
setting_sources list[SettingSource] | None None (CLI defaults: all sources) Kontrol pengaturan filesystem mana yang akan dimuat. Teruskan [] untuk menonaktifkan pengaturan pengguna, proyek, dan lokal. Pengaturan kebijakan terkelola dimuat terlepas dari itu. Lihat Use Claude Code features
max_thinking_tokens int | None None Deprecated - Token maksimal untuk blok thinking. Gunakan thinking sebagai gantinya
thinking ThinkingConfig | None None Mengontrol perilaku extended thinking. Mengambil prioritas atas max_thinking_tokens
effort Literal["low", "medium", "high", "xhigh", "max"] | None None Tingkat usaha untuk kedalaman thinking
session_store SessionStore | None None Cerminkan transkrip sesi ke backend eksternal sehingga host apa pun dapat melanjutkannya. Lihat Persist sessions to external storage
session_store_flush Literal["batched", "eager"] "batched" Kapan membuang entri transkrip yang dicerminkan ke session_store. "batched" membuang sekali per putaran atau ketika buffer penuh; "eager" memicu pembilasan latar belakang setelah setiap frame. Diabaikan ketika session_store adalah None

Menangani respons API yang lambat atau terhenti

Subprocess CLI membaca beberapa variabel lingkungan yang mengontrol timeout API dan deteksi stall. Teruskan melalui ClaudeAgentOptions.env:

options = ClaudeAgentOptions(
    env={
        "API_TIMEOUT_MS": "120000",
        "CLAUDE_CODE_MAX_RETRIES": "2",
        "CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS": "120000",
    },
)
  • API_TIMEOUT_MS: timeout per-permintaan pada klien Anthropic, dalam milidetik. Default 600000. Berlaku untuk loop utama dan semua subagent.
  • CLAUDE_CODE_MAX_RETRIES: maksimal retry API. Default 10. Setiap retry mendapat jendela API_TIMEOUT_MS sendiri, jadi waktu dinding terburuk kira-kira API_TIMEOUT_MS × (CLAUDE_CODE_MAX_RETRIES + 1) ditambah backoff.
  • CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS: watchdog stall untuk subagent yang diluncurkan dengan run_in_background. Default 600000. Direset pada setiap event stream; pada stall itu membatalkan subagent, menandai tugas gagal, dan menampilkan error ke parent dengan hasil parsial apa pun. Tidak berlaku untuk subagent sinkron.
  • CLAUDE_ENABLE_STREAM_WATCHDOG=1 dengan CLAUDE_STREAM_IDLE_TIMEOUT_MS: membatalkan permintaan ketika header telah tiba tetapi badan respons berhenti streaming. Dimatikan secara default. CLAUDE_STREAM_IDLE_TIMEOUT_MS default ke 300000 dan diklem ke minimum itu. Permintaan yang dibatalkan melalui jalur retry normal.

OutputFormat

Konfigurasi untuk validasi output terstruktur. Teruskan ini sebagai dict ke field output_format pada ClaudeAgentOptions:

# Expected dict shape for output_format
{
    "type": "json_schema",
    "schema": {...},  # Your JSON Schema definition
}
Field Diperlukan Deskripsi
type Ya Harus "json_schema" untuk validasi JSON Schema
schema Ya Definisi JSON Schema untuk validasi output

SystemPromptPreset

Konfigurasi untuk menggunakan preset system prompt Claude Code dengan penambahan opsional.

class SystemPromptPreset(TypedDict):
    type: Literal["preset"]
    preset: Literal["claude_code"]
    append: NotRequired[str]
    exclude_dynamic_sections: NotRequired[bool]
Field Diperlukan Deskripsi
type Ya Harus "preset" untuk menggunakan preset system prompt
preset Ya Harus "claude_code" untuk menggunakan system prompt Claude Code
append Tidak Instruksi tambahan untuk ditambahkan ke preset system prompt
exclude_dynamic_sections Tidak Pindahkan konteks per-sesi seperti direktori kerja, status git, dan jalur memori dari system prompt ke pesan pengguna pertama. Meningkatkan reuse prompt-cache di seluruh pengguna dan mesin. Lihat Modify system prompts

SettingSource

Mengontrol sumber konfigurasi berbasis filesystem mana yang dimuat pengaturan SDK.

SettingSource = Literal["user", "project", "local"]
Nilai Deskripsi Lokasi
"user" Pengaturan pengguna global ~/.claude/settings.json
"project" Pengaturan proyek bersama (version controlled) .claude/settings.json
"local" Pengaturan proyek lokal (gitignored) .claude/settings.local.json

Perilaku default

Ketika setting_sources dihilangkan atau None, query() memuat pengaturan filesystem yang sama seperti CLI Claude Code: pengguna, proyek, dan lokal. Pengaturan kebijakan terkelola dimuat dalam semua kasus. Lihat What settingSources does not control untuk input yang dibaca terlepas dari opsi ini, dan cara menonaktifkannya.

Mengapa menggunakan setting_sources

Nonaktifkan pengaturan filesystem:

# Do not load user, project, or local settings from disk
from claude_agent_sdk import query, ClaudeAgentOptions

async for message in query(
    prompt="Analyze this code",
    options=ClaudeAgentOptions(
        setting_sources=[]
    ),
):
    print(message)

Muat semua pengaturan filesystem secara eksplisit:

from claude_agent_sdk import query, ClaudeAgentOptions

async for message in query(
    prompt="Analyze this code",
    options=ClaudeAgentOptions(
        setting_sources=["user", "project", "local"]
    ),
):
    print(message)

Muat hanya sumber pengaturan tertentu:

# Load only project settings, ignore user and local
async for message in query(
    prompt="Run CI checks",
    options=ClaudeAgentOptions(
        setting_sources=["project"]  # Only .claude/settings.json
    ),
):
    print(message)

Lingkungan testing dan CI:

# Ensure consistent behavior in CI by excluding local settings
async for message in query(
    prompt="Run tests",
    options=ClaudeAgentOptions(
        setting_sources=["project"],  # Only team-shared settings
        permission_mode="bypassPermissions",
    ),
):
    print(message)

Aplikasi SDK-only:

# Define everything programmatically.
# Pass [] to opt out of filesystem setting sources.
async for message in query(
    prompt="Review this PR",
    options=ClaudeAgentOptions(
        setting_sources=[],
        agents={...},
        mcp_servers={...},
        allowed_tools=["Read", "Grep", "Glob"],
    ),
):
    print(message)

Memuat instruksi proyek CLAUDE.md:

# Load project settings to include CLAUDE.md files
async for message in query(
    prompt="Add a new feature following project conventions",
    options=ClaudeAgentOptions(
        system_prompt={
            "type": "preset",
            "preset": "claude_code",  # Use Claude Code's system prompt
        },
        setting_sources=["project"],  # Loads CLAUDE.md from project
        allowed_tools=["Read", "Write", "Edit"],
    ),
):
    print(message)

Preseden pengaturan

Ketika beberapa sumber dimuat, pengaturan digabungkan dengan preseden ini (tertinggi ke terendah):

  1. Pengaturan lokal (.claude/settings.local.json)
  2. Pengaturan proyek (.claude/settings.json)
  3. Pengaturan pengguna (~/.claude/settings.json)

Opsi programatis seperti agents dan allowed_tools mengganti pengaturan filesystem pengguna, proyek, dan lokal. Pengaturan kebijakan terkelola mengambil prioritas atas opsi programatis.

AgentDefinition

Konfigurasi untuk subagent yang didefinisikan secara programatis.

@dataclass
class AgentDefinition:
    description: str
    prompt: str
    tools: list[str] | None = None
    disallowedTools: list[str] | None = None
    model: str | None = None
    skills: list[str] | None = None
    memory: Literal["user", "project", "local"] | None = None
    mcpServers: list[str | dict[str, Any]] | None = None
    initialPrompt: str | None = None
    maxTurns: int | None = None
    background: bool | None = None
    effort: Literal["low", "medium", "high", "xhigh", "max"] | int | None = None
    permissionMode: PermissionMode | None = None
Field Diperlukan Deskripsi
description Ya Deskripsi bahasa alami tentang kapan menggunakan agent ini
prompt Ya System prompt agent
tools Tidak Array nama tool yang diizinkan. Jika dihilangkan, mewarisi semua tools
disallowedTools Tidak Array nama tool untuk dihapus dari set tool agent
model Tidak Penggantian model untuk agent ini. Menerima alias seperti "sonnet", "opus", "haiku", atau "inherit", atau ID model lengkap. Jika dihilangkan, menggunakan model utama
skills Tidak Daftar nama skill yang tersedia untuk agent ini
memory Tidak Sumber memori untuk agent ini: "user", "project", atau "local"
mcpServers Tidak Server MCP yang tersedia untuk agent ini. Setiap entri adalah nama server atau dict {name: config} inline
initialPrompt Tidak Auto-submitted sebagai putaran pengguna pertama ketika agent ini berjalan sebagai agent thread utama
maxTurns Tidak Jumlah maksimal putaran agentic sebelum agent berhenti
background Tidak Jalankan agent ini sebagai tugas latar belakang non-blocking ketika dipanggil
effort Tidak Tingkat usaha reasoning untuk agent ini. Menerima tingkat bernama atau integer
permissionMode Tidak Mode izin untuk eksekusi tool dalam agent ini. Lihat PermissionMode

PermissionMode

Mode izin untuk mengontrol eksekusi tool.

PermissionMode = Literal[
    "default",  # Standard permission behavior
    "acceptEdits",  # Auto-accept file edits
    "plan",  # Planning mode - read-only tools only
    "dontAsk",  # Deny anything not pre-approved instead of prompting
    "bypassPermissions",  # Bypass all permission checks (use with caution)
]

CanUseTool

Type alias untuk fungsi callback izin tool.

CanUseTool = Callable[
    [str, dict[str, Any], ToolPermissionContext], Awaitable[PermissionResult]
]

Callback menerima:

  • tool_name: Nama tool yang sedang dipanggil
  • input_data: Parameter input tool
  • context: ToolPermissionContext dengan informasi tambahan

Mengembalikan PermissionResult (baik PermissionResultAllow atau PermissionResultDeny).

ToolPermissionContext

Informasi konteks yang diteruskan ke callback izin tool.

@dataclass
class ToolPermissionContext:
    signal: Any | None = None  # Future: abort signal support
    suggestions: list[PermissionUpdate] = field(default_factory=list)
    blocked_path: str | None = None
    decision_reason: str | None = None
    title: str | None = None
    display_name: str | None = None
    description: str | None = None
Field Tipe Deskripsi
signal Any | None Dicadangkan untuk dukungan sinyal abort di masa depan
suggestions list[PermissionUpdate] Saran pembaruan izin dari CLI. Prompt Bash menyertakan saran dengan destinasi localSettings, jadi mengembalikannya dalam updated_permissions menulis aturan ke .claude/settings.local.json dan bertahan di seluruh sesi.
blocked_path str | None Jalur file yang memicu permintaan izin, jika berlaku. Misalnya, ketika perintah Bash mencoba mengakses jalur di luar direktori yang diizinkan
decision_reason str | None Alasan permintaan izin ini dipicu. Diteruskan dari permissionDecisionReason hook PreToolUse ketika hook mengembalikan "ask"
title str | None Kalimat prompt izin lengkap, seperti Claude wants to read foo.txt. Gunakan sebagai teks prompt utama ketika ada
display_name str | None Frasa kata benda pendek untuk aksi tool, seperti Read file, cocok untuk label tombol
description str | None Subtitle yang dapat dibaca manusia untuk UI izin

PermissionResult

Tipe union untuk hasil callback izin.

PermissionResult = PermissionResultAllow | PermissionResultDeny

PermissionResultAllow

Hasil yang menunjukkan panggilan tool harus diizinkan.

@dataclass
class PermissionResultAllow:
    behavior: Literal["allow"] = "allow"
    updated_input: dict[str, Any] | None = None
    updated_permissions: list[PermissionUpdate] | None = None
Field Tipe Default Deskripsi
behavior Literal["allow"] "allow" Harus "allow"
updated_input dict[str, Any] | None None Input yang dimodifikasi untuk digunakan alih-alih asli
updated_permissions list[PermissionUpdate] | None None Pembaruan izin untuk diterapkan

PermissionResultDeny

Hasil yang menunjukkan panggilan tool harus ditolak.

@dataclass
class PermissionResultDeny:
    behavior: Literal["deny"] = "deny"
    message: str = ""
    interrupt: bool = False
Field Tipe Default Deskripsi
behavior Literal["deny"] "deny" Harus "deny"
message str "" Pesan yang menjelaskan mengapa tool ditolak
interrupt bool False Apakah akan mengganggu eksekusi saat ini

PermissionUpdate

Konfigurasi untuk memperbarui izin secara programatis.

@dataclass
class PermissionUpdate:
    type: Literal[
        "addRules",
        "replaceRules",
        "removeRules",
        "setMode",
        "addDirectories",
        "removeDirectories",
    ]
    rules: list[PermissionRuleValue] | None = None
    behavior: Literal["allow", "deny", "ask"] | None = None
    mode: PermissionMode | None = None
    directories: list[str] | None = None
    destination: (
        Literal["userSettings", "projectSettings", "localSettings", "session"] | None
    ) = None
Field Tipe Deskripsi
type Literal[...] Jenis operasi pembaruan izin
rules list[PermissionRuleValue] | None Aturan untuk operasi add/replace/remove
behavior Literal["allow", "deny", "ask"] | None Perilaku untuk operasi berbasis aturan
mode PermissionMode | None Mode untuk operasi setMode
directories list[str] | None Direktori untuk operasi add/remove direktori
destination Literal[...] | None Di mana menerapkan pembaruan izin

PermissionRuleValue

Aturan untuk ditambahkan, diganti, atau dihapus dalam pembaruan izin.

@dataclass
class PermissionRuleValue:
    tool_name: str
    rule_content: str | None = None

ToolsPreset

Konfigurasi preset tools untuk menggunakan set tool default Claude Code.

class ToolsPreset(TypedDict):
    type: Literal["preset"]
    preset: Literal["claude_code"]

ThinkingConfig

Mengontrol perilaku extended thinking. Union dari tiga konfigurasi:

class ThinkingConfigAdaptive(TypedDict):
    type: Literal["adaptive"]


class ThinkingConfigEnabled(TypedDict):
    type: Literal["enabled"]
    budget_tokens: int


class ThinkingConfigDisabled(TypedDict):
    type: Literal["disabled"]


ThinkingConfig = ThinkingConfigAdaptive | ThinkingConfigEnabled | ThinkingConfigDisabled
Varian Field Deskripsi
adaptive type Claude secara adaptif memutuskan kapan harus berpikir
enabled type, budget_tokens Aktifkan thinking dengan budget token tertentu
disabled type Nonaktifkan thinking

Karena ini adalah kelas TypedDict, mereka adalah dict biasa saat runtime. Baik buatlah sebagai dict literal atau panggil kelas seperti konstruktor; keduanya menghasilkan dict. Akses field dengan config["budget_tokens"], bukan config.budget_tokens:

from claude_agent_sdk import ClaudeAgentOptions, ThinkingConfigEnabled

# Option 1: dict literal (recommended, no import needed)
options = ClaudeAgentOptions(thinking={"type": "enabled", "budget_tokens": 20000})

# Option 2: constructor-style (returns a plain dict)
config = ThinkingConfigEnabled(type="enabled", budget_tokens=20000)
print(config["budget_tokens"])  # 20000
# config.budget_tokens would raise AttributeError

SdkBeta

Tipe literal untuk fitur beta SDK.

SdkBeta = Literal["context-1m-2025-08-07"]

Gunakan dengan field betas dalam ClaudeAgentOptions untuk mengaktifkan fitur beta.

McpSdkServerConfig

Konfigurasi untuk server MCP SDK yang dibuat dengan create_sdk_mcp_server().

class McpSdkServerConfig(TypedDict):
    type: Literal["sdk"]
    name: str
    instance: Any  # MCP Server instance

McpServerConfig

Tipe union untuk konfigurasi server MCP.

McpServerConfig = (
    McpStdioServerConfig | McpSSEServerConfig | McpHttpServerConfig | McpSdkServerConfig
)

McpStdioServerConfig

class McpStdioServerConfig(TypedDict):
    type: NotRequired[Literal["stdio"]]  # Optional for backwards compatibility
    command: str
    args: NotRequired[list[str]]
    env: NotRequired[dict[str, str]]

McpSSEServerConfig

class McpSSEServerConfig(TypedDict):
    type: Literal["sse"]
    url: str
    headers: NotRequired[dict[str, str]]

McpHttpServerConfig

class McpHttpServerConfig(TypedDict):
    type: Literal["http"]
    url: str
    headers: NotRequired[dict[str, str]]

McpServerStatusConfig

Konfigurasi server MCP seperti yang dilaporkan oleh get_mcp_status(). Ini adalah union dari semua varian transport McpServerConfig ditambah varian output-only claudeai-proxy untuk server yang di-proxy melalui claude.ai.

McpServerStatusConfig = (
    McpStdioServerConfig
    | McpSSEServerConfig
    | McpHttpServerConfig
    | McpSdkServerConfigStatus
    | McpClaudeAIProxyServerConfig
)

McpSdkServerConfigStatus adalah bentuk yang dapat diserialisasi dari McpSdkServerConfig dengan hanya field type ("sdk") dan name (str); instance dalam proses dihilangkan. McpClaudeAIProxyServerConfig memiliki field type ("claudeai-proxy"), url (str), dan id (str).

McpStatusResponse

Respons dari ClaudeSDKClient.get_mcp_status(). Membungkus daftar status server di bawah kunci mcpServers.

class McpStatusResponse(TypedDict):
    mcpServers: list[McpServerStatus]

McpServerStatus

Status server MCP yang terhubung, terdapat dalam McpStatusResponse.

class McpServerStatus(TypedDict):
    name: str
    status: McpServerConnectionStatus  # "connected" | "failed" | "needs-auth" | "pending" | "disabled"
    serverInfo: NotRequired[McpServerInfo]
    error: NotRequired[str]
    config: NotRequired[McpServerStatusConfig]
    scope: NotRequired[str]
    tools: NotRequired[list[McpToolInfo]]
Field Tipe Deskripsi
name str Nama server
status str Salah satu dari "connected", "failed", "needs-auth", "pending", atau "disabled"
serverInfo dict (opsional) Nama dan versi server ({"name": str, "version": str})
error str (opsional) Pesan error jika server gagal terhubung
config McpServerStatusConfig (opsional) Konfigurasi server. Bentuk yang sama seperti McpServerConfig (stdio, SSE, HTTP, atau SDK), ditambah varian claudeai-proxy untuk server yang terhubung melalui claude.ai
scope str (opsional) Scope konfigurasi
tools list (opsional) Tools yang disediakan oleh server ini, masing-masing dengan field name, description, dan annotations

SdkPluginConfig

Konfigurasi untuk memuat plugins dalam SDK.

class SdkPluginConfig(TypedDict):
    type: Literal["local"]
    path: str
Field Tipe Deskripsi
type Literal["local"] Harus "local" (hanya plugins lokal yang saat ini didukung)
path str Jalur absolut atau relatif ke direktori plugin

Contoh:

plugins = [
    {"type": "local", "path": "./my-plugin"},
    {"type": "local", "path": "/absolute/path/to/plugin"},
]

Untuk informasi lengkap tentang membuat dan menggunakan plugins, lihat Plugins.

Tipe Pesan

Message

Tipe union dari semua pesan yang mungkin.

Message = (
    UserMessage
    | AssistantMessage
    | SystemMessage
    | ResultMessage
    | StreamEvent
    | RateLimitEvent
)

UserMessage

Pesan input pengguna.

@dataclass
class UserMessage:
    content: str | list[ContentBlock]
    uuid: str | None = None
    parent_tool_use_id: str | None = None
    tool_use_result: dict[str, Any] | None = None
Field Tipe Deskripsi
content str | list[ContentBlock] Konten pesan sebagai teks atau blok konten
uuid str | None Pengenal pesan unik
parent_tool_use_id str | None ID penggunaan tool jika pesan ini adalah respons hasil tool
tool_use_result dict[str, Any] | None Data hasil tool jika berlaku

AssistantMessage

Pesan respons asisten dengan blok konten.

@dataclass
class AssistantMessage:
    content: list[ContentBlock]
    model: str
    parent_tool_use_id: str | None = None
    error: AssistantMessageError | None = None
    usage: dict[str, Any] | None = None
    message_id: str | None = None
Field Tipe Deskripsi
content list[ContentBlock] Daftar blok konten dalam respons
model str Model yang menghasilkan respons
parent_tool_use_id str | None ID penggunaan tool jika ini adalah respons bersarang
error AssistantMessageError | None Tipe error jika respons mengalami error
usage dict[str, Any] | None Penggunaan token per-pesan (kunci yang sama seperti ResultMessage.usage)
message_id str | None ID pesan API. Beberapa pesan dari satu putaran berbagi ID yang sama

AssistantMessageError

Tipe error yang mungkin untuk pesan asisten.

AssistantMessageError = Literal[
    "authentication_failed",
    "billing_error",
    "rate_limit",
    "invalid_request",
    "server_error",
    "max_output_tokens",
    "unknown",
]

SystemMessage

Pesan sistem dengan metadata.

@dataclass
class SystemMessage:
    subtype: str
    data: dict[str, Any]

ResultMessage

Pesan hasil akhir dengan informasi biaya dan penggunaan.

@dataclass
class ResultMessage:
    subtype: str
    duration_ms: int
    duration_api_ms: int
    is_error: bool
    num_turns: int
    session_id: str
    stop_reason: str | None = None
    total_cost_usd: float | None = None
    usage: dict[str, Any] | None = None
    result: str | None = None
    structured_output: Any = None
    model_usage: dict[str, Any] | None = None
    permission_denials: list[Any] | None = None
    deferred_tool_use: DeferredToolUse | None = None
    errors: list[str] | None = None
    api_error_status: int | None = None
    uuid: str | None = None

Dict usage berisi kunci berikut ketika ada:

Kunci Tipe Deskripsi
input_tokens int Total token input yang dikonsumsi.
output_tokens int Total token output yang dihasilkan.
cache_creation_input_tokens int Token yang digunakan untuk membuat entri cache baru.
cache_read_input_tokens int Token yang dibaca dari entri cache yang ada.

Dict model_usage memetakan nama model ke penggunaan per-model. Kunci dict dalam menggunakan camelCase karena nilai diteruskan tanpa modifikasi dari proses CLI yang mendasar, cocok dengan tipe ModelUsage TypeScript:

Kunci Tipe Deskripsi
inputTokens int Token input untuk model ini.
outputTokens int Token output untuk model ini.
cacheReadInputTokens int Token baca cache untuk model ini.
cacheCreationInputTokens int Token pembuatan cache untuk model ini.
webSearchRequests int Permintaan pencarian web yang dibuat oleh model ini.
costUSD float Biaya yang diperkirakan dalam USD untuk model ini, dihitung sisi klien. Lihat Track cost and usage untuk peringatan penagihan.
contextWindow int Ukuran jendela konteks untuk model ini.
maxOutputTokens int Batas token output maksimal untuk model ini.

StreamEvent

Event stream untuk pembaruan pesan parsial selama streaming. Hanya diterima ketika include_partial_messages=True dalam ClaudeAgentOptions. Impor via from claude_agent_sdk.types import StreamEvent.

@dataclass
class StreamEvent:
    uuid: str
    session_id: str
    event: dict[str, Any]  # The raw Claude API stream event
    parent_tool_use_id: str | None = None
Field Tipe Deskripsi
uuid str Pengenal unik untuk event ini
session_id str Pengenal sesi
event dict[str, Any] Data event stream Claude API mentah
parent_tool_use_id str | None ID penggunaan tool induk jika event ini dari subagent

RateLimitEvent

Dipancarkan ketika status rate limit berubah (misalnya, dari "allowed" ke "allowed_warning"). Gunakan ini untuk memperingatkan pengguna sebelum mereka mencapai batas keras, atau untuk mundur ketika status adalah "rejected".

@dataclass
class RateLimitEvent:
    rate_limit_info: RateLimitInfo
    uuid: str
    session_id: str
Field Tipe Deskripsi
rate_limit_info RateLimitInfo Status rate limit saat ini
uuid str Pengenal event unik
session_id str Pengenal sesi

RateLimitInfo

Status rate limit yang dibawa oleh RateLimitEvent.

RateLimitStatus = Literal["allowed", "allowed_warning", "rejected"]
RateLimitType = Literal[
    "five_hour", "seven_day", "seven_day_opus", "seven_day_sonnet", "overage"
]


@dataclass
class RateLimitInfo:
    status: RateLimitStatus
    resets_at: int | None = None
    rate_limit_type: RateLimitType | None = None
    utilization: float | None = None
    overage_status: RateLimitStatus | None = None
    overage_resets_at: int | None = None
    overage_disabled_reason: str | None = None
    raw: dict[str, Any] = field(default_factory=dict)
Field Tipe Deskripsi
status RateLimitStatus Status saat ini. "allowed_warning" berarti mendekati batas; "rejected" berarti batas tercapai
resets_at int | None Timestamp Unix ketika jendela rate limit direset
rate_limit_type RateLimitType | None Jendela rate limit mana yang berlaku
utilization float | None Fraksi rate limit yang dikonsumsi (0.0 hingga 1.0)
overage_status RateLimitStatus | None Status penggunaan overage pay-as-you-go, jika berlaku
overage_resets_at int | None Timestamp Unix ketika jendela overage direset
overage_disabled_reason str | None Mengapa overage tidak tersedia, jika status adalah "rejected"
raw dict[str, Any] Dict mentah lengkap dari CLI, termasuk field yang tidak dimodelkan di atas

TaskStartedMessage

Dipancarkan ketika tugas latar belakang dimulai. Tugas latar belakang adalah apa pun yang dilacak di luar putaran utama: perintah Bash yang di-background, Monitor watch, subagent yang dihasilkan melalui tool Agent, atau agent jarak jauh. Field task_type memberi tahu Anda yang mana. Penamaan ini tidak terkait dengan penggantian nama tool Task-ke-Agent.

@dataclass
class TaskStartedMessage(SystemMessage):
    task_id: str
    description: str
    uuid: str
    session_id: str
    tool_use_id: str | None = None
    task_type: str | None = None
Field Tipe Deskripsi
task_id str Pengenal unik untuk tugas
description str Deskripsi tugas
uuid str Pengenal pesan unik
session_id str Pengenal sesi
tool_use_id str | None ID penggunaan tool yang terkait
task_type str | None Jenis tugas latar belakang: "local_bash" untuk Bash dan Monitor watches di background, "local_agent", atau "remote_agent"

TaskUsage

Data token dan timing untuk tugas latar belakang.

class TaskUsage(TypedDict):
    total_tokens: int
    tool_uses: int
    duration_ms: int

TaskProgressMessage

Dipancarkan secara berkala dengan pembaruan kemajuan untuk tugas latar belakang yang sedang berjalan.

@dataclass
class TaskProgressMessage(SystemMessage):
    task_id: str
    description: str
    usage: TaskUsage
    uuid: str
    session_id: str
    tool_use_id: str | None = None
    last_tool_name: str | None = None
Field Tipe Deskripsi
task_id str Pengenal unik untuk tugas
description str Deskripsi status saat ini
usage TaskUsage Penggunaan token untuk tugas ini sejauh ini
uuid str Pengenal pesan unik
session_id str Pengenal sesi
tool_use_id str | None ID penggunaan tool yang terkait
last_tool_name str | None Nama tool terakhir yang digunakan tugas

TaskNotificationMessage

Dipancarkan ketika tugas latar belakang selesai, gagal, atau dihentikan. Tugas latar belakang termasuk perintah Bash run_in_background, Monitor watches, dan subagent latar belakang.

@dataclass
class TaskNotificationMessage(SystemMessage):
    task_id: str
    status: TaskNotificationStatus  # "completed" | "failed" | "stopped"
    output_file: str
    summary: str
    uuid: str
    session_id: str
    tool_use_id: str | None = None
    usage: TaskUsage | None = None
Field Tipe Deskripsi
task_id str Pengenal unik untuk tugas
status TaskNotificationStatus Salah satu dari "completed", "failed", atau "stopped"
output_file str Jalur ke file output tugas
summary str Ringkasan hasil tugas
uuid str Pengenal pesan unik
session_id str Pengenal sesi
tool_use_id str | None ID penggunaan tool yang terkait
usage TaskUsage | None Penggunaan token akhir untuk tugas

Tipe Blok Konten

ContentBlock

Tipe union dari semua blok konten.

ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock

TextBlock

Blok konten teks.

@dataclass
class TextBlock:
    text: str

ThinkingBlock

Blok konten thinking (untuk model dengan kemampuan thinking).

@dataclass
class ThinkingBlock:
    thinking: str
    signature: str

ToolUseBlock

Blok permintaan penggunaan tool.

@dataclass
class ToolUseBlock:
    id: str
    name: str
    input: dict[str, Any]

ToolResultBlock

Blok hasil eksekusi tool.

@dataclass
class ToolResultBlock:
    tool_use_id: str
    content: str | list[dict[str, Any]] | None = None
    is_error: bool | None = None

Tipe Error

ClaudeSDKError

Kelas exception dasar untuk semua error SDK.

class ClaudeSDKError(Exception):
    """Base error for Claude SDK."""

CLINotFoundError

Diangkat ketika Claude Code CLI tidak diinstal atau tidak ditemukan.

class CLINotFoundError(CLIConnectionError):
    def __init__(
        self, message: str = "Claude Code not found", cli_path: str | None = None
    ):
        """
        Args:
            message: Error message (default: "Claude Code not found")
            cli_path: Optional path to the CLI that was not found
        """

CLIConnectionError

Diangkat ketika koneksi ke Claude Code gagal.

class CLIConnectionError(ClaudeSDKError):
    """Failed to connect to Claude Code."""

ProcessError

Diangkat ketika proses Claude Code gagal.

class ProcessError(ClaudeSDKError):
    def __init__(
        self, message: str, exit_code: int | None = None, stderr: str | None = None
    ):
        self.exit_code = exit_code
        self.stderr = stderr

CLIJSONDecodeError

Diangkat ketika parsing JSON gagal.

class CLIJSONDecodeError(ClaudeSDKError):
    def __init__(self, line: str, original_error: Exception):
        """
        Args:
            line: The line that failed to parse
            original_error: The original JSON decode exception
        """
        self.line = line
        self.original_error = original_error

Tipe Hook

Untuk panduan komprehensif tentang menggunakan hooks dengan contoh dan pola umum, lihat Hooks guide.

HookEvent

Tipe event hook yang didukung.

HookEvent = Literal[
    "PreToolUse",  # Called before tool execution
    "PostToolUse",  # Called after tool execution
    "PostToolUseFailure",  # Called when a tool execution fails
    "UserPromptSubmit",  # Called when user submits a prompt
    "Stop",  # Called when stopping execution
    "SubagentStop",  # Called when a subagent stops
    "PreCompact",  # Called before message compaction
    "Notification",  # Called for notification events
    "SubagentStart",  # Called when a subagent starts
    "PermissionRequest",  # Called when a permission decision is needed
]

HookCallback

Definisi tipe untuk fungsi callback hook.

HookCallback = Callable[[HookInput, str | None, HookContext], Awaitable[HookJSONOutput]]

Parameter:

  • input: Input hook yang kuat dengan union yang dibedakan berdasarkan hook_event_name (lihat HookInput)
  • tool_use_id: Pengenal penggunaan tool opsional (untuk hook terkait tool)
  • context: Konteks hook dengan informasi tambahan

Mengembalikan HookJSONOutput yang mungkin berisi:

  • decision: "block" untuk memblokir tindakan
  • systemMessage: Pesan sistem untuk ditambahkan ke transkrip
  • hookSpecificOutput: Data output spesifik hook

HookContext

Informasi konteks yang diteruskan ke callback hook.

class HookContext(TypedDict):
    signal: Any | None  # Future: abort signal support

HookMatcher

Konfigurasi untuk mencocokkan hooks ke event atau tools tertentu.

@dataclass
class HookMatcher:
    matcher: str | None = (
        None  # Tool name or pattern to match (e.g., "Bash", "Write|Edit")
    )
    hooks: list[HookCallback] = field(
        default_factory=list
    )  # List of callbacks to execute
    timeout: float | None = (
        None  # Timeout in seconds for all hooks in this matcher (default: 60)
    )

HookInput

Tipe union dari semua tipe input hook. Tipe aktual bergantung pada field hook_event_name.

HookInput = (
    PreToolUseHookInput
    | PostToolUseHookInput
    | PostToolUseFailureHookInput
    | UserPromptSubmitHookInput
    | StopHookInput
    | SubagentStopHookInput
    | PreCompactHookInput
    | NotificationHookInput
    | SubagentStartHookInput
    | PermissionRequestHookInput
)

BaseHookInput

Field dasar yang ada di semua tipe input hook.

class BaseHookInput(TypedDict):
    session_id: str
    transcript_path: str
    cwd: str
    permission_mode: NotRequired[str]
Field Tipe Deskripsi
session_id str Pengenal sesi saat ini
transcript_path str Jalur ke file transkrip sesi
cwd str Direktori kerja saat ini
permission_mode str (opsional) Mode izin saat ini

PreToolUseHookInput

Data input untuk event hook PreToolUse.

class PreToolUseHookInput(BaseHookInput):
    hook_event_name: Literal["PreToolUse"]
    tool_name: str
    tool_input: dict[str, Any]
    tool_use_id: str
    agent_id: NotRequired[str]
    agent_type: NotRequired[str]
Field Tipe Deskripsi
hook_event_name Literal["PreToolUse"] Selalu "PreToolUse"
tool_name str Nama tool yang akan dieksekusi
tool_input dict[str, Any] Parameter input untuk tool
tool_use_id str Pengenal unik untuk penggunaan tool ini
agent_id str (opsional) Pengenal subagent, ada ketika hook menyala di dalam subagent
agent_type str (opsional) Tipe subagent, ada ketika hook menyala di dalam subagent

PostToolUseHookInput

Data input untuk event hook PostToolUse.

class PostToolUseHookInput(BaseHookInput):
    hook_event_name: Literal["PostToolUse"]
    tool_name: str
    tool_input: dict[str, Any]
    tool_response: Any
    tool_use_id: str
    agent_id: NotRequired[str]
    agent_type: NotRequired[str]
Field Tipe Deskripsi
hook_event_name Literal["PostToolUse"] Selalu "PostToolUse"
tool_name str Nama tool yang dieksekusi
tool_input dict[str, Any] Parameter input yang digunakan
tool_response Any Respons dari eksekusi tool
tool_use_id str Pengenal unik untuk penggunaan tool ini
agent_id str (opsional) Pengenal subagent, ada ketika hook menyala di dalam subagent
agent_type str (opsional) Tipe subagent, ada ketika hook menyala di dalam subagent

PostToolUseFailureHookInput

Data input untuk event hook PostToolUseFailure. Dipanggil ketika eksekusi tool gagal.

class PostToolUseFailureHookInput(BaseHookInput):
    hook_event_name: Literal["PostToolUseFailure"]
    tool_name: str
    tool_input: dict[str, Any]
    tool_use_id: str
    error: str
    is_interrupt: NotRequired[bool]
    agent_id: NotRequired[str]
    agent_type: NotRequired[str]
Field Tipe Deskripsi
hook_event_name Literal["PostToolUseFailure"] Selalu "PostToolUseFailure"
tool_name str Nama tool yang gagal
tool_input dict[str, Any] Parameter input yang digunakan
tool_use_id str Pengenal unik untuk penggunaan tool ini
error str Pesan error dari eksekusi yang gagal
is_interrupt bool (opsional) Apakah kegagalan disebabkan oleh interrupt
agent_id str (opsional) Pengenal subagent, ada ketika hook menyala di dalam subagent
agent_type str (opsional) Tipe subagent, ada ketika hook menyala di dalam subagent

UserPromptSubmitHookInput

Data input untuk event hook UserPromptSubmit.

class UserPromptSubmitHookInput(BaseHookInput):
    hook_event_name: Literal["UserPromptSubmit"]
    prompt: str
Field Tipe Deskripsi
hook_event_name Literal["UserPromptSubmit"] Selalu "UserPromptSubmit"
prompt str Prompt yang dikirimkan pengguna

StopHookInput

Data input untuk event hook Stop.

class StopHookInput(BaseHookInput):
    hook_event_name: Literal["Stop"]
    stop_hook_active: bool
Field Tipe Deskripsi
hook_event_name Literal["Stop"] Selalu "Stop"
stop_hook_active bool Apakah stop hook aktif

SubagentStopHookInput

Data input untuk event hook SubagentStop.

class SubagentStopHookInput(BaseHookInput):
    hook_event_name: Literal["SubagentStop"]
    stop_hook_active: bool
    agent_id: str
    agent_transcript_path: str
    agent_type: str
Field Tipe Deskripsi
hook_event_name Literal["SubagentStop"] Selalu "SubagentStop"
stop_hook_active bool Apakah stop hook aktif
agent_id str Pengenal unik untuk subagent
agent_transcript_path str Jalur ke file transkrip subagent
agent_type str Tipe subagent

PreCompactHookInput

Data input untuk event hook PreCompact.

class PreCompactHookInput(BaseHookInput):
    hook_event_name: Literal["PreCompact"]
    trigger: Literal["manual", "auto"]
    custom_instructions: str | None
Field Tipe Deskripsi
hook_event_name Literal["PreCompact"] Selalu "PreCompact"
trigger Literal["manual", "auto"] Apa yang memicu pemadatan
custom_instructions str | None Instruksi kustom untuk pemadatan

NotificationHookInput

Data input untuk event hook Notification.

class NotificationHookInput(BaseHookInput):
    hook_event_name: Literal["Notification"]
    message: str
    title: NotRequired[str]
    notification_type: str
Field Tipe Deskripsi
hook_event_name Literal["Notification"] Selalu "Notification"
message str Konten pesan notifikasi
title str (opsional) Judul notifikasi
notification_type str Tipe notifikasi

SubagentStartHookInput

Data input untuk event hook SubagentStart.

class SubagentStartHookInput(BaseHookInput):
    hook_event_name: Literal["SubagentStart"]
    agent_id: str
    agent_type: str
Field Tipe Deskripsi
hook_event_name Literal["SubagentStart"] Selalu "SubagentStart"
agent_id str Pengenal unik untuk subagent
agent_type str Tipe subagent

PermissionRequestHookInput

Data input untuk event hook PermissionRequest. Memungkinkan hooks untuk menangani keputusan izin secara programatis.

class PermissionRequestHookInput(BaseHookInput):
    hook_event_name: Literal["PermissionRequest"]
    tool_name: str
    tool_input: dict[str, Any]
    permission_suggestions: NotRequired[list[Any]]
Field Tipe Deskripsi
hook_event_name Literal["PermissionRequest"] Selalu "PermissionRequest"
tool_name str Nama tool yang meminta izin
tool_input dict[str, Any] Parameter input untuk tool
permission_suggestions list[Any] (opsional) Saran pembaruan izin dari CLI

HookJSONOutput

Tipe union untuk nilai pengembalian callback hook.

HookJSONOutput = AsyncHookJSONOutput | SyncHookJSONOutput

SyncHookJSONOutput

Output hook sinkron dengan field kontrol dan keputusan.

class SyncHookJSONOutput(TypedDict):
    # Control fields
    continue_: NotRequired[bool]  # Whether to proceed (default: True)
    suppressOutput: NotRequired[bool]  # Hide stdout from transcript
    stopReason: NotRequired[str]  # Message when continue is False

    # Decision fields
    decision: NotRequired[Literal["block"]]
    systemMessage: NotRequired[str]  # Warning message for user
    reason: NotRequired[str]  # Feedback for Claude

    # Hook-specific output
    hookSpecificOutput: NotRequired[HookSpecificOutput]

HookSpecificOutput

TypedDict yang berisi nama event hook dan field spesifik event. Bentuknya bergantung pada nilai hookEventName. Untuk detail lengkap tentang field yang tersedia per event hook, lihat Control execution with hooks.

Union yang dibedakan dari tipe output spesifik event. Field hookEventName menentukan field mana yang valid.

class PreToolUseHookSpecificOutput(TypedDict):
    hookEventName: Literal["PreToolUse"]
    permissionDecision: NotRequired[Literal["allow", "deny", "ask", "defer"]]
    permissionDecisionReason: NotRequired[str]
    updatedInput: NotRequired[dict[str, Any]]
    additionalContext: NotRequired[str]


class PostToolUseHookSpecificOutput(TypedDict):
    hookEventName: Literal["PostToolUse"]
    additionalContext: NotRequired[str]
    updatedToolOutput: NotRequired[Any]
    updatedMCPToolOutput: NotRequired[Any]


class PostToolUseFailureHookSpecificOutput(TypedDict):
    hookEventName: Literal["PostToolUseFailure"]
    additionalContext: NotRequired[str]


class UserPromptSubmitHookSpecificOutput(TypedDict):
    hookEventName: Literal["UserPromptSubmit"]
    additionalContext: NotRequired[str]


class NotificationHookSpecificOutput(TypedDict):
    hookEventName: Literal["Notification"]
    additionalContext: NotRequired[str]


class SubagentStartHookSpecificOutput(TypedDict):
    hookEventName: Literal["SubagentStart"]
    additionalContext: NotRequired[str]


class PermissionRequestHookSpecificOutput(TypedDict):
    hookEventName: Literal["PermissionRequest"]
    decision: dict[str, Any]


HookSpecificOutput = (
    PreToolUseHookSpecificOutput
    | PostToolUseHookSpecificOutput
    | PostToolUseFailureHookSpecificOutput
    | UserPromptSubmitHookSpecificOutput
    | NotificationHookSpecificOutput
    | SubagentStartHookSpecificOutput
    | PermissionRequestHookSpecificOutput
)

AsyncHookJSONOutput

Output hook async yang menunda eksekusi hook.

class AsyncHookJSONOutput(TypedDict):
    async_: Literal[True]  # Set to True to defer execution
    asyncTimeout: NotRequired[int]  # Timeout in milliseconds

Contoh Penggunaan Hook

Contoh ini mendaftarkan dua hooks: satu yang memblokir perintah bash berbahaya seperti rm -rf /, dan satu lagi yang mencatat semua penggunaan tool untuk audit. Hook keamanan hanya berjalan pada perintah Bash (melalui matcher), sementara hook logging berjalan pada semua tools.

from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, HookContext
from typing import Any


async def validate_bash_command(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Validate and potentially block dangerous bash commands."""
    if input_data["tool_name"] == "Bash":
        command = input_data["tool_input"].get("command", "")
        if "rm -rf /" in command:
            return {
                "hookSpecificOutput": {
                    "hookEventName": "PreToolUse",
                    "permissionDecision": "deny",
                    "permissionDecisionReason": "Dangerous command blocked",
                }
            }
    return {}


async def log_tool_use(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Log all tool usage for auditing."""
    print(f"Tool used: {input_data.get('tool_name')}")
    return {}


options = ClaudeAgentOptions(
    hooks={
        "PreToolUse": [
            HookMatcher(
                matcher="Bash", hooks=[validate_bash_command], timeout=120
            ),  # 2 min for validation
            HookMatcher(
                hooks=[log_tool_use]
            ),  # Applies to all tools (default 60s timeout)
        ],
        "PostToolUse": [HookMatcher(hooks=[log_tool_use])],
    }
)

async for message in query(prompt="Analyze this codebase", options=options):
    print(message)

Tipe Input/Output Tool

Dokumentasi skema input/output untuk semua tools Claude Code bawaan. Meskipun Python SDK tidak mengekspor ini sebagai tipe, mereka mewakili struktur input dan output tool dalam pesan.

Agent

Nama tool: Agent (sebelumnya Task, yang masih diterima sebagai alias)

Input:

{
    "description": str,  # A short (3-5 word) description of the task
    "prompt": str,  # The task for the agent to perform
    "subagent_type": str,  # The type of specialized agent to use
}

Output:

{
    "result": str,  # Final result from the subagent
    "usage": dict | None,  # Token usage statistics
    "total_cost_usd": float | None,  # Estimated total cost in USD
    "duration_ms": int | None,  # Execution duration in milliseconds
}

AskUserQuestion

Nama tool: AskUserQuestion

Mengajukan pertanyaan klarifikasi kepada pengguna selama eksekusi. Lihat Handle approvals and user input untuk detail penggunaan.

Input:

{
    "questions": [  # Questions to ask the user (1-4 questions)
        {
            "question": str,  # The complete question to ask the user
            "header": str,  # Very short label displayed as a chip/tag (max 12 chars)
            "options": [  # The available choices (2-4 options)
                {
                    "label": str,  # Display text for this option (1-5 words)
                    "description": str,  # Explanation of what this option means
                }
            ],
            "multiSelect": bool,  # Set to true to allow multiple selections
        }
    ],
    "answers": dict | None,  # User answers populated by the permission system
}

Output:

{
    "questions": [  # The questions that were asked
        {
            "question": str,
            "header": str,
            "options": [{"label": str, "description": str}],
            "multiSelect": bool,
        }
    ],
    "answers": dict[str, str],  # Maps question text to answer string
    # Multi-select answers are comma-separated
}

Bash

Nama tool: Bash

Input:

{
    "command": str,  # The command to execute
    "timeout": int | None,  # Optional timeout in milliseconds (max 600000)
    "description": str | None,  # Clear, concise description (5-10 words)
    "run_in_background": bool | None,  # Set to true to run in background
}

Output:

{
    "output": str,  # Combined stdout and stderr output
    "exitCode": int,  # Exit code of the command
    "killed": bool | None,  # Whether command was killed due to timeout
    "shellId": str | None,  # Shell ID for background processes
}

Monitor

Nama tool: Monitor

Menjalankan skrip latar belakang dan mengirimkan setiap baris stdout ke Claude sebagai event sehingga dapat bereaksi tanpa polling. Monitor mengikuti aturan izin yang sama seperti Bash. Lihat Monitor tool reference untuk perilaku dan ketersediaan penyedia.

Input:

{
    "command": str,  # Shell script; each stdout line is an event, exit ends the watch
    "description": str,  # Short description shown in notifications
    "timeout_ms": int | None,  # Kill after this deadline (default 300000, max 3600000)
    "persistent": bool | None,  # Run for the lifetime of the session; stop with TaskStop
}

Output:

{
    "taskId": str,  # ID of the background monitor task
    "timeoutMs": int,  # Timeout deadline in milliseconds
    "persistent": bool | None,  # True when running until TaskStop or session end
}

Edit

Nama tool: Edit

Input:

{
    "file_path": str,  # The absolute path to the file to modify
    "old_string": str,  # The text to replace
    "new_string": str,  # The text to replace it with
    "replace_all": bool | None,  # Replace all occurrences (default False)
}

Output:

{
    "message": str,  # Confirmation message
    "replacements": int,  # Number of replacements made
    "file_path": str,  # File path that was edited
}

Read

Nama tool: Read

Input:

{
    "file_path": str,  # The absolute path to the file to read
    "offset": int | None,  # The line number to start reading from
    "limit": int | None,  # The number of lines to read
}

Output (File teks):

{
    "content": str,  # File contents with line numbers
    "total_lines": int,  # Total number of lines in file
    "lines_returned": int,  # Lines actually returned
}

Output (Gambar):

{
    "image": str,  # Base64 encoded image data
    "mime_type": str,  # Image MIME type
    "file_size": int,  # File size in bytes
}

Write

Nama tool: Write

Input:

{
    "file_path": str,  # The absolute path to the file to write
    "content": str,  # The content to write to the file
}

Output:

{
    "message": str,  # Success message
    "bytes_written": int,  # Number of bytes written
    "file_path": str,  # File path that was written
}

Glob

Nama tool: Glob

Input:

{
    "pattern": str,  # The glob pattern to match files against
    "path": str | None,  # The directory to search in (defaults to cwd)
}

Output:

{
    "matches": list[str],  # Array of matching file paths
    "count": int,  # Number of matches found
    "search_path": str,  # Search directory used
}

Grep

Nama tool: Grep

Input:

{
    "pattern": str,  # The regular expression pattern
    "path": str | None,  # File or directory to search in
    "glob": str | None,  # Glob pattern to filter files
    "type": str | None,  # File type to search
    "output_mode": str | None,  # "content", "files_with_matches", or "count"
    "-i": bool | None,  # Case insensitive search
    "-n": bool | None,  # Show line numbers
    "-B": int | None,  # Lines to show before each match
    "-A": int | None,  # Lines to show after each match
    "-C": int | None,  # Lines to show before and after
    "head_limit": int | None,  # Limit output to first N lines/entries
    "multiline": bool | None,  # Enable multiline mode
}

Output (content mode):

{
    "matches": [
        {
            "file": str,
            "line_number": int | None,
            "line": str,
            "before_context": list[str] | None,
            "after_context": list[str] | None,
        }
    ],
    "total_matches": int,
}

Output (files_with_matches mode):

{
    "files": list[str],  # Files containing matches
    "count": int,  # Number of files with matches
}

NotebookEdit

Nama tool: NotebookEdit

Input:

{
    "notebook_path": str,  # Absolute path to the Jupyter notebook
    "cell_id": str | None,  # The ID of the cell to edit
    "new_source": str,  # The new source for the cell
    "cell_type": "code" | "markdown" | None,  # The type of the cell
    "edit_mode": "replace" | "insert" | "delete" | None,  # Edit operation type
}

Output:

{
    "message": str,  # Success message
    "edit_type": "replaced" | "inserted" | "deleted",  # Type of edit performed
    "cell_id": str | None,  # Cell ID that was affected
    "total_cells": int,  # Total cells in notebook after edit
}

WebFetch

Nama tool: WebFetch

Input:

{
    "url": str,  # The URL to fetch content from
    "prompt": str,  # The prompt to run on the fetched content
}

Output:

{
    "response": str,  # AI model's response to the prompt
    "url": str,  # URL that was fetched
    "final_url": str | None,  # Final URL after redirects
    "status_code": int | None,  # HTTP status code
}

Nama tool: WebSearch

Input:

{
    "query": str,  # The search query to use
    "allowed_domains": list[str] | None,  # Only include results from these domains
    "blocked_domains": list[str] | None,  # Never include results from these domains
}

Output:

{
    "results": [{"title": str, "url": str, "snippet": str, "metadata": dict | None}],
    "total_results": int,
    "query": str,
}

TodoWrite

Nama tool: TodoWrite

Input:

{
    "todos": [
        {
            "content": str,  # The task description
            "status": "pending" | "in_progress" | "completed",  # Task status
            "activeForm": str,  # Active form of the description
        }
    ]
}

Output:

{
    "message": str,  # Success message
    "stats": {"total": int, "pending": int, "in_progress": int, "completed": int},
}

BashOutput

Nama tool: BashOutput

Input:

{
    "bash_id": str,  # The ID of the background shell
    "filter": str | None,  # Optional regex to filter output lines
}

Output:

{
    "output": str,  # New output since last check
    "status": "running" | "completed" | "failed",  # Current shell status
    "exitCode": int | None,  # Exit code when completed
}

KillBash

Nama tool: KillBash

Input:

{
    "shell_id": str  # The ID of the background shell to kill
}

Output:

{
    "message": str,  # Success message
    "shell_id": str,  # ID of the killed shell
}

ExitPlanMode

Nama tool: ExitPlanMode

Input:

{
    "plan": str  # The plan to run by the user for approval
}

Output:

{
    "message": str,  # Confirmation message
    "approved": bool | None,  # Whether user approved the plan
}

ListMcpResources

Nama tool: ListMcpResources

Input:

{
    "server": str | None  # Optional server name to filter resources by
}

Output:

{
    "resources": [
        {
            "uri": str,
            "name": str,
            "description": str | None,
            "mimeType": str | None,
            "server": str,
        }
    ],
    "total": int,
}

ReadMcpResource

Nama tool: ReadMcpResource

Input:

{
    "server": str,  # The MCP server name
    "uri": str,  # The resource URI to read
}

Output:

{
    "contents": [
        {"uri": str, "mimeType": str | None, "text": str | None, "blob": str | None}
    ],
    "server": str,
}

Fitur Lanjutan dengan ClaudeSDKClient

Membangun Antarmuka Percakapan Berkelanjutan

from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    AssistantMessage,
    TextBlock,
)
import asyncio


class ConversationSession:
    """Maintains a single conversation session with Claude."""

    def __init__(self, options: ClaudeAgentOptions | None = None):
        self.client = ClaudeSDKClient(options)
        self.turn_count = 0

    async def start(self):
        await self.client.connect()
        print("Starting conversation session. Claude will remember context.")
        print(
            "Commands: 'exit' to quit, 'interrupt' to stop current task, 'new' for new session"
        )

        while True:
            user_input = input(f"\n[Turn {self.turn_count + 1}] You: ")

            if user_input.lower() == "exit":
                break
            elif user_input.lower() == "interrupt":
                await self.client.interrupt()
                print("Task interrupted!")
                continue
            elif user_input.lower() == "new":
                # Disconnect and reconnect for a fresh session
                await self.client.disconnect()
                await self.client.connect()
                self.turn_count = 0
                print("Started new conversation session (previous context cleared)")
                continue

            # Send message - the session retains all previous messages
            await self.client.query(user_input)
            self.turn_count += 1

            # Process response
            print(f"[Turn {self.turn_count}] Claude: ", end="")
            async for message in self.client.receive_response():
                if isinstance(message, AssistantMessage):
                    for block in message.content:
                        if isinstance(block, TextBlock):
                            print(block.text, end="")
            print()  # New line after response

        await self.client.disconnect()
        print(f"Conversation ended after {self.turn_count} turns.")


async def main():
    options = ClaudeAgentOptions(
        allowed_tools=["Read", "Write", "Bash"], permission_mode="acceptEdits"
    )
    session = ConversationSession(options)
    await session.start()


# Example conversation:
# Turn 1 - You: "Create a file called hello.py"
# Turn 1 - Claude: "I'll create a hello.py file for you..."
# Turn 2 - You: "What's in that file?"
# Turn 2 - Claude: "The hello.py file I just created contains..." (remembers!)
# Turn 3 - You: "Add a main function to it"
# Turn 3 - Claude: "I'll add a main function to hello.py..." (knows which file!)

asyncio.run(main())

Menggunakan Hooks untuk Modifikasi Perilaku

from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    HookMatcher,
    HookContext,
)
import asyncio
from typing import Any


async def pre_tool_logger(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Log all tool usage before execution."""
    tool_name = input_data.get("tool_name", "unknown")
    print(f"[PRE-TOOL] About to use: {tool_name}")

    # You can modify or block the tool execution here
    if tool_name == "Bash" and "rm -rf" in str(input_data.get("tool_input", {})):
        return {
            "hookSpecificOutput": {
                "hookEventName": "PreToolUse",
                "permissionDecision": "deny",
                "permissionDecisionReason": "Dangerous command blocked",
            }
        }
    return {}


async def post_tool_logger(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Log results after tool execution."""
    tool_name = input_data.get("tool_name", "unknown")
    print(f"[POST-TOOL] Completed: {tool_name}")
    return {}


async def user_prompt_modifier(
    input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
    """Add context to user prompts."""
    original_prompt = input_data.get("prompt", "")

    # Add a timestamp as additional context for Claude to see
    from datetime import datetime

    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    return {
        "hookSpecificOutput": {
            "hookEventName": "UserPromptSubmit",
            "additionalContext": f"[Submitted at {timestamp}] Original prompt: {original_prompt}",
        }
    }


async def main():
    options = ClaudeAgentOptions(
        hooks={
            "PreToolUse": [
                HookMatcher(hooks=[pre_tool_logger]),
                HookMatcher(matcher="Bash", hooks=[pre_tool_logger]),
            ],
            "PostToolUse": [HookMatcher(hooks=[post_tool_logger])],
            "UserPromptSubmit": [HookMatcher(hooks=[user_prompt_modifier])],
        },
        allowed_tools=["Read", "Write", "Bash"],
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query("List files in current directory")

        async for message in client.receive_response():
            # Hooks will automatically log tool usage
            pass


asyncio.run(main())

Pemantauan Kemajuan Real-time

from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    AssistantMessage,
    ToolUseBlock,
    ToolResultBlock,
    TextBlock,
)
import asyncio


async def monitor_progress():
    options = ClaudeAgentOptions(
        allowed_tools=["Write", "Bash"], permission_mode="acceptEdits"
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query("Create 5 Python files with different sorting algorithms")

        # Monitor progress in real-time
        async for message in client.receive_response():
            if isinstance(message, AssistantMessage):
                for block in message.content:
                    if isinstance(block, ToolUseBlock):
                        if block.name == "Write":
                            file_path = block.input.get("file_path", "")
                            print(f"Creating: {file_path}")
                    elif isinstance(block, ToolResultBlock):
                        print("Completed tool execution")
                    elif isinstance(block, TextBlock):
                        print(f"Claude says: {block.text[:100]}...")

        print("Task completed!")


asyncio.run(monitor_progress())

Contoh Penggunaan

Operasi file dasar (menggunakan query)

from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ToolUseBlock
import asyncio


async def create_project():
    options = ClaudeAgentOptions(
        allowed_tools=["Read", "Write", "Bash"],
        permission_mode="acceptEdits",
        cwd="/home/user/project",
    )

    async for message in query(
        prompt="Create a Python project structure with setup.py", options=options
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, ToolUseBlock):
                    print(f"Using tool: {block.name}")


asyncio.run(create_project())

Penanganan error

from claude_agent_sdk import query, CLINotFoundError, ProcessError, CLIJSONDecodeError

try:
    async for message in query(prompt="Hello"):
        print(message)
except CLINotFoundError:
    print(
        "Claude Code CLI not found. Try reinstalling: pip install --force-reinstall claude-agent-sdk"
    )
except ProcessError as e:
    print(f"Process failed with exit code: {e.exit_code}")
except CLIJSONDecodeError as e:
    print(f"Failed to parse response: {e}")

Mode streaming dengan klien

from claude_agent_sdk import ClaudeSDKClient
import asyncio


async def interactive_session():
    async with ClaudeSDKClient() as client:
        # Send initial message
        await client.query("What's the weather like?")

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

        # Send follow-up
        await client.query("Tell me more about that")

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


asyncio.run(interactive_session())

Menggunakan tools kustom dengan ClaudeSDKClient

from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    tool,
    create_sdk_mcp_server,
    AssistantMessage,
    TextBlock,
)
import asyncio
from typing import Any


# Define custom tools with @tool decorator
@tool("calculate", "Perform mathematical calculations", {"expression": str})
async def calculate(args: dict[str, Any]) -> dict[str, Any]:
    try:
        result = eval(args["expression"], {"__builtins__": {}})
        return {"content": [{"type": "text", "text": f"Result: {result}"}]}
    except Exception as e:
        return {
            "content": [{"type": "text", "text": f"Error: {str(e)}"}],
            "is_error": True,
        }


@tool("get_time", "Get current time", {})
async def get_time(args: dict[str, Any]) -> dict[str, Any]:
    from datetime import datetime

    current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    return {"content": [{"type": "text", "text": f"Current time: {current_time}"}]}


async def main():
    # Create SDK MCP server with custom tools
    my_server = create_sdk_mcp_server(
        name="utilities", version="1.0.0", tools=[calculate, get_time]
    )

    # Configure options with the server
    options = ClaudeAgentOptions(
        mcp_servers={"utils": my_server},
        allowed_tools=["mcp__utils__calculate", "mcp__utils__get_time"],
    )

    # Use ClaudeSDKClient for interactive tool usage
    async with ClaudeSDKClient(options=options) as client:
        await client.query("What's 123 * 456?")

        # Process calculation response
        async for message in client.receive_response():
            if isinstance(message, AssistantMessage):
                for block in message.content:
                    if isinstance(block, TextBlock):
                        print(f"Calculation: {block.text}")

        # Follow up with time query
        await client.query("What time is it now?")

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


asyncio.run(main())

Konfigurasi Sandbox

SandboxSettings

Konfigurasi untuk perilaku sandbox. Gunakan ini untuk mengaktifkan sandboxing perintah dan mengonfigurasi pembatasan jaringan secara programatis.

class SandboxSettings(TypedDict, total=False):
    enabled: bool
    autoAllowBashIfSandboxed: bool
    excludedCommands: list[str]
    allowUnsandboxedCommands: bool
    network: SandboxNetworkConfig
    ignoreViolations: SandboxIgnoreViolations
    enableWeakerNestedSandbox: bool
Properti Tipe Default Deskripsi
enabled bool False Aktifkan mode sandbox untuk eksekusi perintah
autoAllowBashIfSandboxed bool True Auto-approve perintah bash ketika sandbox diaktifkan
excludedCommands list[str] [] Perintah yang selalu melewati pembatasan sandbox (misalnya, ["docker"]). Ini berjalan tanpa sandbox secara otomatis tanpa keterlibatan model
allowUnsandboxedCommands bool True Izinkan model untuk meminta menjalankan perintah di luar sandbox. Ketika True, model dapat mengatur dangerouslyDisableSandbox dalam input tool, yang jatuh kembali ke sistem izin
network SandboxNetworkConfig None Konfigurasi sandbox spesifik jaringan
ignoreViolations SandboxIgnoreViolations None Konfigurasi pelanggaran sandbox mana yang akan diabaikan
enableWeakerNestedSandbox bool False Aktifkan sandbox bersarang yang lebih lemah untuk kompatibilitas

Contoh penggunaan

from claude_agent_sdk import query, ClaudeAgentOptions, SandboxSettings

sandbox_settings: SandboxSettings = {
    "enabled": True,
    "autoAllowBashIfSandboxed": True,
    "network": {"allowLocalBinding": True},
}

async for message in query(
    prompt="Build and test my project",
    options=ClaudeAgentOptions(sandbox=sandbox_settings),
):
    print(message)

SandboxNetworkConfig

Konfigurasi spesifik jaringan untuk mode sandbox.

class SandboxNetworkConfig(TypedDict, total=False):
    allowedDomains: list[str]
    deniedDomains: list[str]
    allowManagedDomainsOnly: bool
    allowUnixSockets: list[str]
    allowAllUnixSockets: bool
    allowLocalBinding: bool
    allowMachLookup: list[str]
    httpProxyPort: int
    socksProxyPort: int
Properti Tipe Default Deskripsi
allowedDomains list[str] [] Nama domain yang dapat diakses oleh proses dalam sandbox
deniedDomains list[str] [] Nama domain yang tidak dapat diakses oleh proses dalam sandbox. Mengambil prioritas atas allowedDomains
allowManagedDomainsOnly bool False Hanya pengaturan terkelola: ketika diatur dalam pengaturan terkelola, abaikan allowedDomains dari sumber pengaturan non-terkelola. Tidak berpengaruh ketika diatur melalui opsi SDK
allowUnixSockets list[str] [] Jalur Unix socket yang dapat diakses proses (misalnya, Docker socket)
allowAllUnixSockets bool False Izinkan akses ke semua Unix socket
allowLocalBinding bool False Izinkan proses untuk mengikat ke port lokal (misalnya, untuk dev server)
allowMachLookup list[str] [] Hanya macOS: nama layanan XPC/Mach yang diizinkan. Mendukung wildcard di akhir
httpProxyPort int None Port proxy HTTP untuk permintaan jaringan
socksProxyPort int None Port proxy SOCKS untuk permintaan jaringan

SandboxIgnoreViolations

Konfigurasi untuk mengabaikan pelanggaran sandbox tertentu.

class SandboxIgnoreViolations(TypedDict, total=False):
    file: list[str]
    network: list[str]
Properti Tipe Default Deskripsi
file list[str] [] Pola jalur file untuk mengabaikan pelanggaran
network list[str] [] Pola jaringan untuk mengabaikan pelanggaran

Fallback Izin untuk Perintah Tanpa Sandbox

Ketika allowUnsandboxedCommands diaktifkan, model dapat meminta untuk menjalankan perintah di luar sandbox dengan mengatur dangerouslyDisableSandbox: True dalam input tool. Permintaan ini jatuh kembali ke sistem izin yang ada, berarti handler can_use_tool Anda akan dipanggil, memungkinkan Anda menerapkan logika otorisasi kustom.

from claude_agent_sdk import (
    query,
    ClaudeAgentOptions,
    HookMatcher,
    PermissionResultAllow,
    PermissionResultDeny,
    ToolPermissionContext,
)


async def can_use_tool(
    tool: str, input: dict, context: ToolPermissionContext
) -> PermissionResultAllow | PermissionResultDeny:
    # Check if the model is requesting to bypass the sandbox
    if tool == "Bash" and input.get("dangerouslyDisableSandbox"):
        # The model is requesting to run this command outside the sandbox
        print(f"Unsandboxed command requested: {input.get('command')}")

        if is_command_authorized(input.get("command")):
            return PermissionResultAllow()
        return PermissionResultDeny(
            message="Command not authorized for unsandboxed execution"
        )
    return PermissionResultAllow()


# Required: dummy hook keeps the stream open for can_use_tool
async def dummy_hook(input_data, tool_use_id, context):
    return {"continue_": True}


async def prompt_stream():
    yield {
        "type": "user",
        "message": {"role": "user", "content": "Deploy my application"},
    }


async def main():
    async for message in query(
        prompt=prompt_stream(),
        options=ClaudeAgentOptions(
            sandbox={
                "enabled": True,
                "allowUnsandboxedCommands": True,  # Model can request unsandboxed execution
            },
            permission_mode="default",
            can_use_tool=can_use_tool,
            hooks={"PreToolUse": [HookMatcher(matcher=None, hooks=[dummy_hook])]},
        ),
    ):
        print(message)

Pola ini memungkinkan Anda untuk:

  • Audit permintaan model: Catat ketika model meminta eksekusi tanpa sandbox
  • Implementasikan allowlist: Hanya izinkan perintah tertentu untuk berjalan tanpa sandbox
  • Tambahkan alur persetujuan: Memerlukan otorisasi eksplisit untuk operasi istimewa

Lihat juga