Skip to main content
Glama
README.md
# mcp-adf — Azure Data Factory MCP server

One [FastMCP](https://github.com/jlowin/fastmcp) server fronting one or more
Azure Data Factory instances. Every tool takes a `factory` argument naming a
target in `connections.json`; call `list_factories` first to see the configured
targets.

Built on `azure-mgmt-datafactory` + `azure-identity`. Read tools work on any
target; tools that create resources or trigger runs require the target to be
flagged `"writable": true`.

## Tools

**Discovery / read** (any target):
- `list_factories` — configured targets
- `discover_factories` — every ADF in a target's subscription (to fill in config)
- `list_pipelines` / `get_pipeline`
- `list_datasets` / `get_dataset`
- `list_linked_services` / `get_linked_service`
- `list_triggers` / `get_trigger`

**Run monitoring / error analysis** (any target):
- `list_pipeline_runs` — run history over the last N days; filter by pipeline/status
- `get_pipeline_run`
- `list_activity_runs` — per-activity status / timing / error for a run
- `analyze_run_errors` — run message + every failed activity's error code & message

**Write** (only against a `"writable": true` target):
- `create_or_update_linked_service`
- `create_or_update_dataset`
- `create_or_update_pipeline`
- `run_pipeline` — trigger a run, returns the run_id
- `cancel_pipeline_run`
- `start_trigger` / `stop_trigger`

Resource definitions are the JSON you see in ADF Studio's **code** view — pass
either the full `{ "name": ..., "properties": {...} }` object or just the inner
properties object.

## Configure

Copy `connections.example.json` to `connections.json` and fill in your targets:

```json
{
  "dev": {
    "subscription_id": "00000000-0000-0000-0000-000000000000",
    "resource_group": "rg-data-dev",
    "factory_name": "adf-dev",
    "auth": "azure-cli",
    "writable": true
  },
  "prod": {
    "subscription_id": "00000000-0000-0000-0000-000000000000",
    "resource_group": "rg-data-prod",
    "factory_name": "adf-prod",
    "auth": "azure-cli",
    "writable": false
  }
}
```

`connections.json` and `.env` are gitignored — they never leave your machine.

### Auth

Set `"auth"` per target:

| value | how it signs in |
|-------|-----------------|
| `azure-cli` *(default)* | reuses an `az login` token (requires Azure CLI) |
| `broker` | Windows WAM broker popup (no CLI needed; great in tenants that block device-code flow) |
| `interactive` | browser sign-in popup |
| `service-principal` | app registration; secret read from `client_secret_env` (see `.env.example`) |
| `default` | `DefaultAzureCredential` (env → cli → broker → …) |

The identity needs an ADF RBAC role on the factory — **Data Factory
Contributor** for create/trigger, **Reader** for the read tools.

## Setup

```powershell
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
copy connections.example.json connections.json   # then edit it
.\.venv\Scripts\python.exe server.py              # smoke test (Ctrl+C to stop)
```

### Finding your factories

`discover.py` signs in once and lists every subscription and the data factories
in each, so you can fill in `subscription_id` / `resource_group` / `factory_name`:

```powershell
.\.venv\Scripts\python.exe -m pip install azure-mgmt-subscription azure-mgmt-resource
.\.venv\Scripts\python.exe discover.py
```

## Register with an MCP client

See `examples/mcp.json`:

```json
{
  "mcpServers": {
    "adf": {
      "command": "C:\\path\\to\\mcp-adf\\.venv\\Scripts\\python.exe",
      "args": ["C:\\path\\to\\mcp-adf\\server.py"],
      "env": {}
    }
  }
}
```

## Use with Claude Desktop

[Claude Desktop](https://claude.ai/download) reads its MCP servers from
`claude_desktop_config.json`. Open it from **Settings → Developer → Edit Config**
(this creates the file if it doesn't exist), or edit it directly:

- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`

Add this server under `mcpServers`, using **absolute paths** to the venv's
Python and `server.py`:

```json
{
  "mcpServers": {
    "adf": {
      "command": "C:\\path\\to\\mcp-adf\\.venv\\Scripts\\python.exe",
      "args": ["C:\\path\\to\\mcp-adf\\server.py"],
      "env": {}
    }
  }
}
```

On macOS the paths are POSIX, e.g. `"command": "/Users/you/mcp-adf/.venv/bin/python"`.
Save the file and **fully quit and reopen Claude Desktop** (use *Quit* from the
tray/menu-bar icon — closing the window isn't enough). The server's tools then
appear in the tools (🔌) menu of a new chat.

## License

MIT — see [LICENSE](LICENSE).