Skip to main content
Glama
pjatx
by pjatx
README.md
# dagster-mono-mcp

A single-tool [MCP](https://modelcontextprotocol.io/) server for [Dagster](https://dagster.io). One tool, five actions, minimal token overhead.

Dagster has an [official MCP server](https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-mcp), but I couldn't get it working easily. This is a minimal alternative that covers the actions you actually need when debugging pipelines with an LLM: listing runs, inspecting run details, reading logs, and raw GraphQL for everything else.

Supports [Cloudflare Access](https://developers.cloudflare.com/cloudflare-one/applications/configure-apps/self-hosted-apps/) for Dagster instances behind Zero Trust — an easy, free way to secure your Dagster instance.

## Install

### Claude Code

Project-scoped (`.mcp.json` in your project root):

```json
{
  "mcpServers": {
    "dagster": {
      "command": "npx",
      "args": ["-y", "github:pjatx/dagster-mono-mcp"],
      "env": {
        "DAGSTER_GRAPHQL_URL": "https://dagster.example.com/graphql",
        "CF_ACCESS_CLIENT_ID": "your-client-id",
        "CF_ACCESS_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}
```

Global (`~/.claude.json` — available in all projects):

```json
{
  "mcpServers": {
    "dagster": {
      "command": "npx",
      "args": ["-y", "github:pjatx/dagster-mono-mcp"],
      "env": {
        "DAGSTER_GRAPHQL_URL": "https://dagster.example.com/graphql"
      }
    }
  }
}
```

### Cursor

Add to `.cursor/mcp.json` in your project root:

```json
{
  "mcpServers": {
    "dagster": {
      "command": "npx",
      "args": ["-y", "github:pjatx/dagster-mono-mcp"],
      "env": {
        "DAGSTER_GRAPHQL_URL": "https://dagster.example.com/graphql",
        "CF_ACCESS_CLIENT_ID": "your-client-id",
        "CF_ACCESS_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}
```

### Windsurf

Add to `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "dagster": {
      "command": "npx",
      "args": ["-y", "github:pjatx/dagster-mono-mcp"],
      "env": {
        "DAGSTER_GRAPHQL_URL": "https://dagster.example.com/graphql",
        "CF_ACCESS_CLIENT_ID": "your-client-id",
        "CF_ACCESS_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}
```

## Environment Variables

| Variable | Default | Required |
|----------|---------|----------|
| `DAGSTER_GRAPHQL_URL` | `http://localhost:3000/graphql` | No |
| `CF_ACCESS_CLIENT_ID` | — | No (required if behind CF Access) |
| `CF_ACCESS_CLIENT_SECRET` | — | No (required if behind CF Access) |

## Usage

Single tool `dagster` with action dispatch:

### List runs

```json
{"action": "runs"}
{"action": "runs", "status": "FAILURE"}
{"action": "runs", "job": "my_job", "limit": 5}
```

### Run details

```json
{"action": "run", "id": "<run-id>"}
```

### Event logs

```json
{"action": "logs", "id": "<run-id>"}
{"action": "logs", "id": "<run-id>", "limit": 100}
```

### Raw GraphQL

```json
{"action": "graphql", "query": "{ version }"}
{"action": "graphql", "query": "query($id: ID!) { runOrError(runId: $id) { __typename } }", "variables": {"id": "abc123"}}
```

### Help

```json
{"action": "help"}
```

Returns full documentation including available statuses, all parameters, and example queries.

## Design

This project follows the mono-tool pattern: one MCP tool with action dispatch instead of many small tools. Fewer tools means less token overhead for the LLM and simpler tool selection — the model doesn't have to choose between a dozen similar-sounding tools. Inspired by Cloudflare's [Code Mode](https://blog.cloudflare.com/code-mode/) post on rethinking how LLMs interact with MCP servers.

## Development

```bash
npm install
npm run build    # esbuild bundle -> dist/index.js
npm start        # run the MCP server (stdio transport)
```

## License

MIT

TDQS

B3.1/5.0

Scored across 1 tool

Disambiguation5/5

The single tool 'dagster' has clearly distinct actions (runs, run, logs, graphql, help) with no overlap in purpose. Each action targets a specific operation within the Dagster domain, making misselection impossible.

Naming Consistency5/5

The tool naming is perfectly consistent as there is only one tool, 'dagster', and its actions follow a clear, uniform pattern (e.g., 'runs', 'run', 'logs') without any mixing of conventions or styles.

Tool Count2/5

With only one tool, the server feels thin for a Dagster monitoring/debugging domain, as it bundles multiple distinct operations (e.g., querying runs, fetching logs, GraphQL) into a single tool. This may limit clarity and usability compared to a more granular tool set.

Completeness3/5

The tool covers core operations like retrieving runs, logs, and GraphQL queries, but lacks obvious lifecycle actions such as triggering new runs, pausing/resuming, or managing assets. This creates notable gaps for a full Dagster debugging workflow.

Maintenance

ActivityInactive
ResponsivenessNo issues