Loading...
    • Panduan Pengembang
    • Referensi API
    • MCP
    • Sumber daya
    • Catatan Rilis
    Search...
    ⌘K
    Langkah pertama
    Pengenalan ClaudeMulai cepat
    Model & harga
    Ikhtisar modelMemilih modelYang baru di Claude 4.5Migrasi ke Claude 4.5Penghentian modelHarga
    Bangun dengan Claude
    Ikhtisar fiturMenggunakan Messages APIJendela konteksPraktik terbaik prompting
    Kemampuan
    Prompt cachingPengeditan konteksExtended thinkingUpayaStreaming MessagesPemrosesan batchKutipanDukungan multibahasaPenghitungan tokenEmbeddingsVisiDukungan PDFFiles APIHasil pencarianOutput terstruktur
    Alat
    IkhtisarCara mengimplementasikan penggunaan alatStreaming alat berbutir halusAlat BashAlat eksekusi kodePemanggilan alat terprogramAlat penggunaan komputerAlat editor teksAlat pengambilan webAlat pencarian webAlat memoriAlat pencarian alat
    Keterampilan Agen
    IkhtisarMulai cepatPraktik terbaikMenggunakan Keterampilan dengan API
    Agent SDK
    IkhtisarMulai cepatTypeScript SDKTypeScript V2 (pratinjau)Python SDKPanduan Migrasi
    MCP di API
    Konektor MCPServer MCP jarak jauh
    Claude di platform pihak ketiga
    Amazon BedrockMicrosoft FoundryVertex AI
    Rekayasa prompt
    IkhtisarGenerator promptGunakan template promptPenyempurna promptJadilah jelas dan langsungGunakan contoh (multishot prompting)Biarkan Claude berpikir (CoT)Gunakan tag XMLBerikan Claude peran (prompt sistem)Isi sebelumnya respons ClaudeRantai prompt kompleksTips konteks panjangTips extended thinking
    Uji & evaluasi
    Tentukan kriteria kesuksesanKembangkan kasus ujiMenggunakan Alat EvaluasiMengurangi latensi
    Perkuat penjaga
    Kurangi halusinasiTingkatkan konsistensi outputMitigasi jailbreakStreaming penolakanKurangi kebocoran promptJaga Claude tetap dalam karakter
    Administrasi dan pemantauan
    Ikhtisar Admin APIAPI Penggunaan dan BiayaClaude Code Analytics API
    Console
    Log in
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...

    Solutions

    • AI agents
    • Code modernization
    • Coding
    • Customer support
    • Education
    • Financial services
    • Government
    • Life sciences

    Partners

    • Amazon Bedrock
    • Google Cloud's Vertex AI

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Company

    • Anthropic
    • Careers
    • Economic Futures
    • Research
    • News
    • Responsible Scaling Policy
    • Security and compliance
    • Transparency

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Help and security

    • Availability
    • Status
    • Support
    • Discord

    Terms and policies

    • Privacy policy
    • Responsible disclosure policy
    • Terms of service: Commercial
    • Terms of service: Consumer
    • Usage policy
    Agent SDK

    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

    Fiturquery()ClaudeSDKClient
    SesiMembuat sesi baru setiap kaliMenggunakan kembali sesi yang sama
    PercakapanPertukaran tunggalPertukaran berganda dalam konteks yang sama
    KoneksiDikelola secara otomatisKontrol manual
    • Instalasi
    • Memilih Antara query() dan ClaudeSDKClient
    • Perbandingan Cepat
    • Kapan Menggunakan query() (Sesi Baru Setiap Kali)
    • Kapan Menggunakan ClaudeSDKClient (Percakapan Berkelanjutan)
    • Fungsi
    • query()
    • tool()
    • create_sdk_mcp_server()
    • Kelas
    • ClaudeSDKClient
    • Tipe
    • SdkMcpTool
    • ClaudeAgentOptions
    • OutputFormat
    • SystemPromptPreset
    • SettingSource
    • AgentDefinition
    • PermissionMode
    • McpSdkServerConfig
    • McpServerConfig
    • SdkPluginConfig
    • Tipe Pesan
    • Message
    • UserMessage
    • AssistantMessage
    • SystemMessage
    • ResultMessage
    • Jenis Blok Konten
    • ContentBlock
    • TextBlock
    • ThinkingBlock
    • ToolUseBlock
    • ToolResultBlock
    • Jenis Kesalahan
    • ClaudeSDKError
    • CLINotFoundError
    • CLIConnectionError
    • ProcessError
    • CLIJSONDecodeError
    • Jenis Hook
    • HookEvent
    • HookCallback
    • HookContext
    • HookMatcher
    • Contoh Penggunaan Hook
    • Jenis Input/Output Alat
    • Task
    • Bash
    • Edit
    • Read
    • Write
    • Glob
    • Grep
    • NotebookEdit
    • WebFetch
    • WebSearch
    • TodoWrite
    • BashOutput
    • KillBash
    • ExitPlanMode
    • ListMcpResources
    • ReadMcpResource
    • Fitur Lanjutan dengan ClaudeSDKClient
    • Membangun Antarmuka Percakapan Berkelanjutan
    • Menggunakan Hook untuk Modifikasi Perilaku
    • Pemantauan Kemajuan Real-time
    • Contoh Penggunaan
    • Operasi file dasar (menggunakan query)
    • Penanganan kesalahan
    • Mode streaming dengan klien
    • Menggunakan alat kustom dengan ClaudeSDKClient
    • Konfigurasi Sandbox
    • SandboxSettings
    • SandboxNetworkConfig
    • SandboxIgnoreViolations
    • Fallback Izin untuk Perintah Tanpa Sandbox
    • Lihat juga
    Input Streaming✅ Didukung✅ Didukung
    Interupsi❌ Tidak didukung✅ Didukung
    Hooks❌ Tidak didukung✅ Didukung
    Alat Kustom❌ Tidak didukung✅ Didukung
    Lanjutkan Chat❌ Sesi baru setiap kali✅ Mempertahankan percakapan
    Kasus PenggunaanTugas sekali jalanPercakapan 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 iterator async 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
    ) -> AsyncIterator[Message]

    Parameter

    ParameterTipeDeskripsi
    promptstr | AsyncIterable[dict]Prompt input sebagai string atau async iterable untuk mode streaming
    optionsClaudeAgentOptions | NoneObjek konfigurasi opsional (default ke ClaudeAgentOptions() jika None)

    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 alat MCP dengan keamanan tipe.

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

    Parameter

    ParameterTipeDeskripsi
    namestrPengidentifikasi unik untuk alat
    descriptionstrDeskripsi yang dapat dibaca manusia tentang apa yang dilakukan alat
    input_schematype | dict[str, Any]Skema yang mendefinisikan parameter input alat (lihat di bawah)

    Opsi Input Schema

    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 alat 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']}!"
            }]
        }

    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

    ParameterTipeDefaultDeskripsi
    namestr-Pengidentifikasi unik untuk server
    versionstr"1.0.0"String versi server
    toolslist[SdkMcpTool[Any]] | NoneNoneDaftar fungsi alat 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"]
    )

    Kelas

    ClaudeSDKClient

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

    Fitur Utama

    • Kontinuitas Sesi: Mempertahankan konteks percakapan di seluruh panggilan query() berganda
    • Percakapan Sama: Claude mengingat pesan sebelumnya dalam sesi
    • Dukungan Interupsi: Dapat menghentikan Claude di tengah eksekusi
    • Siklus Hidup Eksplisit: Anda mengontrol kapan sesi dimulai dan berakhir
    • Alur Berbasis Respons: Dapat bereaksi terhadap respons dan mengirim tindak lanjut
    • Alat Kustom & Hooks: Mendukung alat kustom (dibuat dengan dekorator @tool) dan hooks
    class ClaudeSDKClient:
        def __init__(self, options: ClaudeAgentOptions | 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 rewind_files(self, user_message_uuid: str) -> None
        async def disconnect(self) -> None

    Metode

    MetodeDeskripsi
    __init__(options)Inisialisasi klien dengan konfigurasi opsional
    connect(prompt)Terhubung 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 iterator async
    receive_response()Terima pesan hingga dan termasuk ResultMessage
    interrupt()Kirim sinyal interupsi (hanya berfungsi dalam mode streaming)
    rewind_files(user_message_uuid)Pulihkan file ke keadaan mereka pada pesan pengguna yang ditentukan. Memerlukan enable_file_checkpointing=True. Lihat File checkpointing
    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 - Claude remembers 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 - Input streaming dengan ClaudeSDKClient

    import asyncio
    from claude_agent_sdk import ClaudeSDKClient
    
    async def message_stream():
        """Generate messages dynamically."""
        yield {"type": "text", "text": "Analyze the following data:"}
        await asyncio.sleep(0.5)
        yield {"type": "text", "text": "Temperature: 25°C"}
        await asyncio.sleep(0.5)
        yield {"type": "text", "text": "Humidity: 60%"}
        await asyncio.sleep(0.5)
        yield {"type": "text", "text": "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 interupsi

    import asyncio
    from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
    
    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")
    
            # Let it run for a bit
            await asyncio.sleep(2)
    
            # Interrupt the task
            await client.interrupt()
            print("Task interrupted!")
    
            # Send a new command
            await client.query("Just say hello instead")
    
            async for message in client.receive_response():
                # Process the new response
                pass
    
    asyncio.run(interruptible_task())

    Contoh - Kontrol izin tingkat lanjut

    from claude_agent_sdk import (
        ClaudeSDKClient,
        ClaudeAgentOptions
    )
    
    async def custom_permission_handler(
        tool_name: str,
        input_data: dict,
        context: dict
    ):
        """Custom logic for tool permissions."""
    
        # Block writes to system directories
        if tool_name == "Write" and input_data.get("file_path", "").startswith("/system/"):
            return {
                "behavior": "deny",
                "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 {
                "behavior": "allow",
                "updatedInput": {**input_data, "file_path": safe_path}
            }
    
        # Allow everything else
        return {
            "behavior": "allow",
            "updatedInput": 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 alat MCP SDK 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]]]
    PropertiTipeDeskripsi
    namestrPengidentifikasi unik untuk alat
    descriptionstrDeskripsi yang dapat dibaca manusia
    input_schematype[T] | dict[str, Any]Skema untuk validasi input
    handlerCallable[[T], Awaitable[dict[str, Any]]]Fungsi async yang menangani eksekusi alat

    ClaudeAgentOptions

    Dataclass konfigurasi untuk kueri Claude Code.

    @dataclass
    class ClaudeAgentOptions:
        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)
        permission_mode: PermissionMode | None = None
        continue_conversation: bool = False
        resume: str | None = None
        max_turns: int | None = None
        disallowed_tools: list[str] = field(default_factory=list)
        model: str | None = None
        output_format: OutputFormat | None = None
        permission_prompt_tool_name: str | None = None
        cwd: 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
        fork_session: bool = False
        agents: dict[str, AgentDefinition] | None = None
        setting_sources: list[SettingSource] | None = None
    PropertiTipeDefaultDeskripsi
    allowed_toolslist[str][]Daftar nama alat yang diizinkan
    system_promptstr | SystemPromptPreset | NoneNoneKonfigurasi prompt sistem. Lewatkan string untuk prompt kustom, atau gunakan {"type": "preset", "preset": "claude_code"} untuk prompt sistem Claude Code. Tambahkan "append" untuk memperluas preset
    mcp_serversdict[str, McpServerConfig] | str | Path{}Konfigurasi server MCP atau jalur ke file konfigurasi
    permission_modePermissionMode | NoneNoneMode izin untuk penggunaan alat
    continue_conversationboolFalseLanjutkan percakapan paling baru
    resumestr | NoneNoneID sesi untuk dilanjutkan
    max_turnsint | NoneNonePutaran percakapan maksimum
    disallowed_toolslist[str][]Daftar nama alat yang tidak diizinkan
    enable_file_checkpointingboolFalseAktifkan pelacakan perubahan file untuk rewinding. Lihat File checkpointing
    modelstr | NoneNoneModel Claude yang akan digunakan
    output_formatOutputFormat | NoneNoneTentukan format output untuk hasil agen. Lihat Structured outputs untuk detail
    permission_prompt_tool_namestr | NoneNoneNama alat MCP untuk prompt izin
    cwdstr | Path | NoneNoneDirektori kerja saat ini
    settingsstr | NoneNoneJalur ke file pengaturan
    add_dirslist[str | Path][]Direktori tambahan yang dapat diakses Claude
    envdict[str, str]{}Variabel lingkungan
    extra_argsdict[str, str | None]{}Argumen CLI tambahan untuk diteruskan langsung ke CLI
    max_buffer_sizeint | NoneNoneByte maksimum saat membuffer stdout CLI
    debug_stderrAnysys.stderrDeprecated - Objek seperti file untuk output debug. Gunakan callback stderr sebagai gantinya
    stderrCallable[[str], None] | NoneNoneFungsi callback untuk output stderr dari CLI
    can_use_toolCanUseTool | NoneNoneFungsi callback izin alat
    hooksdict[HookEvent, list[HookMatcher]] | NoneNoneKonfigurasi hook untuk mengintersepsi acara
    userstr | NoneNonePengidentifikasi pengguna
    include_partial_messagesboolFalseSertakan acara streaming pesan parsial
    fork_sessionboolFalseSaat melanjutkan dengan resume, fork ke ID sesi baru alih-alih melanjutkan sesi asli
    agentsdict[str, AgentDefinition] | NoneNoneSubagen yang didefinisikan secara terprogram
    pluginslist[SdkPluginConfig][]Muat plugin kustom dari jalur lokal. Lihat Plugins untuk detail
    sandboxSandboxSettings | NoneNoneKonfigurasi perilaku sandbox secara terprogram. Lihat Sandbox settings untuk detail
    setting_sourceslist[SettingSource] | NoneNone (no settings)Kontrol pengaturan filesystem mana yang akan dimuat. Saat dihilangkan, tidak ada pengaturan yang dimuat. Catatan: Harus menyertakan "project" untuk memuat file CLAUDE.md

    OutputFormat

    Konfigurasi untuk validasi output terstruktur.

    class OutputFormat(TypedDict):
        type: Literal["json_schema"]
        schema: dict[str, Any]
    BidangDiperlukanDeskripsi
    typeYaHarus "json_schema" untuk validasi JSON Schema
    schemaYaDefinisi JSON Schema untuk validasi output

    SystemPromptPreset

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

    class SystemPromptPreset(TypedDict):
        type: Literal["preset"]
        preset: Literal["claude_code"]
        append: NotRequired[str]
    BidangDiperlukanDeskripsi
    typeYaHarus "preset" untuk menggunakan prompt sistem preset
    presetYaHarus "claude_code" untuk menggunakan prompt sistem Claude Code
    appendTidakInstruksi tambahan untuk ditambahkan ke prompt sistem preset

    SettingSource

    Mengontrol sumber konfigurasi berbasis filesystem mana yang dimuat pengaturan SDK.

    SettingSource = Literal["user", "project", "local"]
    NilaiDeskripsiLokasi
    "user"Pengaturan pengguna global~/.claude/settings.json
    "project"Pengaturan proyek bersama (dikontrol versi).claude/settings.json
    "local"Pengaturan proyek lokal (gitignored).claude/settings.local.json

    Perilaku default

    Ketika setting_sources dihilangkan atau None, SDK tidak memuat pengaturan filesystem apa pun. Ini memberikan isolasi untuk aplikasi SDK.

    Mengapa menggunakan setting_sources?

    Muat semua pengaturan filesystem (perilaku warisan):

    # Load all settings like SDK v0.0.x did
    from claude_agent_sdk import query, ClaudeAgentOptions
    
    async for message in query(
        prompt="Analyze this code",
        options=ClaudeAgentOptions(
            setting_sources=["user", "project", "local"]  # Load all settings
        )
    ):
        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 pengujian 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 hanya SDK:

    # Define everything programmatically (default behavior)
    # No filesystem dependencies - setting_sources defaults to None
    async for message in query(
        prompt="Review this PR",
        options=ClaudeAgentOptions(
            # setting_sources=None is the default, no need to specify
            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"],  # Required to load 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 terprogram (seperti agents, allowed_tools) selalu mengganti pengaturan filesystem.

    AgentDefinition

    Konfigurasi untuk subagen yang didefinisikan secara terprogram.

    @dataclass
    class AgentDefinition:
        description: str
        prompt: str
        tools: list[str] | None = None
        model: Literal["sonnet", "opus", "haiku", "inherit"] | None = None
    BidangDiperlukanDeskripsi
    descriptionYaDeskripsi bahasa alami tentang kapan menggunakan agen ini
    toolsTidakArray nama alat yang diizinkan. Jika dihilangkan, mewarisi semua alat
    promptYaPrompt sistem agen
    modelTidakPenggantian model untuk agen ini. Jika dihilangkan, menggunakan model utama

    PermissionMode

    Mode izin untuk mengontrol eksekusi alat.

    PermissionMode = Literal[
        "default",           # Standard permission behavior
        "acceptEdits",       # Auto-accept file edits
        "plan",              # Planning mode - no execution
        "bypassPermissions"  # Bypass all permission checks (use with caution)
    ]

    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]]

    SdkPluginConfig

    Konfigurasi untuk memuat plugin dalam SDK.

    class SdkPluginConfig(TypedDict):
        type: Literal["local"]
        path: str
    BidangTipeDeskripsi
    typeLiteral["local"]Harus "local" (hanya plugin lokal yang didukung saat ini)
    pathstrJalur 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 plugin, lihat Plugins.

    Tipe Pesan

    Message

    Tipe union dari semua pesan yang mungkin.

    Message = UserMessage | AssistantMessage | SystemMessage | ResultMessage

    UserMessage

    Pesan input pengguna.

    @dataclass
    class UserMessage:
        content: str | list[ContentBlock]

    AssistantMessage

    Pesan respons asisten dengan blok konten.

    @dataclass
    class AssistantMessage:
        content: list[ContentBlock]
        model: str

    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
        total_cost_usd: float | None = None
        usage: dict[str, Any] | None = None
        result: str | None = None

    Jenis Blok Konten

    ContentBlock

    Jenis union dari semua blok konten.

    ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock

    TextBlock

    Blok konten teks.

    @dataclass
    class TextBlock:
        text: str

    ThinkingBlock

    Blok konten pemikiran (untuk model dengan kemampuan pemikiran).

    @dataclass
    class ThinkingBlock:
        thinking: str
        signature: str

    ToolUseBlock

    Blok permintaan penggunaan alat.

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

    ToolResultBlock

    Blok hasil eksekusi alat.

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

    Jenis Kesalahan

    ClaudeSDKError

    Kelas pengecualian dasar untuk semua kesalahan SDK.

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

    CLINotFoundError

    Dimunculkan ketika Claude Code CLI tidak terinstal 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

    Dimunculkan ketika koneksi ke Claude Code gagal.

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

    ProcessError

    Dimunculkan 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

    Dimunculkan ketika penguraian 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

    Jenis Hook

    Untuk panduan komprehensif tentang penggunaan hook dengan contoh dan pola umum, lihat panduan Hook.

    HookEvent

    Jenis peristiwa hook yang didukung. Perhatikan bahwa karena keterbatasan pengaturan, Python SDK tidak mendukung hook SessionStart, SessionEnd, dan Notification.

    HookEvent = Literal[
        "PreToolUse",      # Called before tool execution
        "PostToolUse",     # Called after tool execution
        "UserPromptSubmit", # Called when user submits a prompt
        "Stop",            # Called when stopping execution
        "SubagentStop",    # Called when a subagent stops
        "PreCompact"       # Called before message compaction
    ]

    HookCallback

    Definisi tipe untuk fungsi callback hook.

    HookCallback = Callable[
        [dict[str, Any], str | None, HookContext],
        Awaitable[dict[str, Any]]
    ]

    Parameter:

    • input_data: Data input spesifik hook (lihat panduan Hook)
    • tool_use_id: Pengidentifikasi penggunaan alat opsional (untuk hook terkait alat)
    • context: Konteks hook dengan informasi tambahan

    Mengembalikan kamus 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.

    @dataclass
    class HookContext:
        signal: Any | None = None  # Future: abort signal support

    HookMatcher

    Konfigurasi untuk mencocokkan hook ke peristiwa atau alat 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)

    Contoh Penggunaan Hook

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

    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)

    Jenis Input/Output Alat

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

    Task

    Nama alat: Task

    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,  # Total cost in USD
        "duration_ms": int | None         # Execution duration in milliseconds
    }

    Bash

    Nama alat: 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
    }

    Edit

    Nama alat: 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 alat: 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 alat: 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 alat: 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 alat: 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 (mode konten):

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

    Output (mode files_with_matches):

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

    NotebookEdit

    Nama alat: 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 alat: 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
    }

    WebSearch

    Nama alat: 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 alat: 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 alat: 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 alat: 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 alat: 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 alat: 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 alat: 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):
            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 - Claude remembers all previous messages in this session
                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 Hook 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 timestamp to all prompts
        from datetime import datetime
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
        return {
            'hookSpecificOutput': {
                'hookEventName': 'UserPromptSubmit',
                'updatedPrompt': f"[{timestamp}] {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
            files_created = []
            async for message in client.receive_messages():
                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(f"✅ Completed tool execution")
                        elif isinstance(block, TextBlock):
                            print(f"💭 Claude says: {block.text[:100]}...")
    
                # Check if we've received the final result
                if hasattr(message, 'subtype') and message.subtype in ['success', 'error']:
                    print(f"\n🎯 Task completed!")
                    break
    
    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 kesalahan

    from claude_agent_sdk import (
        query,
        CLINotFoundError,
        ProcessError,
        CLIJSONDecodeError
    )
    
    try:
        async for message in query(prompt="Hello"):
            print(message)
    except CLINotFoundError:
        print("Please install Claude Code: npm install -g @anthropic-ai/claude-code")
    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 alat 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 terprogram.

    class SandboxSettings(TypedDict, total=False):
        enabled: bool
        autoAllowBashIfSandboxed: bool
        excludedCommands: list[str]
        allowUnsandboxedCommands: bool
        network: SandboxNetworkConfig
        ignoreViolations: SandboxIgnoreViolations
        enableWeakerNestedSandbox: bool
    PropertiTipeDefaultDeskripsi
    enabledboolFalseAktifkan mode sandbox untuk eksekusi perintah
    autoAllowBashIfSandboxedboolFalsePersetujuan otomatis perintah bash ketika sandbox diaktifkan
    excludedCommandslist[str][]Perintah yang selalu melewati pembatasan sandbox (misalnya, ["docker"]). Ini berjalan tanpa sandbox secara otomatis tanpa keterlibatan model
    allowUnsandboxedCommandsboolFalseIzinkan model untuk meminta menjalankan perintah di luar sandbox. Ketika True, model dapat mengatur dangerouslyDisableSandbox dalam input alat, yang kembali ke sistem izin
    networkSandboxNetworkConfigNoneKonfigurasi sandbox spesifik jaringan
    ignoreViolationsSandboxIgnoreViolationsNoneKonfigurasi pelanggaran sandbox mana yang akan diabaikan
    enableWeakerNestedSandboxboolFalseAktifkan sandbox bersarang yang lebih lemah untuk kompatibilitas

    Pembatasan akses filesystem dan jaringan TIDAK dikonfigurasi melalui pengaturan sandbox. Sebaliknya, mereka berasal dari aturan izin:

    • Pembatasan baca filesystem: Aturan penolakan baca
    • Pembatasan tulis filesystem: Aturan izin/penolakan edit
    • Pembatasan jaringan: Aturan izin/penolakan WebFetch

    Gunakan pengaturan sandbox untuk sandboxing eksekusi perintah, dan aturan izin untuk kontrol akses filesystem dan jaringan.

    Contoh penggunaan

    from claude_agent_sdk import query, ClaudeAgentOptions, SandboxSettings
    
    sandbox_settings: SandboxSettings = {
        "enabled": True,
        "autoAllowBashIfSandboxed": True,
        "excludedCommands": ["docker"],
        "network": {
            "allowLocalBinding": True,
            "allowUnixSockets": ["/var/run/docker.sock"]
        }
    }
    
    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):
        allowLocalBinding: bool
        allowUnixSockets: list[str]
        allowAllUnixSockets: bool
        httpProxyPort: int
        socksProxyPort: int
    PropertiTipeDefaultDeskripsi
    allowLocalBindingboolFalseIzinkan proses untuk mengikat ke port lokal (misalnya, untuk server dev)
    allowUnixSocketslist[str][]Jalur soket Unix yang dapat diakses oleh proses (misalnya, soket Docker)
    allowAllUnixSocketsboolFalseIzinkan akses ke semua soket Unix
    httpProxyPortintNonePort proxy HTTP untuk permintaan jaringan
    socksProxyPortintNonePort proxy SOCKS untuk permintaan jaringan

    SandboxIgnoreViolations

    Konfigurasi untuk mengabaikan pelanggaran sandbox tertentu.

    class SandboxIgnoreViolations(TypedDict, total=False):
        file: list[str]
        network: list[str]
    PropertiTipeDefaultDeskripsi
    filelist[str][]Pola jalur file untuk mengabaikan pelanggaran
    networklist[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 alat. Permintaan ini kembali ke sistem izin yang ada, artinya handler can_use_tool Anda akan dipanggil, memungkinkan Anda menerapkan logika otorisasi kustom.

    excludedCommands vs allowUnsandboxedCommands:

    • excludedCommands: Daftar statis perintah yang selalu melewati sandbox secara otomatis (misalnya, ["docker"]). Model tidak memiliki kontrol atas ini.
    • allowUnsandboxedCommands: Memungkinkan model memutuskan pada waktu runtime apakah akan meminta eksekusi tanpa sandbox dengan mengatur dangerouslyDisableSandbox: True dalam input alat.
    from claude_agent_sdk import query, ClaudeAgentOptions
    
    async def can_use_tool(tool: str, input: dict) -> bool:
        # Check if the model is requesting to bypass the sandbox
        if tool == "Bash" and input.get("dangerouslyDisableSandbox"):
            # The model wants to run this command outside the sandbox
            print(f"Unsandboxed command requested: {input.get('command')}")
    
            # Return True to allow, False to deny
            return is_command_authorized(input.get("command"))
        return True
    
    async def main():
        async for message in query(
            prompt="Deploy my application",
            options=ClaudeAgentOptions(
                sandbox={
                    "enabled": True,
                    "allowUnsandboxedCommands": True  # Model can request unsandboxed execution
                },
                permission_mode="default",
                can_use_tool=can_use_tool
            )
        ):
            print(message)

    Pola ini memungkinkan Anda untuk:

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

    Perintah yang berjalan dengan dangerouslyDisableSandbox: True memiliki akses sistem penuh. Pastikan handler can_use_tool Anda memvalidasi permintaan ini dengan hati-hati.

    Lihat juga

    • Panduan Python SDK - Tutorial dan contoh
    • Ikhtisar SDK - Konsep SDK umum
    • Referensi TypeScript SDK - Dokumentasi TypeScript SDK
    • Referensi CLI - Antarmuka baris perintah
    • Alur kerja umum - Panduan langkah demi langkah