Build guide

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-driven

A new KEV entry. The post your followers turn notifications on for, because someone is already using it.

Critical CVEs

Event-driven

CVSS 9.0 and up from the NVD API, filtered to the vendors your audience runs.

Ransomware flag

Event-driven

KEV marks entries known to be used in ransomware campaigns. Lead with that when it is set.

Advisories

Event-driven

CISA and ICS advisories from RSS, with one line on who is affected.

Patch Tuesday

Scheduled

The second Tuesday of the month, as one thread: the exploited ones first, then the criticals.

Weekly recap

Scheduled

Every 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:  @yoursecfeed

Let 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 typeTypical volumePlan
KEV additions and criticals, no links5-15 posts a dayPro, $19.99/mo, 20 posts a day
Each alert with its advisory linkUp to 10 link posts a dayAdvanced, $29/mo, unlimited connectors
One account per vendor or sector50+ posts a dayAgency, $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.