Skip to main content
Glama
tenable-vpr-mcp

tenable-vpr-mcp

by Sabastiaz

Tenable VPR MCP

MCP server for Tenable.io / Tenable One (Vulnerability Management API), built for pentest and exposure-management reporting workflows.

Alongside read-only coverage of the usual objects (scans, assets, findings, plugins, tags, agents), it adds three tools aimed at the reporting step of an engagement rather than at raw API access:

compare_vpr_reprioritization

Tenable reports two ratings for the same finding:

  • CVSS-based severity (severity): the static, plugin-assigned bucket

  • VPR (vpr.score): threat-intel and exploitability-weighted score

When you re-scope a client's exposure using VPR instead of raw CVSS, some findings get escalated (low CVSS, actively exploited) and some get downgraded (high CVSS, no real-world exploitation activity). That before/after delta is exactly what you need to show in a CTEM / Tenable One POC deliverable, and building it by hand from raw exports is tedious.

compare_vpr_reprioritization pulls live findings from the vulnerability workbench and returns a sorted table (escalations first) plus a summary rollup, ready to drop into a report or slide.

{
  "summary": {"escalated": 4, "downgraded": 11, "unchanged": 52, "unrated": 2, "total_findings": 69},
  "findings": [
    {
      "plugin_id": 12345,
      "plugin_name": "Example Actively-Exploited RCE",
      "cvss_severity": "medium",
      "vpr_score": 9.4,
      "vpr_severity": "critical",
      "rerating": "escalated",
      "affected_assets": 5
    }
  ]
}

Related MCP server: cve-mcp

check_kev_epss_exposure

VPR is a Tenable proprietary score. This tool backs a re-prioritization argument with two independent, public data sources instead: the CISA KEV catalog (confirmed real-world exploitation) and FIRST.org EPSS (30-day exploitation probability). Each finding gets a signal: confirmed_exploited > high_probability > low_signal > no_cve_data, sorted most urgent first, plus a ransomware-association flag from KEV.

Note: this does one extra Tenable API call per distinct plugin (to resolve CVEs via workbenches.vuln_info), so keep limit modest for interactive use.

scan_delta

Compares a baseline scan against a re-test scan by plugin ID and buckets findings into fixed, still_open, and new_since_baseline, with a remediation-rate percentage. Built for the re-test report every pentest engagement ends with.

All tools

Tool

Description

list_scans

List scans, optionally by folder

get_scan_details

Latest results for one scan (hosts, findings, severity counts)

list_assets

List known assets (capped)

get_asset_details

Full detail for one asset by UUID

search_vulnerabilities

Workbench findings, filterable by severity / plugin family

get_plugin_details

Plugin description, solution, CVEs, VPR drivers

list_tags

Asset tag categories and values

list_agents

Nessus Agent inventory and status

compare_vpr_reprioritization

CVSS vs. VPR before/after comparison table

check_kev_epss_exposure

CVSS/VPR findings cross-referenced against CISA KEV + EPSS

scan_delta

Baseline vs. re-test comparison for remediation validation

This server is read-only by design: no scan launch, edit, or delete tools are exposed, so it's safe to point at a production tenant.

Filter arguments

search_vulnerabilities, compare_vpr_reprioritization, and check_kev_epss_exposure share two optional filters:

  • severity — a list of info / low / medium / high / critical. Case-insensitive; the server capitalizes them to the form the workbench API requires.

  • plugin_family — a list of family names (["Windows", "Web Servers"]) or numeric family IDs. Names are resolved to IDs on first use, since the workbench only filters on plugin.family_id. An unknown name raises before any API call is made.

Output

Every tool returns the same envelope, so credential, authentication, and API errors reach the client as readable text instead of a crash:

{"ok": true,  "data": ...}
{"ok": false, "error": "UnexpectedValueError: ..."}

compare_vpr_reprioritization and check_kev_epss_exposure return a summary rollup plus a findings list sorted most-urgent-first, in the shape shown in the compare_vpr_reprioritization example above. scan_delta returns fixed / still_open / new_since_baseline lists plus a summary with counts and remediation_rate_pct. The remaining tools return the Tenable API payload as-is under data.

Prerequisites

  • Python 3.10 or newer

  • A Tenable.io / Tenable One account that can generate API keys

Setup

See USAGE.md for full setup, client configuration, and example prompts. Quick version:

git clone https://github.com/Sabastiaz/tenable-vpr-mcp
cd tenable-vpr-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e .

export TIO_ACCESS_KEY=your_access_key
export TIO_SECRET_KEY=your_secret_key
# optional, defaults to https://cloud.tenable.com
export TIO_URL=https://cloud.tenable.com

tenable-vpr-mcp

Generate API keys in Tenable.io / Tenable One under Settings > My Account > API Keys. Never pass keys as CLI arguments; use environment variables only.

Claude Code

claude mcp add tenable-vpr -- tenable-vpr-mcp

(with TIO_ACCESS_KEY / TIO_SECRET_KEY set in your shell environment before running the command above).

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "tenable-vpr": {
      "command": "tenable-vpr-mcp",
      "env": {
        "TIO_ACCESS_KEY": "your_access_key",
        "TIO_SECRET_KEY": "your_secret_key"
      }
    }
  }
}

Limitations

  • The vulnerability workbench caps every query at 5,000 findings. This is a Tenable API limit, not a limit of this server — raising limit past 5,000 returns no more records. On a large tenant, filter by severity or plugin_family to keep each query under the cap, or the results are silently truncated. (pyTenable also marks the workbench module deprecated in favour of the exports API; moving to exports is the fix for full-tenant extraction and is not implemented yet.)

  • check_kev_epss_exposure issues one extra Tenable API call per distinct plugin to resolve CVEs via workbenches.vuln_info. Keep limit modest (20–30) for interactive use. Plugin CVE lookups are not cached between calls; the CISA KEV catalog is cached in-process for six hours.

  • Findings are aggregated per plugin, not per host. affected_assets is a host count; use get_scan_details or scan_delta when you need scan-scoped, per-host detail.

  • search_vulnerabilities and compare_vpr_reprioritization read tenant-wide state, not the results of one scan.

  • A VPR score of None is reported as unrated, not as low risk. Tenable does not score every plugin — end-of-life and configuration findings frequently have no VPR at all, so they need to be reviewed separately rather than sorted to the bottom.

  • No write operations (scan launch/configure, tag assignment, asset deletion) are implemented, by design.

Development

pip install -e ".[dev]"
pytest tests/ -v

(Quote the extras — unquoted .[dev] is a glob pattern in zsh.)

The suite runs with no live Tenable / CISA / FIRST.org calls:

File

Covers

tests/test_findings.py

Normalizing the workbench's flat records and integer severities

tests/test_vpr.py

CVSS vs. VPR comparison and bucket boundaries

tests/test_kev.py

KEV/EPSS signal classification and CVE extraction

tests/test_scan_diff.py

Baseline vs. re-test bucketing

tests/test_server_filters.py

Severity capitalization and family-name resolution

tests/fixtures.py

Payloads captured verbatim from a live tenant

Keep tests/fixtures.py faithful to what the API actually returns. The workbench sends plugin_id / plugin_name / vpr_score at the top level and severity as an integer 0–4, not the nested, label-severity shape most Tenable API examples use — fixtures written in the nested shape pass while every live call fails.

demo.py exercises all 11 tools through their real code path with the Tenable client and KEV/EPSS lookups faked, so it needs no credentials:

python demo.py

License

MIT

Available Tools

11 tools
check_kev_epss_exposureA

Cross-reference live findings against two independent, publicly sourced exploitation signals (not Tenable's proprietary VPR):

  • CISA KEV: CVEs with confirmed real-world exploitation

  • FIRST.org EPSS: probability of exploitation in the next 30 days

Useful alongside compare_vpr_reprioritization to back a re-prioritization argument with vendor-independent evidence. Each finding gets a signal: confirmed_exploited > high_probability > low_signal > no_cve_data, sorted most urgent first.

limit bounds how many distinct plugins get a CVE lookup (one extra Tenable API call per plugin), so keep it modest for interactive use. Filter the underlying findings by CVSS severity and/or plugin_family first, same as search_vulnerabilities.

Inputs: limit, severity, plugin_family, epss_high_confidence_threshold. Returns: object

compare_vpr_reprioritizationA

Build a before/after re-prioritization table for live findings: CVSS-based severity vs. VPR-based severity, per plugin, with a 'rerating' flag (escalated / downgraded / unchanged / unrated) and affected asset count. Designed for POC/assessment deliverables that need to show clients how VPR re-ranks their existing scan data (e.g. a Tenable One CTEM engagement). Escalated findings are sorted first since they represent the highest-priority remediation gap a CVSS-only view would have missed.

Optionally filter the underlying findings by CVSS severity and/or plugin_family before comparison, same as search_vulnerabilities.

Inputs: limit, severity, plugin_family. Returns: object

get_asset_detailsA

Get full detail for a single asset by UUID: network interfaces, installed software, tags, and exposure scores (ACR/AES) if licensed.

Inputs: asset_uuid (required). Returns: object

get_plugin_detailsA

Get full plugin detail: description, solution, CVSS vectors, CVEs, and VPR drivers for a given Tenable plugin ID.

Inputs: plugin_id (required). Returns: object

get_scan_detailsA

Get the latest results for a single scan by ID: hosts scanned, per-plugin findings, and vulnerability counts by severity.

Inputs: scan_id (required). Returns: object

list_agentsA

List Nessus Agents linked to the tenant with status, platform, and last connect / last scanned timestamps. Capped at limit records.

Inputs: limit. Returns: object

list_assetsA

List assets known to Tenable.io / Tenable One (hostname, IPs, UUID, last seen, sources). Capped at limit records to keep responses small.

Inputs: limit. Returns: object

list_scansA

List scans visible to the authenticated API key, optionally filtered by folder ID. Returns id, name, status, and last run time per scan.

Inputs: folder_id. Returns: object

list_tagsA

List all asset tag categories and values configured in the tenant.

Inputs: no named parameters. Returns: object

scan_deltaA

Compare a baseline scan against a re-test scan by plugin ID and return three buckets: fixed (present in baseline, gone in re-test), still_open (present in both), and new_since_baseline. Includes a remediation-rate percentage. Built for pentest/assessment re-test reporting where a client needs proof of what got remediated between engagement rounds.

Inputs: retest_scan_id (required), baseline_scan_id (required). Returns: object

search_vulnerabilitiesA

Search current findings across the tenant via the vulnerability workbench. Filter by CVSS severity (any of "info", "low", "medium", "high", "critical" — case-insensitive) and/or plugin family (e.g. ["Windows", "Web Servers"]). Returns per-plugin aggregate records including CVSS severity, VPR score, and affected asset count. Capped at limit records.

Inputs: limit, severity, plugin_family. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 11 tools

    Disambiguation5/5

    Each tool targets a clearly distinct resource or action: assets, vulnerabilities, plugins, tags, agents, scans, and specialized analyses (VPR comparison, KEV/EPSS cross-reference, scan delta). No two tools have overlapping purposes.

    Naming Consistency4/5

    Most tools follow a verb_noun pattern (get_asset_details, search_vulnerabilities, list_scans, compare_vpr_reprioritization, check_kev_epss_exposure). However, 'scan_delta' deviates as a noun-noun compound, breaking the otherwise consistent convention.

    Tool Count5/5

    11 tools is well within the ideal 3-15 range and each tool serves a specific purpose for the server's VPR-focused analysis domain. The count feels neither excessive nor thin.

    Completeness4/5

    The server covers core retrieval and comparison workflows well, including asset and scan details, vulnerability search, and specialized reporting tools. A minor gap is the lack of a per-asset vulnerability findings endpoint, but existing tools can work around this.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server to query and manage CISA Known Exploited Vulnerabilities catalog with EPSS overlay, enabling vulnerability checks and remediation deadline tracking.
      56 PyPI
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Unifies NVD, EPSS, CISA KEV, GitHub Advisory, and OSV into a single MCP server, enabling AI agents to query vulnerability intelligence conversationally with 23 tools for incident response, prioritization, dependency audits, and threat monitoring.
      41
      292 npm
      30
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      MCP server for ConnectSecure vulnerability management, exposing 285 read-only tools to query assets, vulnerabilities, Active Directory, and more via natural language.
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server for Tenable Vulnerability Management and the Tenable One platform, enabling LLMs to query assets, vulnerabilities, scans, exposure metrics, attack paths, and more via natural language.
      2
      MIT