Unlike query(), ClaudeSDKClient additionally enables custom tools and hooks, both of which can be defined as Python functions.
Custom Tools (as In-Process SDK MCP Servers)
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.
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 Claude Code Hooks Reference.
For more examples, see examples/hooks.py.
fromclaude_agent_sdkimportClaudeAgentOptions, ClaudeSDKClient, HookMatcherasyncdefcheck_bash_command(input_data, tool_use_id, context):
tool_name=input_data["tool_name"]
tool_input=input_data["tool_input"]
iftool_name!="Bash":
return {}
command=tool_input.get("command", "")
block_patterns= ["foo.sh"]
forpatterninblock_patterns:
ifpatternincommand:
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]),
],
}
)
asyncwithClaudeSDKClient(options=options) asclient:
# Test 1: Command with forbidden pattern (will be blocked)awaitclient.query("Run the bash command: ./foo.sh --help")
asyncformsginclient.receive_response():
print(msg)
print("\n"+"="*50+"\n")
# Test 2: Safe command that should workawaitclient.query("Run the bash command: echo 'Hello from hooks example!'")
asyncformsginclient.receive_response():
print(msg)
If you're upgrading from the Claude Code SDK (versions < 0.1.0), please see the CHANGELOG.md for details on breaking changes and new features, including:
ClaudeCodeOptions → ClaudeAgentOptions rename
Merged system prompt configuration
Settings isolation and explicit control
New programmatic subagents and session forking features