An open API service indexing awesome lists of open source software.

https://github.com/yangkyeongmo/mcp-server-apache-airflow


https://github.com/yangkyeongmo/mcp-server-apache-airflow

Last synced: 25 days ago
JSON representation

Awesome Lists containing this project

README

          

[![MseeP.ai Security Assessment Badge](https://mseep.net/pr/yangkyeongmo-mcp-server-apache-airflow-badge.png)](https://mseep.ai/app/yangkyeongmo-mcp-server-apache-airflow)

# mcp-server-apache-airflow

[![smithery badge](https://smithery.ai/badge/@yangkyeongmo/mcp-server-apache-airflow)](https://smithery.ai/server/@yangkyeongmo/mcp-server-apache-airflow)
![PyPI - Downloads](https://img.shields.io/pypi/dm/mcp-server-apache-airflow)

A Model Context Protocol (MCP) server implementation for Apache Airflow, enabling seamless integration with MCP clients. This project provides a standardized way to interact with Apache Airflow through the Model Context Protocol.


Server for Apache Airflow MCP server

## About

This project implements a [Model Context Protocol](https://modelcontextprotocol.io/introduction) server that wraps Apache Airflow's REST API, allowing MCP clients to interact with Airflow in a standardized way. It uses the official Apache Airflow client library to ensure compatibility and maintainability.

## Feature Implementation Status

| Feature | API Path | Status |
| -------------------------------- | --------------------------------------------------------------------------------------------- | ------ |
| **DAG Management** | | |
| List DAGs | `/api/v1/dags` | βœ… |
| Get DAG Details | `/api/v1/dags/{dag_id}` | βœ… |
| Pause DAG | `/api/v1/dags/{dag_id}` | βœ… |
| Unpause DAG | `/api/v1/dags/{dag_id}` | βœ… |
| Update DAG | `/api/v1/dags/{dag_id}` | βœ… |
| Delete DAG | `/api/v1/dags/{dag_id}` | βœ… |
| Get DAG Source | `/api/v1/dagSources/{file_token}` | βœ… |
| Patch Multiple DAGs | `/api/v1/dags` | βœ… |
| Reparse DAG File | `/api/v1/dagSources/{file_token}/reparse` | βœ… |
| **DAG Runs** | | |
| List DAG Runs | `/api/v1/dags/{dag_id}/dagRuns` | βœ… |
| Create DAG Run | `/api/v1/dags/{dag_id}/dagRuns` | βœ… |
| Get DAG Run Details | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}` | βœ… |
| Update DAG Run | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}` | βœ… |
| Delete DAG Run | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}` | βœ… |
| Get DAG Runs Batch | `/api/v1/dags/~/dagRuns/list` | βœ… |
| Clear DAG Run | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/clear` | βœ… |
| Set DAG Run Note | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/setNote` | βœ… |
| Get Upstream Dataset Events | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/upstreamDatasetEvents` | βœ… |
| **Tasks** | | |
| List DAG Tasks | `/api/v1/dags/{dag_id}/tasks` | βœ… |
| Get Task Details | `/api/v1/dags/{dag_id}/tasks/{task_id}` | βœ… |
| Get Task Instance | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}` | βœ… |
| List Task Instances | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances` | βœ… |
| Update Task Instance | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}` | βœ… |
| Get Task Instance Log | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/logs/{task_try_number}` | βœ… |
| Clear Task Instances | `/api/v1/dags/{dag_id}/clearTaskInstances` | βœ… |
| Set Task Instances State | `/api/v1/dags/{dag_id}/updateTaskInstancesState` | βœ… |
| List Task Instance Tries | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/tries` | βœ… |
| **Variables** | | |
| List Variables | `/api/v1/variables` | βœ… |
| Create Variable | `/api/v1/variables` | βœ… |
| Get Variable | `/api/v1/variables/{variable_key}` | βœ… |
| Update Variable | `/api/v1/variables/{variable_key}` | βœ… |
| Delete Variable | `/api/v1/variables/{variable_key}` | βœ… |
| **Connections** | | |
| List Connections | `/api/v1/connections` | βœ… |
| Create Connection | `/api/v1/connections` | βœ… |
| Get Connection | `/api/v1/connections/{connection_id}` | βœ… |
| Update Connection | `/api/v1/connections/{connection_id}` | βœ… |
| Delete Connection | `/api/v1/connections/{connection_id}` | βœ… |
| Test Connection | `/api/v1/connections/test` | βœ… |
| **Pools** | | |
| List Pools | `/api/v1/pools` | βœ… |
| Create Pool | `/api/v1/pools` | βœ… |
| Get Pool | `/api/v1/pools/{pool_name}` | βœ… |
| Update Pool | `/api/v1/pools/{pool_name}` | βœ… |
| Delete Pool | `/api/v1/pools/{pool_name}` | βœ… |
| **XComs** | | |
| List XComs | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/xcomEntries` | βœ… |
| Get XCom Entry | `/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/xcomEntries/{xcom_key}` | βœ… |
| **Datasets** | | |
| List Datasets | `/api/v1/datasets` | βœ… |
| Get Dataset | `/api/v1/datasets/{uri}` | βœ… |
| Get Dataset Events | `/api/v1/datasetEvents` | βœ… |
| Create Dataset Event | `/api/v1/datasetEvents` | βœ… |
| Get DAG Dataset Queued Event | `/api/v1/dags/{dag_id}/dagRuns/queued/datasetEvents/{uri}` | βœ… |
| Get DAG Dataset Queued Events | `/api/v1/dags/{dag_id}/dagRuns/queued/datasetEvents` | βœ… |
| Delete DAG Dataset Queued Event | `/api/v1/dags/{dag_id}/dagRuns/queued/datasetEvents/{uri}` | βœ… |
| Delete DAG Dataset Queued Events | `/api/v1/dags/{dag_id}/dagRuns/queued/datasetEvents` | βœ… |
| Get Dataset Queued Events | `/api/v1/datasets/{uri}/dagRuns/queued/datasetEvents` | βœ… |
| Delete Dataset Queued Events | `/api/v1/datasets/{uri}/dagRuns/queued/datasetEvents` | βœ… |
| **Monitoring** | | |
| Get Health | `/api/v1/health` | βœ… |
| **DAG Stats** | | |
| Get DAG Stats | `/api/v1/dags/statistics` | βœ… |
| **Config** | | |
| Get Config | `/api/v1/config` | βœ… |
| **Plugins** | | |
| Get Plugins | `/api/v1/plugins` | βœ… |
| **Providers** | | |
| List Providers | `/api/v1/providers` | βœ… |
| **Event Logs** | | |
| List Event Logs | `/api/v1/eventLogs` | βœ… |
| Get Event Log | `/api/v1/eventLogs/{event_log_id}` | βœ… |
| **System** | | |
| Get Import Errors | `/api/v1/importErrors` | βœ… |
| Get Import Error Details | `/api/v1/importErrors/{import_error_id}` | βœ… |
| Get Health Status | `/api/v1/health` | βœ… |
| Get Version | `/api/v1/version` | βœ… |

## Setup

### Dependencies

This project depends on the official Apache Airflow client library (`apache-airflow-client`). It will be automatically installed when you install this package.

### Environment Variables

Set the following environment variables:

```
AIRFLOW_HOST= # Optional, defaults to http://localhost:8080
AIRFLOW_API_VERSION=v1 # Optional, defaults to v1
READ_ONLY=true # Optional, enables read-only mode (true/false, defaults to false)
```

#### Authentication

Choose one of the following authentication methods:

**Basic Authentication (default):**
```
AIRFLOW_USERNAME=
AIRFLOW_PASSWORD=
```

**JWT Token Authentication:**
```
AIRFLOW_JWT_TOKEN=
```

To obtain a JWT token, you can use Airflow's authentication endpoint:

```bash
ENDPOINT_URL="http://localhost:8080" # Replace with your Airflow endpoint
curl -X 'POST' \
"${ENDPOINT_URL}/auth/token" \
-H 'Content-Type: application/json' \
-d '{ "username": "", "password": "" }'
```

> **Note**: If both JWT token and basic authentication credentials are provided, JWT token takes precedence.

### Usage with Claude Desktop

Add to your `claude_desktop_config.json`:

**Basic Authentication:**
```json
{
"mcpServers": {
"mcp-server-apache-airflow": {
"command": "uvx",
"args": ["mcp-server-apache-airflow"],
"env": {
"AIRFLOW_HOST": "https://your-airflow-host",
"AIRFLOW_USERNAME": "your-username",
"AIRFLOW_PASSWORD": "your-password"
}
}
}
}
```

**JWT Token Authentication:**
```json
{
"mcpServers": {
"mcp-server-apache-airflow": {
"command": "uvx",
"args": ["mcp-server-apache-airflow"],
"env": {
"AIRFLOW_HOST": "https://your-airflow-host",
"AIRFLOW_JWT_TOKEN": "your-jwt-token"
}
}
}
}
```

For read-only mode (recommended for safety):

**Basic Authentication:**
```json
{
"mcpServers": {
"mcp-server-apache-airflow": {
"command": "uvx",
"args": ["mcp-server-apache-airflow"],
"env": {
"AIRFLOW_HOST": "https://your-airflow-host",
"AIRFLOW_USERNAME": "your-username",
"AIRFLOW_PASSWORD": "your-password",
"READ_ONLY": "true"
}
}
}
}
```

**JWT Token Authentication:**
```json
{
"mcpServers": {
"mcp-server-apache-airflow": {
"command": "uvx",
"args": ["mcp-server-apache-airflow", "--read-only"],
"env": {
"AIRFLOW_HOST": "https://your-airflow-host",
"AIRFLOW_JWT_TOKEN": "your-jwt-token"
}
}
}
}
```

Alternative configuration using `uv`:

**Basic Authentication:**
```json
{
"mcpServers": {
"mcp-server-apache-airflow": {
"command": "uv",
"args": [
"--directory",
"/path/to/mcp-server-apache-airflow",
"run",
"mcp-server-apache-airflow"
],
"env": {
"AIRFLOW_HOST": "https://your-airflow-host",
"AIRFLOW_USERNAME": "your-username",
"AIRFLOW_PASSWORD": "your-password"
}
}
}
}
```

**JWT Token Authentication:**
```json
{
"mcpServers": {
"mcp-server-apache-airflow": {
"command": "uv",
"args": [
"--directory",
"/path/to/mcp-server-apache-airflow",
"run",
"mcp-server-apache-airflow"
],
"env": {
"AIRFLOW_HOST": "https://your-airflow-host",
"AIRFLOW_JWT_TOKEN": "your-jwt-token"
}
}
}
}
```

Replace `/path/to/mcp-server-apache-airflow` with the actual path where you've cloned the repository.

### Selecting the API groups

You can select the API groups you want to use by setting the `--apis` flag.

```bash
uv run mcp-server-apache-airflow --apis dag --apis dagrun
```

The default is to use all APIs.

Allowed values are:

- config
- connections
- dag
- dagrun
- dagstats
- dataset
- eventlog
- importerror
- monitoring
- plugin
- pool
- provider
- taskinstance
- variable
- xcom

### Read-Only Mode

You can run the server in read-only mode by using the `--read-only` flag or by setting the `READ_ONLY=true` environment variable. This will only expose tools that perform read operations (GET requests) and exclude any tools that create, update, or delete resources.

Using the command-line flag:
```bash
uv run mcp-server-apache-airflow --read-only
```

Using the environment variable:
```bash
READ_ONLY=true uv run mcp-server-apache-airflow
```

In read-only mode, the server will only expose tools like:
- Listing DAGs, DAG runs, tasks, variables, connections, etc.
- Getting details of specific resources
- Reading configurations and monitoring information
- Testing connections (non-destructive)

Write operations like creating, updating, deleting DAGs, variables, connections, triggering DAG runs, etc. will not be available in read-only mode.

You can combine read-only mode with API group selection:

```bash
uv run mcp-server-apache-airflow --read-only --apis dag --apis variable
```

### Manual Execution

You can also run the server manually:

```bash
make run
```

`make run` accepts following options:

Options:

- `--port`: Port to listen on for SSE (default: 8000)
- `--transport`: Transport type (stdio/sse/http, default: stdio)

Or, you could run the sse server directly, which accepts same parameters:

```bash
make run-sse
```

Also, you could start service directly using `uv` like in the following command:

```bash
uv run src --transport http --port 8080
```

### Installing via Smithery

To install Apache Airflow MCP Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@yangkyeongmo/mcp-server-apache-airflow):

```bash
npx -y @smithery/cli install @yangkyeongmo/mcp-server-apache-airflow --client claude
```

## Development

### Setting up Development Environment

1. Clone the repository:
```bash
git clone https://github.com/yangkyeongmo/mcp-server-apache-airflow.git
cd mcp-server-apache-airflow
```

2. Install development dependencies:
```bash
uv sync --dev
```

3. Create a `.env` file for environment variables (optional for development):
```bash
touch .env
```

> **Note**: No environment variables are required for running tests. The `AIRFLOW_HOST` defaults to `http://localhost:8080` for development and testing purposes.

### Running Tests

The project uses pytest for testing with the following commands available:

```bash
# Run all tests
make test
```

### Code Quality

```bash
# Run linting
make lint

# Run code formatting
make format
```

### Continuous Integration

The project includes a GitHub Actions workflow (`.github/workflows/test.yml`) that automatically:

- Runs tests on Python 3.10, 3.11, and 3.12
- Executes linting checks using ruff
- Runs on every push and pull request to `main` branch

The CI pipeline ensures code quality and compatibility across supported Python versions before any changes are merged.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

The package is deployed automatically to PyPI when project.version is updated in `pyproject.toml`.
Follow semver for versioning.

Please include version update in the PR in order to apply the changes to core logic.

## License

[MIT License](LICENSE)