@pipeworx/threatfox

Connect: https://gateway.pipeworx.io/threatfox/mcp · Install: one-click buttons

No MCP client? Skip the connection: POST https://gateway.pipeworx.io/v1/tools/search_packs {"query":"..."} to find a tool below, GET /v1/tools/<name> for its schema, POST the same URL with arguments for the data — see For AI agents.

Tools: 4

ThreatFox (abuse.ch) MCP — community IOC feed.

Tools

  • search_ioc(indicator, exact_match?)
  • recent_iocs(days?)
  • search_hash(hash) — see below, it asks TWO upstream queries
  • search_malware(malware, limit?)

search_hash asks both hash relations

ThreatFox stores hashes in two unrelated places and abuse.ch’s own query: "search_hash" only searches one of them:

relationwhat it meansupstream query
sample_to_c2the hash is a malware SAMPLE; rows are the C&C servers it talks tosearch_hash
hash_listed_as_iocthe hash is itself published as an indicator (threat_type: "payload")search_ioc

Asking only the first made this tool 34-for-34 empty over the 30d to 2026-09-16. It was never a broken endpoint — abuse.ch answers illegl_hash (their typo) for a malformed hash and no_result for a well-formed one, so our request was parsed and accepted throughout. It was the wrong question: da168c3ff95c749beec0a2f29a1e6b82, taken from this pack’s own recent_iocs, returns nothing from search_hash and a full row from search_ioc.

The tool now tries both and returns matched_relation saying which answered (null when neither did, alongside searched_relations). The second call only runs when the first found nothing, so a non-empty answer still costs one request. Do not collapse the two into one unlabelled list: “this file phones home to that C2” and “this file is itself flagged as a payload” are different security facts.

Empty is a real answer here. ThreatFox tracks C&C infrastructure, not samples — most hashes are in neither relation. Measured 2026-09-16: 7 of 40 recent MalwareBazaar sample hashes and 2 of 88 of ThreatFox’s own hash IOCs resolved. For sample metadata use the malwarebazaar pack (same vendor, same key), which indexes every sample.

Committed examples go stale by design. abuse.ch expires every IOC older than six months (“IOCs older than 6 months are no longer exposed on the ThreatFox API and ThreatFox Export”), which is why abuse.ch’s OWN documentation example hash 2151c4b970eff0071948dbbc19066aa4 returns no_result today — it points at IOC id 4726, from 2021. Re-verify the examples in workers/gateway/src/tool-examples.json when they age out; never commit a placeholder like d41d8cd98f00b204e9800998ecf8427e (the MD5 of the empty string), which is what taught every caller the wrong shape.

Auth

  • Platform key: gateway env PLATFORM_ABUSECH_KEY (shared with malwarebazaar).
  • BYO: ?_apiKey=<key> after registering at https://auth.abuse.ch.

Data source

https://threatfox-api.abuse.ch/api/v1/ — header Auth-Key, POST with JSON body.

Tools

  • search_ioc — Look up a specific indicator of compromise (IP, domain, URL, hash, etc.). Returns matching IOCs with malware family, confidence, threat-type, first/last seen, tags, references.
  • recent_iocs — IOCs added to ThreatFox in the last N days. Useful for daily threat-intel ingestion.
  • search_hash — Everything ThreatFox knows about one file hash (md5 / sha1 / sha256), across BOTH relations it stores hashes in —
  • search_malware — IOCs tagged to a malware family (e.g., “Cobalt Strike”, “Emotet”, “QakBot”).

Tools

  • recent_iocs — IOCs added to ThreatFox in the last N days. Useful for daily threat-intel ingestion.
  • search_hash — Everything ThreatFox knows about one file hash (md5 / sha1 / sha256), across BOTH relations it stores hashes in —
  • search_ioc — Look up a specific indicator of compromise (IP, domain, URL, hash, etc.). Returns matching IOCs with malware family, confidence, threat-type, first/last seen, tags, references.
  • search_malware — IOCs tagged to a malware family (e.g., Cobalt Strike , Emotet , QakBot ).

Regenerated from source · build September 24, 2026