{"name":"whisper","title":"Whisper: agent identity, egress and internet intelligence","description":"A routable IPv6 address of its own for an AI agent, on AS219419, with reverse DNS, a public RDAP record and a DANE certificate in DNSSEC-signed DNS; egress that sources from that address; a DNS resolver whose policy you set; and answers to security questions about any domain, address, ASN or file hash.","websiteUrl":"https://whisper.online","protocolVersion":"2025-06-18","serverInfo":{"name":"whisper","version":"0.219.2"},"capabilities":{"tools":{"listChanged":false}},"remotes":[{"type":"streamable-http","url":"https://whisper.online/mcp"}],"packages":[{"registryType":"npm","identifier":"@whisper-security/whisper-mcp","transport":{"type":"stdio"}}],"authentication":{"required":false,"schemes":[],"optional":{"in":"header","type":"apiKey","name":"X-API-Key","description":"Optional. Without it the tools listed here answer in full. With it, the provisioning and governance tools appear as well. Obtain one from an email address alone by calling whisper_signup; no account and no human step."}},"tools":[{"name":"whisper_signup","title":"Get a Whisper API key","description":"Start or complete Whisper signup from an email address alone, and receive an API key that unlocks the provisioning and governance skills on this card. Send {\"email\":\"...\"} to start; a six-digit code arrives by email; send {\"signup_id\":\"...\",\"code\":\"123456\"} to complete. No human step, no account needed first. Example call: {\"skill\":\"signup\",\"input\":{\"email\":\"agent@example.com\"}}","inputSchema":{"type":"object","properties":{"input":{"type":"object","description":"Arguments for this operation, as an object. The example passes {\"email\":\"agent@example.com\"}."}},"required":["input"]},"outputSchema":{"type":"object","description":"The result of a signup step: an id to continue with, or the API key itself.","properties":{"ok":{"type":"boolean","description":"Whether the step succeeded."},"signup_id":{"type":"string","description":"Returned by the first step. Send it back with the six-digit code from the email to finish."},"api_key":{"type":"string","description":"Returned by the second step. This is the credential; send it as the X-API-Key header and the provisioning and governance tools appear in tools/list."},"message":{"type":"string","description":"What to do next, in a sentence."}},"required":["ok"]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_verify","title":"Verify a Whisper agent identity","description":"Is this IPv6 address or hostname a real Whisper agent, and whose? Grades the full keyless trust chain: the reverse DNS record, the forward AAAA confirming it back to the same address, and the DANE-EE certificate pin published in DNSSEC-signed DNS. Returns is_whisper_agent with the evidence for the verdict either way, so a negative answer is an answer and not an error. Answers without an API key, and every leg of it is independently checkable from the DNS root with dig. Example call: {\"skill\":\"verify\",\"input\":\"2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478."}},"required":["input"]},"outputSchema":{"type":"object","description":"Whether an address or hostname is a Whisper agent, with the evidence for the verdict either way. Every leg is independently checkable from the DNS root with dig.","properties":{"is_whisper_agent":{"type":"boolean","description":"The verdict. False is an ANSWER, not a failure: the address or name is simply not a Whisper agent, and the evidence says which leg of the chain is missing."},"evidence":{"type":"object","description":"What was checked and what was found: the address or fqdn as given, the PTR, and the forward record that did or did not confirm it."},"detail":{"type":"string","description":"A sentence explaining a negative verdict. Absent on a positive one."},"fqdn":{"type":"string","description":"The agent's canonical hostname, forward-confirmed against the address. Positive verdicts only."},"operator":{"type":"string","description":"The opaque handle of the account that owns this agent."},"tenant":{"type":"string","description":"The tenant handle, which also appears inside the fqdn."},"dane_ok":{"type":"boolean","description":"Whether the certificate this address actually serves satisfies the DANE-EE pin published for it in DNSSEC-signed DNS. This is the leg that cannot be forged without the zone."},"jws_ok":{"type":"boolean","description":"Whether a verifiable signed identity document can be produced for this agent."},"verified_at":{"type":"string","description":"When this verdict was graded, ISO 8601."}},"required":["is_whisper_agent","evidence"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_rdap","title":"Look up an address in RDAP","description":"The public registration record for any address in Whisper's space, in RFC 9083 form: the handle, the agent's label, its country, and the entities behind it. The same document the RDAP service serves at /ip/{address}, which any RDAP client can already read. Answers without an API key. Example call: {\"skill\":\"rdap\",\"input\":\"2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478."}},"required":["input"]},"outputSchema":{"type":"object","description":"The public registration record for one address, RFC 9083 shaped, byte-for-byte what the RDAP service serves at /ip/{address}.","properties":{"objectClassName":{"type":"string","description":"Always \"ip network\" for this tool (RFC 9083)."},"handle":{"type":"string","description":"The registry handle for this address."},"name":{"type":"string","description":"The label its owner gave it."},"type":{"type":"string","description":"What kind of allocation this is."},"country":{"type":"string","description":"Two-letter country code of the registration."},"ipVersion":{"type":"string","description":"\"v6\" or \"v4\"."},"startAddress":{"type":"string","description":"First address of the range."},"endAddress":{"type":"string","description":"Last address of the range."},"status":{"type":"array","description":"Registry status values for the object."},"entities":{"type":"array","description":"The parties behind the registration, in RFC 9083 entity form."},"events":{"type":"array","description":"Registration lifecycle events with their timestamps."},"remarks":{"type":"array","description":"Free-text notes the registry publishes with the object."},"links":{"type":"array","description":"Related RDAP and web resources."},"notices":{"type":"array","description":"Service-level notices, including the terms of use."},"rdapConformance":{"type":"array","description":"The RDAP extensions this answer conforms to."}},"required":["objectClassName","handle"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_identify","title":"identify","description":"Identify an indicator (domain, IP, hash, …) against the graph. Answers without an API key. Example call: {\"skill\":\"identify\",\"input\":\"example.com\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_assess","title":"assess","description":"Assess the risk/policy posture of one or more indicators. Answers without an API key. Example call: {\"skill\":\"assess\",\"input\":\"example.com\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_walk","title":"walk","description":"Walk the graph from an indicator across its relationships. Answers without an API key. Example call: {\"skill\":\"walk\",\"input\":\"example.com\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_watch","title":"watch","description":"Watch an indicator for change/activity over time. Answers without an API key. Example call: {\"skill\":\"watch\",\"input\":{\"action\":\"list\"}}","inputSchema":{"type":"object","properties":{"input":{"type":"object","description":"Arguments for this operation, as an object. The example passes {\"action\":\"list\"}."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_explain","title":"explain","description":"Explain a verdict - the evidence and reasoning behind it. Answers without an API key. Example call: {\"skill\":\"explain\",\"input\":\"example.com\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_variants","title":"variants","description":"Enumerate variants/permutations of an indicator. Answers without an API key. Example call: {\"skill\":\"variants\",\"input\":\"example.com\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_origins","title":"origins","description":"Trace the origins/provenance of an indicator. Answers without an API key. Example call: {\"skill\":\"origins\",\"input\":\"example.com\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_history","title":"history","description":"Historical records for an indicator (incl. whois/bgp history). Answers without an API key. Example call: {\"skill\":\"history\",\"input\":\"example.com\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_lookupTlsFingerprint","title":"lookupTlsFingerprint","description":"Look up a TLS (JA3/JA4) fingerprint in the graph. Answers without an API key. Example call: {\"skill\":\"lookupTlsFingerprint\",\"input\":\"ja3:771,4865-4866-4867\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes ja3:771,4865-4866-4867."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_lookupTorRelay","title":"lookupTorRelay","description":"Look up Tor relay metadata for an address. Answers without an API key. Example call: {\"skill\":\"lookupTorRelay\",\"input\":\"185.220.101.1\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes 185.220.101.1."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_asset","title":"asset","description":"Resolve an asset and its catalog of attributes. Answers without an API key. Example call: {\"skill\":\"asset\",\"input\":\"example.com\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_threatintel","title":"threatintel","description":"Threat-intelligence indicator family (candidate apex/CDN/hosting). A family verb: name the sub-verb as \"sub\" alongside the input. Sub-verbs: candidateCdnApex, candidateMultiTenantApex, candidateSharedHostingIp.. Answers without an API key. Example call: {\"skill\":\"threatintel\",\"sub\":\"candidateCdnApex\",\"input\":5}","inputSchema":{"type":"object","properties":{"input":{"type":"integer","description":"A row limit. The example passes 5."},"sub":{"type":"string","description":"Which sub-verb of this family to run. The example runs \"candidateCdnApex\"."}},"required":["sub","input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_psl","title":"psl","description":"Public-suffix-list family (tld-plus-one, is-public-suffix, affiliation). A family verb: name the sub-verb as \"sub\" alongside the input. Sub-verbs: tldPlusOne, isPublicSuffix, affiliation.. Answers without an API key. Example call: {\"skill\":\"psl\",\"sub\":\"tldPlusOne\",\"input\":\"a.b.example.co.uk\"}","inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes a.b.example.co.uk."},"sub":{"type":"string","description":"Which sub-verb of this family to run. The example runs \"tldPlusOne\"."}},"required":["sub","input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}},{"name":"whisper_topAsnsByPrefixCount","title":"topAsnsByPrefixCount","description":"Top ASNs ranked by announced-prefix count. Answers without an API key. Example call: {\"skill\":\"topAsnsByPrefixCount\",\"input\":10}","inputSchema":{"type":"object","properties":{"input":{"type":"integer","description":"A row limit. The example passes 10."}},"required":["input"]},"outputSchema":{"type":"object","description":"A tabular graph answer: the column names, the rows keyed by them, and the cost.","properties":{"columns":{"type":"array","items":{"type":"string"},"description":"The column names, in order. Every row object has exactly these keys, so this is the row shape and reading it is cheaper than inspecting a row."},"rows":{"type":"array","items":{"type":"object"},"description":"The answers, one object per row, keyed by the column names above. An empty array means the question was understood and nothing matched, which is an answer and not a failure."},"statistics":{"type":"object","description":"What the query cost.","properties":{"rowCount":{"type":"integer","description":"How many rows came back."},"executionTimeMs":{"type":"integer","description":"Milliseconds the graph spent answering."}},"required":["rowCount"]}},"required":["columns","rows"]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}}]}