airflow.providers.common.ai.tools.claude_agent_sdk¶
Give Airflow tools to an agent loop run by the Claude Agent SDK.
Note
Experimental; see Stable and experimental features.
Classes¶
Airflow's tools for an agent loop run by the Claude Agent SDK. |
Module Contents¶
- class airflow.providers.common.ai.tools.claude_agent_sdk.AirflowTools(*sources, server_name='airflow')[source]¶
Airflow’s tools for an agent loop run by the Claude Agent SDK.
Pass toolsets that implement
ToolProvider, such asSQLToolsetandHookToolset, or individualAirflowToolobjects. They are served through an in-process MCP server; add it andallowed_toolstoClaudeAgentOptions, or build them withbuild_options(), and drive the SDK’squery()withrun():from claude_agent_sdk import query from airflow.providers.common.ai.tools.claude_agent_sdk import AirflowTools from airflow.providers.common.ai.toolsets.sql import SQLToolset tools = AirflowTools(SQLToolset(db_conn_id="warehouse", allowed_tables=["orders"])) options = tools.build_options(model="claude-sonnet-5", max_turns=10) result = await tools.run(query(prompt="...", options=options))
Each tool keeps the source tool’s name, description and argument schema, and every result passes through Airflow’s secret masker first. A failure the model can correct, such as a query naming a missing column, reaches it as an
is_errortool result. A failure the model cannot fix, such as a hook raising, makesrun()raiseToolCallError, so the task fails and Airflow retries it. The SDK’s own tool dispatch catches every exception a handler raises and turns it into anis_errorresult the model reads, so drive the query withrun()rather than iterating it yourself.An instance runs one query at a time: build a new
AirflowToolsper task, or callrun()again once the previous run has finished. A tool call that arrives after a run has ended is refused until the nextrun()starts. A call that lands after the next run has started cannot be told apart and is served by that run.- Parameters:
sources (airflow.providers.common.ai.tools.ToolProvider | airflow.providers.common.ai.tools.AirflowTool) – Toolsets and tools to serve, in order.
server_name (str) – The MCP server name the tools are served under. Also the prefix of each tool’s name in
allowed_tools(mcp__<server_name>__<tool name>).
- build_options(**kwargs)[source]¶
Build
ClaudeAgentOptionswired to this instance’s tools, with safe defaults.ClaudeAgentOptions()on its own loads every settings source on the worker (~/.claude, project settings, a project.mcp.json) and leaves the CLI’s built-in tools on, including a worker-hostBash. This method instead defaultstoolsto[](no built-in tools),setting_sourcesto[](no settings files) andstrict_mcp_configtoTrue(only the MCP servers passed here), andverbatim_promptstoTrue. It addsserverandallowed_toolsto whatevermcp_serversandallowed_toolsthe caller passes. A keyword this method does not default, such asmodelorenv, is passed through unchanged.verbatim_promptsstops the CLI from expanding@pathfile mentions in a prompt; otherwise anyone who controls the prompt could send a file the worker user can read to the model, without passing the secret masker. It also turns off slash command dispatch and the CLI’s turn-start attachment pass.When
can_use_toolis passed, the Airflow tools are not added toallowed_tools, because an allowed tool never reaches the callback, andpermission_modedefaults to"default". The callback then decides on every Airflow tool call; the names are still inallowed_toolsif you want to allow some by hand.Everything it builds can also be assembled by hand; see
serverandallowed_tools.- Raises:
ValueError – when
mcp_serversalready has a server namedserver_name.
- async run(messages)[source]¶
Drive
messages, the streamquery()orClaudeSDKClient.receive_response()returns.ClaudeSDKClient.receive_messages()is not supported: it never ends.messagesis closed when this returns or raises. Forquery()that ends the CLI session, but only once the SDK finishes tearing down, so a tool call can still arrive after this returns or raises; it is answered with anis_error“Not run” result. AClaudeSDKClientstays connected until you disconnect it, for example by leaving itsasync withblock.- Raises:
RuntimeError – when this instance is already running a query, when
messagesends without aResultMessage, or, forClaudeSDKClient.receive_response(), when the result message hasis_errorset (for examplemax_turnsreached or an API failure). For a streamed prompt, any result message withis_errorset raises, even when a later turn succeeds.ResultError – for
query()when the result message hasis_errorset. The CLI exits non-zero right after such a result, so the SDK raisesclaude_agent_sdk.ResultError(aProcessError) from the stream before this method checks the result.ToolCallError – when a tool failed in a way the model cannot fix.