Build a CVE alert bot for X
exploited vulns, criticals, advisories
A 30-line script posts every new entry in CISA's Known Exploited Vulnerabilities catalog. The NVD API adds critical CVEs, and the RSS connector adds advisories with no code. No X developer account, no per-post billing.
Card required, cancel any time.
The short answer
Poll CISA's KEV catalog at https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json every 15 minutes, sort by dateAdded, and post each new cveID to POST https://opentweet.io/api/v1/posts. For critical CVEs, query the NVD API 2.0 with cvssV3Severity=CRITICAL. For advisories, add https://www.cisa.gov/cybersecurity-advisories/all.xml to the OpenTweet RSS connector.
Six post types for a security account
Raw CVE dumps are noise. Accounts that get followed filter hard and say in one line who needs to act.
Exploited now
Event-drivenA new KEV entry. The post your followers turn notifications on for, because someone is already using it.
Critical CVEs
Event-drivenCVSS 9.0 and up from the NVD API, filtered to the vendors your audience runs.
Ransomware flag
Event-drivenKEV marks entries known to be used in ransomware campaigns. Lead with that when it is set.
Advisories
Event-drivenCISA and ICS advisories from RSS, with one line on who is affected.
Patch Tuesday
ScheduledThe second Tuesday of the month, as one thread: the exploited ones first, then the criticals.
Weekly recap
ScheduledEvery KEV addition of the week in one thread, for people who check once a week.
The KEV watcher
Run it every 15 minutes with cron or a scheduled GitHub Action. The first run only records what is already in the catalog, so you do not post 1,754 old entries. After that, each new addition becomes one post, with no link, so it never counts as a link post.
Python
import json, pathlib, requests
OT_KEY = "ot_your_key"
KEV = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
POSTED = pathlib.Path("posted_kev.json")
seen = set(json.loads(POSTED.read_text())) if POSTED.exists() else None
vulns = requests.get(KEV, timeout=30).json()["vulnerabilities"]
vulns.sort(key=lambda v: v["dateAdded"]) # the file is not in date order
if seen is None: # first run: remember, don't post
seen = {v["cveID"] for v in vulns}
else:
for v in [v for v in vulns if v["cveID"] not in seen][:10]:
ransomware = " Used in ransomware." if v["knownRansomwareCampaignUse"] == "Known" else ""
text = (
f"Actively exploited: {v['cveID']}\n"
f"{v['vendorProject']} {v['product']}: {v['vulnerabilityName']}.{ransomware}\n"
f"Added to CISA KEV {v['dateAdded']}. Federal patch deadline {v['dueDate']}."
)
requests.post(
"https://opentweet.io/api/v1/posts",
headers={"Authorization": f"Bearer {OT_KEY}"},
json={"text": text[:280], "publish_now": True},
)
seen.add(v["cveID"])
POSTED.write_text(json.dumps(sorted(seen)))Critical CVEs from the NVD API
Get a free key from NVD to move from 5 to 50 requests per 30 seconds. Remember the CVE IDs you posted, the same way as the KEV script.
# Critical CVEs published in the last 24 hours
curl -s -H "apiKey: $NVD_API_KEY" \
"https://services.nvd.nist.gov/rest/json/cves/2.0?cvssV3Severity=CRITICAL&pubStartDate=2026-10-22T00:00:00.000&pubEndDate=2026-10-23T00:00:00.000"Every OpenTweet field is in the API reference.
Advisories without code: the RSS connector
CISA publishes every advisory, including ICS advisories, in one RSS feed. Add it as a connector, write the prompt once, and each advisory becomes a post. Vendor security blogs and release feeds work the same way.
Connectors -> New connector -> Blog or newsletter (RSS)
Feed URL: https://www.cisa.gov/cybersecurity-advisories/all.xml
Prompt: One sentence for sysadmins: the product, what an
attacker could do, and whether a fix exists.
Vendor name first. No emoji, no hype words.
Frequency: Every 15 minutes
X account: @yoursecfeedLet an AI agent write the one-liner
Vendor descriptions are long and vague. Connect Claude Code, Cursor or ChatGPT to the OpenTweet MCP server, give it the KEV or NVD record, and ask for one sentence a sysadmin can act on. Keep the IDs and dates from the record; let the model write only the words around them.
Which plan fits your account
Flat monthly price. The deciding numbers are posts a day and how many carry a link.
| Account type | Typical volume | Plan |
|---|---|---|
| KEV additions and criticals, no links | 5-15 posts a day | Pro, $19.99/mo, 20 posts a day |
| Each alert with its advisory link | Up to 10 link posts a day | Advanced, $29/mo, unlimited connectors |
| One account per vendor or sector | 50+ posts a day | Agency, $49/mo, 300 posts a day |
Link posts: Pro 1 a day, Advanced 10, Agency 20, plus link credits. See pricing.
Facts from the record. The CVE ID, product, dates and severity come from KEV or NVD, never from a model. A wrong CVE ID sends people to patch the wrong thing.
No exploit code. Describe the risk and the fix. Posting working payloads is a fast way to lose the account.
Label it. Turn on the Automated label in your X settings and do not auto-tag vendors. More in X automation rules.
Frequently asked questions
What is the best source for a CVE alert bot?
Start with CISA's Known Exploited Vulnerabilities (KEV) catalog. It lists only vulnerabilities with evidence of exploitation in the wild, so every entry matters to defenders, and it is a free JSON file at https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json (1,754 entries on October 21, 2026). Add critical CVEs from the NVD API for breadth, and CISA advisories from its RSS feed for context.
How do I get new KEV entries from the JSON feed?
Download the file, sort the vulnerabilities array by dateAdded, and keep the cveID values you have not posted before. Do not rely on file order: the list is not sorted by date. Each entry has cveID, vendorProject, product, vulnerabilityName, shortDescription, dateAdded, dueDate and knownRansomwareCampaignUse, which is enough for a complete post.
What are the NVD API rate limits?
The NVD CVE API 2.0 (https://services.nvd.nist.gov/rest/json/cves/2.0) allows 5 requests per 30 seconds without a key and 50 per 30 seconds with a free key, which is passed in the apiKey header. Filter with pubStartDate, pubEndDate and cvssV3Severity=CRITICAL. A bot that checks every 15 minutes needs a handful of calls a day.
How many critical CVEs are published a week?
Dozens. The NVD API returned 75 CVEs rated CVSS v3 critical with a publish date between October 15 and October 22, 2026. Posting each one is about 10 a day, which fits every plan; posting every CVE regardless of severity does not, and nobody wants to read it.
Do NVD or advisory links count as link posts?
Yes. Any URL, and any bare domain such as nvd.nist.gov, makes it a link post: $0.20 on the X API, and it counts toward your OpenTweet link allowance (1 a day on Pro, 10 on Advanced, 20 on Agency). The CVE ID itself is searchable, so most security accounts post the ID without a link and save links for the big ones.
Can an AI agent write the alerts?
Yes, from the record, not from memory. Pass the KEV or NVD entry to your model and ask for one plain sentence: what is affected, what an attacker gets, what to do. Keep the CVE ID, product and dates copied straight from the data. Or connect Claude, ChatGPT or Cursor to the OpenTweet MCP server and approve each draft before it posts.
Will X limit an automated security account?
Original posts on your own timeline are fine. Turn on the Automated label, post each CVE once, and do not auto-tag vendors or reply to their posts. Do not post exploit code or working proof-of-concept payloads; describe the risk and the fix.
Posting tools and releases instead of vulnerabilities? See the GitHub trending bot. Firing alerts from any other source? See the alert bot, or the AI news account for a curated feed.
Everything you can build on X with OpenTweet
Post to X from your code, a watcher, or an AI agent. Start anywhere in the cluster.
OpenTweet vs the X API
Post, schedule, and automate X without a developer account or the $200/mo minimum.
X DM outreach, human-approved
Find and qualify leads, AI-draft DMs, approve each one, and drip-send from your own account via API or MCP.
Post to X without an API
The clean, account-safe way to post to X from your code or an AI agent.
Twitter MCP Server
Give Claude, Cursor, and OpenClaw the ability to post to X. 44 tools included.
Developer docs
Quickstart, API keys, MCP setup, and the REST reference for posting to X from code or an agent.
Cross-posting reference
One call posts to X, Bluesky and LinkedIn. The platforms field, per-network results, and why a network gets skipped.
Social media API for AI agents
Three ways an agent can post to X, Bluesky and LinkedIn, and the trade-offs of each.
LinkedIn MCP server
Post and schedule to a LinkedIn profile from Claude or Cursor through the official LinkedIn API.
XMCP vs OpenTweet
X's official MCP server bills per API call and cannot schedule. Compare it with the flat-fee hosted MCP.
MCP for AI agents
Connect your AI client to X in under two minutes, no X developer account.
Developer API and keys
REST endpoints, one bearer key, and usage tracking. Build on OpenTweet.
OpenTweet for AI agents
The posting layer for autonomous agents and automations that live on X.
Build an AI Twitter persona
Give your AI agent its own X account. Setup, cadence, and the rules that keep it safe.
Best MCP servers for social media
The 2026 ranked list. How the hosted OpenTweet MCP compares with the official X MCP and others.
Cheapest way to post to X via code
Flat fee vs pay-per-use. Why the $0.20 per-link fee flips the math past ~145 link posts a month.
X API pricing 2026
Every pay-per-use X API endpoint price from docs.x.com in one searchable table.
Bluesky posting API
Post and schedule to Bluesky with one REST call and OAuth, and cross-post to X and LinkedIn in the same request.
Automate LinkedIn posts
Post to LinkedIn from an AI agent, n8n or a script through the official Posts API, with one REST or MCP call.
Ship your security feed on X today
Connect X, create a key, and the next KEV addition goes out within 15 minutes.