Workflow gallery
The shared gallery of investigation workflows behind the MCP server: discover with list_workflows, run with run_workflow, cite the evidence.
On this page (8)
Workflow gallery Documentation
The workflow gallery is a shared library of fifteen business-oriented investigation workflows. It's the same library that powers the use cases on this site and the investigations in the console. Over MCP, an agent finds a workflow with list_workflows and runs it with run_workflow. A single run_workflow call can cover a multi-step pivot — resolve DNS to an IP, the IP to its ASN, check threat intel — and every step comes back with the query that produced it.
This is the connector's headline feature. Instead of stitching together five query round-trips, an agent runs one named workflow and gets chained, evidence-backed results.
Each of the fifteen workflows is a deep build-out that runs the union of several narrower query patterns in one call — one input in (usually a domain, IP, ASN, or prefix), a full cross-layer answer out. Every one of them is also surfaced as a use case on this site; list_workflows is the authoritative, always-current index — the table below is a starting point, not a copy you should hand-maintain.
The gallery was curated down from a larger, more granular catalogue (2026-07): several narrow, single-purpose slugs — a coverage-only verdict check, a standalone WHOIS/BGP history diff, a bulk risk scorecard — were folded into indicator, which now runs as one unified deep-dive with no mode param: point it at a domain, IP, ASN, or prefix and it returns the verdict, the historical WHOIS/BGP context, and the surrounding infrastructure in a single call.
The gallery holds fifteen workflows and no recipes (measured 2026-10-11). The narrower copy-paste pivots live in Recipes and are not addressable through run_workflow.
New to the connector? Start with the Setup guide, then the Reference for the full 7-tool, read-only surface. The two gallery tools are
list_workflowsandrun_workflow.
How it works
- Discover.
list_workflowssearches the gallery and returns matching workflows, each with its summary and its full parameter space — every dial, with options, ranges, and defaults — so an agent can run any variant, not just the default. - Run.
run_workflowtakes one or more slugs (with optionalinput/params) and runs them in a single call. It returns the chained per-step record and, by default, a ready markdown report the agent can relay verbatim. - Cite. Every step in that record carries the exact Cypher that ran, its row count and its latency, and the report's
## Evidenceappendix maps each citation back to one of them. The agent can show its work.
The workflow slugs
Gallery workflows are addressed by slug — a stable, human-readable identifier you pass to run_workflow. A few of the most-used:
| Slug | What it answers |
|---|---|
typosquat | Registered typosquats and lookalikes of a domain (14 mutation algorithms), scored and enriched |
indicator | Full-depth investigation of a domain, IP, ASN, or prefix — verdict, historical WHOIS/BGP context, and everything connected to it, single-mode |
infrastructure-mapping | The owned estate behind one indicator — true owner, subdomains, networks, physical footprint, up to the vendor border |
supply-chain | What a domain depends on — every external provider by function, with dependency chains and single-vendor (SPOF) signals |
attack-surface | Everything a domain exposes to the outside world — DNS, mail, IPs, subdomains, CDN-origin candidates — scored for risk |
indicator-enrichment | One domain or IP as a full context card — registrant, hosting, mail, location, and a reputation read |
These six cover the most common one-shot investigations — a brand sweep, a full indicator deep-dive, owned-estate and dependency mapping, an exposure sweep, and single-indicator enrichment.
The other nine round out the catalogue: anycast-dns-root-sovereignty (how resilient a country's core DNS is if cut off from the world), bgp-hijack-exposure (grade a network's routing security and trace conflicts to affected domains), build-takedown-evidence-package (a ready-to-submit takedown dossier for a scam or phishing domain), email-security-posture (SPF, DKIM, DMARC, MX and DNSSEC graded on presence and hygiene), nameserver-hijack-dns-consistency (the name-server misconfigs that enable DNS hijack), route-health (BGP route health — prefixes, peers, MOAS conflicts, RPKI), subdomain-takeover (subdomains pointing at abandoned services an attacker could claim), threat-actor-attribution (from an indicator to a named actor, or from an actor to their techniques and infrastructure), and xray (everything a domain stands on in one read: verdict, web, nameserver and mail strands, networks, subdomains, physical layer and look-alikes).
Thirteen of the fifteen are also advertised as MCP prompts, so your client's prompt picker shows them as one-click investigations; the Reference documents the prompt surface. The two exceptions are attack-surface and indicator, which are not advertised as prompts yet. Both stay reachable through run_workflow by slug: indicator has a fixed step count and completes inside the run budget, so it behaves like any other workflow, while attack-surface cannot finish inside a single tool call on any input and is refused up front — notRun: true, with a reason and a howToNarrow hint — rather than started.
Flagship workflows
| Slug | What it answers | Example input |
|---|---|---|
typosquat | Registered lookalikes of a brand domain | paypal.com |
indicator-enrichment | Registrant, hosting, mail, location and reputation for one indicator, on one card | github.com |
infrastructure-mapping | The owned estate behind one indicator, up to the vendor border | www.cloudflare.com |
supply-chain | Every external provider a domain depends on, with SPOF signals | shopify.com |
build-takedown-evidence-package | A ready-to-submit takedown dossier for a scam or phishing domain | ickaoex.com |
route-health | A network's routing and reachability health card | AS3356 |
The gallery holds fifteen workflows in total — list_workflows is the authoritative, always-current index. Treat this table as a starting point, not the whole catalogue.
When a workflow returns nothing
A partial run is not a clean result, and the response says which it is. Read three fields before you believe an empty answer:
coverage.stepsWithDatabelowcoverage.stepsTotalis a coverage gap and therefore a finding. Report it as one.coverage.stepsSkippedmeans a step did not run — most often because its gate did not apply to your input type (a prefix-only step on an ASN), sometimes because a capability layer is not live on the deployment.incompleteSteps[]carries the reason for each, andreadyLayers[]in thewhisper://serverresource lists the live layers.truncations[]records everything the report's token budget dropped. An untruncated-looking report is not complete until this array is empty.
Two known gaps, so you can tell them apart from your own mistake:
route-healthreturnscomplete: falseon an ASN. Four of its steps are prefix-scoped (BGP status, MOAS conflicts, RIR allocation, prefix hierarchy) and only run when the input is a prefix, so on an ASN they are reported as skipped — a live run onAS3356on 2026-09-02 returnedsuccess: truein 1.6 s with five of the ten steps carrying data — andincompleteSteps[]andwarnings[]name each gap rather than passing it off as clean. Give it a prefix when the routing status of one block is the question.attack-surfaceis refused up front (success: true,notRun: true, plusreasonandhowToNarrow) because it cannot finish inside a tool call on any input. That is a successful, actionable refusal, not an error. Any other run that reaches its wall-clock budget comes back as a successful partial —success: true,partial: true, with guidance inwarnings[]— never a hang.
If one of these returns nothing, you did not do it wrong.
list_workflows — the contract
Search the gallery; get back each item's summary and its full parameter space. All four filters are optional: keyword, persona, task and layer. Called with no arguments it returns the entire catalogue, uncapped.
Returns
{
"workflows": [
{
"slug": "typosquat",
"kind": "workflow",
"title": "Typosquat & Brand-Impersonation Scanner",
"summary": "Find registered look-alikes of your brand and check which ones are dangerous.",
"personas": ["Brand protection", "Threat intelligence"],
"task": ["detect", "cluster", "enrich", "pivot"],
"layers": ["DNS", "threat-intel", "BGP", "GeoIP", "WHOIS", "historical"],
"inputs": [{ "name": "domain", "passAs": "input", "label": "Brand domain", "kind": "domain", "required": false }],
"params": [],
"stepCount": 10,
"docPath": "/docs/workflows/typosquat"
}
],
"count": 1
}
Two keys are optional and appear only where they apply: outputKind (what the run produces, for example "report" or "routing") and requiresCapability (a capability layer the workflow needs, for example ["ct-subdomains"] on attack-surface). The catalogue entry carries no prose description and no icon — the prose is one read_docs(docPath) call away, and the icon rides on the run_workflow result.
params[] is the dial list. Where a workflow has one, each entry is described in full (name, kind, label, description, default, and options[] for a select), so an agent can run a non-default variant without guessing the shape — attack-surface, infrastructure-mapping and supply-chain all take a level of quick / standard / deep / comprehensive / exhaustive, and anycast-dns-root-sovereignty takes an instanceType. An empty params: [], as on typosquat, means the workflow has no dials.
Note stepCount: it is the workflow's declared step count, and the coverage.stepsTotal you get back from run_workflow is what actually ran. When the two differ, the difference is the story.
Read
coveragebeforeband. Only known-clean — coverage: known-clean. In coverage, no malicious evidence. licenses the word "clean"; no-data — coverage: no-data. Not in coverage. This is not a verdict — nothing was looked at. means unknown, which is a different thing again; malicious-evidenced — coverage: malicious-evidenced. In coverage, with positive evidence of malice. and ambiguous — coverage: ambiguous. In coverage, and the evidence points both ways. mean there is evidence, whatever the band says. Full contract: Coverage — what we looked at.
run_workflow — the contract
Run one or more workflows by slug in a single call.
Input
{
"runs": [
{ "slug": "typosquat", "input": "paypal.com" },
{ "slug": "indicator-enrichment", "input": "paypal.com" }
]
}
runs[]— one or more{ slug, input?, params? }. Multiple runs execute in the same call. The entity goes ininput;paramscarries the settings.list_workflowssays which is which for every field it describes: each entry ininputs[]carries anameand apassAsof either"input"or"params". ReadpassAsand place the value accordingly — apassAs: "input"field sent insideparamsis not the same request, and the workflow will run against a default it was not given.profile—console/website/mcp/raw(defaultmcp), a top-level sibling ofoutput. The profile is what decides the result shape: on the defaultmcpprofile each step returns itscypher,rowCountandexecutionTimeMs, and the findings arrive as a ready, budgeted markdown report inresults[].markdown.steps[]never carries rows; to get them, run a step'scypherthroughquery.output— optional{ emit, slices }fine-tuning, applied on top of whichever profile resolves. Sending it at all replaces the profile's slice list and overrides itsemit— it does not merge — so omit it entirely (the default) to keep the profile's markdown.
Output
{
"results": [
{
"slug": "typosquat",
"input": "paypa1.com",
"paramValues": {},
"success": true,
"icon": "Tag",
"docPath": "/docs/workflows/typosquat",
"steps": [
{
"stepId": "registered",
"title": "Registered look-alikes",
"reason": "The candidate set every later arm is scoped to",
"status": "done",
"cypher": "CALL whisper.variants($domain) YIELD variant, method, exists, confidence\nWHERE exists AND variant <> $domain\nRETURN variant, method, confidence ORDER BY confidence DESC LIMIT 500",
"rowCount": 44,
"executionTimeMs": 136
},
{ "stepId": "curate", "title": "curate", "status": "done", "cypher": null, "rowCount": 0, "executionTimeMs": 2 }
],
"complete": true,
"coverage": { "stepsTotal": 11, "stepsWithData": 10, "stepsEmpty": 1, "stepsSkipped": 0, "stepsError": 0 },
"derived": {},
"totalLatencyMs": 2712,
"markdown": "## Findings\n\n- 7 third-party look-alike(s) are listed in a threat feed …\n\n## Evidence\n\n1. 44 registered look-alike(s) found for paypa1.com …",
"truncations": [
{ "layer": "profile", "kind": "rows", "target": "inactive", "dropped": 10, "of": 30 }
],
"profile": "mcp"
}
],
"slugsRun": ["typosquat"]
}
steps[] is the audit trail. There is no separate evidence array: each step ships the exact parameterised Cypher it ran, its rowCount and its executionTimeMs, which is what lets an agent cite the query behind a conclusion. The rows themselves do not come back on the default mcp profile — the findings arrive already written.
On that profile markdown is the piece to hand to the user: a verdict, findings, and a numbered ## Evidence appendix that each [n] citation in the findings resolves against. Relay it verbatim rather than re-summarizing it.
Anything the report's budget dropped is recorded in truncations[] ({layer, kind, target?, dropped, of, guidance?}) and non-fatal warnings land in profileWarnings[] — never silently. complete and the coverage counters flag any step that was skipped or returned nothing; a coverage gap is a finding, not a clean result (no-data != benign), and incompleteSteps[] carries the reason per step when one fires. coverage is computed over the workflow's declared step list, so a step that never reported back shows as skipped rather than disappearing.
paramValues records exactly which dials actually ran — an out-of-range param is clamped or filtered, never rejected, and the effective value is echoed back here. inputSource appears when the entity arrived inside params under the input's own name (it is still used), and ignoredParams lists any key that matched no declared param. derived carries rolled-up signals where a workflow projects them and is {} where it does not.
The result carries no static documentation links: the schema, Cypher and API references are reached through read_docs, and docPath on the result points at the workflow's own page.
Worked example: a typosquat sweep, end to end
A user asks: "Is anyone squatting on paypal.com, and is any of it dangerous?"
1 — discover the workflow.
list_workflows({ keyword: "typosquat brand protection" })
→ { workflows: [{ slug: "typosquat", kind: "workflow", inputs: [{name:"domain", passAs:"input"}], params: [], stepCount: 10, docPath: "/docs/workflows/typosquat" }], count: 1 }
2 — run it.
run_workflow({ runs: [{ slug: "typosquat", input: "paypal.com" }] })
3 — relay the report. On the default mcp profile the answer arrives ready-made: results[].markdown is a budgeted report — verdict, findings, and a numbered ## Evidence appendix — that the agent relays verbatim, not re-summarized.
A live run on 2026-09-20 against paypa1.com returned 44 registered look-alikes, each tagged with the generation method that found it (homoglyph, bitsquatting, TLD-swap, hyphenation, …), of which 7 are listed in a threat feed. It took 2.7 s across 11 steps, reported complete: true, and coverage came back stepsWithData: 10, stepsEmpty: 1.
Read exists carefully: it means registered or observed, not malicious. Look-alikes existing at all is normal for a brand of any size; the feed-listed ones and the operator clusters are the finding.
Behind the report, every [n] citation maps back to the step that produced it, and each step carries the query it ran:
| Step | Cypher (abridged) | Rows | Latency |
|---|---|---|---|
registered | CALL whisper.variants($domain) YIELD variant, method, exists, confidence … | 44 | 136 ms |
whois | the registrant pivot over the registered set | 200 | 1,077 ms |
4 — pivot, still in one call. To go further, chain a second workflow in the same run_workflow:
run_workflow({ runs: [
{ slug: "typosquat", input: "paypal.com" },
{ slug: "build-takedown-evidence-package", input: "paypa1.com" }
]})
That returns the lookalikes and a ready-to-send takedown dossier on the worst offender — two investigations, one round-trip, each with its own steps[] trail and its own report.
Live numbers will differ. WhisperGraph reflects the current state of the internet, not a fixed snapshot — counts, verdicts, and registrants change as feeds and routing refresh. The figures above are what one dated run returned, not a guarantee about the next one.
Next steps
- Your first investigation — one alert worked end to end, with the pivot and the falsification step.
- MCP Reference — the full 7-tool, read-only surface and the per-step evidence model.
- Setup guide — connect a client and run your first investigation.
- Use cases — the same fifteen workflows, as guided flows you can run in the browser.
- Recipes — the narrower pivots the gallery does not carry, as copy-paste Cypher.