GeoaCVE Guard

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

Add the MCP server
claude mcp add --transport http geoa-cve https://cve.geoa.io/mcp
Install the /geoa-cve slash command + skill
bash <(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

.cursor/mcp.json
{
  "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

~/.codex/config.toml
[mcp_servers.geoa-cve]
url = "https://cve.geoa.io/mcp"

Restart Codex; /mcp shows geoa-cve with its tools.

Any agent

Paste this prompt into your 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

  1. Add the server (once per machine, or per project with -s project):
    claude mcp add --transport http geoa-cve https://cve.geoa.io/mcp
  2. 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.

  3. Check it: claude mcp list shows geoa-cve: https://cve.geoa.io/mcp (HTTP) - ✓ Connected.

Example prompts

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:

Prompt
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
curl -s https://cve.geoa.io/api/vuln/CVE-2021-44228

Returns { 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
curl -s https://cve.geoa.io/api/feed?filter=kev&limit=20

Returns { 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
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/check

Returns { 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
curl -s -X POST -H 'content-type: application/json' -d '{"url":"https://example.com","proof":"your-token"}' https://cve.geoa.io/api/url

Returns { 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
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/fix

Returns { 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
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/watch

Returns { stackId, rssUrl, feedUrl, reportUrl, stackUrl, report, warnings }

GET /api/stacks/:id

A watched stack: files (hashes only), channels (redacted), last report, alerts.

curl
curl -s https://cve.geoa.io/api/stacks/stk_xxxxxxxxxxxx

Returns { id, label, createdAt, lastChecked, channels, files, packageCount, rssUrl, lastReport, alerts }

POST /api/report

Store a shareable proof report (signed id).

curl
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/report

Returns { 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
curl -s https://cve.geoa.io/r/rep_xxxxxxxxxxxx.signature.json

Returns { id, url, kind, title, createdAt, state, body }

GET /healthz

Liveness, counts per table, last ingest, mounted modules.

curl
curl -s https://cve.geoa.io/healthz

Returns { ok, version, mode, offline, counts:{vulns,kev,epss,advisories,affected}, lastIngest, modules }

07 RSS feeds

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.

A · file
<site>/.well-known/geoa-cve-guard.txt  →  text/plain, one line: geoa-cve-guard=<your token>
B · DNS
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

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

14 Honest notes