Skip to main content
Glama
brendanong95

tenable-activity-mcp

by brendanong95

tenable-activity-mcp

Tests

Ein MCP-Server, der das Tenable Vulnerability Management Audit-/Aktivitätsprotokoll (GET /audit-log/v1/events) als eine kleine Reihe von Tools bereitstellt, sodass jeder MCP-Client auf Anfrage nach Plattformaktivität, API-Key-Nutzung und anomalem Verhalten fragen kann.

Der Server übernimmt die Analyse. Zählen, Gruppieren, Ratenberechnung und Schwellenwertvergleiche erfolgen in Python; die Tools liefern fertige, strukturierte Ergebnisse (failure_rate_pct, by_actor, findings mit Begründung), anstatt rohe Ereignisse zum Aufsummieren an das Modell weiterzugeben.

Was Sie erhalten

Tool

Zweck

list_activity_events

Ereignisfeed für ein Zeitfenster, mit Akteur-/Aktionsfiltern. Die Paginierung wird automatisch verfolgt; bei Erreichen einer Sicherheitsgrenze wird ein fortsetzbarer next_token zurückgegeben.

summarize_activity

Deterministische Zusammenfassung für ein Zeitfenster: Zählungen nach Akteur, Aktion, CRUD-Typ und Zugriffstyp, plus Fehler-/Anonymraten.

get_api_key_usage

Nur API-Key-basierte Aktivität, gruppiert nach Akteur: Aktionsaufschlüsselung, eindeutige Quell-IPs, erstes/letztes Auftreten.

detect_anomalies

Vergleicht ein Zeitfenster mit der gespeicherten Baseline jedes Akteurs. Meldet neue Akteure, Volumenspitzen, unbekannte Quell-IPs, Fehlerbursts, anhaltende Fehlerraten, Aktivität außerhalb der Geschäftszeiten und noch nie gesehene Aktionen – jeweils mit Beleg und Begründungssatz.

get_actor_profile

Das vollständige Bild eines Akteurs: Rolle (best effort), Aktionsaufschlüsselung über alle Zeiten, Zugriffstypen, alle gesehenen Quell-IPs.

check_permission_prereqs

Bestanden/nicht bestanden, ob die konfigurierten Schlüssel das Audit-Protokoll tatsächlich lesen können, mit Hinweisen zur Behebung.

Wissenswerte Sicherheitseigenschaften:

  • Es werden niemals Anmeldeinformationen zurückgegeben. Feldwerte, deren Schlüsselnamen auf ein Geheimnis hindeuten (secret_key, api_key, token, password, ...) oder deren Wert wie Tenable-Schlüsselmaterial aussieht, werden auf die letzten 4 Zeichen maskiert.

  • Die Paginierung ist begrenzt auf 20 Seiten / 100.000 Ereignisse pro Tool-Aufruf; das Erreichen der Grenze wird explizit gemeldet, zusammen mit dem Cursor, der zum Fortsetzen benötigt wird.

  • 429-Antworten werden mit Backoff behandelt unter Verwendung des X-RateLimit-Reset-Headers (der Endpunkt sendet kein Retry-After), mit exponentiellem Fallback und einer Retry-Obergrenze.

Related MCP server: Entra Identity Posture MCP

Anforderungen

  • Python 3.11+

  • uv

  • Tenable-VM-API-Schlüssel, deren Besitzer das Audit-Protokoll lesen kann

Tenable-Rolle / Berechtigungen

Das Lesen von audit-log/v1/events erfordert die Rolle Administrator oder eine benutzerdefinierte Rolle mit expliziter Leseberechtigung für das Audit-Protokoll, und zwar für den Benutzer, dem die API-Schlüssel gehören. Alles andere führt zu HTTP 403; check_permission_prereqs meldet das in verständlicher Sprache.

Generieren Sie Schlüssel in Tenable VM unter Einstellungen → Mein Konto → API-Schlüssel. Die Schlüssel erben die Berechtigungen des Benutzers, der sie erstellt hat.

get_actor_profile versucht zusätzlich, die Rolle eines Akteurs aus dem Benutzerverzeichnis aufzulösen. Wenn die Schlüssel keine Benutzer auflisten können, wird das Profil trotzdem zurückgegeben – nur ohne das Rollenlabel.

Einrichtung

uv sync --extra dev

Kopieren Sie dann .env.example in .env und füllen Sie Ihre Schlüssel aus:

cp .env.example .env

Überprüfen Sie Anmeldeinformationen und Berechtigungen, bevor Sie es in einen Client einbinden:

uv run python -c "from dotenv import load_dotenv; load_dotenv(); from src.server import check_permission_prereqs; print(check_permission_prereqs())"

Führen Sie den Server direkt aus (er spricht MCP über stdio, wird also einfach dasitzen und auf einen Client warten – das ist das korrekte Verhalten):

uv run python -m src.server

Verbinden eines Clients

Verwenden Sie den absoluten Pfad zu Ihrem Klon in der folgenden Konfiguration. Um ihn auszugeben, führen Sie pwd im Repository-Stammverzeichnis unter macOS/Linux aus, oder (Get-Location).Path in PowerShell.

Claude Desktop

Bearbeiten Sie claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "tenable-activity": {
      "command": "uv",
      "args": [
        "--directory",
        "C:\\path\\to\\tenable-activity-mcp",
        "run",
        "python",
        "-m",
        "src.server"
      ],
      "env": {
        "TENABLE_ACCESS_KEY": "your_access_key",
        "TENABLE_SECRET_KEY": "your_secret_key",
        "TENABLE_MCP_BASE_URL": "https://cloud.tenable.com"
      }
    }
  }
}

Starten Sie Claude Desktop danach neu. Unter macOS/Linux verwenden Sie einen POSIX-Pfad (/Users/you/tenable-activity-mcp).

Wenn uv nicht im PATH des Launchers ist, verwenden Sie seinen absoluten Pfad (which uv / (Get-Command uv).Source) als command.

Claude Code

claude mcp add tenable-activity --env TENABLE_ACCESS_KEY=your_access_key --env TENABLE_SECRET_KEY=your_secret_key -- uv --directory /absolute/path/to/tenable-activity-mcp run python -m src.server

Oder fügen Sie denselben Block wie oben zu einer projektweiten .mcp.json hinzu.

Über env übergebene Anmeldeinformationen haben Vorrang vor .env; die .env-Datei ist eine Bequemlichkeit für die lokale Entwicklung, und beide Mechanismen funktionieren.

Beispielhafte Fragen, die Sie nach dem Verbinden stellen können

  • „Überprüfe, ob meine Tenable-Anmeldeinformationen das Audit-Protokoll lesen können."

  • „Fasse die Tenable-Plattformaktivität der letzten 7 Tage zusammen – wer war am aktivsten, und wie hoch ist die Fehlerrate?"

  • „Welche API-Schlüssel wurden in den letzten 30 Tagen gegen Tenable verwendet, und von welchen Quell-IPs?"

  • „Suche nach Anomalien in der Tenable-Aktivität der letzten 3 Tage im Vergleich zu einer 30-Tage-Baseline und erkläre alles, was du markierst."

  • „Zeig mir alles, was Akteur 00000000-1111-4222-8333-444444444444 je getan hat – Aktionen, Zugriffstypen und IPs."

So funktioniert die Anomalieerkennung

detect_anomalies benötigt Verlauf zum Vergleich, der in einer lokalen SQLite-Datei (state.db, automatisch erstellt) gespeichert wird:

  1. Wenn gespeicherte Baselines älter als BASELINE_REFRESH_MAX_AGE_HOURS (12) sind, ruft der Server die baseline_days unmittelbar vor Ihrem Zeitfenster ab und berechnet pro Akteur Durchschnittswerte, bekannte IPs, bekannte Aktionen und ein Stunden-Histogramm neu.

  2. Ihr Zeitfenster wird abgerufen und mit diesen Baselines verglichen.

  3. Ereignisse im analysierten Zeitfenster werden nicht in die Baseline einbezogen, sodass das erneute Ausführen desselben Zeitfensters dieselben Ergebnisse liefert.

Jeder Schwellenwert ist eine benannte Konstante am Anfang von src/anomaly.py und wird in jedem Ergebnis unter thresholds zurückgegeben:

Konstante

Standard

Bedeutung

SPIKE_MULTIPLIER

3.0

Ereignisse/Tag im Fenster müssen dieses Vielfache des Baseline-Durchschnitts überschreiten

SPIKE_MIN_WINDOW_EVENTS

20

Untergrenze, bevor eine Spitze überhaupt markiert werden kann

NEW_IP_LOOKBACK_DAYS

30

Wie kürzlich eine IP gesehen worden sein muss, um als „bekannt" zu gelten

FAILED_AUTH_BURST_COUNT / FAILED_AUTH_BURST_WINDOW_MINUTES

5 / 10

Auslöser für Fehler-Clustering

HIGH_FAILURE_RATE_PCT

50.0

Auslöser für anhaltende Fehlerrate (über mindestens 10 Ereignisse)

OFF_HOURS_START_HOUR / OFF_HOURS_END_HOUR

20 / 6 (UTC)

Band außerhalb der Geschäftszeiten

OFF_HOURS_RATIO_MULTIPLIER

2.0

Der Anteil außerhalb der Geschäftszeiten muss dieses Vielfache des Baseline-Anteils des Akteurs überschreiten

Baselines sind pro Akteur, sodass ein Dienstkonto, das legitimerweise 500 Scans pro Tag ausführt, nicht dafür markiert wird, genau das zu tun.

Aufbau

src/
  server.py          MCP entrypoint (FastMCP-style) + the six tool definitions
  tenable_client.py  Auth, filter building, cursor pagination, 429 backoff, typed errors
  classifier.py      API-key vs UI/session tagging, IP extraction, redaction, rollups
  anomaly.py         Thresholds and the individual anomaly checks
  state.py           SQLite: cursors, accumulated actor history, computed baselines
tests/
  test_pagination.py test_classifier.py test_anomaly.py

Die Abhängigkeitsrichtung ist einseitig: server → {anomaly, classifier, state} → tenable_client.

Testen

Drei Ebenen, in der Reihenfolge, in der Sie sie ausführen sollten.

1. Unit-Tests (keine Anmeldeinformationen, kein Netzwerk)

uv run pytest -q

105 Tests, die Paginierungs-/Cursor-Handling, Rate-Limit-Backoff, API-Key- vs. Sitzungsklassifizierung, Redaktion und jeden Anomalie-Schwellenwert abdecken. Jede API-Antwort wird über einen Stub-Transport vorgetäuscht, sodass die Suite niemals einen echten Mandanten berührt.

2. Offline-End-to-End (keine Anmeldeinformationen, kein Netzwerk)

uv run python scripts/smoke_local.py

Führt alle sechs Tools gegen ein skriptbasiertes Fake-Tenable aus (einen ruhigen Baseline-Monat, dann eine laute Nacht von einer neuen IP) und prüft die Ergebnisse: markierte Anomalien, redigierte eingepflanzte Geheimnisse, schlechte Eingaben, die als strukturierter Fehler statt als Ausnahme zurückgegeben werden. Beendet sich bei jedem Fehler mit einem Nicht-Null-Status, funktioniert also als Pre-Commit- oder CI-Gate.

3. Live-Check gegen Ihren Mandanten (nur lesend)

Mit ausgefüllter .env:

uv run python scripts/live_check.py 7

Überprüft zuerst die Audit-Protokoll-Berechtigungen und stoppt mit Hinweisen zur Behebung, wenn sie falsch sind, und gibt dann eine echte Zusammenfassung, API-Key-Nutzungsaufschlüsselung, Anomalie-Ergebnisse und das Profil des aktivsten Akteurs für die letzten N Tage (Standard 7) aus. Alle Aufrufe sind GETs; es wird nichts an Tenable geschrieben.

4. Über einen MCP-Client

Jeder MCP-Client funktioniert. Um die Tools interaktiv ohne Chat-Client auszuprobieren:

npx @modelcontextprotocol/inspector uv --directory . run python -m src.server

Oder binden Sie es in Claude Desktop / Claude Code ein (oben) und stellen Sie eine der Beispielfragen. check_permission_prereqs ist der richtige erste Aufruf – er bestätigt, dass der Server gestartet ist, seine Anmeldeinformationen gefunden hat und das Audit-Protokoll erreichen kann.

Lokalen Zustand untersuchen

uv run python -c "from src.state import StateStore; print(StateStore().stats())"

Löschen Sie state.db, um Baselines zurückzusetzen; der nächste detect_anomalies-Aufruf baut sie neu auf.

Bekannte Einschränkungen

  • Erfordert die Administrator-Rolle. Das Lesen von audit-log/v1/events erfordert, dass der Benutzer, dem die API-Schlüssel gehören, über die Administrator-Rolle oder eine benutzerdefinierte Rolle mit expliziter audit-log-Leseberechtigung verfügt. Alles Geringere führt zu HTTP 403. Führen Sie zuerst check_permission_prereqs aus - es meldet genau dies, mit Hinweisen zur Behebung.

  • Anomalieerkennung benötigt Historie, bevor sie nützlich ist. Der erste detect_anomalies-Aufruf gegen eine neue state.db erstellt Basislinien aus den 30 Tagen vor Ihrem Zeitfenster und vergleicht dann mit diesen. Akteure mit wenig oder keiner früheren Aktivität werden als new_actor gekennzeichnet, daher sind frühe Läufe verrauschter als spätere.

  • Die Rollenauflösung erfolgt nach dem Best-Effort-Prinzip. get_actor_profile versucht, die Tenable-Rolle eines Akteurs aus dem Benutzerverzeichnis aufzulösen. Wenn die API-Schlüssel keine Benutzer auflisten können, wird das Profil dennoch zurückgegeben - nur ohne das Rollen-Label.

  • Die Erkennung von Aktivitäten außerhalb der Geschäftszeiten verwendet ein festes UTC-Band. Das Zeitfenster außerhalb der Geschäftszeiten ist 20:00-06:00 UTC und passt sich nicht an die Arbeitszeitzone des Mandanten an. Verteilte Teams sehen Ergebnisse außerhalb der Geschäftszeiten, die schlicht dem Arbeitsmorgen einer anderen Region entsprechen.

  • Basislinien sind lokal auf dem Rechner, auf dem der Server läuft. state.db wird nicht zwischen Installationen geteilt, sodass zwei Betreiber, die ihre eigenen Kopien ausführen, unabhängige Basislinien aufbauen und zu unterschiedlichen Schlussfolgerungen über dasselbe Zeitfenster gelangen können.

  • Große Zeitfenster liefern konstruktionsbedingt Teilergebnisse. Ein Tool-Aufruf durchläuft höchstens 20 Seiten / 100.000 Ereignisse. Das Erreichen dieser Obergrenze wird explizit zusammen mit dem zum Fortsetzen benötigten next_token gemeldet, sodass es sich nie um ein stilles Abschneiden handelt - aber ein sehr großes Zeitfenster erfordert mehrere Aufrufe.

  • Nur die ersten 1.000 Ereignisse werden inline zurückgegeben. list_activity_events begrenzt das Inline-events-Array auf 1.000 und setzt inline_truncated, wenn dies geschieht. Der summary-Block umfasst weiterhin jedes abgerufene Ereignis, sodass die aggregierten Zahlen korrekt bleiben, auch wenn die Inline-Liste gekürzt wird.

  • get_actor_profile reicht höchstens 365 Tage zurück und kann nicht weiter zurückblicken, als das Audit-Log selbst reicht.

Hinweise

  • Entwickelt auf Basis von mcp==2.0.0, in dem das SDK FastMCP in MCPServer umbenannt hat. server.py importiert den Namen, den das installierte SDK bereitstellt, sodass es auch unter mcp 1.x funktioniert.

  • Der Ereignisabruf erfolgt über die TenableIO-Sitzung von pyTenable (audit_log.events(..., return_json=True)), die die Authentifizierungs- und Verbindungsbehandlung in der gepflegten Bibliothek belässt und gleichzeitig den pagination.next-Cursor für uns sichtbar lässt. Wenn pyTenable nicht verfügbar ist, übernimmt ein gleichwertiger requests-Transport, der den Header X-ApiKeys: accessKey=...;secretKey=... verwendet.

  • Zeitstempel sind überall in UTC, einschließlich des Zeitfensters außerhalb der Geschäftszeiten.

  • state.db sammelt die Historie pro Akteur. Löschen Sie diese Datei, um alle Basislinien zurückzusetzen; der nächste detect_anomalies-Aufruf erstellt sie neu.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Exposes Azure Log Analytics workspace data with tools for querying AuditLogs and AzureActivity tables, supporting custom KQL queries, time range filters, and pagination.
  • A
    license
    Not graded
    quality
    C
    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.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    MCP server for Tenable.io/One Vulnerability Management that provides read-only tools for querying scans, assets, plugins, and vulnerabilities, plus specialized reporting tools for VPR re-prioritization, CISA KEV/EPSS exposure, and scan delta comparisons.
    11
    2
    MIT

View all related MCP servers

Related MCP Connectors

  • A paid remote MCP for AI SDK data query MCP, built to return verdicts, receipts, usage logs, and aud

  • Read-only MCP access to sessions, funnels, campaigns, errors, live visitors, and anomalies.

  • Read-only access to Auralogs production logs: search logs, inspect errors, review AI analyses.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/brendanong95/tenable-activity-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server