Run this on your config
The walkthrough below is an illustrative example. To get a real, config-scoped cross-server toxic-flow analysis for the servers you actually run together, paste a config (or a launch command) below — the form also takes a live URL or a GitHub/npm source, though the cross-server flow attaches only when the input resolves to a multi-server config. In that case we request the runtime-observed cross-server flow (observe_cross_server_flow) so the report can include the static reader→sink join, the multi-step attack-graph synthesis, and — in a sandbox — a genuinely observed flow. You land on /scan/:id, which shows the result as it completes.
Paste your MCP client config. Remote entries are connected to; stdio entries are resolved to their published package and scanned.
Both kinds of entry are scanned. A url entry is connected to over MCP; a command entry is resolved to the npm or PyPI package it names and the published artifact is scanned. Any entry that cannot be resolved is listed in the report with the reason. env values are never read.
Full registry scan — all 183 active rules
Every one of the 183 active rules is browsable and individually selectable above — nothing a full registry scan runs is hidden from this catalogue.
The composer and report below are a hand-authored design preview (the fixture is flagged illustrative: true) — a fixed three-server scenario, not a live scan. It shows what a real run looks like; the picks and the one “observed” edge are illustrative. Run the real thing above.
- github-mcp.get_issue (SOURCE) → filesystem-mcp.read_file (READER). Provenance: Observed, agent-mediated. DESIGN PREVIEW of what an "observed" edge renders like — NOT a record of a real execution of THIS flow. An observed edge is now reachable from a real producer: the Wave 3 executed-behavior producer (engine.ts `ExecutedBehavior`) emits `provenance: "observed"` for a tool it actually ran in the ADR-007 T3 sandbox, and contract.ts `fromSandboxExecutedBehavior` maps that to an observed edge — a single tool observed reading private data and egressing off-box in one invocation, measured from the host side of the jail. This particular source→reader chained leg is instead hand-authored to preview the observed state; the static-analyzer cross-server join emits only `inferred_binding`. Read this edge as a design preview, never as a claim that this specific data movement was witnessed by a live scan.
- filesystem-mcp.read_file (READER) → slack-mcp.post_message (SINK). Provenance: Inferred binding, agent-mediated. post_message targets a live third-party Slack endpoint. Under ADR-007 T1 we never invoke tools/call against a third party's live server, so this leg was WITHHELD. read_file's output is schema-compatible with post_message's `text` parameter and the agent has both tools in scope, so the binding is INFERRED from capability, not observed.
The toxic flow is a property of the configuration, not of any one server. These are the servers’ own intrinsic scores, exactly as the registry shows them in isolation — the config-level finding does not deduct from any of them.
Read the two units apart: a per-server score answers “is this server safe to install?”; the config verdict answers “is this combination safe to wire into one agent?” A clean server can still be one leg of a toxic flow.
Provenance summary: Illustrative: the source → reader leg is shown in the observed state as a design preview (hand-authored, not from a live scan — see the edge note). The sink leg is an inferred binding — withheld for safety, not confirmed. Final leg: Inferred binding.
Observed vs. inferred — what the labels mean
An observed edge is drawn solid (with a subtle flow animation). It means we executed the step and watched the data move: the artifact ran inside a measured, egress-denied sandbox (ADR-007 T3), the upstream tool’s output reached the downstream tool’s argument, and the call fired against our own copy in our own container.
It is evidence of a real flow, not a guess. Only executed steps earn this label.
An inferred binding edge is drawn dashed. The downstream tool is a live third-party sink, so we withheld it: ADR-007 T1 forbids tools/call against a stranger’s server. The binding is reasoned from schema compatibility and shared agent scope — it is not observed.
It marks a plausible, unconfirmed leg. We label it as inference precisely so a withheld step is never quietly presented as a proven one.
Two things we never do. A safety-withheld sink leg is never redrawn as “observed” to make a cleaner story. And registry-wide co-existence of capable servers is never drawn as an attack path — this view is config-scoped: it only reasons about servers that share one client configuration, never “these two servers both exist, therefore risk.”