Skip to main content
Glama

dag-studio-mcp

CI License: Apache 2.0

Model Context Protocol (MCP) server for the DAG Studio causal-inference engine. It lets AI agents construct, analyze, and validate causal directed acyclic graphs (DAGs) using the same engine that powers the DAG Studio canvas.

Built and maintained by Black Swan Causal Labs. Listed in the RWE MCP Registry.

Tools

Tool

What it does

analyze_dag

Backdoor paths, minimal sufficient adjustment sets, identifiability

parse_dagitty

Parse dagitty DSL (raw or R-wrapped) into the structured DAG model

generate_code

R / Python analysis code for a DAG, plus a one-click DAG Studio URL

check_overadjustment

Detect adjustment for mediators, colliders, and descendants of exposure

simulate_data

Simulate data from a DAG under user-specified structural coefficients

compute_bias

Empirical bias of an adjustment strategy against the simulated truth

classify_effect_modification

Classify effect-modifier structure (direct, indirect, proxy, common-cause, pure interaction)

get_canonical_example

Canonical teaching DAGs (confounding, M-bias, frontdoor, and others)

validate_engine

Run the full canonical validation suite and report engine version

Every analytical response carries an engine_version stamp, a concordance attestation, a diagnostics block with severity-coded flags, and citations to the underlying methods literature.

Related MCP server: StatTools

Validation

The engine is validated four ways for coherence: against Pearl (2009) theory, against the reference implementation dagitty (Textor et al. 2016), against DAG Studio's own analytical results, and empirically via compute_bias on simulated data.

  • 35 canonical cases: T01 to T15 (structural identification) and EM01 to EM20 (effect modification), runnable live via validate_engine.

  • A release-gate concordance check runs the engine head-to-head against dagitty (vendored at upstream commit 7a65777) and stamps the attestation surfaced in tool responses.

  • 93 unit and integration tests across the engine bindings, the tool layer, and the auth gate.

Hosted endpoint

The server runs as a Cloudflare Worker (Streamable HTTP):

https://dagstudio-mcp.blackswancausallabs.com/mcp

Access is token-gated during the trial period. Request a token at jdiazdecaro@blackswancausallabs.com. Tokens are accepted either as a bearer header or as a ?token= query parameter (the query form exists for clients whose connector UI cannot set custom headers, such as the Claude.ai web connector).

Claude Code:

claude mcp add --transport http dag-studio \
  https://dagstudio-mcp.blackswancausallabs.com/mcp \
  --header "Authorization: Bearer <your token>"

Claude.ai web: add a custom connector pointed at https://dagstudio-mcp.blackswancausallabs.com/mcp?token=<your token>.

Repository layout

  • dag-engine.js / dag-engine.d.ts: the analytical engine, a pure ESM module with no runtime dependencies

  • src/tools/: one file per tool, each exporting { InputSchema, OutputSchema, descriptor, handler }

  • src/worker/: Cloudflare Worker transport and the token gate (auth.ts)

  • src/index.ts: stdio entry point for local use

  • ci/: release-gate concordance harness against vendored dagitty

  • tests/: unit and integration tests (npm test)

  • MCP_REQUIREMENTS.md: the v1 specification

  • FDA_GUIDANCE_ALIGNMENT.md: mapping of DAG Studio capabilities onto FDA draft RWE guidance protocol elements

The engine is developed alongside the DAG Studio canvas app and the vendored copy here is synced at release time. This repository is self-contained: clone it, npm install, and everything builds and tests without further setup.

Development

npm install
npm test                  # full suite
npm run dev               # stdio server via tsx
npm run worker:typecheck  # worker bundle typecheck
npm run worker:deploy     # deploy (stamps engine_version from git HEAD first)

For interactive inspection: npx @modelcontextprotocol/inspector.

Protocol status

Built on @modelcontextprotocol/sdk (TypeScript). Current against the finalized MCP specification revision 2025-11-25. Migration to the 2026-07-28 revision is planned once stable SDK support ships.

License

Apache License 2.0 (see LICENSE).

Exception: ci/dagitty-src/ contains the dagitty reference engine (GPL-2.0, Textor et al.), vendored at upstream commit 7a65777 solely as a release-time CI fixture for the concordance check. It retains its own license, is excluded from the published npm package, and is not part of the deployed worker bundle.

Available Tools

9 tools
analyze_dagAInspect

Returns identifiability status and minimal adjustment sets given the DAG provided. Specifically: open backdoor paths from exposure to outcome (Pearl 2009 Theorem 3.3.2), the minimal sufficient adjustment sets that block them, and all directed paths.

Accepts either a canonical DAG object or a dagitty_string. Returns a diagnostics block summarizing identifiability, unmeasured confounding, and any flagged issues, plus a static concordance attestation for the engine release.

DAG Studio verifies analyses given a DAG. It does not verify that the DAG correctly encodes domain knowledge or that the variables are measurable in any specific dataset. Outputs are conditional on the encoded structure.

When the DAG is meant to depict a paper's causal model, the encoded structure should reflect the paper's own structural assumptions, including those implicit in its analytical approach (what is adjusted for, what is treated as exposure or outcome, what is decomposed into mediators, what is acknowledged as unmeasured or latent confounding, and what is conditioned on as a collider), rather than an external theoretical framing imported from other literature. If the paper contains no explicit DAG, surface the construct-vs-reproduce ambiguity to the user before treating downstream analysis as a reproduction of the paper.

Inputs: edges, nodes, outcome, exposure, +1 more.

check_overadjustmentAInspect

Given a DAG and a proposed adjustment set, identify variables whose inclusion biases the estimate. Detects three failure modes: • descendant_of_exposure — variable is caused by the exposure; conditioning on it blocks part of the causal effect being estimated, changing the estimand (Schisterman 2009). • collider — variable is a collider on a non-causal X→Y path whose conditioning opens that path; conditioning is unjustified unless another set member re-blocks it. • descendant_of_collider — variable is downstream of an unconditioned collider; conditioning induces the same M-bias as conditioning on the collider directly (Greenland 2003).

Accepts either a canonical DAG object or a dagitty_string; both forms must be paired with adjustment_set.

Outputs are conditional on the encoded structure. DAG Studio verifies analyses given a DAG; it does not verify the DAG correctly encodes domain knowledge.

Inputs: adjustment_set (required), dag, dagitty_string.

classify_effect_modificationAInspect

For each modifier annotation on the DAG, classify the effect-modification structure per VanderWeele & Robins (2007) and Weinberg (2007). The five types and their regulatory implications: • direct — modifier is structurally independent of the E-D system; subgroup-specific effects are interpretable as pure modification. • indirect — modifier acts through a mediator; subgroup effects conflate modification with mediation. • common-cause — modifier shares an ancestor with the exposure; subgroup effects are confounded unless the ancestor is also adjusted. • proxy — modifier is unobserved; subgroup analyses rest on a downstream proxy. • pure-interaction — modifier has a direct edge to the outcome; the appropriate estimand is the joint effect, not a subgroup-specific effect (Weinberg 2007).

Outputs are conditional on the encoded structure.

Inputs: dag (required).

compute_biasAInspect

Numerically demonstrate the bias of a proposed adjustment set. Computes the true total effect analytically from the SEM edge coefficients (sum of products along all directed X→Y paths), then fits two OLS regressions on simulated data: crude (Y ~ X) and adjusted (Y ~ X + Z). Reports each estimate, each bias against the true effect, and the bias reduction |crude_bias| − |adjusted_bias|.

Translates a structural claim ("adjust for {age, smoking}") into a numerical demonstration. Composes check_overadjustment internally — any overadjustment flags emitted there are surfaced in this tool's diagnostics as well, so a single call captures both the numerical bias and the structural reason for it.

Outputs are conditional on the linear Gaussian SEM (see simulate_data for assumptions).

Inputs: dag (required), adjustment_set (required), n, seed, +1 more.

generate_codeAInspect

Emit idiomatic Python (networkx.DiGraph) or R (dagitty DSL) source representing the DAG. The identifier_map lets agents trace canvas labels to sanitized code identifiers when these differ (e.g., when labels contain spaces or special characters that aren't valid Python/R identifiers). Useful for handing the DAG to a downstream analysis pipeline. Also returns dagstudio_url — a one-click deep-link that opens the same DAG on the DAG Studio canvas at dagstudio.blackswancausallabs.com. Surface this URL to the user alongside the generated code so they can paste-free open the DAG visually, regardless of which language was requested.

If the DAG depicts a paper's causal model, whether the paper presents a DAG explicitly or only implies one through its analytical approach, the emitted code should reflect that paper's structural assumptions. Do not let the choice of downstream language (Python or R analysis pipeline) become an opportunity to substitute external theoretical commitments for what the paper actually claims as its estimand.

Inputs: dag (required), language (required).

get_canonical_exampleAInspect

Return one of the canonical validated DAGs from the engine's test suite by ID (T01–T15 for backdoor / adjustment-set canonical structures, EM01–EM20 for effect-modification structures from VanderWeele-Robins 2007 and Weinberg 2007). Useful for few-shot prompting, regression checks, and teaching. The returned DAG is the same one the engine is validated against, so analyze_dag's output on it will match the listed expected values.

Inputs: id (required).

parse_dagittyAInspect

Parse a dagitty DSL string into the canonical DAG shape used by other DAG Studio tools. Accepts dagitty('dag { ... }'), dagitty("..."), and dagitty::dagitty(...) forms. Bidirected (<->) and undirected (--) edges are skipped — DAG Studio represents only directed edges.

This tool parses notation; it does not validate that the encoded DAG is a correct or complete causal model. That is a domain-knowledge question outside the scope of any graph tool.

When the DAG depicts a paper's causal model, encode the structural assumptions of the study being protocolized, including those that are implicit in the analytical approach (what is adjusted for, what is treated as exposure or outcome, what is decomposed into mediators, what is acknowledged as unmeasured or latent confounding, and what is conditioned on as a collider), rather than only what is formally depicted. Most papers contain no explicit DAG; the structural commitments live in the methods and the choice of estimator. Surface the construct-vs-reproduce ambiguity to the user before constructing the DAG, and do not silently overlay normative or theoretical positions from outside literature onto the paper's stated estimand.

Inputs: dagitty_string (required).

simulate_dataAInspect

Generate synthetic data from a Linear Gaussian Structural Equation Model consistent with the DAG. Root variables are sampled N(0,1); each non-root is a linear combination of its parents (default β = 0.5 per edge, overridable via coefficients) plus N(0, 0.25) noise. Output is deterministic given seed (default 42).

Useful for sensitivity analysis and for demonstrating structural claims (e.g., 'adjustment for {age, smoking} eliminates the confounding shown by these data'). Outputs are consistent with the DAG under the linear Gaussian model only — real datasets generated under unknown processes will not in general match these distributions.

Inputs: dag (required), n, seed, format, +1 more.

validate_engineAInspect

Run the canonical validation suite (T01–T15 backdoor / adjustment-set cases, EM01–EM20 effect-modification structures from VanderWeele-Robins 2007 and Weinberg 2007) against the current engine and return pass/fail per case. Use this when an agent or reviewer wants to verify the engine is trustworthy before relying on analyze_dag, check_overadjustment, or classify_effect_modification.

Inputs: suite.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.3/5.0

    Scored across 9 tools

    Disambiguation5/5

    Each tool has a unique action (parse, analyze, check, get, validate, generate, classify, simulate, compute) targeting distinct aspects of DAG analysis. Even the adjustment-related tools are clearly separated: analyze_dag finds adjustment sets, check_overadjustment validates a proposed set, and compute_bias demonstrates numerical bias.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern using lowercase and underscores. The naming is predictable and uniform, with no mixing of conventions.

    Tool Count5/5

    With 9 tools, the server is well-scoped for its purpose, covering parsing, analysis, validation, simulation, and code generation without redundancy or bloat. Each tool earns its place in the workflow.

    Completeness5/5

    The tool set covers the full DAG analysis workflow: input parsing, identifiability and minimal adjustment sets, overadjustment detection, effect modification classification, data simulation, bias computation, code generation, and engine validation. No obvious gaps exist for the intended domain.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers