MCPHook

Use MCPHook to connect a Dag task to an MCP (Model Context Protocol) server. The hook manages the server’s connection configuration – transport type, URL or subprocess command, and credentials – and builds the matching client transport, so a Dag never hard-codes a server URL or an auth token. Three transport types are supported: HTTP (Streamable HTTP), SSE, and stdio.

See also

MCP server connection for connection configuration and JSON examples.

Role in a Dag: use MCPToolset, not the hook directly

Most Dags should not instantiate MCPHook directly. The recommended entry point is MCPToolset (see MCP servers: MCPToolset), which resolves the hook lazily from an Airflow connection and manages the underlying session lifecycle for you:

airflow/providers/common/ai/example_dags/example_mcp.py[source]

@dag(tags=["example"])
def example_mcp_toolset():
    """Use an MCP server configured via an Airflow connection."""
    AgentOperator(
        task_id="mcp_agent",
        prompt="What tools are available? Run the hello tool.",
        llm_conn_id="pydanticai_default",
        system_prompt="You are a helpful assistant with access to MCP tools.",
        toolsets=[
            MCPToolset(mcp_conn_id="my_mcp_server"),
        ],
    )


Pass one or more MCPToolset instances to AgentOperator’s toolsets parameter and it drives MCPHook internally on every call. Under the hood, MCPToolset builds an MCPHook from mcp_conn_id, tool_prefix, token_provider, and env_provider, then calls hook.get_conn() the first time it needs the server.

What MCPHook itself does

MCPHook.get_conn() reads the connection’s transport type from Extra.transport and returns a configured pydantic-ai MCPToolset – an upstream pydantic-ai class, distinct from Airflow’s own MCPToolset described above – built over the matching FastMCP transport:

  • http (default): fastmcp.client.transports.StreamableHttpTransport

  • sse: fastmcp.client.transports.SSETransport

  • stdio: fastmcp.client.transports.StdioTransport

When tool_prefix is set, the returned toolset is wrapped so every tool name gets that prefix (e.g. "weather" yields weather_get_forecast). The result is cached for the lifetime of the hook instance.

test_connection() validates that the connection has the fields required for its configured transport, but does not connect to the server – doing so requires the async context manager that MCPToolset drives.

token_provider and env_provider replace a static token or a static Extra.env value with a zero-argument callable, invoked once the first time the hook establishes a connection; MCP servers: MCPToolset explains both.

Connection fields

MCPHook uses the mcp connection type. MCP server connection documents each field (host, password and the transport, command, args, env and timeout keys in extra) with a JSON example per transport.

Dependencies

Install the mcp extra:

pip install "apache-airflow-providers-common-ai[mcp]"

Was this entry helpful?