Claude Agent 用の Python SDK です。詳細はClaude Agent SDK ドキュメントをご覧ください。
pip install claude-agent-sdk前提条件:
- Python 3.10+
注:Claude Code CLI は自動的にパッケージに含まれています。別途インストールは不要です。SDK はデフォルトでバンドルされた CLI を使用します。システム全体のインストールまたは特定バージョンを使用する場合は、以下の方法があります:
- Claude Code を別途インストール:
curl -fsSL https://claude.ai/install.sh | bash - カスタムパスを指定:
ClaudeAgentOptions(cli_path="/path/to/claude")
import anyio
from claude_agent_sdk import query
async def main():
async for message in query(prompt="What is 2 + 2?"):
print(message)
anyio.run(main)query() は Claude Code をクエリするための非同期関数です。レスポンスメッセージの AsyncIterator を返します。src/claude_agent_sdk/query.py を参照してください。
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock
# Simple query
async for message in query(prompt="Hello Claude"):
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text)
# With options
options = ClaudeAgentOptions(
system_prompt="You are a helpful assistant",
max_turns=1
)
async for message in query(prompt="Tell me a joke", options=options):
print(message)デフォルトでは、Claude は完全な Claude Code ツールセット(Read、Write、Edit、Bash など)にアクセスできます。allowed_tools はパーミッション許可リストです。リストに記載されているツールは自動的に承認され、リストに記載されていないツールは permission_mode と can_use_tool で判定されます。これは Claude のツールセットからツールを削除するわけではありません。特定のツールをブロックするには、disallowed_tools を使用してください。詳細な評価順序については、パーミッションガイドを参照してください。
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Bash"], # auto-approve these tools
permission_mode='acceptEdits' # auto-accept file edits
)
async for message in query(
prompt="Create a hello.py file",
options=options
):
# Process tool use and results
passfrom pathlib import Path
options = ClaudeAgentOptions(
cwd="/path/to/project" # or Path("/path/to/project")
)ClaudeSDKClient は Claude Code との双方向的でインタラクティブな会話をサポートしています。src/claude_agent_sdk/client.py を参照してください。
query() とは異なり、ClaudeSDKClient はさらにカスタムツールとフックをサポートしており、両方とも Python 関数として定義することができます。
カスタムツールは、Claude が必要に応じて呼び出すために提供できる Python 関数です。
カスタムツールは、Python アプリケーション内で直接実行されるインプロセス MCP サーバーとして実装されており、通常の MCP サーバーが必要とする別々のプロセスの必要性を排除します。
エンドツーエンドの例については、MCP Calculator を参照してください。
from claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeAgentOptions, ClaudeSDKClient
# Define a tool using the @tool decorator
@tool("greet", "Greet a user", {"name": str})
async def greet_user(args):
return {
"content": [
{"type": "text", "text": f"Hello, {args['name']}!"}
]
}
# Create an SDK MCP server
server = create_sdk_mcp_server(
name="my-tools",
version="1.0.0",
tools=[greet_user]
)
# Use it with Claude. allowed_tools pre-approves the tool so it runs
# without a permission prompt; it does not control tool availability.
options = ClaudeAgentOptions(
mcp_servers={"tools": server},
allowed_tools=["mcp__tools__greet"]
)
async with ClaudeSDKClient(options=options) as client:
await client.query("Greet Alice")
# Extract and print response
async for msg in client.receive_response():
print(msg)- サブプロセス管理が不要 - アプリケーションと同じプロセスで実行されます
- より優れたパフォーマンス - ツール呼び出しのIPC オーバーヘッドがありません
- より簡単なデプロイメント - 複数のプロセスではなく単一の Python プロセスです
- より簡単なデバッグ - すべてのコードが同じプロセスで実行されます
- 型安全性 - 型ヒント付きの直接的な Python 関数呼び出しです
# BEFORE: External MCP server (separate process)
options = ClaudeAgentOptions(
mcp_servers={
"calculator": {
"type": "stdio",
"command": "python",
"args": ["-m", "calculator_server"]
}
}
)
# AFTER: SDK MCP server (in-process)
from my_tools import add, subtract # Your tool functions
calculator = create_sdk_mcp_server(
name="calculator",
tools=[add, subtract]
)
options = ClaudeAgentOptions(
mcp_servers={"calculator": calculator}
)SDK と外部 MCP サーバーの両方を同時に使用できます。
options = ClaudeAgentOptions(
mcp_servers={
"internal": sdk_server, # In-process SDK server
"external": { # External subprocess server
"type": "stdio",
"command": "external-server"
}
}
)フックは Python 関数で、Claude Code アプリケーション(Claude ではなく)が Claude エージェントループの特定の時点で呼び出します。フックは決定論的な処理と Claude への自動フィードバックを提供できます。詳細は エージェントの動作をインターセプトして制御するフックを参照してください。
その他の例については examples/hooks.py を参照してください。
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient, HookMatcher
async def check_bash_command(input_data, tool_use_id, context):
tool_name = input_data["tool_name"]
tool_input = input_data["tool_input"]
if tool_name != "Bash":
return {}
command = tool_input.get("command", "")
block_patterns = ["foo.sh"]
for pattern in block_patterns:
if pattern in command:
return {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": f"Command contains invalid pattern: {pattern}",
}
}
return {}
options = ClaudeAgentOptions(
allowed_tools=["Bash"],
hooks={
"PreToolUse": [
HookMatcher(matcher="Bash", hooks=[check_bash_command]),
],
}
)
async with ClaudeSDKClient(options=options) as client:
# Test 1: Command with forbidden pattern (will be blocked)
await client.query("Run the bash command: ./foo.sh --help")
async for msg in client.receive_response():
print(msg)
print("\n" + "=" * 50 + "\n")
# Test 2: Safe command that should work
await client.query("Run the bash command: echo 'Hello from hooks example!'")
async for msg in client.receive_response():
print(msg)完全な型定義については src/claude_agent_sdk/types.py を参照してください:
ClaudeAgentOptions- 設定オプションAssistantMessage、UserMessage、SystemMessage、ResultMessage- メッセージ型TextBlock、ToolUseBlock、ToolResultBlock- コンテンツブロック
from claude_agent_sdk import (
ClaudeSDKError, # Base error
CLINotFoundError, # Claude Code not installed
CLIConnectionError, # Connection issues
ProcessError, # Process failed
CLIJSONDecodeError, # JSON parsing issues
)
try:
async for message in query(prompt="Hello"):
pass
except CLINotFoundError:
print(
— GitHub から取得した原文(一部省略の場合あり)
Python SDK for Claude Agent. See the Claude Agent SDK documentation for more information.
pip install claude-agent-sdk
Prerequisites:
- Python 3.10+
Note: The Claude Code CLI is automatically bundled with the package - no separate installation required! The SDK will use the bundled CLI by default. If you prefer to use a system-wide installation or a specific version, you can:
- Install Claude Code separately:
curl -fsSL https://claude.ai/install.sh | bash
- Specify a custom path:
ClaudeAgentOptions(cli_path="/path/to/claude")
import anyio
from claude_agent_sdk import query
async def main():
async for message in query(prompt="What is 2 + 2?"):
print(message)
anyio.run(main)
query() is an async function for querying Claude Code. It returns an AsyncIterator of response messages. See src/claude_agent_sdk/query.py.
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock
# Simple query
async for message in query(prompt="Hello Claude"):
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text)
# With options
options = ClaudeAgentOptions(
system_prompt="You are a helpful assistant",
max_turns=1
)
async for message in query(prompt="Tell me a joke", options=options):
print(message)
By default, Claude has access to the full Claude Code toolset (Read, Write, Edit, Bash, and others). allowed_tools is a permission allowlist: listed tools are auto-approved, and unlisted tools fall through to permission_mode and can_use_tool for a decision. It does not remove tools from Claude's toolset. To block specific tools, use disallowed_tools. See the permissions guide for the full evaluation order.
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Bash"], # auto-approve these tools
permission_mode='acceptEdits' # auto-accept file edits
)
async for message in query(
prompt="Create a hello.py file",
options=options
):
# Process tool use and results
pass
from pathlib import Path
options = ClaudeAgentOptions(
cwd="/path/to/project" # or Path("/path/to/project")
)
ClaudeSDKClient supports bidirectional, interactive conversations with Claude
Code. See src/claude_agent_sdk/client.py.
Unlike query(), ClaudeSDKClient additionally enables custom tools and hooks, both of which can be defined as Python functions.
A custom tool is a Python function that you can offer to Claude, for Claude to invoke as needed.
Custom tools are implemented in-process MCP servers that run directly within your Python application, eliminating the need for separate processes that regular MCP servers require.
For an end-to-end example, see MCP Calculator.
from claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeAgentOptions, ClaudeSDKClient
# Define a tool using the @tool decorator
@tool("greet", "Greet a user", {"name": str})
async def greet_user(args):
return {
"content": [
{"type": "text", "text": f"Hello, {args['name']}!"}
]
}
# Create an SDK MCP server
server = create_sdk_mcp_server(
name="my-tools",
version="1.0.0",
tools=[greet_user]
)
# Use it with Claude. allowed_tools pre-approves the tool so it runs
# without a permission prompt; it does not control tool availability.
options = ClaudeAgentOptions(
mcp_servers={"tools": server},
allowed_tools=["mcp__tools__greet"]
)
async with ClaudeSDKClient(options=options) as client:
await client.query("Greet Alice")
# Extract and print response
async for msg in client.receive_response():
print(msg)
- No subprocess management - Runs in the same process as your application
- Better performance - No IPC overhead for tool calls
- Simpler deployment - Single Python process instead of multiple
- Easier debugging - All code runs in the same process
- Type safety - Direct Python function calls with type hints
# BEFORE: External MCP server (separate process)
options = ClaudeAgentOptions(
mcp_servers={
"calculator": {
"type": "stdio",
"command": "python",
"args": ["-m", "calculator_server"]
}
}
)
# AFTER: SDK MCP server (in-process)
from my_tools import add, subtract # Your tool functions
calculator = create_sdk_mcp_server(
name="calculator",
tools=[add, subtract]
)
options = ClaudeAgentOptions(
mcp_servers={"calculator": calculator}
)
You can use both SDK and external MCP servers together:
options = ClaudeAgentOptions(
mcp_servers={
"internal": sdk_server, # In-process SDK server
"external": { # External subprocess server
"type": "stdio",
"command": "external-server"
}
}
)
A hook is a Python function that the Claude Code application (not Claude) invokes at specific points of the Claude agent loop. Hooks can provide deterministic processing and automated feedback for Claude. Read more in Intercept and control agent behavior with hooks.
For more examples, see examples/hooks.py.
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient, HookMatcher
async def check_bash_command(input_data, tool_use_id, context):
tool_name = input_data["tool_name"]
tool_input = input_data["tool_input"]
if tool_name != "Bash":
return {}
command = tool_input.get("command", "")
block_patterns = ["foo.sh"]
for pattern in block_patterns:
if pattern in command:
return {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": f"Command contains invalid pattern: {pattern}",
}
}
return {}
options = ClaudeAgentOptions(
allowed_tools=["Bash"],
hooks={
"PreToolUse": [
HookMatcher(matcher="Bash", hooks=[check_bash_command]),
],
}
)
async with ClaudeSDKClient(options=options) as client:
# Test 1: Command with forbidden pattern (will be blocked)
await client.query("Run the bash command: ./foo.sh --help")
async for msg in client.receive_response():
print(msg)
print("\n" + "=" * 50 + "\n")
# Test 2: Safe command that should work
await client.query("Run the bash command: echo 'Hello from hooks example!'")
async for msg in client.receive_response():
print(msg)
See src/claude_agent_sdk/types.py for complete type definitions:
ClaudeAgentOptions - Configuration options
AssistantMessage, UserMessage, SystemMessage, ResultMessage - Message types
TextBlock, ToolUseBlock, ToolResultBlock - Content blocks
from claude_agent_sdk import (
ClaudeSDKError, # Base error
CLINotFoundError, # Claude Code not installed
CLIConnectionError, # Connection issues
ProcessError, # Process failed
CLIJSONDecodeError, # JSON parsing issues
)
try:
async for message in query(prompt="Hello"):
pass
except CLINotFoundError:
print(
RELATED
同じカテゴリの他のツール