MCP-Airflow-API
MCP-Airflow-API is an MCP server that lets Claude, OpenWebUI, and other MCP clients inspect and operate Apache Airflow through its REST API (v1 for Airflow 2.x, v2 for Airflow 3.x).
DAGs: list/filter DAGs, get details and batches with latest run info, view task graph and source code, trigger runs, pause/unpause, and list running or failed DAGs.
Tasks & runs: list tasks in a DAG, analyze DAG run and task durations, show schedule/execution calendar, and list or inspect task instances (rich date/state/duration/pool filtering).
Task instance diagnostics: fetch details, extra links, logs by try number, and XCom entries.
Cluster health & config: check health, Airflow version, full config, config sections, and search config options.
Pools & variables: list/get pools; list/get variables.
Connections: list, get, create, update, and delete connections.
Monitoring: event logs (list/get, per-DAG and all-DAG summaries) and import errors (list/get, summary).
Users & access (v1 only): list users, get user, list permissions and roles.
Plugins & providers: list installed plugins and provider packages; get provider details.
Lineage: datasets and dataset events (v1 only; Airflow 3.x uses Assets, which are v2-only).
Deployment options: local stdio or Streamable HTTP transport, MCPB bundle for Claude Desktop, Docker Compose for OpenWebUI, and optional MCPO OpenAPI proxy.
Provides comprehensive monitoring and management of Apache Airflow clusters through natural language queries, including DAG inspection, task monitoring, health checks, cluster analytics, pool management, variable management, XCom operations, and event logging without requiring direct API complexity.
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., "@MCP-Airflow-API show me currently running DAGs"
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.
MCP-Airflow-API
Use Claude, OpenWebUI, and other MCP clients to inspect and operate Apache Airflow through its REST API.
What is MCP-Airflow-API?
MCP-Airflow-API turns plain-language requests into Apache Airflow REST API
calls. One server supports Airflow 2.x API v1 and Airflow 3.x API v2, selected
with AIRFLOW_API_VERSION.
Inspect DAGs, DAG runs, task instances, pools, variables, connections, and cluster health.
Trigger, pause, and manage supported Airflow resources using the permissions of the configured Airflow account.
Use local stdio or Streamable HTTP transport.
Run with Claude Desktop, OpenWebUI, any MCP client, or the optional MCPO OpenAPI compatibility proxy.
Example requests:
Show the currently running DAGs.
List failed task instances from the last 24 hours.
Trigger the example_etl DAG with today's processing date.
Show assets updated by data_ingestion. # Airflow 3.x onlyMore requests to try: see Example queries by area for DAGs, task instances, XComs, pools, variables, configuration, monitoring, assets, datasets, users, plugins, and providers.
Related MCP server: mcp-airflow
Quick Start
Choose one path. Both require an Airflow account and network access to its API. For a test cluster, see Airflow-Docker-Compose.
Option A: Claude Desktop with MCPB
Download
mcp-airflow-api-<version>.mcpbfrom the latest GitHub Release.In Claude Desktop, open Settings → Extensions → Advanced settings → Install Extension… and select the bundle.
Choose API
v1for Airflow 2.x orv2for Airflow 3.x, then enter the API base URL, user name, and password.Ask:
Show the health of my Airflow cluster.
The base URL excludes the version suffix, for example
http://localhost:8080/api. See the
Claude Desktop guide for uvx, source, and
remote alternatives.
Option B: OpenWebUI with Docker Compose
Requirements: Git, Docker with the Compose plugin, and a model provider for OpenWebUI whose model supports tool calling.
1. Configure
git clone https://github.com/call518/MCP-Airflow-API.git
cd MCP-Airflow-API
cp .env.example .env
cp mcp-config.json.http mcp-config.json.http.local
chmod 600 mcp-config.json.http.local
openssl rand -hex 32 # use the output as WEBUI_SECRET_KEY
vi .env # set WEBUI_SECRET_KEY and the AIRFLOW_* values2. Start
docker compose up -d
docker compose ps # wait until mcp-server is healthyThe default stack exposes only localhost:
OpenWebUI:
http://localhost:3002MCP server:
http://localhost:18002/mcpOptional MCPO/OpenAPI proxy:
http://localhost:8002
3. Connect a model provider
These steps apply to both the direct MCP connection and MCPO.
Open
http://localhost:3002and create the administrator account.Under Settings → Admin → Connections, add an OpenAI connection with URL
https://api.openai.com/v1, AuthBearerwith your OpenAI API key, and API Type set to Chat Completions, then save it. For another provider, see the OpenWebUI guide.The Quick Start calls tools through Chat Completions with model reasoning turned off, using this default already present in
.env.example:DEFAULT_MODEL_PARAMS={"reasoning_effort":"none"}This value requires API Type: Chat Completions. With Responses, OpenWebUI still sends
reasoning_effort, and every request fails withUnsupported parameter: 'reasoning_effort'. If theopen-webui-datavolume already exists, set the same value under Settings → Admin → Models → Model Defaults → Model Parameters because its saved database value takes precedence. To keep model reasoning through Responses instead, see the OpenWebUI guide.
4. Connect the MCP server
Under Settings → Admin → Tools → Integrations → External Tool Servers, add a connection of type MCP (Streamable HTTP) with the internal Docker URL
http://mcp-server:8000/mcpand authenticationNone. Do not use the host URL from inside the Docker network.In a new chat, enable the connection under Integrations → Tools and ask:
Use mcp-airflow-api to show the Airflow cluster health.
MCPO is optional. OpenWebUI connects directly to MCP; MCPO exists for OpenAPI clients. Start without it using
docker compose up -d mcp-server open-webui.
See the OpenWebUI guide for MCPO setup, authentication, OpenAI reasoning models, and troubleshooting.
Other installation methods
Method | Command or guide |
PyPI with |
|
Claude Desktop JSON configuration | |
Local development |
|
Streamable HTTP |
|
OpenWebUI and MCPO |
Configuration
Variable | Required | Description |
| No |
|
| Yes | API root without |
| Yes | Airflow API user name |
| Yes | Airflow API password |
| No |
|
| No |
|
| HTTP only | Bind address; defaults to |
| HTTP only | Listen port; defaults to |
| HTTP only | Enable Bearer authentication |
| When auth enabled | Bearer token shared with MCP clients |
See Configuration and security for Docker port settings, authentication, and client examples.
Safety and security
The server can change Airflow state when the configured account permits it. Review tool calls and use a least-privilege Airflow account.
Keep
.envandmcp-config.json.*.localfiles out of Git. Tracked examples contain placeholders only.Compose binds HTTP ports to
127.0.0.1by default. Before exposing the MCP server remotely, enable Bearer authentication and put it behind HTTPS.MCPB runs locally over stdio and does not use the HTTP Bearer settings.
Compatibility
Python 3.12 or newer
Airflow 2.x through REST API v1
Airflow 3.x through REST API v2; asset tools are v2-only
Claude Desktop MCPB, generic stdio/Streamable HTTP MCP clients, OpenWebUI, and optional MCPO/OpenAPI clients
Exact endpoint availability still depends on the Airflow version and the configured account's permissions.
Documentation
Guide | Contents |
MCPB, | |
Model provider, direct MCP, optional MCPO, OpenAI API type and reasoning models, troubleshooting | |
Environment variables, ports, Bearer authentication | |
Detailed tool and Airflow endpoint coverage |
Development
uv sync --frozen
uv run pytest -raRun locally over stdio:
AIRFLOW_API_VERSION=v1 \
AIRFLOW_API_BASE_URL=http://localhost:8080/api \
AIRFLOW_API_USERNAME=airflow \
AIRFLOW_API_PASSWORD=airflow \
uv run mcp-airflow-apiBuild an MCPB without including local configuration or credentials:
scripts/build-mcpb.sh 0.0.0 /tmp/mcp-airflow-api-mcpb-check
unzip -l /tmp/mcp-airflow-api-mcpb-check/mcp-airflow-api-0.0.0.mcpbLicense
Available Tools
53 toolsall_dag_event_summaryB
[Tool Role]: Provides summary of event logs across all DAGs.
Inputs: no named parameters. Returns: object
all_dag_import_summaryA
[Tool Role]: Provides summary of import errors across all DAGs.
Inputs: no named parameters. Returns: object
create_connectionC
[Tool Role]: Creates a new connection.
Inputs: connection_data (required). Returns: object
dag_calendarC
[Tool Role]: Shows DAG schedule and execution calendar for a date range.
Inputs: dag_id (required), end_date (required), start_date (required). Returns: object
dag_codeC
[Tool Role]: Retrieves the source code for the specified DAG.
Inputs: dag_id (required). Returns: object
dag_graphB
[Tool Role]: Retrieves task graph structure for the specified DAG.
Inputs: dag_id (required). Returns: object
dag_run_durationC
[Tool Role]: Analyzes DAG run durations and performance metrics.
Inputs: dag_id (required), limit. Returns: object
dag_task_durationC
[Tool Role]: Analyzes task durations within a DAG run.
Inputs: dag_id (required), dag_run_id. Returns: object
delete_connectionC
[Tool Role]: Deletes a connection.
Inputs: connection_id (required). Returns: object
failed_dagsB
[Tool Role]: Lists all recently failed DAG runs in the Airflow cluster.
Inputs: no named parameters. Returns: object
get_configC
[Tool Role]: Retrieves Airflow configuration.
Inputs: no named parameters. Returns: object
get_config_sectionB
[Tool Role]: Gets all options within a specific configuration section.
Inputs: section_name (required). Returns: object
get_connectionC
[Tool Role]: Gets details for a specific connection.
Inputs: connection_id (required). Returns: object
get_dagC
[Tool Role]: Retrieves detailed information for a specific DAG.
Inputs: dag_id (required). Returns: object
get_dags_detailed_batchB
[Tool Role]: Retrieves detailed information for multiple DAGs in batch with latest run information.
Inputs: limit, offset, fetch_all, is_active, +3 more. Returns: object
get_datasetB
[Tool Role]: Gets details of a specific dataset (v1 API only - v2 uses Assets).
Inputs: dataset_uri (required). Returns: object
get_dataset_eventsB
[Tool Role]: Gets events for a specific dataset (v1 API only - v2 uses Assets).
Inputs: dataset_uri (required), limit, offset. Returns: object
get_event_logB
[Tool Role]: Retrieves a specific event log entry.
Inputs: event_log_id (required). Returns: object
get_healthA
[Tool Role]: Checks Airflow cluster health status.
Inputs: no named parameters. Returns: object
get_import_errorB
[Tool Role]: Retrieves a specific import error.
Inputs: import_error_id (required). Returns: object
get_poolB
[Tool Role]: Gets details for a specific pool.
Inputs: pool_name (required). Returns: object
get_providerB
[Tool Role]: Gets details of a specific provider package.
Inputs: provider_name (required). Returns: object
get_task_instance_detailsC
[Tool Role]: Gets detailed information for a specific task instance.
Inputs: dag_id (required), task_id (required), dag_run_id (required). Returns: object
get_task_instance_extra_linksC
[Tool Role]: Gets extra links for a task instance.
Inputs: dag_id (required), task_id (required), dag_run_id (required). Returns: object
get_task_instance_logsC
[Tool Role]: Retrieves logs for a specific task instance.
Inputs: dag_id (required), task_id (required), dag_run_id (required), try_number. Returns: object
get_userC
[Tool Role]: Gets details of a specific user (v1 API only).
Inputs: username (required). Returns: object
get_variableB
[Tool Role]: Gets the value of a specific variable.
Inputs: variable_key (required). Returns: object
get_versionB
[Tool Role]: Gets Airflow version information.
Inputs: no named parameters. Returns: object
get_xcom_entryC
[Tool Role]: Gets a specific XCom entry.
Inputs: dag_id (required), task_id (required), xcom_key (required), dag_run_id (required). Returns: object
list_config_sectionsB
[Tool Role]: Lists all configuration sections with summary.
Inputs: no named parameters. Returns: object
list_connectionsC
[Tool Role]: Lists all connections in Airflow.
Inputs: limit, offset. Returns: object
list_dagsB
[Tool Role]: Lists all DAGs registered in the Airflow cluster with pagination support.
Inputs: limit, offset, fetch_all, id_contains, +1 more. Returns: object
list_dataset_eventsA
[Tool Role]: Lists dataset events for data lineage tracking (v1 API only - v2 uses Assets).
Inputs: limit, offset, dataset_uri, source_dag_id. Returns: object
list_datasetsB
[Tool Role]: Lists all datasets in the Airflow system (v1 API only - v2 uses Assets).
Inputs: limit, offset, uri_pattern. Returns: object
list_event_logsC
[Tool Role]: Lists event logs from Airflow.
Inputs: limit, dag_id, offset. Returns: object
list_import_errorsC
[Tool Role]: Lists import errors in Airflow.
Inputs: limit, offset. Returns: object
list_permissionsB
[Tool Role]: Lists all permissions available in the Airflow system (v1 API only).
Inputs: no named parameters. Returns: object
list_pluginsA
[Tool Role]: Lists all installed plugins in the Airflow system.
Inputs: no named parameters. Returns: object
list_poolsB
[Tool Role]: Lists all pools in Airflow.
Inputs: limit, offset. Returns: object
list_providersA
[Tool Role]: Lists all provider packages installed in the Airflow system.
Inputs: no named parameters. Returns: object
list_rolesB
[Tool Role]: Lists all roles in the Airflow system (v1 API only).
Inputs: limit, offset. Returns: object
list_task_instances_allC
[Tool Role]: Lists task instances with comprehensive filtering options.
Inputs: pool, limit, state, dag_id, +11 more. Returns: object
list_task_instances_batchC
[Tool Role]: Lists task instances in batch with date and state filtering.
Inputs: limit, state, offset, start_date_gte, +1 more. Returns: object
list_tasksB
[Tool Role]: Lists all tasks within the specified DAG.
Inputs: dag_id (required). Returns: object
list_usersB
[Tool Role]: Lists all users in the Airflow system (v1 API only).
Inputs: limit, offset. Returns: object
list_variablesC
[Tool Role]: Lists all variables in Airflow.
Inputs: limit, offset. Returns: object
list_xcom_entriesC
[Tool Role]: Lists XCom entries for a specific task instance.
Inputs: dag_id (required), task_id (required), dag_run_id (required), limit, +1 more. Returns: object
pause_dagA
[Tool Role]: Pauses the specified Airflow DAG (prevents scheduling new runs).
Inputs: dag_id (required). Returns: object
running_dagsA
[Tool Role]: Lists all currently running DAG runs in the Airflow cluster.
Inputs: no named parameters. Returns: object
search_config_optionsC
[Tool Role]: Searches for configuration options matching a term.
Inputs: search_term (required). Returns: object
trigger_dagC
[Tool Role]: Triggers a new DAG run for a specified Airflow DAG.
Inputs: dag_id (required). Returns: object
unpause_dagB
[Tool Role]: Unpauses the specified Airflow DAG (allows scheduling new runs).
Inputs: dag_id (required). Returns: object
update_connectionC
[Tool Role]: Updates an existing connection.
Inputs: connection_id (required), connection_data (required). Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 53 tools
Most tools map to a distinct resource+action, but several clusters overlap: list_task_instances_all vs list_task_instances_batch vs get_task_instance_details, list_event_logs/get_event_log/all_dag_event_summary, and list_datasets/get_dataset_events/list_dataset_events (the last two read as near-duplicates). list_dags vs get_dags_detailed_batch vs get_dag is also a subtle distinction an agent could easily misfire on.
The dominant pattern is snake_case verb_noun (list_pools, get_pool, create_connection), which is good. However, a sizeable minority break the verb-first rule: running_dags, failed_dags, dag_graph, dag_code, dag_calendar, all_dag_event_summary, all_dag_import_summary. The mixed conventions are still readable but not predictable.
53 tools is far past the comfortable range for an agent to select from reliably, and Airflow's breadth doesn't fully excuse it. Many families (config, event logs, import errors, dataset events) could be collapsed into fewer parameterized tools, e.g. one list_task_instances with filters instead of two plus a batch variant.
Coverage is lopsided: connections get full CRUD, but variables, pools, users, roles, and datasets are read-only, and there is no way to clear/delete a DAG run, mark a task instance success/failed, or create/delete a DAG. Common operational recovery workflows (clear and rerun, set variable) are dead ends for an agent.
Maintenance
Related MCP Connectors
Query your warehouse or a CSV with Claude/ChatGPT over MCP, governed by table-level ACL + audit.
Text-to-SQL MCP server: read-only queries on PostgreSQL, MySQL and SQL Server with your real schema
MCP observability. Query live traffic, errors, duration, and alerts from your AI agent.
Related MCP Servers
AlicenseAqualityFmaintenanceAn MCP server that enables AI assistants to interact with Apache Airflow's REST API for DAG management, task monitoring, and system diagnostics. It provides comprehensive tools for triggering workflows, retrieving logs, and inspecting system health across Airflow 2.x and 3.x versions.3113Apache 2.0- AlicenseAqualityBmaintenanceMCP server exposing Apache Airflow REST API operations as tools — list DAGs, inspect runs and task instances, trigger DAG runs, and check failed DAGs and scheduler health72MIT
- AlicenseAqualityCmaintenanceAn MCP server that enables AI coding assistants to interact with a local Airflow cluster via its REST API for triggering DAG runs, monitoring status, reading logs, and diagnosing errors.1027 PyPI1MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server for controlling Apache Airflow 3 via its REST API, enabling operations like DAG management, task monitoring, and more through natural language.MIT