mcpField
D
Dagster Mcp

Dagster Mcp

Local
github.com/fabdendevCloud & Infra18Updated 4w ago

About Dagster Mcp

This MCP server gives AI agents tools to monitor and operate Dagster instances, covering runs, assets, jobs, schedules, sensors, and instance health. It supports multiple environments, with write operations enabled through configuration.

Key features

  1. 01Inspect run status, logs, and failure summaries
  2. 02Search assets and check their health
  3. 03List jobs, schedules, and sensors
  4. 04Check instance and code location status
  5. 05Operate runs, assets, and schedules
  6. 06Configure multiple Dagster environments

Use cases

  1. 01Diagnose failed data pipeline runs
  2. 02Find stale or unhealthy assets
  3. 03Check schedules and sensors that stopped triggering
  4. 04Launch jobs or stop stuck runs

MCP support

The MCP server exposes Dagster run, asset, job, schedule, sensor, and instance-management tools to MCP clients. It defaults to read-only tools; setting DAGSTER_READ_ONLY to false enables write operations.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"dagster": {
"command": "uvx",
"args": [
"dagster-mcp"
],
"env": {
"DAGSTER_URL": "<DAGSTER_URL>"
}
}
}
}
Run commanduvx dagster-mcp
Environment variables to set
DAGSTER_URL

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
pypidagster-mcp

Tools

17

Saved tool list · updated 2w ago

ParameterTypeRequiredDescription
envanyNo
limitintegerNo
job_nameanyNo
statusesanyNo

Details

From the project README

Dagster MCP

PyPI version Downloads License: MIT Python 3.12+ Tests

An MCP server that gives AI agents full visibility and control over your Dagster instance — like an SRE for your data pipelines.

Works with any MCP client: Claude Code, Claude Desktop, Cursor, and more.

Dagster officially develops and supports their own Dagster Plus MCP server. See the documentation here.

Why this exists

Data pipelines break at 3 AM. Schedules silently stop firing. Assets go stale. Instead of waking up to a dashboard full of red, give your AI agent the tools to monitor, diagnose, and fix your Dagster instance autonomously.

Agent: Checking instance health...
       get_instance_status() -> healthy: false, daemon "SCHEDULER" unhealthy

Agent: Scheduler daemon is down. Let me check recent failures...
       get_runs(statuses=["FAILURE"], limit=5) -> 3 failed runs in the last hour

Agent: Diagnosing the most recent failure...
       get_run_failure_summary("run_abc123") ->
         failed_steps: ["transform_orders"]
         root_cause: "NullPointerError: column 'price' is null"
         suggestions: ["Single step failed — consider re-running from failure"]

Agent: Re-launching the failed job...
       launch_job("etl_pipeline", "my_project") -> run_id: "run_def456", status: STARTED

Agent: One sensor keeps firing on bad data. Checking its ticks...
       get_tick_history("orders_sensor", "SENSOR") -> 12 consecutive FAILURE ticks

Agent: Stopping it until the upstream fix lands...
       stop_sensor("orders_sensor") -> status: STOPPED

What it does

27 tools across 6 categories, designed for autonomous DataOps workflows:

CategoryToolsWhat an agent can do
Runsget_runs get_run_status get_run_logs get_run_stats get_run_failure_summaryFind failures, diagnose root causes, inspect logs and step timing
Assetssearch_assets resolve_asset_selection get_asset_details get_recent_materializations get_asset_healthDiscover assets, preview lineage selections, check freshness, detect stale data
Jobslist_jobsInventory jobs across code locations, with optional repository/location filters
Schedules & Sensorslist_schedules list_sensors get_tick_historyDetect silent failures, missed ticks, sensor errors
Instanceget_instance_status list_code_locations list_backfillsGlobal health check, daemon status, code location errors
Actionsmaterialize_assets backfill_assets launch_job launch_job_with_partitions terminate_run start_schedule stop_schedule start_sensor stop_sensor reload_code_locationMaterialize concrete assets with config, backfill partitions, launch jobs, stop stuck runs, start or stop schedules and sensors, reload after deploy

Actions are opt-in: set DAGSTER_READ_ONLY=false to enable write operations.

Quick start

Prerequisites
  • Python 3.12+
  • uv (recommended) or pip
  • A running Dagster instance (self-hosted or Cloud)
Install

The package is published on PyPI.

Option A — run directly with uvx (no install needed):

uvx dagster-mcp

Option B — install with pip:

pip install dagster-mcp

Option C — clone and run:

git clone https://github.com/fabdendev/dagster-mcp.git
cd dagster-mcp
uv sync
Configure
Single environment
VariableDescriptionDefault
DAGSTER_URLBase URL of your Dagster instancehttp://localhost:3000
DAGSTER_API_TOKENDagster Cloud API token (leave empty for self-hosted)(empty)
DAGSTER_EXTRA_HEADERSJSON object of additional request headers sent to Dagster GraphQL(empty)
DAGSTER_READ_ONLYWhen true, only read tools are exposed (no launch/terminate/reload, no schedule or sensor start/stop)true

Self-hosted:

export DAGSTER_URL=http://localhost:3000

Dagster Cloud:

export DAGSTER_URL=https://myorg.dagster.cloud/prod
export DAGSTER_API_TOKEN=your-dagster-cloud-user-token

Custom auth / proxy headers:

export DAGSTER_EXTRA_HEADERS='{"Authorization":"Bearer your-token","X-My-Header":"value"}'
Multiple environments

Use DAGSTER_ENVS to configure several Dagster instances in one server. Every tool then accepts an optional env parameter so the LLM can target the right instance.

VariableDescriptionDefault
DAGSTER_ENVSJSON object mapping env names to {url, token?, extra_headers?} configs(empty)
DAGSTER_DEFAULT_ENVEnv name to use when env is not passed to a tool(empty)
export DAGSTER_ENVS='{
  "prod": {"url": "https://myorg.dagster.cloud/prod", "token": "prod-token"},
  "staging": {"url": "https://myorg.dagster.cloud/staging", "token": "stg-token"},
  "dev": {"url": "http://localhost:3000"}
}'
export DAGSTER_DEFAULT_ENV=prod

When DAGSTER_ENVS is set, DAGSTER_URL / DAGSTER_API_TOKEN / DAGSTER_EXTRA_HEADERS are ignored. If only one env is defined, it is used automatically even without DAGSTER_DEFAULT_ENV.

Add to your MCP client
Claude Code

Add to ~/.claude/settings.json:

Single env:

{
  "mcpServers": {
    "dagster": {
      "command": "uvx",
      "args": ["dagster-mcp"],
      "env": {
        "DAGSTER_URL": "http://localhost:3000"
      }
    }
  }
}

Multiple envs:

{
  "mcpServers": {
    "dagster": {
      "command": "uvx",
      "args": ["dagster-mcp"],
      "env": {
        "DAGSTER_ENVS": "{\"prod\":{\"url\":\"https://myorg.dagster.cloud/prod\",\"token\":\"prod-token\"},\"dev\":{\"url\":\"http://localhost:3000\"}}",
        "DAGSTER_DEFAULT_ENV": "prod"
      }
    }
  }
}
Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "dagster": {
      "command": "uvx",
      "args": ["dagster-mcp"],
      "env": {
        "DAGSTER_URL": "http://localhost:3000"
      }
    }
  }
}
From a local clone
{
  "mcpServers": {
    "dagster": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/dagster-mcp", "dagster-mcp"],
      "env": {
        "DAGSTER_URL": "http://localhost:3000"
      }
    }
  }
}

Tool reference

Runs
ToolDescription
get_runsList recent runs, filter by job name and/or status
get_run_statusGet status, config, tags, and run lineage (re-execution chain via rootRunId/parentRunId)
get_run_logsGet structured log events with pagination and optional level filtering (ERROR, WARNING, INFO); EngineEvent events include metadataEntries
get_run_statsGet per-step execution stats: timing, materializations, expectation results
get_run_failure_summaryConsolidated failure diagnosis — failed steps, root cause error, step durations, and suggestions in one call
Assets
ToolDescription
search_assetsDiscover assets by key prefix or group name
resolve_asset_selectionResolve key/group/tag/kind/owner predicates, wildcards, boolean logic, roots/sinks, and lineage traversal into concrete asset keys without launching anything
get_asset_detailsGet description, upstream/downstream dependencies, partitions, latest materialization
get_recent_materializationsGet materialization history with metadata for an asset
get_asset_healthConsolidated health view — staleness, freshness policy, last run status (works with single asset or entire group)
Two-step asset workflow

Start by resolving and reviewing a selection expression:

resolve_asset_selection(
  asset_selection="group:analytics and (kind:dbt or key:*benchmark)"
)

→ {
    "asset_keys": [
      "warehouse/analytics/orders",
      "warehouse/analytics/reranker_benchmark"
    ],
    "assets": [...]
  }

For concrete, unpartitioned assets, pass the returned keys to materialize_assets with any required launch config and tags:

materialize_assets(
  asset_keys=[
    "warehouse/analytics/orders",
    "warehouse/analytics/reranker_benchmark"
  ],
  run_config={"ops": {"benchmark": {"config": {"limit": 1000}}}},
  tags={"triggered_by": "agent"}
)

For partitioned assets, pass the same resolved keys to backfill_assets instead:

backfill_assets(
  asset_keys=["warehouse/analytics/daily_orders"],
  partition_start="2026-07-01",
  partition_end="2026-07-07",
  run_config={"resources": {"warehouse": {"config": {"pool": "benchmark"}}}}
)

resolve_asset_selection is available in both read-only and read-write modes. It returns external, observable, non-executable, and partitioned matches so the caller can inspect the complete result. The write tools re-fetch current asset definitions before execution. resolve_asset_selection and materialize_assets require Dagster 1.9+.

Jobs, Schedules & Sensors
ToolDescription
list_jobsList jobs across code locations, optionally filtered by exact repository_name and/or location_name (use to find names for launch_job)
list_schedulesList schedules with status (RUNNING/STOPPED), cron, target job, next tick
list_sensorsList sensors with status and target jobs
get_tick_historyTick-by-tick history for a schedule or sensor — essential for detecting silent failures. Accepts optional repository_name / location_name to disambiguate a name shared by several code locations

list_jobs filters are independent and use AND semantics when combined. For example, list_jobs(repository_name="example_repository") finds that repository across locations, while list_jobs(repository_name="example_repository", location_name="example_location") targets one repository and code-location pair. Calls with only one filter use a lightweight repository-discovery request followed by one batched job request — it isn't free: that's a second round-trip against Dagster, traded for a smaller payload when only a subset of repositories matches. Request counts per call: 1 for no filters, 1 for both filters, 2 for exactly one filter.

If a code location relevant to the filter failed to load or is still loading, list_jobs raises a RuntimeError naming the location instead of silently returning an empty result — an empty filtered result means no match among code locations Dagster could actually load. A non-empty filtered result can still be incomplete: if some repositories matched, list_jobs returns them rather than raising, even when another code location could not be searched. This check rides along in the same requests above (workspaceOrError, which list_code_locations already queries), so it adds no extra round-trip. The unfiltered call (list_jobs() with no filters) is unchanged: it omits this check and keeps returning whatever is loaded, since an agent won't misread a long inventory listing as "nothing exists" the way it would misread an empty filtered result — use list_code_locations or get_instance_status to check load health directly.

Instance & Code Locations
ToolDescription
get_instance_statusStart here — global health: daemon status, queued run count, code location errors
list_code_locationsList all code locations and their load status
list_backfillsList recent backfills with status and partition progress
Write Operations
ToolDescription
materialize_assetsLaunch concrete, unpartitioned asset keys with run config and tags; infers one compatible repository/job, includes compatible checks, and expands required non-subsettable multi-asset neighbors. On a failed launch it returns the preflight context plus error and message rather than raising, and omits launched_asset_keys
backfill_assetsLaunch a partition backfill by asset selection with optional run config; respects each asset's BackfillPolicy server-side
launch_jobLaunch a named job; asset_keys remains supported for compatibility and is sent through GraphQL assetSelection, but the two-step asset workflow is preferred
launch_job_with_partitionsLaunch a partitioned job for one or more partition keys; creates a backfill (supports from_failure to retry only failed steps)
start_scheduleStart (enable) a schedule so it launches runs on its cron
stop_scheduleStop (disable) a schedule — persists across restarts; does not terminate in-flight runs
start_sensorStart (enable) a sensor so it resumes evaluating
stop_sensorStop (disable) a sensor — the fix for a runaway or erroring sensor found via get_tick_history

Schedule/sensor names are unique only within a repository. If the same name exists in several code locations, the start/stop tools refuse to act and list the candidates; pass repository_name / location_name to disambiguate. Successful calls echo the resolved repository and location. | terminate_run | Stop a stuck or runaway run | | reload_code_location | Reload a code location after deploy |

Write tools require DAGSTER_READ_ONLY=false (default is true).

How it differs from Dagster's official AI tooling

Dagster builds and supports its own AI tooling. If you are a Dagster+ customer, start with theirs — it is first-party, needs no local runtime, and reaches Dagster+ platform objects (alerting, Issues, Insights) that this project cannot. This project exists mainly for people running open-source / self-hosted Dagster, which the official server's documented setup does not cover.

Everything in the "official" column comes from Dagster's own docs at https://docs.dagster.io/guides/labs/dagster-mcp (retrieved 2026-07-30), or from Dagster directly in #21. Dagster's docs nowhere state that open-source or self-hosted Dagster is unsupported; what they document is a Dagster-hosted URL, a required Dagster-Cloud-Organization header, and a Dagster+ user token. Their capability matrix is a snapshot of today and Dagster expects to keep adding to it, so treat the gaps below as current rather than permanent.

dagster-mcp (this project)Dagster+ MCP server (official)dagster-expert skill (official)
What it isMCP server you run yourself (Python, MIT)Dagster-hosted remote MCP endpoint at https://mcp.agent.dagster.cloud/mcpAn Agent Skill — markdown instructions loaded by your coding agent, not an MCP server
When you use itOperations time, against a live instanceOperations time, against a Dagster+ deploymentDevelopment time, against your local codebase
Works with self-hosted / OSS DagsterYes — points at any Dagster webserver (DAGSTER_URL, default http://localhost:3000; /graphql is appended). No token requiredNot per the documented setup: the only URL given is Dagster-hosted, and connecting requires a Dagster-Cloud-Organization header plus a Dagster+ user tokenYes — Apache-2.0 markdown files you copy locally
Works with Dagster+Yes — sends a Dagster-Cloud-Api-Token header; extra headers via DAGSTER_EXTRA_HEADERSYes — this is its only documented targetn/a
SetupLocal process launched by your MCP client (Python 3.12+, e.g. uvx dagster-mcp), configured with env varsNo local runtime: claude mcp add --transport http dagster-plus https://mcp.agent.dagster.cloud/mcp --header "Dagster-Cloud-Organization: …" --header "Authorization: Bearer …"Copy the skill files into your agent
Maturityv0.8.0 on PyPI (pre-1.0), MIT, single maintainer with occasional outside contributions, "AS IS, WITHOUT WARRANTY OF ANY KIND", no SLALabelled by Dagster as Preview: "under active development, and not considered ready for production use… the APIs may change", and published under /guides/labs/Current, no preview label
RunsView, launch, terminate, per-step stats, log retrieval, consolidated failure summaryView ✅, Create/Launch ✅, Delete/Terminate ✅, Insights metrics ✅, Update ❌ (Dagster's matrix); run logs View ✅n/a
AssetsView, search, health, resolve selection syntax, and materialize specific assets (resolve_asset_selection → materialize_assets, with run config and partition ranges)View ✅ and Insights metrics ✅; Create/Launch, Update and Delete marked ❌ — i.e. no asset-level materialization tool, though launching a run is supportedn/a
Schedules & sensorsList, tick history, start/stopNot supported today — confirmed by Dagster, who expect to add itn/a
Backfills & partitionsList backfills, launch partitioned jobs, backfill assets over a partition rangeNot listed in Dagster's capability matrixn/a
Code locations & instance healthList/reload code locations, instance status, daemon heartbeats, queued-run countsDeployments View ✅ and Insights ✅; code locations and daemon health not listed (Dagster+ manages the daemon)n/a
Alerting, Insights, Dagster+ IssuesNot supported — no alerting, cost/Insights metrics, or Issues equivalentAlert policies and Dagster+ Issues: View / Create / Update / Delete all ✅. Insights metrics ✅ on Runs, Assets and Deployments. All three are documented Dagster+ features (Issues is in limited early access)n/a
Multiple instancesYes — DAGSTER_ENVS maps names to arbitrary URLs and tokens, with a per-tool env argument; you can mix OSS and Dagster+Deployments within one Dagster+ organization, selected per tool calln/a
Write safety17 read tools always registered; the 10 write tools are registered only when DAGSTER_READ_ONLY=false (default true), so clients cannot even see them otherwise. This is a convenience guardrail, not a security boundary: it is a process-level env var read at import, and the API token you configure keeps whatever rights it hasEnforced server-side by Dagster+ token permissions. The docs default to a personal user token; a service user is offered as the alternative for scoped, non-human auth (service users are a Dagster+ Pro feature)n/a
SupportBest-effort, community, GitHub issues; no SECURITY.md or documented disclosure processFirst-party vendorFirst-party vendor

Use the official Dagster+ MCP server if you are on Dagster+ and want alerting, Issues or Insights/cost analysis from an agent, want no local runtime, or need vendor support and a supplier your procurement process will accept.

Use this project if you run open-source or self-hosted Dagster, or you need asset-level materialization, schedule/sensor control, backfills, or code-location and daemon operations from an agent.

For Dagster+ users the two are complementary rather than competing — nothing stops you running both. This project is not affiliated with or endorsed by Dagster Labs.

Compatibility

The monitoring and existing action tools are tested with Dagster 1.6+. resolve_asset_selection and materialize_assets require Dagster 1.9+ and verify the required GraphQL capabilities before querying or launching. The RunsFilter field name (jobName vs pipelineName) is auto-detected via schema introspection. Configured asset backfills also feature-detect LaunchBackfillParams.runConfigData and return a clear compatibility error when an older schema does not expose it. Schedule and sensor start/stop work on Dagster 1.6+: the stop mutations are sent with the originId/selectorId argument pair sourced from InstigationState.id/selectorId, which modern Dagster re-parses as a compound id and older versions accept directly, so no version branch is needed. The mutations select error messages via the ... on Error interface fragment rather than per-type fragments, because ScheduleNotFoundError only joined ScheduleMutationResult in Dagster 1.9 and spreading it on 1.6-1.8 would fail document validation.

Development

uv sync --extra dev
uv run ruff check dagster_mcp/    # lint
uv run pytest                     # run the test suite
uv run python -m dagster_mcp      # start server locally

License

MIT

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.