Pipedream
Wiring agent identity into a no-code workflow usually means a generic HTTP node, a hand-built JSON body, and a prayer that you got the escaping right.
One unescaped quote in an agent label and your Cypher call breaks; one leaked bearer in a step export and it's in your run history forever. Whisper's Pipedream app removes all of that: a real app with typed props, a Cypher-literal builder that can't be broken by user input, and a response decoder that turns the control-plane envelope into a plain array of records - 43 actions in total: 12 identity/control actions plus egress-IP lookup and raw Cypher, split into a keyless tier anyone can drag onto a canvas and a keyed control tier that provisions and governs your fleet, and 29 more that put the whisper.security graph itself on the canvas (see The graph actions below).
Two tiers, one app
The whisper app follows the same Postel's-Law shape as every Whisper integration (see the integration standard): the credential is what unlocks the second tier, not a separate product.
- Tier 1 - keyless. Reads Whisper's public, anonymous identity API at
rdap.whisper.online. No connected account. Same data anyone on the internet can query. - Tier 2 - control plane. Connect a Whisper account (one
whisper_live_…key) and the fleet-management actions unlock: register agents, allocate identities, read logs, set policy, wire up egress, revoke.
The app registers one optional auth field, api_key. Leave it blank and the five keyless actions still work; every keyed action checks for it up front and throws a ConfigurationError - a clear message, not a bare 401 three steps into a workflow - if it's missing.
The identity & control actions
| # | Action | Tier | Op / endpoint |
|---|---|---|---|
| 1 | Verify Agent Identity | keyless | GET /verify-identity?ip= |
| 2 | Lookup RDAP Record | keyless | GET /ip/<addr> |
| 3 | Get Transparency Log | keyless | GET /ip/<addr>/transparency |
| 4 | Get Inbound Lookups | keyless | GET /ip/<addr>/lookups |
| 5 | Get Egress IP | keyless | GET /egress-ip |
| 6 | Register Agent | control | op:register |
| 7 | Allocate Identity | control | op:identity |
| 8 | List Agents | control | op:list |
| 9 | Get Agent | control | op:agent |
| 10 | Set Policy | control | op:policy |
| 11 | Get Logs | control | op:logs |
| 12 | Connect Egress | control | op:connect |
| 13 | Revoke Agent | control | op:revoke |
| 14 | Run Cypher | control | raw whisper.agents-style graph query |
All eight identity-mutating actions carry the same admin:dns (write) or read scope that a matching whisper CLI subcommand carries, and every one is confined to the caller's own tenant - there is no cross-tenant argument to smuggle through args.
The graph actions (29 more)
The same app also ships one action per entry in the whisper.security graph catalog - the identical 14 direct procedures and 15 multi-step flows that back the n8n Graph resource and the MCP server's recipe tools, generated from the same catalog so the action list can't drift from what the graph actually offers. whisper-graph-assess, whisper-graph-identify, whisper-graph-variants, whisper-graph-typosquat, whisper-graph-subdomain-takeover, whisper-graph-bgp-hijack-exposure and 23 others each drop onto the canvas as one typed action with the recipe's own input fields - no raw Cypher required unless you reach for the general-purpose Run Cypher action above it. These 29 are keyed the same way as the control tier: attach the whisper account and they run against the graph directly.
Under the hood: one Cypher verb
Every control action is a thin wrapper over a single call: CALL whisper.agents({op:'<op>', args:{…}}), POSTed as {"query": "..."} to https://graph.whisper.online/api/query with the caller's key in X-API-Key - never in the body. This is the exact contract documented in the Graph API reference and implemented once, correctly, in the whisper CLI's reference client.
With stock tools - build and send the same call by hand with curl and jq:
curl -s https://graph.whisper.online/api/query \
-H "X-API-Key: whisper_live_…" \
-H 'content-type: application/json' \
-d '{"query":"CALL whisper.agents({op:'"'"'register'"'"', args:{label:'"'"'scout'"'"'}})"}' \
| jq '.rows[0].result'
Get the string-escaping wrong - an unescaped ' in a label like O'Brien's bot - and that quote closes the Cypher literal early and the query fails, or worse, is misparsed. Doing this safely by hand means writing your own doubled-quote escaper and a two-shape response decoder (the control endpoint can return either a procedure-row table or a flat {ok,status,result,error} envelope - see the reference for both shapes).
With Whisper - the app does the escaping and decoding for you; the action just takes typed props:
Register Agent
Name: scout
Contact Email: (optional)
→ $summary: "Registered agent scout at 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4"
→ returns: { agent, address, fqdn, ptr, state, api_key }
That api_key field is the new agent's own credential and is returned once - capture it in the same run (write it to a connected secrets step, not to a public output).
The app's Cypher builder mirrors the CLI's exactly: a string value is single-quoted with ' and \ each doubled (Tim O'Reilly → 'Tim O''Reilly'), map keys are emitted in sorted order so the wire query is byte-stable, and the response decoder accepts both envelope shapes plus a bare problem object - surfacing detail (or title, or type) verbatim on failure rather than an opaque 500. That's the Robustness Principle (RFC 761) applied to a no-code canvas: conservative in what the action emits on the wire, liberal in what it accepts back.
A worked example: gate a Slack alert on agent identity
Say a workflow ingests inbound webhook traffic and you want to flag anything not coming from a genuine Whisper agent before it reaches a downstream step.
With stock tools (a Pipedream Node code step, no Whisper software):
import { axios } from "@pipedream/platform";
export default defineComponent({
async run({ steps, $ }) {
const ip = steps.trigger.event.headers["x-forwarded-for"];
const r = await axios($, {
url: "https://rdap.whisper.online/verify-identity",
params: { ip },
headers: { Accept: "application/json" },
validateStatus: () => true,
});
if (!r.is_whisper_agent) throw new Error(`${ip} is not a verified Whisper agent`);
return r;
},
});
With Whisper - drop in the Verify Agent Identity action (no code, no auth needed), then branch on its is_whisper_agent export directly in the workflow's conditional path - one action, typed output, no hand-rolled HTTP client.
Connect Egress - the one action with secrets in it
op:connect is the odd one out: its result carries live transport secrets (an et_… bearer embedded in http_proxy/connection_string for the socks5/anyip tiers, or a client_private_key for a zero-key WireGuard setup). Because a hosted Pipedream step's output can end up in run history and downstream step data, the action follows the same bearer-hygiene rule as every other Whisper integration: don't wire the raw secret fields into a Slack message, a database row, or anything outside the same run's next HTTP step. If your workflow just needs a routed egress endpoint to hand to an HTTP-request node's proxy setting, that's exactly what this action is for - use it as a proxy config, not a value to persist.
Installing it
The app is contributed as source against PipedreamHQ/pipedream under components/whisper/, submitted as an open pull request (#21299) rather than merged into the main repo yet - the same self-serve model as the Whisper n8n, Make, and Power Platform connectors, just earlier in Pipedream's own review queue. Until it merges, the code is readable straight from the PR branch, with no vendor account required. Once it lands and goes live in the workspace picker, search "Whisper" when adding an app to a workflow; the keyless actions need nothing further, and the control and graph actions prompt you to connect an account with your whisper_live_… key.
The key-gated DNS resolver (/dns-query) is intentionally not wrapped here - it's a stateful per-tenant :53/DoH endpoint, not a request/response action. Point your own resolver config at it directly; see DoH.
Next
Graph API - the whisper.agents control verb · Integrations catalog