Open API · No key · CC-BY 4.0

Build on the list.

Every known-bad skill, MCP server and package, as signed open data.

Four URLs to read.

Try it in ten seconds.

List every known-bad target

curl -s https://threat.cafe/feed.json \
  | jq -r '.vulnerabilities[]
      | select(.database_specific.verdict == "known_bad")
      | .database_specific.target'

Verify the signature

curl -sO https://threat.cafe/feed.json -O https://threat.cafe/pubkey.pem
curl -s https://threat.cafe/feed.json.sig | jq -r .signature_b64 | base64 -d > feed.sig
openssl pkeyutl -verify -pubin -inkey pubkey.pem -rawin -in feed.json -sigfile feed.sig

Each record carries target, verdict, ioc, OWASP tags and the finder. Browser apps can fetch it from any origin.

Send us a finding.

From a scanner, a bot or a script. A person reviews every one.

Report without a key (Python, standard library)

import hashlib, json, urllib.request
API = "https://threat.cafe/api/intake.php"

# A short puzzle keeps bots out: find n where sha256("challenge:n") starts with `difficulty` zero bits.
ch = json.load(urllib.request.urlopen(API + "?challenge=1"))
n = 0
while int.from_bytes(hashlib.sha256(f"{ch['challenge']}:{n}".encode()).digest()[:4], "big") >> (32 - ch["difficulty"]):
    n += 1

report = {"action": "report", "artifact": "npm:[email protected]",
          "evidence_url": "https://example.com/write-up", "notes": "Reads ~/.ssh in postinstall",
          "credit": "Your name", "pow": {"challenge": ch["challenge"], "nonce": str(n)}}
req = urllib.request.Request(API, json.dumps(report).encode(), {"Content-Type": "application/json"})
print(json.load(urllib.request.urlopen(req)))

With a reporter key, no puzzle

curl -s https://threat.cafe/api/intake.php \
  -H 'Authorization: Bearer tcr_your_key' \
  -H 'Content-Type: application/json' \
  -d '{"action": "report", "artifact": "npm:[email protected]",
       "evidence_url": "https://example.com/write-up"}'

The answer

{"ok": true, "receipt_id": "tc_report_3f9a1c2b7d4e",
 "artifact": "npm:[email protected]", "remaining_today": 4,
 "next": "Sorted by code within 6 hours, read by AI once a day, ..."}
  • Any ecosystemnpm, pypi, mcp, clawhub, skillssh, gh, vscode, docker. Version * means all.
  • Fair limitsA half-second puzzle, then 5 an hour and 20 a day per address. A reporter key skips the puzzle and allows 500 a day.
  • People decideNothing is listed on a report alone. "action": "audit" asks us to check an unknown item; disputes use "action": "dispute".

Three rules.

  1. Never "safe".Show known bad, no known bad or unknown.
  2. Give credit.Name threat.cafe and the finder (CC-BY 4.0).
  3. Stay fresh.Refresh before the feed's expires time.

Need an SLA?

Webhooks, a private feed and support for platforms.