Skip to content
C.W.K.
Stream
Lesson 03 of 08 · published

ClaudeAgentOptions: Every Knob That Matters

~18 min · options, configuration, ClaudeAgentOptions

Level 0Observer
0 XP0/64 lessons0/13 achievements
0/150 XP to next level150 XP to go0% complete

The configuration object

ClaudeAgentOptions is the single place every agent decision lives. Working directory, system prompt, available and pre-approved tools, MCP servers, hooks, model selection, thinking, environment variables — all of it. Treat it like a typed config struct, not a free-for-all kwargs blob.

The fields you will touch most

cwd (working directory), system_prompt (preset, string, or list of blocks), tools (which built-in tools exist at all; [] disables them), allowed_tools (which of them run without a permission prompt; it does not restrict anything), disallowed_tools (removed from the model's context outright), model (which Claude tier), permission_mode ('default' / 'acceptEdits' / 'bypassPermissions' / 'plan' / 'dontAsk', and more in newer releases), mcp_servers (dict mapping server name to launch config), hooks (PreToolUse, PostToolUse, etc.), env (environment variables for the subprocess).

Avoid bypassPermissions in production

permission_mode='bypassPermissions' disables every permission gate. Useful for trusted CI scripts, dangerous for anything user-facing. Default to 'default' (interactive prompts) or 'acceptEdits' (auto-accept file writes only) and document why if you ever need to bypass.

Principle: Options is policy. The agent's behavior is the options object's shape, not the prompt's wording.

Code

A production-shaped options object·python
from claude_agent_sdk import ClaudeAgentOptions

options = ClaudeAgentOptions(
    cwd="/srv/myapp",
    model="claude-sonnet-4-6",
    system_prompt="You are a deployment review assistant. Read CHANGELOG.md and report risks.",
    tools=["Read", "Grep", "Bash"],         # what exists: no Write, no Edit
    allowed_tools=["Read", "Grep"],         # what runs without asking
    permission_mode="default",              # Bash still asks
    env={"PATH": "/usr/local/bin:/usr/bin"},  # merged over the parent environment
    thinking={"type": "adaptive"},          # max_thinking_tokens is deprecated
)
Restricting tools to read-only·python
from claude_agent_sdk import ClaudeAgentOptions

# tools= decides what exists; allowed_tools= only decides what skips the prompt.
READ_ONLY_TOOLS = ["Read", "Grep", "Glob", "WebFetch"]

options = ClaudeAgentOptions(
    cwd="/data/audit",
    tools=READ_ONLY_TOOLS,          # Write, Edit and Bash are not in the model's toolbox at all
    allowed_tools=READ_ONLY_TOOLS,  # and these four run without asking
    system_prompt="You are a read-only auditor. Never modify files.",
)

External links

Exercise

For one Agent SDK call in your code, audit the options object. Verify model is pinned, tools is the smallest set that works, allowed_tools pre-approves only what should never prompt, permission_mode is conservative, and system_prompt is structured (not stream-of-consciousness).
Hint
If you cannot remember why a tool is allowed, remove it. If breakage exposes the need, add it back with a comment.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.