Interactive Apps in Notebooks
Most RootCause MCP tools ship with an interactive app: the consoles that render inline when you use RootCause from Claude, ChatGPT, or Copilot. The SDK mounts those same apps under notebook cells. Nothing is re-implemented per widget; whatever the platform can render in a chat client, your notebook can render too, and every control round-trips live through the platform with your session's credentials.
Install
pip install "rootcause-sdk[jupyter]"The distribution is
rootcause-sdk, notrootcause. Only the import name isrootcause;pip install "rootcause[jupyter]"reaches an unrelated PyPI project.
That is the whole installation. There is no separate extension, no jupyter labextension install, no enable step. The widget front end ships inside the package and renders in JupyterLab, Notebook 7, VS Code notebooks, and Colab.
Results display as their app
The result objects mount their app on their own: display one — as the last expression of a cell, or through display() — and the interactive console appears instead of a static table.
>>> twin.graph # the causal-graph console
>>> result = twin.intervene({"Contract": rc.set("Two year")})
>>> result # the What-If Studio, over this run
>>> twin.explain(effect="Churn") # the explanation, as its own app
>>> sweep_run.sweep() # the dose-response curve
>>> twin.env("berlin") # the environment listingThree rules keep this honest:
Displaying never computes. The app mounts over the result you already have (
resultre-reads the stored run; nothing re-simulates). Assigning to a variable renders nothing, and scripts outside a notebook never enter this path.Displaying never raises. No
jupyterextra, an older platform, a fetch that fails — the object falls back to the same static HTML repr it always had.There is a kill switch.
rc.auto_apps(False)(orROOTCAUSE_AUTO_APPS=0) turns every display back into the static repr — the right setting for headless notebook executors and exported documents.
Every run result mounts by run id, so the platform decides which app fits the family that ran: SimulationResult, ForecastResult and PredictionResult all reach the same readback, and an intervention arrives as the What-If Studio with the dials and Run exact live on a scenario you ran minutes or months ago, while an explanation or a diagnosis arrives as its own view of that run. ScoreResult mounts the scoring register over the digest it already holds. Graph mounts the twin console, sweeps mount the curve explorer, and a panel twin's environment subsets mount the environment listing.
![A cell reading result = twin.intervene({"tenure": rc.set(60)}, outcomes=["TotalCharges", "MonthlyCharges"]) followed by result on its own line. Under it, the What-if studio renders the completed run: a tenure slider set to 60, KPI cards reading avg_TotalCharges 2.1k to 4.2k (+97.6 percent, statistically significant) and avg_MonthlyCharges no change, a bar chart against the dashed baseline, the narration Setting tenure to 60 moves avg_TotalCharges +2.1k, and the opening scenario pinned below.](https://docs.rootcause.ai/~gitbook/image?url=https%3A%2F%2F1662811113-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FBXg3gZLR0e2Q8SzeQmql%252Fuploads%252Fgit-blob-2cc25785863d5d97fa29e6ac4ace9f3356ee7771%252Fsdk-auto-display-studio.png%3Falt%3Dmedia&width=768&dpr=3&quality=100&sign=e6bbf481f5cf448abde1d8f682edf45f&sv=3)

The twin console
The causal-graph console appears under the cell: the DAG, edge strengths, intervention inputs, and a Run scenario button that executes against the platform and updates in place.

Every control in that screenshot is live. The sliders pin interventions, Run scenario executes the simulation server side through the MCP gateway with your credentials, and the result lands back in the widget without the cell re-running.
Try it yourself with the quickstart notebook, which ends on this exact console:
The causal-flow Sankey
twin.sankey draws how causal influence propagates through the graph — everything flowing into and out of one variable, or the paths running through one specific edge:

Exactly one of node and edge is required; depth bounds how many hops the traversal walks on either side.
The graph review console
twin.review runs the platform's structural review of the causal graph — cycles, isolated nodes, weak or wrong-direction edges, over-connected hubs — and mounts the findings as an interactive console:

The What-If Studio
twin.studio takes a question in plain English, runs the scenario server side, and mounts the studio over the answer — with the dials behind the result, so moving a control re-runs a tweaked scenario without leaving the notebook:

Structured pins are available when inference should not decide: targets= for exact outcome variables, horizon= for forecast steps, and environments= / aggregate= on panel twins.
All four verbs together, on a twin of your own:
Any tool's app
The typed verbs cover the twin consoles. For everything else, rootcause.jupyter.app runs any MCP tool and mounts whichever app that tool declares:
A tool with no app of its own renders through the generic widgets app, which draws whatever widgets the result carries as cards and falls back to plain text when it carries none. The tool executes server side when the cell runs; the app receives the result and takes over from there.
How it works
The app bundles are self-contained HTML documents that speak a small JSON-RPC protocol with their host. In a chat client, the host is Claude or ChatGPT. In a notebook, the SDK is the host: the bundle runs in a sandboxed iframe, and when it calls a tool (re-running a scenario, expanding a table), the SDK forwards the call to the platform's MCP gateway over HTTPS and returns the result to the iframe. Bundles are fetched from your platform deployment at render time, so they are always the version your server ships.
Last updated

