nexus-adf
Enables Claude to diagnose and fix Azure Data Factory pipeline failures with automated rollback.
README
Nexus ADF MCP Server
Standalone MCP stdio server exposing Azure Data Factory diagnostic and self-remediation tools to Claude Desktop.
Given a failing pipeline, it walks Claude through diagnosing the actual root cause (activity errors, run history, raw pipeline/dataset/linked-service/data-flow definitions), proposing a fix, applying it with human approval, and rolling back automatically if verification shows it didn't work.
- š Diagnose first ā evidence-driven root-cause analysis before any fix is proposed
- ā Human-in-the-loop ā every mutating call requires explicit approval with a stated reason
- āŖ Always reversible ā every checkpoint (pipeline, dataset, linked service, data flow, global parameter) is snapshotted before a mutating change, so nothing destructive is ever unrecoverable
- š¦ Self-contained ā has its own
.venvand.env, no dependency on any other folder
Contents
- Setup
- Register with Claude Desktop
- Configure permissions in Claude Desktop
- Instructions
- Tools ā 62 tools across 7 categories
- Structure
Setup
python -m venv .venv
.venv\Scripts\pip install -r requirements.txt
Fill in .env with the target factory's service principal credentials:
| Variable | Description |
|---|---|
ADF_TENANT_ID |
Azure AD tenant ID |
ADF_CLIENT_ID |
Service principal client ID |
ADF_CLIENT_SECRET |
Service principal client secret |
ADF_SUBSCRIPTION_ID |
Azure subscription ID |
ADF_RESOURCE_GROUP |
Resource group containing the factory |
ADF_FACTORY_NAME |
Target Data Factory name |
Register with Claude Desktop
In Claude Desktop's claude_desktop_config.json, point at this folder's venv interpreter and mcp_adf/server.py (add this alongside your existing config, don't replace it):
{
"mcpServers": {
"nexus-adf": {
"command": "C:\\ABSOLUTE\\PATH\\TO\\THIS\\FOLDER\\.venv\\Scripts\\python.exe",
"args": ["C:\\ABSOLUTE\\PATH\\TO\\THIS\\FOLDER\\mcp_adf\\server.py"],
"env": {
"PYTHONPATH": "C:\\ABSOLUTE\\PATH\\TO\\THIS\\FOLDER"
}
}
},
...claude default settings
}
Note: Use absolute paths ā relative paths are not resolved reliably by Claude Desktop's launcher.
PYTHONPATHis required soserver.py'sfrom mcp_adf import ...imports resolve when Claude Desktop launches the script directly (its own cwd isn't this folder).
Configure permissions in Claude Desktop
After adding the server to claude_desktop_config.json and restarting Claude Desktop, go to Settings ā Connectors ā nexus-adf and set:
| Setting | Value | Why |
|---|---|---|
Read-only tools (list_*, get_*) |
Always Allow | Can't mutate anything (readOnlyHint=True) ā approving per-call adds friction with no safety benefit |
Write/delete tools (create_*, update_*, rerun_*, rollback_*, back_*, forward_*, start_*, stop_*, cancel_*) |
Ask every time | Each surfaces a native approval dialog showing the tool's reason argument before it runs (see Instructions) |
| Capabilities ā Generate memory from chat history | Enabled | Lets Claude carry diagnosis context (e.g. recurring failure patterns for a given pipeline) across sessions |
| Tool access mode | Tools already loaded |
Instructions
The server ships its own instructions to Claude automatically (mcp_adf/server.py's _INSTRUCTIONS, passed to the Server(...) constructor) ā no manual copy-paste is needed for the MCP connection itself.
If you're instead setting this up as a Claude Desktop Project (Projects ā New Project), paste the same instructions into the project's instructions field so Claude follows the diagnose ā propose ā execute ā verify workflow there too, and upload the team's SOP doc(s) into the project's context:
<details> <summary><strong>Show instructions text</strong></summary>
This server exposes Azure Data Factory diagnostic and self-remediation tools. Follow this
workflow for every failure investigation ā don't skip straight to a fix.
1. DIAGNOSE FULLY before proposing or taking any action. Start with get_activity_run_error
(or get_pipeline_run_history + get_activity_run_history) to find the failing activity, then
list_activity_runs / get_activity_run_io for the actual input/output data, and
get_pipeline_definition_raw / get_dataset_definition_raw / get_data_flow_definition /
get_linked_service_definition_raw for the real configuration (timeout, query, dataset or
linked-service reference, host/port). Don't guess a fix from the error message alone if a
raw-definition or activity-IO tool would show the actual cause.
2. PROPOSE a numbered remediation plan in your response before calling any mutating tool.
State the diagnosed root cause, the specific fix, which tool(s) will apply it, and how you'll
verify it worked. If the failure is credential_expired, permissions, or a genuine platform
outage, these are human-only, permanently, regardless of which tool exists ā report and stop
instead of proposing a fix.
3. EXECUTE one mutating step at a time. Every mutating tool call surfaces its own native
approval dialog showing your `reason` ā write it to state the specific diagnosis, not a
generic phrase, since it's the only context the human sees at the moment of approval.
4. VERIFY after applying a fix (rerun, check status/error) ā don't declare success just
because the write succeeded.
5. If verification shows the fix didn't work, undo it rather than leaving a bad change in
place ā use the matching back_*_definition tool for "undo just this last change" (no
state_name needed). Use rollback_*_definition instead only when jumping to a specific
earlier named checkpoint (list_*_snapshots shows what's available); forward_*_definition
re-applies a change after stepping back from it. None of these delete history ā every
checkpoint stays reachable.
</details>
Tools
62 tools, grouped by resource type. Type marks whether a tool mutates anything: read-only tools are safe to Always Allow; mutating tools always require a reason argument and surface a native approval dialog (see Configure permissions).
<details open> <summary><strong>Pipelines</strong> (18 tools)</summary>
| Tool | Type | What it's for |
|---|---|---|
list_pipelines |
read-only | List all pipeline names in the factory. |
get_pipeline_definition |
read-only | Activity graph (names/types/ExecutePipeline refs) only ā no timeout/query/dataset detail. |
get_pipeline_definition_raw |
read-only | Full definition ā typeProperties, queries, dataset/linked-service refs, timeout/retry policy. The evidence tool for diagnosis, and the editable input to update_pipeline_definition. |
get_pipeline_run_status |
read-only | Current status of one specific run (freshness check before rerun). |
get_pipeline_run_history |
read-only | Recent runs for one pipeline. |
list_pipeline_runs |
read-only | Recent runs across the whole factory in a time window ā matches ADF Studio's Monitor tab ("last 24 hours"). |
get_activity_run_history |
read-only | Aggregated failure counts/last error code per activity across recent runs. |
get_activity_run_error |
read-only | Error detail for the most recent failed run of a pipeline ā usually the diagnosis starting point. |
list_activity_runs |
read-only | Every activity in one specific run (name/type/status/timing/activity_run_id), no input/output payload. |
get_activity_run_io |
read-only | Full resolved input/output payload for one specific activity run. |
create_pipeline |
mutating | Create a brand-new pipeline; fails if the name already exists. |
update_pipeline_definition |
mutating | Overwrite a pipeline's full definition to apply a fix. |
rerun_pipeline |
mutating | Trigger a new run. |
cancel_pipeline_run |
mutating | Cancel a running/hung run. |
list_pipeline_snapshots |
read-only | List named checkpoints in a pipeline's history. |
rollback_pipeline_definition |
mutating | Jump to a specific named checkpoint. |
back_pipeline_definition |
mutating | Step one checkpoint back (like git checkout HEAD~1). |
forward_pipeline_definition |
mutating | Step one checkpoint forward after a back_* call. |
</details>
<details> <summary><strong>Triggers</strong> (13 tools)</summary>
| Tool | Type | What it's for |
|---|---|---|
list_triggers |
read-only | Factory-wide sweep ā every trigger's name, type, runtime state. |
get_trigger |
read-only | One trigger's runtime state (Started/Stopped/Disabled). |
get_trigger_run_history |
read-only | Trigger-run history ā needed for tumbling-window/event triggers, where the trigger run (not the pipeline run it invokes) is the unit that fails/reruns/cancels. |
create_trigger |
mutating | Create a brand-new trigger (e.g. a ScheduleTrigger); fails if the name already exists. Created Stopped. |
update_trigger_definition |
mutating | Overwrite a trigger's full definition to apply a fix (e.g. correct a schedule). |
start_trigger |
mutating | Start a stopped/disabled trigger. |
stop_trigger |
mutating | Stop a running trigger. |
rerun_trigger_run |
mutating | Rerun a specific trigger run (tumbling-window/event triggers rerun_pipeline can't reach). |
cancel_trigger_run |
mutating | Cancel a specific in-progress trigger run. |
list_trigger_snapshots |
read-only | List named checkpoints in a trigger's history. |
rollback_trigger_definition |
mutating | Jump to a specific named checkpoint. |
back_trigger_definition |
mutating | Step one checkpoint back. |
forward_trigger_definition |
mutating | Step one checkpoint forward. |
</details>
<details> <summary><strong>Linked services</strong> (9 tools)</summary>
| Tool | Type | What it's for |
|---|---|---|
list_linked_services |
read-only | Factory-wide sweep of linked services. |
get_linked_service |
read-only | Name and type only ā no connection details. |
get_linked_service_definition_raw |
read-only | Full definition including the real host/port/connection string. Diagnosis tool for network/config failures, and the editable input to update_linked_service_definition. |
create_linked_service |
mutating | Create a brand-new linked service; fails if the name already exists. |
update_linked_service_definition |
mutating | Overwrite a linked service's full definition (e.g. fix a wrong host/port). |
list_linked_service_snapshots |
read-only | List named checkpoints in a linked service's history. |
rollback_linked_service_definition |
mutating | Jump to a specific named checkpoint. |
back_linked_service_definition |
mutating | Step one checkpoint back. |
forward_linked_service_definition |
mutating | Step one checkpoint forward. |
</details>
<details> <summary><strong>Datasets</strong> (7 tools)</summary>
| Tool | Type | What it's for |
|---|---|---|
list_datasets |
read-only | Factory-wide sweep ā name, type, backing linked service. |
get_dataset_definition_raw |
read-only | Full definition (schema, structure, linked-service ref, parameters) ā the evidence for schema-drift diagnosis, and the editable input to update_dataset_definition. |
update_dataset_definition |
mutating | Overwrite a dataset's full definition (e.g. correct a drifted schema). |
list_dataset_snapshots |
read-only | List named checkpoints in a dataset's history. |
rollback_dataset_definition |
mutating | Jump to a specific named checkpoint. |
back_dataset_definition |
mutating | Step one checkpoint back. |
forward_dataset_definition |
mutating | Step one checkpoint forward. |
</details>
<details> <summary><strong>Data flows</strong> (6 tools)</summary>
| Tool | Type | What it's for |
|---|---|---|
get_data_flow_definition |
read-only | Full Mapping Data Flow definition (sources, sinks, transformation script) ā the only way to see inside the transformation graph itself. |
update_data_flow_definition |
mutating | Overwrite a data flow's full definition to apply a fix. |
list_data_flow_snapshots |
read-only | List named checkpoints in a data flow's history. |
rollback_data_flow_definition |
mutating | Jump to a specific named checkpoint. |
back_data_flow_definition |
mutating | Step one checkpoint back. |
forward_data_flow_definition |
mutating | Step one checkpoint forward. |
</details>
<details> <summary><strong>Global parameters</strong> (7 tools)</summary>
| Tool | Type | What it's for |
|---|---|---|
list_global_parameters |
read-only | Factory-wide sweep ā name, type, value of every global parameter. |
get_global_parameter_definition_raw |
read-only | Full {"type", "value"} definition ā the editable input to update_global_parameter_definition. |
update_global_parameter_definition |
mutating | Overwrite a global parameter's type/value (e.g. fix a stale connection string or flipped env flag). |
list_global_parameter_snapshots |
read-only | List named checkpoints in a global parameter's history. |
rollback_global_parameter_definition |
mutating | Jump to a specific named checkpoint. |
back_global_parameter_definition |
mutating | Step one checkpoint back. |
forward_global_parameter_definition |
mutating | Step one checkpoint forward. |
</details>
<details> <summary><strong>Integration runtimes</strong> (2 tools)</summary>
| Tool | Type | What it's for |
|---|---|---|
get_integration_runtime_status |
read-only | An IR's state ā works for Azure, self-hosted, and Azure-SSIS types. Check before start_integration_runtime. |
start_integration_runtime |
mutating | Start a stopped Azure-SSIS (managed) IR. Does not work on self-hosted IRs ā no remote-start API exists; that's human-only. |
</details>
Structure
mcp_adf/ the MCP server package
āāā server.py MCP entrypoint, stdio transport, tool dispatch
āāā auth.py service-principal auth / ADF client construction
āāā audit.py audit-log writer (project/_logs/)
āāā tools/ tool implementations, one module per ADF resource kind
ā āāā _shared.py shared helpers (client construction, wire-dict conversion, miscased-key checks)
ā āāā _checkpoints.py snapshot/rollback/back/forward engine, shared by every resource kind
ā āāā pipelines.py pipeline tools ā list/get/create/update/rerun/cancel, snapshot/rollback/back/forward
ā āāā triggers.py trigger tools ā list/get/start/stop/rerun/cancel, run history
ā āāā linked_services.py linked-service tools ā list/get/update, snapshot/rollback/back/forward
ā āāā datasets.py dataset tools ā list/get/update, snapshot/rollback/back/forward
ā āāā data_flows.py data-flow tools ā get/update, snapshot/rollback/back/forward
ā āāā global_parameters.py global-parameter tools ā list/get/update, snapshot/rollback/back/forward
ā āāā integration_runtimes.py integration-runtime tools ā get status/start
ā āāā __init__.py assembles TOOL_REGISTRY from the modules above
āāā schemas/ MCP tool-schema definitions, mirroring tools/ by resource kind
ā āāā pipelines.py schema for pipeline tools
ā āāā triggers.py schema for trigger tools
ā āāā linked_services.py schema for linked-service tools
ā āāā datasets.py schema for dataset tools
ā āāā data_flows.py schema for data-flow tools
ā āāā global_parameters.py schema for global-parameter tools
ā āāā integration_runtimes.py schema for integration-runtime tools
ā āāā __init__.py assembles the schema list server.py exposes via list_tools()
ā
project/
āāā _snapshot/ pre-change pipeline/dataset/data-flow definitions, for rollback (gitignored, created at runtime)
āāā _logs/ audit log of tool calls, one dated folder per day (gitignored, created at runtime)
docs/TEST_ADF_CONTEXT.md living design/decision doc for this R&D effort ā read before making changes
.env real credentials (gitignored, never commit)
.env.example template ā copy to .env
requirements.txt pinned dependencies
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.