Docs
Everything you can ask it, and how.
Geoa CVE Guard is one service with three doors: this site, a REST API, and an MCP server your coding agent can call. Same data, same ranking, same "why this matters to you".
01 Connect your agent
The MCP server lives at https://cve.geoa.io/mcp (Streamable HTTP, no login). It exposes exactly seven tools: get_vulnerability, list_feed, check_stack, check_url, explain_impact, propose_fix, watch_stack.
Claude Code
claude mcp add --transport http geoa-cve https://cve.geoa.io/mcpbash <(curl -s https://cve.geoa.io/plugin/install.sh)Then ask /geoa-cve CVE-2021-44228 or "check my package-lock.json with geoa-cve".
Cursor
{
"mcpServers": {
"geoa-cve": {
"url": "https://cve.geoa.io/mcp"
}
}
}Project-level file; use ~/.cursor/mcp.json for every project. Cursor lists the seven tools under MCP in settings.
Codex
[mcp_servers.geoa-cve]
url = "https://cve.geoa.io/mcp"Restart Codex; /mcp shows geoa-cve with its tools.
Any agent
Set up the Geoa CVE Guard MCP server for me: name geoa-cve, transport Streamable HTTP, URL https://cve.geoa.io/mcp, no login. Confirm it lists the tools get_vulnerability, list_feed, check_stack, check_url, explain_impact, propose_fix, watch_stack, then look up one recent CVE and summarize it.Works with any MCP-capable agent. Tools: get_vulnerability, list_feed, check_stack, check_url, explain_impact, propose_fix, watch_stack.
02 Claude Code
- Add the server (once per machine, or per project with -s project):
claude mcp add --transport http geoa-cve https://cve.geoa.io/mcp - Install the /geoa-cve slash command and the skill (copies geoa-cve.md to ~/.claude/commands/ and registers the MCP server if missing):
bash <(curl -s https://cve.geoa.io/plugin/install.sh)Prefer to read it first? /plugin/install.sh · the command · the skill.
- Check it: claude mcp list shows geoa-cve: https://cve.geoa.io/mcp (HTTP) - ✓ Connected.
Example prompts
- /geoa-cve CVE-2021-44228 · one vulnerability, explained.
- "Use geoa-cve to check this project's lockfiles and tell me what is actually mine. Include src/ for reachability."
- "What was added to CISA KEV this week that touches npm?" (list_feed with filter kev and ecosystem npm)
- "Explain the impact of CVE-2021-23337 given that lodash is a dev-only transitive dependency here." (explain_impact)
- "Propose the fix for the lodash finding, run the tests in the sandbox and show me the diff." (propose_fix, local mode, Docker)
- "Watch this stack and alert me on Telegram chat 123456." (watch_stack)
Advisory text reaches the agent inside [BEGIN UNTRUSTED …] blocks: it is data to summarise, never instructions to follow.
03 Cursor
Create .cursor/mcp.json in the project (or ~/.cursor/mcp.json globally) with the JSON shown under Connect, open Settings → MCP and enable geoa-cve. Then ask the agent in chat, e.g. "check_stack with my package-lock.json".
04 Codex
Add the [mcp_servers.geoa-cve] table to ~/.codex/config.toml (see Connect) and restart. /mcp inside Codex lists the server and its tools.
05 Any agent
Any MCP client that speaks Streamable HTTP works. If your agent can edit its own configuration, paste this:
Set up the Geoa CVE Guard MCP server for me: name geoa-cve, transport Streamable HTTP, URL https://cve.geoa.io/mcp, no login. Confirm it lists the tools get_vulnerability, list_feed, check_stack, check_url, explain_impact, propose_fix, watch_stack, then look up one recent CVE and summarize it.06 REST API
Plain JSON over HTTPS, no keys. Errors are { "error": "…" } with 400 (bad input), 404, 413 (too large), 415 (not JSON), 429 (rate limited, with retry-after).
GET /api/vuln/:id
One merged vulnerability by CVE, GHSA or any alias.
curl -s https://cve.geoa.io/api/vuln/CVE-2021-44228Returns { id, aliases, title, summary, details, published, modified, cvss:{score,vector,version}, severity, cwes, kev:{dateAdded,dueDate,ransomware}|null, epss:{score,percentile,date}|null, affected:[{ecosystem,package,ranges,versions,rangeText,firstPatched,functions}], references, sources, danger:{score,tier,reasons}, why }
GET /api/feed
Newest first. filter=all|critical|high|kev|likely|ecosystem:npm, limit, offset, since, q.
curl -s https://cve.geoa.io/api/feed?filter=kev&limit=20Returns { items:[{ id, title, summary, published, modified, cvss, severity, kev, epss, epssPct, danger, tier, why, ecosystems, packages }], total }
POST /api/check
Lockfiles (+ optional source files for reachability) → ranked findings with "why this matters to you".
curl -s -X POST -H 'content-type: application/json' -d '{"files":[{"name":"package-lock.json","content":"..."}],"source":[{"path":"src/app.mjs","content":"..."}],"label":"my-app"}' https://cve.geoa.io/api/checkReturns { id, createdAt, label, lockfiles:[{name,type,ecosystem,packages}], packageCount, findings:[{ vuln:{id,aliases,title,cvss,severity,kev,epss,danger,why}, package, ecosystem, version, fixed, direct, dev, reach:{level,evidence}, danger:{score,tier,reasons}, why }], counts:{exploited,likely,elevated,notable,low}, summary, warnings, reportUrl? }
POST /api/url
Fingerprint a site you own and map versions to vulnerabilities. proof is required in public mode.
curl -s -X POST -H 'content-type: application/json' -d '{"url":"https://example.com","proof":"your-token"}' https://cve.geoa.io/api/urlReturns { url, finalUrl, fetchedAt, ownership, fingerprints:[{kind,product,version,evidence}], findings:[…same shape as /api/check…], exposures:[{id,path,severity,title}], counts, summary, warnings, error? }
POST /api/fix
Propose an upgrade for one finding, run the project tests in a Docker sandbox on a copy, return a diff. Local mode only.
curl -s -X POST -H 'content-type: application/json' -d '{"projectDir":"/path/inside/GEOA_FIX_ROOTS","finding":{"package":"lodash","ecosystem":"npm","version":"4.17.20","fixed":"4.17.21","vulnId":"CVE-2021-23337"}}' https://cve.geoa.io/api/fixReturns { id, status:"ready"|"tests_failed"|"no_fix"|"error", plan:{package,from,to,command}, diff, tests:{ran,passed,exitCode,output}, sandbox:{image,seconds}, instructions, prBody }
POST /api/watch
Save a stack; re-checked on every ingest; one alert per real problem.
curl -s -X POST -H 'content-type: application/json' -d '{"label":"my-app","files":[{"name":"package-lock.json","content":"..."}],"channels":{"rss":true,"telegram":{"chatId":"123"},"webhook":{"url":"https://hooks.example.com/geoa","secret":"..."}}}' https://cve.geoa.io/api/watchReturns { stackId, rssUrl, feedUrl, reportUrl, stackUrl, report, warnings }
GET /api/stacks/:id
A watched stack: files (hashes only), channels (redacted), last report, alerts.
curl -s https://cve.geoa.io/api/stacks/stk_xxxxxxxxxxxxReturns { id, label, createdAt, lastChecked, channels, files, packageCount, rssUrl, lastReport, alerts }
POST /api/report
Store a shareable proof report (signed id).
curl -s -X POST -H 'content-type: application/json' -d '{"kind":"check","title":"Stack check: my-app","body":{"summary":"...","findings":[]}}' https://cve.geoa.io/api/reportReturns { id, url:"/r/<signed id>", absoluteUrl, kind, title, createdAt }
GET /r/:id · GET /r/:id.json
The proof report page (checked → patched → verified) and its JSON.
curl -s https://cve.geoa.io/r/rep_xxxxxxxxxxxx.signature.jsonReturns { id, url, kind, title, createdAt, state, body }
GET /healthz
Liveness, counts per table, last ingest, mounted modules.
curl -s https://cve.geoa.io/healthzReturns { ok, version, mode, offline, counts:{vulns,kev,epss,advisories,affected}, lastIngest, modules }
07 RSS feeds
- https://cve.geoa.io/feed · everything, newest first (RSS 2.0; add ?format=atom or ?format=json).
- https://cve.geoa.io/feed?filter=critical · CVSS 9+ only.
- https://cve.geoa.io/feed?filter=high · CVSS 7+.
- https://cve.geoa.io/feed?filter=kev · exploited in the wild (every CISA KEV addition).
- https://cve.geoa.io/feed/stack/<stack id>.xml · private alerts for one watched stack.
Every item carries the plain-language why and the tier as its category. Feeds are cacheable for 5 minutes.
08 Watch a stack
Save lockfiles once (Check your stack → Watch this stack, or POST /api/watch, or the watch_stack tool). Every ingest re-checks the stack. You get one alert per (vulnerability, package), a second one only if that finding later becomes exploited in the wild, and resolved findings are recorded. Channels: a private RSS feed (always), Telegram (channels.telegram.chatId; the bot token is server-side configuration), or a webhook (POST, JSON, X-Geoa-Signature: sha256=<HMAC of the body with your secret>). This instance has alerts muted: they are recorded and visible in the stack feed, but not delivered to Telegram or webhooks.
09 Ownership proof (check_url in public mode)
Scanning sites you do not own is not on offer. In public mode check_url and POST /api/url require a token that you publish on the site, then send with the request. Local mode makes it optional.
<site>/.well-known/geoa-cve-guard.txt → text/plain, one line: geoa-cve-guard=<your token>TXT record on the hostname: geoa-cve-guard=<your token>Outbound fetches go through an SSRF guard: http(s) only, ports 80, 443, DNS resolved and pinned, private/loopback/link-local/metadata addresses refused, every redirect re-checked, 2 MB and 10 s per response.
10 How danger is ranked
Exploitation evidence beats probability beats impact. Exploited in the wild: on CISA KEV. Likely to be exploited: EPSS ≥ 30 %. Elevated: EPSS ≥ 5 % or CVSS ≥ 9. Notable: CVSS ≥ 7. Low: the rest. For your stack the score then moves with context: direct dependency (+), transitive (−), dev-only (−), your code calls the vulnerable function (+) or imports the package (+), nothing imports it (−). The reasons are listed on every finding.
11 Data sources and licences
- CVE List (CVE Program, cvelistV5 on GitHub): CVE records are used under the CVE Program terms of use.
- GitHub Advisory Database: reviewed advisories, CC-BY 4.0.
- OSV (osv.dev): aggregated advisories, each under the licence of its source database.
- CISA KEV: Known Exploited Vulnerabilities catalog, public domain (US Government work).
- EPSS (FIRST): scores used under FIRST's EPSS usage terms; attribution: "EPSS scores by FIRST".
- NVD (NIST): CPE-based lookups for check_url; NVD data is public domain, "This product uses the NVD API but is not endorsed or certified by the NVD".
12 Privacy
Lockfiles are processed in memory and stored only when you ask for a report or a watch. A stored check keeps the computed report (package names, versions, findings), not the files. A watch keeps the lockfiles so they can be re-checked. Reports are reachable only through their signed link. No analytics, no external requests from the pages (fonts and scripts are served from this origin), no cookies. The server logs request paths and timings without bodies; tokens never appear in logs, URLs or responses.
13 Limits
- Request body: 5 MB; one lockfile: 4 MB; files per check: 40; source for reachability: 8 MB; packages per check: 20,000.
- Rate limits per client address: 120 requests per minute overall; 12 per minute for check_url, propose_fix, watch and report creation. Over the limit: 429 with retry-after.
- check_url: 20 requests and 25 s per check, 8 scripts, 2 MB per response.
- propose_fix: local mode only, project must be inside GEOA_FIX_ROOTS, Docker required, 600 s sandbox timeout.
14 Honest notes
- "No findings" means no known, published match for the exact versions in your lockfile. Unpublished issues, misconfigurations and vulnerable code you wrote yourself are out of scope.
- Reachability is static and textual (imports, requires, direct calls of the named functions) for JavaScript/TypeScript and Python. "Not imported" lowers the score; it does not prove safety.
- EPSS is a 30-day probability model, not a verdict. KEV is the only hard evidence here.
- Version ranges are only as good as the advisory: a GHSA range that was never corrected is reproduced as published.
- The catalog covers the last 14 days of CVE List changes plus everything referenced by KEV, GHSA and your checks; older CVEs are fetched on demand when online.
- This instance runs in public mode.