adf-mcp-server
This is a read-only MCP server for Azure Data Factory monitoring and root-cause analysis.
Health & auth:
health_checkconfirms the server is running;check_authvalidates Azure credentials.Factory discovery:
list_factoriesfinds all accessible Data Factories;get_factoryreturns details for one.Pipeline inspection:
list_pipelinesshows pipelines with lightweight activity summaries;get_pipelinegets a full activity list.Pipeline run monitoring:
list_pipeline_runslists runs in a time window with optional filters;get_pipeline_runfetches full run details.Activity-level RCA:
list_activity_runslists all activities in a run;get_failed_activity_detailsreturns only failed activities with extracted error details.Trigger diagnostics:
list_triggersandget_trigger_statusreveal whether triggers are started/stopped;list_trigger_runsshows trigger firing history.Hierarchical RCA:
get_pipeline_run_treerecursively walks Execute Pipeline activities to find failures across master/child pipeline runs.
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., "@adf-mcp-serverShow me failed pipeline runs in the last 24 hours"
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.
adf-mcp-server
Read-only MCP (Model Context Protocol) server for Azure Data Factory monitoring and root-cause analysis, built for use from VS Code / Claude Code.
Status: Step 1 (skeleton + health check). No Azure connectivity yet - that's added in Step 2 (auth) and Step 3 (ADF tools).
Requirements
Python 3.11+
One of:
An Azure AD App Registration (Service Principal) with Reader role on the Data Factory resource(s), or
Your own Entra ID user account with Reader role on the same (see "Auth modes" below)
Related MCP server: azure-query-mcp
Local setup
cd adf-mcp-server
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
cp .env.example .envAuth modes
This server supports two ways to authenticate to Azure, controlled by
ADF_MCP_AUTH_MODE in .env. Both go through the same check_auth /
get_credential() code path - nothing else in the codebase cares which
one is active.
Service Principal (service_principal)
Uses an app registration + client secret. Good for shared/CI use where no human needs to be present.
az ad sp create-for-rbac \
--name "adf-mcp-server-reader" \
--role "Reader" \
--scopes "/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RG_NAME>/providers/Microsoft.DataFactory/factories/<FACTORY_NAME>"Map the output into .env: AZURE_CLIENT_ID (appId), AZURE_CLIENT_SECRET
(password), AZURE_TENANT_ID (tenant).
Interactive Browser (interactive_browser)
Uses your own Entra ID sign-in - the same identity you use to log into the Azure portal - via a browser popup. No app registration or secret to manage. Good fit for solo local/VS Code use.
ADF_MCP_AUTH_MODE=interactive_browser
AZURE_TENANT_ID=<your tenant ID> # recommended - see note below
AZURE_SUBSCRIPTION_ID=<your subscription ID>RBAC note: in this mode, Azure checks your own user account's permissions, not an app registration's. Your account (or a group you're in) needs Reader on the target Data Factory - ask whoever manages RBAC to run:
az role assignment create --assignee <your-email-or-object-id> --role "Reader" \
--scope "/subscriptions/<SUB_ID>/resourceGroups/<RG>/providers/Microsoft.DataFactory/factories/<FACTORY>"Behavior:
The first time any tool needs a token, a browser window opens for you to sign in.
After that, the token is cached in memory for the life of the server process - no repeat popups until it restarts.
By default, the token cache is also persisted (encrypted, via your OS's keychain/credential manager) so restarting the server usually doesn't prompt again either. Set
ADF_MCP_AZURE_USE_PERSISTENT_TOKEN_CACHE=falsein.envto disable this and always use an in-memory-only cache.Setting
AZURE_TENANT_IDis recommended: without it, sign-in uses the multi-tenant "organizations" endpoint, which can prompt you to pick a tenant if your account belongs to more than one (e.g. a personal Microsoft account plus a work Entra ID tenant).
Running the server
python -m adf_mcp.server
# or, after `pip install -e .`:
adf-mcp-serverThe server communicates over stdio - running it directly in a terminal
will look like it hangs; that's expected, it's waiting for an MCP client
(VS Code extension, Claude Code, mcp dev, etc.) to connect via stdin/stdout.
Configuring in VS Code
Point your MCP-capable extension's server config at:
{
"command": "python",
"args": ["-m", "adf_mcp.server"],
"cwd": "/absolute/path/to/adf-mcp-server"
}Once connected:
Call
health_check- should return{"status": "ok", ...}without touching Azure at all.Call
check_auth- this makes one real call to Azure AD to acquire an ARM token. Success looks like:{"authenticated": true, "auth_mode": "service_principal", "token_expires_on": 1735000000}Failure returns a structured (not stack-trace) explanation, e.g. missing env vars or an invalid secret - see Troubleshooting below.
Call
list_factories- this makes a real call to Azure Data Factory. Returns each factory'sresource_group, which every other tool below needs as an input:{"factories": [{"name": "shell-prod-adf", "resource_group": "rg-shell-prod", "location": "eastus"}]}
Available tools (Step 3)
All tools are read-only - none of them can create, modify, trigger, or delete anything in Azure Data Factory.
Tool | Required args | Notes |
| — | No Azure calls |
| — | Verifies the Service Principal only |
| — | Start here - returns |
|
| |
|
| Lightweight: name + activity count/names |
|
| Full activity list for one pipeline |
|
|
|
|
| Full, untruncated run detail - get |
Example RCA flow for an agent: list_factories → list_pipeline_runs(status="Failed")
→ get_failed_activity_details(run_id=...) for the error breakdown directly.
Available tools (Step 4 additions)
Tool | Required args | Notes |
|
| Full activity list for a run; |
|
| The RCA tool - only failed activities, with |
|
| All triggers + current runtime state (Started/Stopped) |
|
| One trigger's runtime state - catches "pipeline never ran because its trigger was stopped" |
|
|
|
|
| Master/child RCA tool - recursively walks every Execute Pipeline activity to its child run, returning the full nested tree plus a flattened |
Full RCA flow for a failed pipeline: list_pipeline_runs(status="Failed") →
get_failed_activity_details(run_id=...) for the error, and separately
get_trigger_status(trigger_name=...) to rule out "it never even fired."
For a master pipeline with child pipelines (Execute Pipeline
activities), use get_pipeline_run_tree(run_id=<master's run_id>) instead
of chaining get_failed_activity_details manually level by level - it
walks the whole tree in one call and tells you exactly which child
pipeline (and which activity inside it) actually failed, however deep.
Running tests
pip install -e ".[dev]" pytest-asyncio
pytest -vProject layout
See src/adf_mcp/ - server.py (MCP transport), config.py (settings),
logging_config.py (structured logging). Domain logic and Azure
connectivity are added under src/adf_mcp/domain/ from Step 3 onward.
Troubleshooting
Client shows "server disconnected" immediately: check
python -m adf_mcp.serverruns cleanly on its own first - a startup exception will kill the process before the client ever connects.Client can't parse responses / garbled output: something wrote to stdout other than the MCP protocol itself (e.g. a stray
print()). All logging in this project goes to stderr for exactly this reason.check_authreturns "Missing required Service Principal setting(s)": one ofAZURE_TENANT_ID/AZURE_CLIENT_ID/AZURE_CLIENT_SECRETis empty in.env. Note these three do NOT use theADF_MCP_prefix.check_authreturns "Azure authentication failed": usually an expired/rotated client secret, a disabled App Registration, or a tenant ID typo. Re-verify withaz ad sp show --id <AZURE_CLIENT_ID>.ClientAuthenticationError: AADSTS7000215: invalid client secret - regenerate it in the App Registration and update.env.A tool returns
{"error": "AZURE_SUBSCRIPTION_ID is not set..."}: addAZURE_SUBSCRIPTION_IDto.env- required for every ADF tool (notcheck_auth, which only needs tenant/client/secret).A tool returns
{"error": "Azure API error (403): ..."}: the Service Principal lacks Reader access to that factory/resource group - re-check theaz ad sp create-for-rbac --role Reader --scopes ...assignment from setup.A tool returns
{"error": "Azure API error (404): ..."}: check theresource_group/factory_name/pipeline_namespelling - these are case-sensitive and must match exactly whatlist_factories/list_pipelinesreturned.get_failed_activity_detailsreturns an empty list but you know the pipeline failed: the failure may be at the pipeline level (e.g. an invalid parameter) rather than any single activity - check the parent run's ownmessageviaget_pipeline_runinstead.A pipeline "just didn't run" with no failed runs at all: check
get_trigger_statusfor its trigger -runtime_state: "Stopped"means the trigger was disabled and never fired, which won't show up as a failed run because no run was ever created.check_authopens a browser but sign-in never completes / times out:interactive_browsermode waits 5 minutes by default. If you're on VS Code Remote/SSH or in a container without a reachable local browser, this mode may not work at all - fall back toservice_principalin that environment.Browser popup appears every single time you restart the server: persistence may have silently failed and fallen back to in-memory-only (check server logs for "Persistent token cache unavailable"). This is common on headless Linux without a keyring daemon running - either install/enable one (e.g.
gnome-keyringorkwallet), or accept the repeat prompts as the tradeoff of that environment.check_authsucceeds but every ADF tool returns a 403: ininteractive_browsermode this means your own account lacks Reader on the factory (not an app registration) - see the RBAC note above.get_pipeline_run_treeshows a child's activities as an empty list, but you know it has activities: the child run may have started outside the sharedstart_time/end_timewindow (default: last 7 days) - widen the window explicitly if a master pipeline runs for an unusually long time relative to its children.A deeply nested child pipeline is missing from the tree: check
truncated: trueon its parent node -max_depth(default 5) was reached. Re-run with a highermax_depthif your pipelines nest that deep.
Available Tools
13 toolscheck_authA
Verify Azure Service Principal credentials by acquiring a real ARM token.
Makes no Azure Data Factory calls - it only proves auth is configured correctly (tenant/client/secret valid, SPN enabled) before any ADF connectivity exists. Run this after health_check and before Step 3.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly states that this tool makes no Azure Data Factory calls and only proves auth configuration, and that it acquires a real ARM token. This is strong disclosure of scope and side effects. It could have described potential failure behaviors (e.g., what happens on invalid credentials), but the stated behavior is transparent and sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, with the core purpose front-loaded. Every sentence adds value: the first states what it does and the second clarifies scope and when to use it. There is zero redundancy or filler, making it highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters, an output schema exists (so return values are covered), and the description provides clear purpose, scope, and usage sequence, nothing is missing for correct invocation. It fully covers the essential context an agent needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the input schema is empty, so there are no parameter semantics to explain. The baseline for 0 params is 4, and the description already communicates the tool's purpose and usage, requiring no additional parameter context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Verify') and resource ('Azure Service Principal credentials') and explains the action ('acquiring a real ARM token'). It explicitly distinguishes itself from siblings by noting it makes no ADF calls and is for auth verification only, so an agent can clearly tell it apart from health_check or list_factories without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit sequencing guidance: 'Run this after health_check and before Step 3.' It also clarifies the context ('before any ADF connectivity exists') and states what the tool does not do, steering the agent away from using it for other purposes. Alternatives are not named but the sibling tools are all ADF operations, so the intended use is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_factoryC
Get details for a single Data Factory instance.
| Name | Required | Description | Default |
|---|---|---|---|
| factory_name | Yes | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. The description only says 'Get details', which implies a read operation, but it doesn't explicitly state that it has no side effects, what permissions (if any) are required, or what the response contains beyond the output schema. Minimal disclosure beyond the obvious.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words, which makes it concise and front-loaded. However, it is arguably under-specified rather than efficiently concise, as it misses crucial guidance. Still, for what it conveys, it is well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 12 siblings, no annotations, and zero parameter descriptions, the description is insufficient. It doesn't help an agent decide when to use it versus alternatives, doesn't explain parameters, and doesn't provide any behavioral context. While an output schema exists, that alone does not make the tool adequately described for effective selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has zero description coverage for its two parameters (resource_group and factory_name), and the description provides no additional meaning about them. The description doesn't explain what these parameters are used for, how they should be formatted, or any constraints beyond their names. The description fails to compensate for the lack of schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Get' and names the resource 'Data Factory instance', which clearly distinguishes it from sibling tools like list_factories (which lists many) and get_pipeline (which targets a different resource). It is unambiguous about what the tool does, though it doesn't specify what 'details' entails, which is partly covered by the output schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus its siblings. The description doesn't mention when to prefer get_factory over list_factories or get_pipeline, nor does it provide any conditions or alternatives. An agent would have to infer usage based on the tool name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_failed_activity_detailsA
RCA convenience tool: returns only the activities that failed within a pipeline run, each with error_code/message/failure_type already extracted. Prefer this over list_activity_runs when you just need "what went wrong" rather than the full activity list.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | ||
| end_time | No | ||
| start_time | No | ||
| factory_name | Yes | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It reveals the core behavior (filtering and extracting fields) but does not explicitly state whether the operation is read-only or if there are any side effects, permissions, or rate limits. However, the description implies a retrieval action, which is acceptable for a read tool, but it lacks explicit safety disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with high information density. The key phrase 'RCA convenience tool' is front-loaded, and every part contributes to understanding the tool's purpose and usage. No wasted words or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, and the description mentions the output fields (error_code/message/failure_type), which helps the agent understand the return format. It also gives a clear use case. However, it does not mention the required parameters (resource_group, factory_name, run_id) or any preconditions, and the lack of parameter guidance makes it less complete for a 5-parameter tool with no schema descriptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description provides no explanation of any of the five parameters (run_id, start_time, end_time, factory_name, resource_group). It does not mention what each parameter means or how they affect the call, leaving the agent to infer from names alone. This is a significant gap given the zero coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is an 'RCA convenience tool' that returns only failed activities with extracted error_code/message/failure_type. It explicitly distinguishes itself from list_activity_runs by narrowing scope to failures, making the purpose unambiguous and distinct from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit guidance to 'Prefer this over list_activity_runs when you just need "what went wrong" rather than the full activity list.' This names the alternative and the condition, leaving no ambiguity about when to choose this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pipelineC
Get a single pipeline's activity list.
| Name | Required | Description | Default |
|---|---|---|---|
| factory_name | Yes | ||
| pipeline_name | Yes | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It only says 'Get', which implies a read operation, but provides no information about authentication requirements, rate limits, side effects, or error behavior. This is a significant gap for a tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, which is concise, but it is under-specified rather than appropriately sized. While it is front-loaded with the main purpose, every remaining piece of useful information (usage, parameters, behavior) is absent. This is a case of over-trimming that sacrifices necessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although an output schema exists (so return values are covered), the description lacks essential context about what an 'activity list' is, the required Azure Data Factory identifiers, and any operational constraints. Given the tool has three required parameters and no annotation support, the description is incomplete and would leave an agent guessing at invocation details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, meaning the schema provides no semantic explanation for the three required parameters. The description does not mention any of the parameters at all. The parameter names (resource_group, factory_name, pipeline_name) are somewhat self-explanatory, but the description adds no meaning, leaving the agent to guess at concepts like resource_group or factory_name without context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get') and the resource ('a single pipeline's activity list'), and the word 'single' distinguishes it from list operations. However, it doesn't explicitly differentiate from similar siblings like list_activity_runs, and 'activity list' could be ambiguous (definitions vs runs), but the overall purpose is understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool instead of alternatives. It doesn't mention any preconditions, exclusions, or scenarios where another tool would be more appropriate. The agent is left to infer usage from the minimal context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pipeline_runB
Get full, untruncated detail for a single pipeline run.
Get run_id from list_pipeline_runs first.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | ||
| factory_name | Yes | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the result is 'full, untruncated' (implying complete data without pagination), but does not mention authentication requirements, error behavior, or rate limits. The output schema covers return structure, but the description adds minimal behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no unnecessary padding. The primary purpose is front-loaded, and the usage hint is placed immediately after. It is concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, so return values are defined separately. However, the description does not explain two of the three required parameters, nor does it mention authentication or error handling. The guidance to fetch run_id first is helpful, but the overall context is incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It only hints at run_id via the usage note, but does not explain resource_group or factory_name at all. The agent is left to infer these from context, which is insufficient for a required-parameter-heavy tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'single pipeline run', and adds the specific qualifier 'full, untruncated detail'. This distinguishes it from list_pipeline_runs, which lists runs, though it does not explicitly name other siblings like get_failed_activity_details.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The second sentence provides a concrete usage prerequisite: 'Get run_id from list_pipeline_runs first.' This tells the agent where to obtain a required parameter. However, it does not explicitly state when this tool should be preferred over alternatives like get_failed_activity_details.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_trigger_statusB
Get a single trigger's current runtime state. A stopped trigger is a common silent cause of "why didn't this pipeline run today" - the pipeline simply was never invoked, so pipeline-run history alone won't show it.
| Name | Required | Description | Default |
|---|---|---|---|
| factory_name | Yes | ||
| trigger_name | Yes | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It implies a read-only operation ('Get') and reveals that a trigger can be stopped, which is key behavior. However, it doesn't mention potential error conditions, permissions, or the exact meaning of 'runtime state' (e.g., other states beyond stopped). For a simple getter, this is acceptable but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core action and followed by a motivating example. Every word earns its place—there's no redundancy or excess. It balances specificity with brevity perfectly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the primary use case and leverages the output schema for return details, so it doesn't need to explain outputs. However, it doesn't guide the agent on prerequisites like calling list_triggers to obtain trigger names, nor does it mention any authentication or resource-location expectations. For a tool with three required parameters and no schema descriptions, more contextual guidance would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description mentions none of the three parameters (resource_group, factory_name, trigger_name). While the names are somewhat self-explanatory, the description provides no additional context about their meaning, format, or relationships. This is a significant gap when the schema itself lacks descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the purpose: 'Get a single trigger's current runtime state.' It also differentiates from pipeline-run history by explaining that a stopped trigger won't appear there, which helps the agent understand the tool's unique value. However, it doesn't explicitly contrast with sibling tools like list_triggers, so it isn't fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a concrete usage scenario: when a pipeline didn't run today, check if the trigger is stopped. It explains why pipeline-run history alone is insufficient, giving a clear 'when to use' signal. It doesn't explicitly name alternatives or exclusions, but the scenario effectively guides the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
health_checkA
Report that the MCP server is up and configuration loaded correctly.
Useful as a first call from any MCP client (VS Code, Claude Code) to confirm the server started, before any Azure-dependent tools exist.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It clearly indicates a read-only status check (no mutation implied) and adds a timing context ('before any Azure-dependent tools exist') that is useful. It doesn't explicitly state 'no side effects' or failure behavior, but the output schema likely covers those details. The added context is valuable and goes beyond the tool's name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise: two short sentences. The first front-loads the core purpose, and the second provides usage context. No filler or repetition, every sentence earned its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with an output schema present, the description fully covers purpose and usage. It tells the agent exactly when to call it and why, and the output schema handles return details. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema is trivially fully described (empty object). Per the baseline rule for 0 params, a score of 4 is appropriate; the description needs no parameter information since none exist.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Report') and a clear resource ('MCP server is up and configuration loaded correctly'). It is obviously distinct from the sibling Azure tools (factories, pipelines, triggers), leaving no ambiguity about what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs when to use: 'first call from any MCP client (VS Code, Claude Code) to confirm the server started, before any Azure-dependent tools exist.' This gives clear context and implicitly advises against using it after other tools, making its role in the workflow obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_activity_runsA
List every activity run within a pipeline run, each with error detail populated if it failed. Time window defaults to the last 7 days. Get run_id from list_pipeline_runs first.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | ||
| end_time | No | ||
| start_time | No | ||
| factory_name | Yes | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must disclose behavioral traits. It adds value by stating the default 7-day time window and that error details are populated on failure. However, it omits potential pagination, permission requirements, or any limits on the result set. While the disclosed details are useful, significant behavioral aspects remain unaddressed, so a 3 reflects adequate but incomplete transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences. The first sentence immediately states the core action and error detail, and the second covers the time default and prerequisite. There is no fluff or unnecessary detail, and the most important information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists, return values are already specified. The description covers the essential prerequisites (run_id acquisition), the default time window, and the scope (activity runs within a pipeline). It does not explicitly explain parameter formats or edge cases, but for a list tool in a familiar Azure Data Factory context, it is nearly complete. A 4 reflects its adequacy with minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies run_id (source via list_pipeline_runs) and implies start_time/end_time semantics through the 'time window defaults to last 7 days' note. However, it does not explain factory_name or resource_group roles, nor the expected format for time values. This is partial compensation for a low-coverage schema, earning a 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the exact function: 'List every activity run within a pipeline run, each with error detail populated if it failed.' It uses a specific verb ('List') and resource ('activity run within a pipeline run'), and distinguishes itself from siblings like list_pipeline_runs by referencing that tool as the source of run_id. This makes the tool's role unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear prerequisite: 'Get run_id from list_pipeline_runs first.' It also implies the time window context. However, it does not explicitly compare with alternative tools like get_failed_activity_details or get_pipeline_run, nor state when not to use this tool. The guidance is sufficient for a straightforward list operation but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_factoriesA
List all Data Factory instances the configured Service Principal can see.
Returns each factory's resource_group, which every other ADF tool below requires as an input - call this first.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the tool lists only instances visible to the configured Service Principal, implying scoped access, and notes that it returns resource_group values. It does not explicitly state it is read-only, but a listing operation with no side effects is implied. This is adequate transparency for a simple read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, with the core purpose and return value front-loaded, followed by a crucial usage directive. No wasted words, and each sentence earns its place. Excellent structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless listing tool with an output schema, the description covers the essential points: what it lists, what it returns (resource_group), and when to call it (first). It is complete enough for an agent to call it correctly without further explanation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the input schema is an empty object. The description correctly does not mention parameters because none are needed. There is nothing to add beyond the schema, and the baseline for 0 params is 4, but given the clarity of 'no inputs required', a 5 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'List', the resource 'Data Factory instances', and the scope 'the configured Service Principal can see'. It also differentiates from sibling tools like list_pipelines and list_triggers by emphasizing that it lists factories specifically, and its role as a prerequisite for other ADF tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs to 'call this first' and explains that every other ADF tool requires the returned resource_group as input. This gives clear, unambiguous usage guidance and points to its role as an entry point, making it easy for an agent to know when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pipeline_runsA
List pipeline runs in a time window (default: last 24 hours).
Time values are ISO 8601 strings, e.g. "2026-08-22T00:00:00Z". Narrow results with pipeline_name and/or status (e.g. "Failed", "Succeeded", "InProgress"). Run messages are truncated to 500 chars here - use get_pipeline_run with a run_id from this result for full detail.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | ||
| end_time | No | ||
| start_time | No | ||
| factory_name | Yes | ||
| pipeline_name | No | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It reveals the default time window (last 24 hours), specifies ISO 8601 time formats, and discloses message truncation. It doesn't mention pagination, sorting, or whether results are limited, but for a read-only list operation with an output schema, the disclosed traits are significant and useful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no redundancy. Purpose and default are up front; filters and format follow; truncation and alternative are saved for the end. Every sentence earns its place and the structure is tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core behavior (listing runs, filters, default window, truncation) and points to get_pipeline_run for full detail. An output schema exists, so return structure is handled elsewhere. It omits pagination or sorting details, but those may be in the output schema or are secondary for a list operation. Overall, sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains start_time/end_time format, gives status examples, and describes pipeline_name as a filter. It doesn't explain resource_group/factory_name, but they are required and contextually obvious (factory and resource group). The description adds real meaning beyond the raw schema, though not exhaustive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists pipeline runs within a time window, including a default window, and mentions filtering by name and status. It distinguishes itself from get_pipeline_run (which retrieves a single run) but doesn't explicitly contrast with list_pipelines or list_activity_runs, so it's clear but not sharply differentiated from all siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says run messages are truncated to 500 chars and directs the agent to use get_pipeline_run with a run_id for full detail—a clear when-to-use-alternative instruction. It also implies this is the tool for listing runs, not for retrieving individual run details. No ambiguity about selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pipelinesA
List pipelines in a factory with a lightweight activity summary (count and names only - use get_pipeline for full detail on one).
| Name | Required | Description | Default |
|---|---|---|---|
| factory_name | Yes | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full transparency burden. It discloses a key behavioral trait: the result is a lightweight summary with 'count and names only,' and it points to get_pipeline for detailed data. This goes beyond the bare function name. However, it does not cover aspects like authentication, pagination, or error handling, but for a simple list tool these may be less critical.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the primary action and then adds the key nuance (lightweight vs. full detail). There is no wasted wording, and the structure is easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a straightforward list tool with an output schema present, the description covers the main intent and the distinction from the detailed counterpoint. However, it omits any mention of prerequisites (e.g., valid resource group) or ordering/pagination behavior, which could be relevant for an agent. It is adequate but leaves some room for improvement.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, and the description itself does not explain the parameters factory_name and resource_group. While the names might be self-explanatory within the Azure Data Factory domain, the description adds no semantic context to compensate for the missing schema descriptions. This is a clear gap given the low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List pipelines in a factory') with a specific verb and resource. It distinguishes itself from sibling get_pipeline by explicitly saying to use that for full detail. This is unambiguous and allows an agent to separate it from the other pipeline-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description names the primary alternative (get_pipeline) and explains when to use it (for full detail), providing clear guidance for the main distinction. It does not explicitly exclude other siblings like list_pipeline_runs or list_activity_runs, but it gives enough context to infer that this is the lightweight list tool. A brief mention of what it is not would push this to a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_trigger_runsA
List trigger firing history (default: last 7 days). Omit trigger_name to see every trigger's runs, or narrow to one; filter by status (e.g. "Succeeded", "Failed") to spot triggers that fired but errored.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | ||
| end_time | No | ||
| start_time | No | ||
| factory_name | Yes | ||
| trigger_name | No | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the default time range (last 7 days), the filtering options (trigger_name, status), and hints at the use case (spotting failures). However, it does not mention pagination, ordering, rate limits, or any side-effect profile (though 'List' implies read-only). Given the read-only nature and the output schema, this is adequate but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with high information density. The purpose is front-loaded, and each clause earns its place by explaining a distinct aspect (default range, trigger_name behavior, status filter). No redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list operation with an output schema and six parameters, the description covers the essential usage patterns: default time range, filtering by trigger and status. It does not mention time-format requirements or pagination, but these are typical for list tools and the output schema may provide details. Overall, an agent can call this correctly based on the description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the semantics of trigger_name (omit vs. narrow), status (filter), and implies start_time/end_time via the default range. Resource_group and factory_name are not elaborated, but they are standard identifiers and obvious from tool context. The description adds meaningful detail to the key filtering parameters, which is valuable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and resource ('trigger firing history'), which clearly distinguishes it from sibling tools like list_triggers (which lists definitions) and get_trigger_status (current status). It explicitly frames the tool as history-of-runs, so an agent can immediately identify when this is the right choice.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on when to use the tool (to inspect firing history, especially to spot errored runs) and gives operational guidance: omit trigger_name for all triggers, filter by status. It does not explicitly name alternatives or state when not to use it, but the context is sufficient for selection among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_triggersA
List every trigger in a factory with its current runtime state (Started/Stopped).
| Name | Required | Description | Default |
|---|---|---|---|
| factory_name | Yes | ||
| resource_group | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It says 'List', which implies a non-destructive read operation, but it doesn't explicitly state that it's read-only, mention any permissions required, or disclose behavior like pagination or error conditions. The mention of 'current runtime state' adds some behavioral context but is more about the return content than operational traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence communicates the tool's purpose and output state without any redundancy. The essential information (scope and state) is front-loaded, making it quick to parse. No filler or unnecessary detail is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists and the tool is a straightforward list operation, the description covers the core requirements: what is listed and the nature of the state. It lacks explicit mention of pagination or any exceptional cases, but those are less critical for a simple list tool. The absence of usage guidance is already penalized elsewhere, so this dimension remains adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage for parameters, and the tool description adds no explanation of resource_group or factory_name. While the parameter names are self-explanatory in a data-factory domain, the description fails to clarify their significance, expected format, or how they affect the result, which leaves an agent to infer from name alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (list) and the resource (every trigger in a factory), and specifies the key output (current runtime state with Started/Stopped). This distinguishes it from siblings like get_trigger_status (single trigger) and list_trigger_runs (runs, not triggers) without needing to inspect their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance on when to use this tool versus alternatives like get_trigger_status or list_trigger_runs. The context of 'every trigger' implies a bulk listing, but there is no mention of exclusions or conditions that would route an agent to a different sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
13 tool updates
v0.1.0- First observed
check_auth - First observed
get_factory - First observed
get_failed_activity_details - First observed
get_pipeline - First observed
get_pipeline_run - First observed
get_trigger_status - First observed
health_check - First observed
list_activity_runs - First observed
list_factories - First observed
list_pipeline_runs - First observed
list_pipelines - First observed
list_trigger_runs - First observed
list_triggers
TDQS
Scored across 13 tools
Each tool targets a distinct layer of the ADF workflow: health/auth bootstrap, factory discovery, pipeline inspection, run monitoring, activity diagnostics, and trigger management. Even the closest pair, list_activity_runs and get_failed_activity_details, is clearly separated by scope and purpose.
The naming is overwhelmingly consistent with list_/get_ + resource noun in snake_case, and the run-related tools follow a clear pattern. health_check is a minor convention break compared to check_auth, but this is a small deviation in an otherwise predictable set.
13 tools is well-scoped for an ADF server: each tool maps to a distinct object hierarchy or bootstrap step without unnecessary redundancy. The count is substantial enough to cover real workflows but not bloated.
The set covers the read-only factory, pipeline, run, activity, and trigger diagnostics lifecycle well, including failure RCA. It lacks any management/remediation operations such as stopping or starting triggers, canceling runs, or rerunning pipelines, so it is slightly incomplete for full operational control.
Maintenance
Related MCP Connectors
Read-only MCP access to sessions, funnels, campaigns, errors, live visitors, and anomalies.
Read-only MCP for identity resolution and write guardrails.
Provides read access to your GKE and Kubernetes resources.
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables interaction with Azure Data Factory instances, allowing users to list, read, create, update, and trigger pipelines, datasets, linked services, and runs through natural language.MIT
- AlicenseAqualityCmaintenanceEnables read-only querying of Azure Log Analytics and Azure Resource Graph through MCP, supporting KQL queries, workspace discovery, and resource inventory exploration with Azure RBAC authentication.52MIT
- FlicenseAqualityCmaintenanceProvides a read-only MCP interface for Azure Data Factory monitoring and root-cause analysis, with a health check for MCP clients.1-
- FlicenseNot gradedqualityBmaintenanceEnables read-only monitoring and root-cause analysis of Azure Data Factory resources through MCP, allowing users to inspect factories, pipelines, and pipeline runs and diagnose failures via natural language.-