cveasy-mcp
Provides MCP clients like Claude with tools to query and manage security scans, CVEs, assets, findings, threat intel, and generate polished reports by acting as a lightweight adapter over the CVEasy backend API.
README
CVEasy AI — MCP Server
A Model Context Protocol server that exposes a live CVEasy AI install — scans, findings, CVEs, assets, threat intel, metrics — to MCP clients like Claude Desktop and Claude Code.
Its purpose is to refine report-making. Today CVEasy fills report narrative sections with the bundled local model using only aggregate numbers, which keeps prose thin and occasionally wrong. This server flips that: it lets a far more capable model (Claude) pull the real, structured data behind any report and draft or critique the prose grounded in actual figures — then render the final HTML/PDF through the same backend.
┌────────────────────┐ stdio (JSON-RPC) ┌──────────────────┐ HTTP :3001 ┌─────────────────────┐
│ Claude Desktop / │ ───────────────────▶ │ cveasy-mcp │ ─────────────▶ │ CVEasy AI backend │
│ Claude Code (LLM) │ ◀─────────────────── │ (this package) │ ◀───────────── │ (Hono, SQLite, AI) │
└────────────────────┘ tools/prompts/res └──────────────────┘ /api/* └─────────────────────┘
The server is a thin client over the CVEasy REST API — it never touches the database directly. That avoids lock contention with the running desktop app, reuses the backend's scoring/dedup logic, and survives schema changes.
Quick start
git clone https://github.com/CVEasy/cveasy-mcp && cd cveasy-mcp
bun install
bun run smoke # spins up the server and exercises it against your live backend
bun run smoke should print SMOKE TEST PASSED if the CVEasy AI app is running (backend on :3001).
Then wire it into a client (below) and ask: "Use CVEasy to draft an executive risk summary for Acme Corp."
Requires the CVEasy AI desktop app (or
bun run backend/src/index.ts) running so the backend answers on:3001. The server starts fine without it and every tool simply returns a clear "backend not reachable" error until it's up.
Configuration
All configuration is via environment variables; defaults match a stock local install.
| Variable | Default | Purpose |
|---|---|---|
CVEASY_BASE_URL |
http://127.0.0.1:3001 |
Backend base URL. |
CVEASY_TIMEOUT_MS |
120000 |
Per-request timeout (report/AI calls can be slow). |
CVEASY_REPORT_DIR |
$HOME/Downloads |
Where report_generate saves files by default. |
CVEASY_ALLOW_WRITES |
1 |
When 0, all mutating tools (triage, risk, enrich, scans) are hidden. |
CVEASY_ALLOW_SCANS |
1 |
When 0, only the BAS scan-launching tools are hidden. |
CVEASY_SESSION_TOKEN |
— | Operator session token, only needed if RBAC is enabled on the backend (sent as x-session-token). |
CVEASY_ACCESS_TOKEN |
— | Access token, only needed if the backend runs in production/deployment mode (sent as x-access-token). |
On a normal local CVEasy install RBAC is off (/api/auth/status → authEnabled:false), so no tokens are required even for writes.
Wiring into a client
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"cveasy": {
"command": "/Users/<you>/.bun/bin/bun",
"args": ["run", "/absolute/path/to/cveasy-mcp/src/index.ts"],
"env": { "CVEASY_BASE_URL": "http://127.0.0.1:3001" }
}
}
}
Use the absolute path to bun (which bun) — Claude Desktop doesn't inherit your shell PATH. Restart Claude Desktop; "cveasy" appears in the tools menu.
Claude Code
# from anywhere
claude mcp add cveasy -- /Users/<you>/.bun/bin/bun run /absolute/path/to/cveasy-mcp/src/index.ts
Or commit a project-scoped .mcp.json so the team shares it:
{
"mcpServers": {
"cveasy": {
"command": "bun",
"args": ["run", "cveasy-mcp/src/index.ts"],
"env": { "CVEASY_BASE_URL": "http://127.0.0.1:3001" }
}
}
}
Standalone binary (no bun on PATH)
bun run compile # → dist/cveasy-mcp (self-contained)
# then point the client's "command" at the absolute path of dist/cveasy-mcp with no args
The report-refinement workflow
This is the core use case. The pattern is always pull data → write/refine → (optionally) render.
- Pull the ground truth.
report_context { type: "executive" }returns one JSON bundle with metrics, top risks, priority bands, patch compliance, threat feed, and the org profile. Every sub-source is fetched independently; any that fail land inwarningsinstead of failing the whole call. - Draft or refine. Use a prompt — e.g.
refine_executive_summary— which instructs the model to ground every number in that context and follow house style. Or just ask in natural language. (report_template_guidereturns the recommended section skeleton per type.) - Render the deliverable.
report_render { type, kpis, sections }lays Claude's authored prose + tables into a polished, branded, print-ready HTML document using the built-in design system, and saves it. The user opens it and chooses Print → Save as PDF. This closes the loop entirely in the MCP layer — Claude controls the prose AND the layout, no backend involvement. - Critique loop.
critique_report { report_type: "executive", report_text: "…" }reviews an existing report against live data and lists factual errors, gaps, and rewrites.
Two ways to render
report_render (MCP-side) |
report_generate (backend) |
|
|---|---|---|
| Prose | Claude's authored sections | The local model's narrative |
| Templates | Built into this server (src/template/) — branded, print-tuned |
The app's own report templates |
| Output | Print-ready HTML (→ Save as PDF) | HTML, plus PDF for executive/findings/roadmap |
| Backend changes | None | None today; a narrative-injection endpoint would let report_generate use Claude's prose too (see Roadmap) |
Use report_render for the refined deliverable; use report_generate when you want the exact in-app report.
The template engine
src/template/ is a small, dependency-free, offline-safe design system:
design.ts— one shared stylesheet (system fonts, KPI cards, severity badges, callouts,@page/page-break print rules) + per-type accent presets.markdown.ts— injection-safe Markdown→HTML (escapes first;_is left literal sofinding_fp_hash/T1110_001survive).render.ts—renderReport(model)assembles the full HTML from aReportModel(header+logo, KPI band, sections with prose/bullets/tables/callouts, footer).
Improving a template here improves every rendered report. To port the same look into the in-app reports later, lift these into backend/src/services/report-builder.ts.
Tools (50)
Posture & metrics
| Tool | Purpose |
|---|---|
posture_health |
Backend reachability + AI/Ollama/BASzy status. Call first if things fail. |
posture_stats |
Global counts (CVEs, assets, scans). |
posture_metrics_summary |
Headline risk metrics + band distribution — best source of grounded numbers. |
posture_metrics_dashboard |
Full Command Center metric bundle. |
posture_burndown |
Remediation burndown / velocity over time. |
posture_compliance |
Control coverage for a named framework (pci-dss, hipaa, …). |
CVEs
| Tool | Purpose |
|---|---|
cve_search |
Search/browse + filter by severity, sort by TRIS/EPSS/CVSS/date. |
cve_get |
Full enriched detail for one CVE. |
cve_top_risk |
Highest-risk CVEs by TRIS. |
cve_top_exploitable |
Most likely to be exploited (EPSS + KEV/PoC/ransomware). |
cve_priority_board |
CVEs grouped into P0–P3 bands with SLAs. |
cve_recent |
Most recently published/ingested CVEs. |
cve_attack_chain |
Kill-chain steps + narrative for a CVE. |
cve_remediation |
Generate/fetch remediation guidance (write — caches result). |
Inventory & assets
| Tool | Purpose |
|---|---|
inventory_list |
Canonical assets with criticality/OS/risk. |
inventory_stats |
Asset counts by criticality / scan coverage. |
inventory_get |
One asset's detail + its CVEs. |
inventory_affected_by_cve |
Assets affected by a given CVE (blast radius). |
inventory_asset_stats |
Scanner-side asset statistics. |
Findings
| Tool | Purpose |
|---|---|
triage_list |
The triage work queue (filter by status/CVE). |
triage_stats |
Aggregate triage counts. |
bas_findings_search |
Search BAS findings (severity/module/MITRE/CVE/scan; carries validation verdicts). |
cve_validation_status |
Whether a CVE is BAS-confirmed exploitable in this environment. |
BAS scans (read)
| Tool | Purpose |
|---|---|
bas_scans_list |
List attack-simulation scans. |
bas_scan_get |
One scan's status/progress (poll after starting). |
bas_scan_findings |
Findings for a scan. |
bas_stats |
Aggregate BAS stats. |
bas_mitre_coverage |
MITRE ATT&CK coverage matrix. |
Threat intel
| Tool | Purpose |
|---|---|
threat_feed |
Board feed: top-exploitable, recent KEV, briefings, IoC stats, headlines. |
threat_briefings |
Curated briefings (filter by category/severity). |
threat_actors |
Known actors, sectors, CVEs, TTPs. |
threat_headlines |
Live security-news headlines (RSS). |
Reports
| Tool | Purpose |
|---|---|
report_types |
List the report types CVEasy can produce. |
org_profile |
Org name/industry + settings (compliance frameworks, AI provider). |
report_context |
Assemble the structured data feeding a report type — call before writing prose. |
report_render |
Lay author-supplied prose + tables into polished, print-ready HTML using the built-in templates. The refinement deliverable. |
report_template_guide |
The recommended section skeleton per report type (for report_render). |
report_generate |
Render the backend's own HTML/PDF report (local-model narrative) and save it. |
system_open_file |
Reveal a saved file in Finder. |
Mutating tools — gated by CVEASY_ALLOW_WRITES (scan tools also by CVEASY_ALLOW_SCANS)
| Tool | Purpose |
|---|---|
triage_create / triage_batch_add |
Add CVE(s) to the triage queue. |
triage_update / triage_delete |
Update state/owner/notes, or remove. |
risk_accept / risk_approve |
File / approve a risk acceptance. |
business_context_set |
Attach asset-criticality / data-classification / impact to a CVE. |
enrich_cve / enrich_batch |
Refresh EPSS/KEV/TRIS scoring. |
bas_scan_start |
Launch a BAS scan (target must be within an active authorization scope). |
bas_validate_cve |
Targeted scan to confirm a CVE's exploitability. |
Prompts (6)
Reusable, data-grounded report-writing workflows. Improving the prose rules here improves every report.
| Prompt | Args | What it does |
|---|---|---|
refine_executive_summary |
company_name?, focus? |
Tight 3-paragraph exec summary + recommended actions. |
draft_board_narrative |
tone? (board/security/engineering), company_name? |
Board-level Situation→Complication→Resolution narrative. |
write_remediation_roadmap |
horizon? |
Phased Now/Next/Later plan with owners, SLAs, expected risk reduction. |
attack_sim_writeup |
scan_id? |
Narrates BAS results + MITRE coverage, CONFIRMED_EXPLOITABLE first. |
patch_compliance_brief |
— | Compliance rate, worst SLA violations, top hosts, 3 actions. |
critique_report |
report_type, report_text? |
Adversarially reviews a report against live data. |
Each prompt tells the model to call the relevant data tool first and forbids invented figures.
Resources (5)
Read-only snapshots for clients with a resource/"attach context" UI: cveasy://reports/types, cveasy://metrics/summary, cveasy://posture/status, cveasy://org/profile, cveasy://threat/feed.
Safety & permissions
- Writes are on by default but can be disabled wholesale (
CVEASY_ALLOW_WRITES=0) for a read-only deployment. Mutating tools are annotateddestructiveHintwhere they change/delete state, so clients can prompt before running them. - Scans (
bas_scan_start,bas_validate_cve) actively probe systems and require the target to be inside an active BAS authorization scope on the backend (else403). They can be disabled separately (CVEASY_ALLOW_SCANS=0). - RBAC: when access control is enabled on the backend, mutating actions need an operator session token (
CVEASY_SESSION_TOKEN). - All logs go to stderr — stdout is reserved for the JSON-RPC stream.
Development
bun run typecheck # tsc --noEmit (strict, no unused)
bun run smoke # end-to-end stdio test against the live backend
bun run dev # hot-reload the server
bun run build # → dist/index.js
bun run compile # → dist/cveasy-mcp (standalone binary)
Layout: src/config.ts (env), src/client.ts (HTTP), src/util.ts (result helpers + tool registration), src/tools/* (domain tools — incl. render.ts), src/template/* (the design system + Markdown + renderer), src/prompts.ts, src/resources.ts, src/index.ts (wiring). Adding a tool = one registerTool(...) call in the relevant module.
Roadmap / nice-to-haves
- Port the
src/template/design system into the backend (report-builder.ts) so the in-app reports match the rendered ones, and optionally add a narrative-injection endpoint (POST /api/reports/generate { narrative }) soreport_generatecan use Claude's prose too. (The MCP-side loop is already closed byreport_render.) - Native one-click PDF in
report_render(currently print-to-PDF). Would need a PDF lib or headless renderer; print-ready HTML is intentionally dependency-free for now. report_render_from_context— a convenience that pullsreport_contextand pre-fills the KPI band/tables, leaving Claude to write only the prose.- More section primitives (charts via inline SVG, two-column layouts, appendix tables).
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。