Endpoints: 28,729MCP servers: 18,413Payout addresses: 2,071Paid calls: 1,536Letters: 14Defects: 1,322counted 3 min ago
teppi

Server definition

Hash
sha256:9a69a4720e3461e1ee59693d3dbbb85d4fe4191a61b7489522acf1960919e949
What it is
What a remote MCP server returned when asked what it offers: 17 tools

The blob, as servednamed by its sha256

{ "instructions": "Whisper gives an AI agent a routable IPv6 address of its own on AS219419, with reverse DNS, a public RDAP record and a DANE certificate in DNSSEC-signed DNS, plus egress that sources from that address and a resolver whose policy you set. It also answers security questions about any domain, address, ASN or file hash from a graph of internet infrastructure. The tools whose names you can see without a key really work without one. For the rest, run whisper_signup with your email address: a key arrives with no account and no human in the loop, and then pass it as the X-API-Key header.", "tools": [ { "description": "Assess the risk/policy posture of one or more indicators. Answers without an API key. Example call: {\"skill\":\"assess\",\"input\":\"example.com\"}", "inputSchema": { "properties": { "input": { "description": "The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_assess", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "description": "Resolve an asset and its catalog of attributes. Answers without an API key. Example call: {\"skill\":\"asset\",\"input\":\"example.com\"}", "inputSchema": { "properties": { "input": { "description": "The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_asset", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "description": "Explain a verdict - the evidence and reasoning behind it. Answers without an API key. Example call: {\"skill\":\"explain\",\"input\":\"example.com\"}", "inputSchema": { "properties": { "input": { "description": "The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_explain", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "description": "Historical records for an indicator (incl. whois/bgp history). Answers without an API key. Example call: {\"skill\":\"history\",\"input\":\"example.com\"}", "inputSchema": { "properties": { "input": { "description": "The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_history", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "description": "Identify an indicator (domain, IP, hash, …) against the graph. Answers without an API key. Example call: {\"skill\":\"identify\",\"input\":\"example.com\"}", "inputSchema": { "properties": { "input": { "description": "The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_identify", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "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": { "properties": { "input": { "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.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_lookupTlsFingerprint", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "description": "Look up Tor relay metadata for an address. Answers without an API key. Example call: {\"skill\":\"lookupTorRelay\",\"input\":\"185.220.101.1\"}", "inputSchema": { "properties": { "input": { "description": "The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes 185.220.101.1.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_lookupTorRelay", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "description": "Trace the origins/provenance of an indicator. Answers without an API key. Example call: {\"skill\":\"origins\",\"input\":\"example.com\"}", "inputSchema": { "properties": { "input": { "description": "The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_origins", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "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": { "properties": { "input": { "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.", "type": "string" }, "sub": { "description": "Which sub-verb of this family to run. The example runs \"tldPlusOne\".", "type": "string" } }, "required": [ "sub", "input" ], "type": "object" }, "name": "whisper_psl", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "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": { "properties": { "input": { "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.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_rdap", "outputSchema": { "description": "The public registration record for one address, RFC 9083 shaped, byte-for-byte what the RDAP service serves at /ip/{address}.", "properties": { "country": { "description": "Two-letter country code of the registration.", "type": "string" }, "endAddress": { "description": "Last address of the range.", "type": "string" }, "entities": { "description": "The parties behind the registration, in RFC 9083 entity form.", "type": "array" }, "events": { "description": "Registration lifecycle events with their timestamps.", "type": "array" }, "handle": { "description": "The registry handle for this address.", "type": "string" }, "ipVersion": { "description": "\"v6\" or \"v4\".", "type": "string" }, "links": { "description": "Related RDAP and web resources.", "type": "array" }, "name": { "description": "The label its owner gave it.", "type": "string" }, "notices": { "description": "Service-level notices, including the terms of use.", "type": "array" }, "objectClassName": { "description": "Always \"ip network\" for this tool (RFC 9083).", "type": "string" }, "rdapConformance": { "description": "The RDAP extensions this answer conforms to.", "type": "array" }, "remarks": { "description": "Free-text notes the registry publishes with the object.", "type": "array" }, "startAddress": { "description": "First address of the range.", "type": "string" }, "status": { "description": "Registry status values for the object.", "type": "array" }, "type": { "description": "What kind of allocation this is.", "type": "string" } }, "required": [ "objectClassName", "handle" ], "type": "object" } }, { "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\":\"[email protected]\"}}", "inputSchema": { "properties": { "input": { "description": "Arguments for this operation, as an object. The example passes {\"email\":\"[email protected]\"}.", "type": "object" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_signup", "outputSchema": { "description": "The result of a signup step: an id to continue with, or the API key itself.", "properties": { "api_key": { "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.", "type": "string" }, "message": { "description": "What to do next, in a sentence.", "type": "string" }, "ok": { "description": "Whether the step succeeded.", "type": "boolean" }, "signup_id": { "description": "Returned by the first step. Send it back with the six-digit code from the email to finish.", "type": "string" } }, "required": [ "ok" ], "type": "object" } }, { "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": { "properties": { "input": { "description": "A row limit. The example passes 5.", "type": "integer" }, "sub": { "description": "Which sub-verb of this family to run. The example runs \"candidateCdnApex\".", "type": "string" } }, "required": [ "sub", "input" ], "type": "object" }, "name": "whisper_threatintel", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "description": "Top ASNs ranked by announced-prefix count. Answers without an API key. Example call: {\"skill\":\"topAsnsByPrefixCount\",\"input\":10}", "inputSchema": { "properties": { "input": { "description": "A row limit. The example passes 10.", "type": "integer" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_topAsnsByPrefixCount", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "description": "Enumerate variants/permutations of an indicator. Answers without an API key. Example call: {\"skill\":\"variants\",\"input\":\"example.com\"}", "inputSchema": { "properties": { "input": { "description": "The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_variants", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "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": { "properties": { "input": { "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.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_verify", "outputSchema": { "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": { "dane_ok": { "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.", "type": "boolean" }, "detail": { "description": "A sentence explaining a negative verdict. Absent on a positive one.", "type": "string" }, "evidence": { "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.", "type": "object" }, "fqdn": { "description": "The agent's canonical hostname, forward-confirmed against the address. Positive verdicts only.", "type": "string" }, "is_whisper_agent": { "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.", "type": "boolean" }, "jws_ok": { "description": "Whether a verifiable signed identity document can be produced for this agent.", "type": "boolean" }, "operator": { "description": "The opaque handle of the account that owns this agent.", "type": "string" }, "tenant": { "description": "The tenant handle, which also appears inside the fqdn.", "type": "string" }, "verified_at": { "description": "When this verdict was graded, ISO 8601.", "type": "string" } }, "required": [ "is_whisper_agent", "evidence" ], "type": "object" } }, { "description": "Walk the graph from an indicator across its relationships. Answers without an API key. Example call: {\"skill\":\"walk\",\"input\":\"example.com\"}", "inputSchema": { "properties": { "input": { "description": "The indicator to look up: a domain, an IP address, an ASN or a file hash. The example passes example.com.", "type": "string" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_walk", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } }, { "description": "Watch an indicator for change/activity over time. Answers without an API key. Example call: {\"skill\":\"watch\",\"input\":{\"action\":\"list\"}}", "inputSchema": { "properties": { "input": { "description": "Arguments for this operation, as an object. The example passes {\"action\":\"list\"}.", "type": "object" } }, "required": [ "input" ], "type": "object" }, "name": "whisper_watch", "outputSchema": { "description": "A tabular graph answer: the column names, the rows keyed by them, and the cost.", "properties": { "columns": { "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.", "items": { "type": "string" }, "type": "array" }, "rows": { "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.", "items": { "type": "object" }, "type": "array" }, "statistics": { "description": "What the query cost.", "properties": { "executionTimeMs": { "description": "Milliseconds the graph spent answering.", "type": "integer" }, "rowCount": { "description": "How many rows came back.", "type": "integer" } }, "required": [ "rowCount" ], "type": "object" } }, "required": [ "columns", "rows" ], "type": "object" } } ] }
Verify it yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:9a69a4720e3461e1ee59693d3dbbb85d4fe4191a61b7489522acf1960919e949 | sha256sum