~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.",
)
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.