airflow-mcp-server
This server provides a curated interface for inspecting and operating Apache Airflow 2 via its REST API, offering both read-only access and guarded write capabilities.
Read capabilities:
get_airflow_version– Check the Airflow version and confirm API connectivityget_airflow_health– View health status of Airflow components (metadatabase, scheduler, triggerer, dag-processor)list_dags– List DAGs with pause state, schedule, owners, and tags (filterable by tag, paused state, and dag_id pattern)get_dag– Get details of a single DAG by IDlist_dag_runs– List runs of a DAG, most recent first (filterable by state, limit, offset)get_dag_run– Get a single DAG run by DAG ID and run IDlist_task_instances– List task instances in a DAG run with states and timings (filterable by state)get_task_instance– Get a single task instance by DAG ID, run ID, and task IDget_task_logs– Read logs for a specific task attempt (supports tailing for large logs)list_import_errors– List DAG parse/import errors with filenames and stack traceslist_pools– List worker pools with slot usage (occupied, running, queued, open)
Write capabilities (disabled when AIRFLOW_MCP_READ_ONLY=true):
trigger_dag_run– Trigger a new DAG run, optionally with a custom run ID, logical date, config, and noteset_dag_paused– Pause or unpause a DAG to stop/resume schedulingclear_task_instances– Clear (retry) task instances; supportsdry_run=Trueto preview affected tasks without making changes, with options to filter by task IDs, run ID, failed-only, and include upstream/downstream tasks
Allows inspection and operation of Apache Airflow over its REST API, providing tools for managing DAGs, DAG runs, task instances, logs, pools, and import errors.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@airflow-mcp-server what's the health of my Airflow instance?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
airflow-mcp-server
An MCP server that lets Claude inspect and operate Apache Airflow over its REST API. It exposes safe, curated tools (read + a few guarded writes) rather than mirroring the whole API.
Targets Airflow 2 (stable REST API /api/v1). Airflow 3 is intentionally
out of scope.
Runs as a local stdio server: each user runs it on their own machine with their own Airflow credentials, which keeps Airflow RBAC intact.
Status
Working read and write tools against Airflow 2; not yet published.
Read: get_airflow_version, get_airflow_health, list_pools,
list_dags, get_dag, list_dag_runs, get_dag_run, list_task_instances,
get_task_instance, get_task_logs, list_import_errors.
Write (refused when AIRFLOW_MCP_READ_ONLY=true): trigger_dag_run,
set_dag_paused, clear_task_instances (supports dry_run to preview, and
reopens a finished DAG run by default so cleared tasks actually get scheduled).
Related MCP server: MCP Server for Apache Airflow
Configuration
All settings come from AIRFLOW_MCP_* environment variables (prefixed to avoid
clashing with Airflow's own env). See .env.example.
Variable | Required | Default | Notes |
| yes | - | e.g. |
| one auth method | - | Basic auth |
| one auth method | - | Bearer token; wins over basic auth |
| no |
|
|
| no |
| |
| no |
| seconds |
Use with Claude
Run it straight from GitHub - no clone needed (uvx fetches and runs it):
{
"mcpServers": {
"airflow": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/ssasuoirafen/airflow-mcp-server",
"airflow-mcp"
],
"env": {
"AIRFLOW_MCP_BASE_URL": "http://localhost:8080",
"AIRFLOW_MCP_USERNAME": "airflow",
"AIRFLOW_MCP_PASSWORD": "airflow"
}
}
}
}Pin a version by appending a ref, e.g. git+https://github.com/ssasuoirafen/airflow-mcp-server@v0.1.0.
For local development, point at a checkout instead:
"command": "uv",
"args": ["run", "--directory", "C:\\path\\to\\airflow-mcp-server", "airflow-mcp"]The package also installs an airflow-mcp-server executable (same thing) for the longer name.
If published to PyPI later, this simplifies to "command": "uvx", "args": ["airflow-mcp"].
Development
uv sync # install deps
uv run pytest # unit tests (mocked, no network)
uv run pytest -m e2e # opt-in live test; needs a .env pointing at a real Airflow 2
uv run airflow-mcp # run the server (expects an MCP client on stdio)Roadmap
Foundation + connectivity (version, health). done
Read tools: DAGs, DAG runs, task instances, logs, import errors, pools. done
Safe writes: trigger DAG, pause/unpause, clear/retry tasks (gated by read-only). done
Packaging metadata and LICENSE. done
Publish to PyPI. pending
License
MIT - see LICENSE.
Available Tools
14 toolsclear_task_instancesADestructive
Clear task instances so they re-run (retry).
Clearing resets task state and the scheduler re-runs them, so it is
destructive - it can re-execute work. Use dry_run=True first to preview
exactly which task instances would be affected without changing anything.
Inputs: dag_id (required), dag_run_id, task_ids, include_downstream, +3 more. Returns: task_instances, total_entries
get_airflow_healthARead-only
Return Airflow component health: metadatabase, scheduler, triggerer, dag-processor.
Inputs: no named parameters. Returns: metadatabase, scheduler, triggerer, dag_processor
get_airflow_versionARead-only
Return the Airflow version reported by the API.
Handy for confirming connectivity and which Airflow major version is in use.
Inputs: no named parameters. Returns: version, git_version
get_dagBRead-only
Get a single DAG's details by dag_id.
Inputs: dag_id (required). Returns: dag_id, is_paused, is_active, description, +6 more
get_dag_runARead-only
Get a single DAG run by dag_id and dag_run_id.
Inputs: dag_id (required), dag_run_id (required). Returns: dag_run_id, dag_id, state, run_type, +6 more
get_task_instanceBRead-only
Get a single task instance by dag_id, dag_run_id, and task_id.
Inputs: dag_id (required), dag_run_id (required), task_id (required). Returns: task_id, dag_id, dag_run_id, state, +7 more
get_task_logsARead-only
Read the log for one task attempt.
Task logs can be large, so by default only the trailing portion is returned (where the error and traceback usually are).
Inputs: dag_id (required), dag_run_id (required), task_id (required), try_number, +1 more. Returns: result
list_dag_runsBRead-only
List runs of a DAG, most recent first.
Inputs: dag_id (required), limit, offset, state, +1 more. Returns: dag_runs, total_entries
list_dagsARead-only
List DAGs with their pause state, schedule, owners, and tags.
Inputs: limit, offset, only_active, paused, +2 more. Returns: dags, total_entries
list_import_errorsARead-only
List DAG import errors (parse failures), with filename and stack trace.
The quickest way to find why a DAG is missing from the list or broken.
Inputs: limit, offset. Returns: import_errors, total_entries
list_poolsARead-only
List worker pools with their slot usage (occupied/running/queued/open).
Inputs: limit, offset. Returns: pools, total_entries
list_task_instancesARead-only
List task instances in a DAG run, with their states and timings.
Inputs: dag_id (required), dag_run_id (required), limit, offset, +1 more. Returns: task_instances, total_entries
set_dag_pausedAIdempotent
Pause or unpause a DAG.
Inputs: dag_id (required), is_paused (required). Returns: dag_id, is_paused, is_active, description, +6 more
trigger_dag_runB
Trigger a new run of a DAG.
Inputs: dag_id (required), conf, logical_date, dag_run_id, +1 more. Returns: dag_run_id, dag_id, state, run_type, +6 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 14 tools
Each tool has a clearly distinct purpose. For example, 'get_dag' retrieves a single DAG, while 'list_dags' lists multiple; 'clear_task_instances' resets tasks, distinct from 'trigger_dag_run'. No overlapping functionality.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., 'get_dag', 'list_pools', 'set_dag_paused'). Verbs like 'get' for single entities, 'list' for collections, 'clear', 'set', and 'trigger' are used uniformly.
14 tools is well-scoped for an Airflow MCP server. Core operations for DAGs, runs, task instances, pools, health, and version are covered without bloat or excessive specialization.
The toolset covers the main lifecycle for DAGs (list, get, pause, trigger), runs, and task instances (list, get, clear, logs). However, it lacks management operations for pools (only list), DAG run deletion, and advanced task retry options, leaving minor gaps for some workflows.
Related MCP Connectors
Every Canopy public API operation as a tool, run as you after a browser sign-in or on an API key.
AI-callable tools for API mocking, testing, monitoring, security, and automation.
Query your team's drift, vulnerability, and upgrade data from any AI assistant. OAuth 2.1, 51 tools.
Access Pollinations models and API capabilities through agent tools.
Related MCP Servers
- AlicenseCqualityDmaintenanceProvides a standardized way for MCP clients to interact with Apache Airflow's REST API, supporting operations like DAG management and monitoring Airflow system health.681,311 PyPI182MIT
- AlicenseNot gradedqualityDmaintenanceProvides integration with Apache Airflow's REST API, allowing AI assistants to programmatically interact with Airflow workflows, monitor DAG runs, and manage tasks.MIT
- AlicenseAqualityCmaintenanceEnables inspection and management of Apache Airflow DAGs, runs, and logs across multiple instances. It provides tools for monitoring workflows and performing gated write operations like triggering DAGs or clearing task instances.1656 PyPI2Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables natural language interaction with Apache Airflow for querying DAGs, monitoring execution, and troubleshooting failures.28 PyPI1MIT