
이전 글에서 API Key 없이 Claude Agent 서버를 만드는 방법을 다뤘습니다. 그 서버의 핵심에는 ClaudeAgentOptions라는 클래스가 있었죠.
options = ClaudeAgentOptions(
permission_mode="bypassPermissions",
allowed_tools=["Read", "Write", "Edit", "Bash"],
)
이전 글에서는 딱 이 두 줄만 썼지만, 실제로 ClaudeAgentOptions에는 30개가 넘는 옵션이 있습니다. 이 글에서는 하나하나 뜯어보면서, 어떤 상황에서 어떤 옵션을 쓰면 되는지 정리합니다.
ClaudeAgentOptions는 Python dataclass로 정의되어 있고, query() 함수에 넘겨서 Claude Agent의 동작을 제어합니다.
from claude_agent_sdk import query, ClaudeAgentOptions
options = ClaudeAgentOptions(
# 여기에 옵션들을 넣는다
)
async for message in query(prompt="할 일", options=options):
...
모든 필드에는 기본값이 있으므로, 필요한 것만 골라서 쓰면 됩니다.
30개가 넘는 옵션을 용도별로 7개 그룹으로 나눠서 설명합니다.
이 그룹이 가장 중요합니다. Claude Agent는 파일을 읽고, 쓰고, 코드를 실행할 수 있는데, 이걸 어디까지 허용할지 결정합니다.
permission_modepermission_mode: Literal["default", "acceptEdits", "plan", "bypassPermissions", "dontAsk"] | None
에이전트의 전반적인 권한 수준을 설정합니다.
| 모드 | 설명 | 언제 쓰나 |
|---|---|---|
"default" | 위험한 동작마다 사용자에게 확인 요청 | 대화형 CLI에서 기본값 |
"acceptEdits" | 파일 편집은 자동 허용, 나머지는 확인 | 코드 수정 자동화 |
"plan" | 읽기만 허용, 수정 불가 | 코드 분석/리뷰 |
"bypassPermissions" | 모든 동작 자동 허용 | 서버/자동화 환경 필수 |
"dontAsk" | 확인 안 하고, 허용 안 된 건 건너뜀 | CI/CD 파이프라인 |
서버 환경에서는 사용자에게 "이거 실행해도 될까요?"라고 물어볼 수 없으므로, "bypassPermissions"가 사실상 필수입니다.
# 서버 환경에서의 기본 설정
options = ClaudeAgentOptions(
permission_mode="bypassPermissions"
)
allowed_tools / disallowed_toolsallowed_tools: list[str] # 기본값: []
disallowed_tools: list[str] # 기본값: []
에이전트가 사용할 수 있는 도구를 화이트리스트/블랙리스트로 제어합니다.
# 파일 읽기/쓰기만 허용하고, 명령어 실행은 금지
options = ClaudeAgentOptions(
permission_mode="bypassPermissions",
allowed_tools=["Read", "Write", "Edit", "Glob", "Grep"],
disallowed_tools=["Bash"], # 셸 명령 차단
)
주요 도구 목록:
Read — 파일 읽기Write — 파일 생성Edit — 파일 수정Bash — 셸 명령 실행Glob — 파일 패턴 검색Grep — 파일 내용 검색WebFetch — 웹 요청WebSearch — 웹 검색can_use_toolcan_use_tool: Callable | None # 기본값: None
도구 사용 요청이 올 때마다 호출되는 콜백 함수입니다. 단순 허용/차단보다 세밀한 제어가 필요할 때 씁니다.
async def my_permission_check(tool_name, tool_input, context):
# rm -rf 같은 위험한 명령은 차단
if tool_name == "Bash" and "rm -rf" in tool_input.get("command", ""):
return PermissionResultDeny(message="위험한 명령입니다")
return PermissionResultAllow()
options = ClaudeAgentOptions(
can_use_tool=my_permission_check
)
model / fallback_modelmodel: str | None # 기본값: None (CLI 기본 모델)
fallback_model: str | None # 기본값: None
사용할 모델을 지정합니다. model이 실패하면 fallback_model로 자동 전환됩니다.
options = ClaudeAgentOptions(
model="claude-sonnet-4-6",
fallback_model="claude-haiku-4-5-20251001",
)
thinking / effortthinking: ThinkingConfig | None
effort: Literal["low", "medium", "high", "max"] | None
Claude의 사고 깊이를 조절합니다.
# 복잡한 문제: 깊게 생각하게 하기
options = ClaudeAgentOptions(
thinking={"type": "enabled", "budget_tokens": 10000},
effort="max",
)
# 단순한 작업: 빠르게 처리
options = ClaudeAgentOptions(
thinking={"type": "disabled"},
effort="low",
)
thinking에는 3가지 모드가 있습니다:
{"type": "adaptive"} — Claude가 알아서 판단{"type": "enabled", "budget_tokens": N} — 최대 N 토큰까지 사고{"type": "disabled"} — 사고 과정 비활성화max_turnsmax_turns: int | None # 기본값: None (제한 없음)
에이전트의 최대 턴 수를 제한합니다. 한 턴은 "Claude 응답 → 도구 실행 → 결과 반환"의 한 사이클입니다.
# 간단한 질문에는 3턴이면 충분
options = ClaudeAgentOptions(max_turns=3)
무한 루프 방지에 유용합니다. 서버 환경에서는 반드시 설정하는 것을 권장합니다.
max_budget_usdmax_budget_usd: float | None # 기본값: None
API 비용 상한선을 달러 단위로 설정합니다.
options = ClaudeAgentOptions(max_budget_usd=1.0) # 1달러 초과 시 중단
task_budgettask_budget: TaskBudget | None # 기본값: None
토큰 단위로 예산을 설정합니다. 모델이 남은 예산을 인식하고, 예산 내에서 작업을 마무리하려고 시도합니다.
options = ClaudeAgentOptions(
task_budget={"total": 50000} # 5만 토큰 예산
)
system_promptsystem_prompt: str | SystemPromptPreset | SystemPromptFile | None
3가지 방식으로 시스템 프롬프트를 설정할 수 있습니다.
# 방법 1: 직접 문자열로
options = ClaudeAgentOptions(
system_prompt="너는 Python 전문가야. 항상 타입 힌트를 포함해서 코드를 작성해."
)
# 방법 2: Claude Code 기본 프롬프트 + 추가 지시
options = ClaudeAgentOptions(
system_prompt={
"type": "preset",
"preset": "claude_code",
"append": "한국어로 답변해줘."
}
)
# 방법 3: 파일에서 읽기
options = ClaudeAgentOptions(
system_prompt={
"type": "file",
"path": "/path/to/system-prompt.md"
}
)
session_id / continue_conversation / resume / fork_sessionsession_id: str | None # 기본값: None
continue_conversation: bool # 기본값: False
resume: str | None # 기본값: None
fork_session: bool # 기본값: False
Claude Agent는 대화 내역을 세션 단위로 관리합니다.
# 새 대화 시작 (기본)
options = ClaudeAgentOptions()
# 기존 세션 이어서 대화
options = ClaudeAgentOptions(
session_id="abc-123",
continue_conversation=True,
)
# 가장 최근 세션 재개
options = ClaudeAgentOptions(resume="most-recent")
# 기존 세션을 복제해서 새 세션으로 분기
options = ClaudeAgentOptions(
session_id="abc-123",
continue_conversation=True,
fork_session=True, # 원본 세션은 건드리지 않음
)
cwdcwd: str | Path | None # 기본값: None (현재 디렉토리)
에이전트의 작업 디렉토리를 설정합니다. 에이전트가 파일을 읽고 쓸 때 이 디렉토리를 기준으로 동작합니다.
options = ClaudeAgentOptions(
cwd="/app/workspace" # 에이전트를 이 디렉토리에 가둔다
)
Docker 환경에서는 볼륨 마운트된 디렉토리를 지정하면, 에이전트의 파일 작업을 호스트와 공유할 수 있습니다.
envenv: dict[str, str] # 기본값: {}
에이전트 프로세스에 전달할 환경변수입니다.
options = ClaudeAgentOptions(
env={
"NODE_ENV": "production",
"DATABASE_URL": "postgresql://localhost:5432/mydb",
}
)
cli_pathcli_path: str | Path | None # 기본값: None (자동 탐색)
Claude Code CLI의 경로를 직접 지정합니다. 여러 버전의 CLI가 설치되어 있을 때 유용합니다.
add_dirsadd_dirs: list[str | Path] # 기본값: []
추가 작업 디렉토리를 지정합니다. 여러 프로젝트에 걸쳐 작업할 때 씁니다.
options = ClaudeAgentOptions(
cwd="/app/frontend",
add_dirs=["/app/backend", "/app/shared"], # 이 디렉토리들도 접근 가능
)
toolstools: list[str] | ToolsPreset | None # 기본값: None
allowed_tools가 "이 도구들을 자동 승인"이라면, tools는 "이 도구들만 로드"입니다. Claude Code의 기본 도구셋을 쓰려면 프리셋을 사용합니다.
# Claude Code 기본 도구셋 사용
options = ClaudeAgentOptions(
tools={"type": "preset", "preset": "claude_code"}
)
mcp_serversmcp_servers: dict[str, McpServerConfig] | str | Path
MCP(Model Context Protocol) 서버를 연결합니다. 외부 도구를 Claude에 붙일 수 있는 확장 포인트입니다.
options = ClaudeAgentOptions(
mcp_servers={
"my-db-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"],
}
}
)
hookshooks: dict[HookEvent, list[HookMatcher]] | None
에이전트의 동작에 훅을 걸 수 있습니다. 도구 실행 전/후, 중지 시점 등에 콜백을 등록합니다.
async def log_tool_use(input_data, tool_use_id, context):
print(f"도구 사용: {input_data['tool_name']}")
return {}
options = ClaudeAgentOptions(
hooks={
"PreToolUse": [
HookMatcher(matcher=None, hooks=[log_tool_use])
]
}
)
지원되는 훅 이벤트:
PreToolUse — 도구 실행 전PostToolUse — 도구 실행 후PostToolUseFailure — 도구 실행 실패 시UserPromptSubmit — 사용자 프롬프트 제출 시Stop — 에이전트 종료 시SubagentStart / SubagentStop — 서브 에이전트 시작/종료 시output_formatoutput_format: dict[str, Any] | None # 기본값: None
Claude의 응답을 정해진 JSON 스키마로 받을 수 있습니다.
options = ClaudeAgentOptions(
output_format={
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"summary": {"type": "string"},
"severity": {"type": "string", "enum": ["low", "medium", "high"]},
"suggestions": {"type": "array", "items": {"type": "string"}},
},
"required": ["summary", "severity", "suggestions"],
}
}
)
코드 리뷰 자동화 같은 상황에서, 항상 같은 구조의 결과를 받고 싶을 때 유용합니다.
agentsagents: dict[str, AgentDefinition] | None
커스텀 서브 에이전트를 정의합니다. 복잡한 작업을 여러 에이전트로 분업시킬 수 있습니다.
options = ClaudeAgentOptions(
agents={
"code-reviewer": AgentDefinition(
description="코드 리뷰 전문가",
prompt="코드를 분석하고 개선점을 제안해줘.",
tools=["Read", "Glob", "Grep"],
model="claude-sonnet-4-6",
),
"test-writer": AgentDefinition(
description="테스트 코드 작성가",
prompt="주어진 코드에 대한 테스트를 작성해줘.",
tools=["Read", "Write", "Bash"],
),
}
)
sandboxsandbox: SandboxSettings | None
Bash 명령을 샌드박스 안에서 격리 실행합니다.
options = ClaudeAgentOptions(
sandbox={
"enabled": True,
"autoAllowBashIfSandboxed": True,
"excludedCommands": ["docker", "git"], # 이 명령은 샌드박스 밖에서 실행
"network": {
"allowLocalBinding": True,
},
}
)
include_partial_messagesinclude_partial_messages: bool # 기본값: False
True로 설정하면 Claude가 응답을 생성하는 도중의 부분 메시지도 스트림으로 받을 수 있습니다. 실시간 타이핑 효과를 구현할 때 쓰입니다.
enable_file_checkpointingenable_file_checkpointing: bool # 기본값: False
파일 변경 이력을 추적합니다. 나중에 특정 시점으로 파일을 되돌릴 수 있습니다.
options = ClaudeAgentOptions(
permission_mode="plan", # 읽기만 허용
system_prompt="코드를 리뷰하고 개선점을 JSON으로 반환해.",
model="claude-sonnet-4-6",
max_turns=5,
effort="high",
output_format={
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"issues": {"type": "array", "items": {"type": "string"}},
"score": {"type": "integer"},
},
"required": ["issues", "score"],
}
},
)
options = ClaudeAgentOptions(
permission_mode="bypassPermissions",
allowed_tools=["Read", "Write", "Edit", "Glob", "Grep"],
disallowed_tools=["Bash"], # 명령 실행은 차단
cwd="/app/workspace",
max_turns=20,
max_budget_usd=0.5,
thinking={"type": "adaptive"},
)
# 첫 번째 요청
options = ClaudeAgentOptions(
permission_mode="bypassPermissions",
cwd="/app/workspace",
)
# session_id를 저장해둔다
# 두 번째 요청 — 이전 대화 이어서
options = ClaudeAgentOptions(
permission_mode="bypassPermissions",
session_id=saved_session_id,
continue_conversation=True,
cwd="/app/workspace",
)
| 옵션 | 타입 | 기본값 | 한 줄 설명 |
|---|---|---|---|
permission_mode | str | None | 권한 모드 (default/acceptEdits/plan/bypassPermissions/dontAsk) |
allowed_tools | list[str] | [] | 자동 승인할 도구 목록 |
disallowed_tools | list[str] | [] | 사용 금지할 도구 목록 |
can_use_tool | Callable | None | 도구 승인 콜백 함수 |
tools | list[str] | None | 로드할 도구 목록 / 프리셋 |
model | str | None | 사용할 모델 |
fallback_model | str | None | 폴백 모델 |
thinking | dict | None | 사고 모드 설정 (adaptive/enabled/disabled) |
effort | str | None | 사고 깊이 (low/medium/high/max) |
max_turns | int | None | 최대 턴 수 |
max_budget_usd | float | None | 비용 상한 (달러) |
task_budget | dict | None | 토큰 예산 |
system_prompt | str/dict | None | 시스템 프롬프트 |
session_id | str | None | 세션 ID |
continue_conversation | bool | False | 기존 세션 이어서 대화 |
resume | str | None | 세션 재개 |
fork_session | bool | False | 세션 분기 |
cwd | str/Path | None | 작업 디렉토리 |
add_dirs | list | [] | 추가 작업 디렉토리 |
env | dict | {} | 환경변수 |
cli_path | str/Path | None | CLI 경로 |
settings | str | None | 설정 파일 경로 |
mcp_servers | dict | {} | MCP 서버 설정 |
hooks | dict | None | 훅 콜백 설정 |
agents | dict | None | 커스텀 서브 에이전트 |
output_format | dict | None | 구조화된 출력 스키마 |
sandbox | dict | None | Bash 샌드박스 설정 |
include_partial_messages | bool | False | 부분 메시지 스트리밍 |
enable_file_checkpointing | bool | False | 파일 변경 추적 |
betas | list | [] | 베타 기능 활성화 |
plugins | list | [] | 플러그인 설정 |
ClaudeAgentOptions는 단순한 설정 클래스가 아니라, Claude Agent의 동작 범위를 결정하는 제어판입니다.
처음 시작한다면 이 3가지만 기억하세요:
1. permission_mode — 서버에서는 "bypassPermissions"
2. allowed_tools / disallowed_tools — 도구 범위 제한
3. max_turns — 무한 루프 방지
나머지는 필요할 때 하나씩 추가하면 됩니다.
전체 소스 코드는 GitHub에서 확인할 수 있습니다:
👉 GitHub 레포지토리 링크