Skip to main content
Glama
brendanong95

tenable-activity-mcp

by brendanong95

tenable-activity-mcp

Tests

Tenable Vulnerability Management 감사/활동 로그(GET /audit-log/v1/events)를 소수의 도구로 노출하는 MCP 서버로, 모든 MCP 클라이언트가 플랫폼 활동, API 키 사용, 비정상 동작을 요청 시 조회할 수 있습니다.

서버가 분석을 수행합니다. 카운팅, 그룹화, 비율 계산, 임계값 비교는 모두 Python에서 이루어지며, 도구는 모델이 직접 더하도록 원시 이벤트를 던져주는 대신 완성된 구조적 결과(failure_rate_pct, by_actor, 근거가 포함된 findings)를 반환합니다.

제공 기능

도구

용도

list_activity_events

특정 기간의 이벤트 피드, 행위자/작업 필터 포함. 페이지네이션은 자동으로 이어지며, 안전 한도에 도달하면 재개 가능한 next_token을 반환합니다.

summarize_activity

특정 기간에 대한 결정적 롤업: 행위자, 작업, CRUD 유형, 액세스 유형별 집계와 실패/익명 비율을 포함합니다.

get_api_key_usage

API 키 기반 활동만 행위자별로 그룹화: 작업 분류, 고유 소스 IP, 첫/마지막 사용 시각.

detect_anomalies

특정 기간을 각 행위자의 저장된 기준선과 비교합니다. 새 행위자, 볼륨 급증, 처음 본 소스 IP, 실패 이벤트 버스트, 지속적 실패율, 업무 시간 외 급증, 전례 없는 작업을 각각 증거와 추론 문장과 함께 플래그로 표시합니다.

get_actor_profile

한 행위자의 전체 그림: 역할(최선 노력), 전체 기간 작업 분류, 액세스 유형, 본 모든 소스 IP.

check_permission_prereqs

구성된 키가 실제로 감사 로그를 읽을 수 있는지 통과/실패 여부와 해결 방법 텍스트를 제공합니다.

알아두면 좋은 안전 속성:

  • 자격 증명처럼 보이는 것은 절대 반환되지 않습니다. 키 이름이 비밀을 나타내는 필드 값(secret_key, api_key, token, password, ...) 또는 값이 Tenable 키 자료처럼 보이는 것은 마지막 4자로 마스킹됩니다.

  • 페이지네이션은 도구 호출당 20페이지 / 10만 이벤트로 제한됩니다. 한도에 도달하면 계속하는 데 필요한 커서와 함께 명시적으로 보고됩니다.

  • 429 응답은 X-RateLimit-Reset 헤더를 사용해 백오프합니다 (엔드포인트는 Retry-After를 보내지 않습니다). 지수 백오프와 재시도 상한이 적용됩니다.

Related MCP server: Entra Identity Posture MCP

요구 사항

  • Python 3.11+

  • uv

  • 감사 로그를 읽을 수 있는 소유자의 Tenable VM API 키

Tenable 역할 / 권한

audit-log/v1/events를 읽으려면 API 키를 소유한 사용자에게 Administrator 역할 또는 명시적 감사 로그 읽기 권한이 있는 사용자 지정 역할이 필요합니다. 그보다 낮은 권한은 HTTP 403을 받으며, check_permission_prereqs가 이를 평이한 언어로 보고합니다.

Tenable VM에서 설정 → 내 계정 → API 키 아래에서 키를 생성합니다. 키는 생성한 사용자의 권한을 상속합니다.

get_actor_profile은 추가로 사용자 디렉터리에서 행위자의 역할을 확인하려 시도합니다. 키가 사용자를 나열할 수 없으면 역할 라벨 없이 프로필이 여전히 반환됩니다.

설정

uv sync --extra dev

그런 다음 .env.example.env로 복사하고 키를 입력하세요:

cp .env.example .env

클라이언트에 연결하기 전에 자격 증명과 권한을 확인하세요:

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

서버를 직접 실행합니다 (stdio를 통해 MCP를 사용하므로 클라이언트를 기다리며 대기합니다 - 이것이 정상적인 동작입니다):

uv run python -m src.server

클라이언트 연결

아래 구성에서 클론의 절대 경로를 사용하세요. 이를 출력하려면 macOS/Linux에서는 저장소 루트에서 pwd를 실행하고, PowerShell에서는 (Get-Location).Path를 실행하세요.

Claude Desktop

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"
      }
    }
  }
}

이후 Claude Desktop을 다시 시작하세요. macOS/Linux에서는 POSIX 경로(/Users/you/tenable-activity-mcp)를 사용하세요.

uv가 실행 프로그램의 PATH에 없으면 절대 경로(which uv / (Get-Command uv).Source)를 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

또는 위와 같은 블록을 프로젝트 수준의 .mcp.json에 추가하세요.

env로 전달된 자격 증명은 .env보다 우선합니다. .env 파일은 로컬 개발 편의를 위한 것이며, 두 방식 모두 동작합니다.

연결 후 물어볼 수 있는 예시 질문

  • "내 Tenable 자격 증명이 감사 로그를 읽을 수 있는지 확인해 줘."

  • "지난 7일간 Tenable 플랫폼 활동을 요약해 줘 - 누가 가장 활발했고, 실패율은 어때?"

  • "지난 30일간 Tenable에 대해 사용된 API 키는 무엇이고, 소스 IP는 어디인가?"

  • "지난 3일간 Tenable 활동에서 30일 기준선 대비 이상 징후를 찾아보고, 플래그로 표시된 항목을 설명해 줘."

  • "행위자 00000000-1111-4222-8333-444444444444가 지금까지 한 모든 것(작업, 액세스 유형, IP)을 보여 줘."

이상 탐지 작동 방식

detect_anomalies는 비교할 이력이 필요하며, 이 이력은 로컬 SQLite 파일(state.db, 자동 생성)에 저장됩니다:

  1. 저장된 기준선이 BASELINE_REFRESH_MAX_AGE_HOURS(12)보다 오래된 경우, 서버는 해당 기간 바로 앞의 baseline_days를 가져와 행위자별 평균, 알려진 IP, 알려진 작업, 시간대별 히스토그램을 다시 계산합니다.

  2. 해당 기간의 데이터를 가져와 그 기준선과 비교합니다.

  3. 분석된 기간의 이벤트는 기준선에 포함되지 않으므로, 같은 기간을 다시 실행해도 동일한 결과가 반환됩니다.

모든 임계값은 src/anomaly.py 상단에 있는 명명된 상수이며, 각 결과의 thresholds 아래에 다시 반영됩니다:

상수

기본값

의미

SPIKE_MULTIPLIER

3.0

창의 일일 이벤트 수가 기준선 평균의 이 배수를 초과해야 함

SPIKE_MIN_WINDOW_EVENTS

20

급증이 플래그될 수 있는 최소 기준

NEW_IP_LOOKBACK_DAYS

30

IP가 '알려진' 것으로 간주되려면 얼마나 최근에 보였어야 하는지

FAILED_AUTH_BURST_COUNT / FAILED_AUTH_BURST_WINDOW_MINUTES

5 / 10

실패 집중 트리거

HIGH_FAILURE_RATE_PCT

50.0

지속적 실패율 트리거 (최소 10개 이벤트 기준)

OFF_HOURS_START_HOUR / OFF_HOURS_END_HOUR

20 / 6 (UTC)

업무 시간 외 구간

OFF_HOURS_RATIO_MULTIPLIER

2.0

업무 시간 외 비율이 행위자의 기준선 비율의 이 배수를 초과해야 함

기준선은 행위자별로 관리되므로, 하루에 500건의 스캔을 합법적으로 실행하는 서비스 계정은 그 행동만으로 플래그되지 않습니다.

구조

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

의존성 방향은 단방향입니다: server → {anomaly, classifier, state} → tenable_client.

테스트

실행해야 할 순서대로 나열한 세 가지 수준입니다.

1. 단위 테스트 (자격 증명 없음, 네트워크 없음)

uv run pytest -q

페이지네이션/커서 처리, 속도 제한 백오프, API 키와 세션 분류, 마스킹, 모든 이상 징후 임계값을 다루는 105개 테스트. 모든 API 응답은 스텁 전송을 통해 가짜로 처리되므로, 테스트 스위트는 실제 테넌트에 접촉하지 않습니다.

2. 오프라인 종단 간 테스트 (자격 증명 없음, 네트워크 없음)

uv run python scripts/smoke_local.py

스크립트로 작성된 가짜 Tenable(조용한 기준선 한 달, 그다음 새 IP에서의 시끄러운 밤)에 대해 여섯 가지 도구를 모두 실행하고 결과를 검증합니다: 플래그된 이상 징후, 심어진 비밀의 마스킹, 잘못된 입력이 예외 대신 구조화된 오류로 반환되는지. 실패 시 0이 아닌 종료 코드를 반환하므로 pre-commit 또는 CI 게이트로 사용할 수 있습니다.

3. 테넌트 대상 라이브 확인 (읽기 전용)

.env가 채워진 상태에서:

uv run python scripts/live_check.py 7

먼저 감사 로그 권한을 확인하고, 권한이 잘못된 경우 해결 방법 텍스트와 함께 중지합니다. 그런 다음 실제 요약, API 키 사용 분류, 이상 징후 결과, 지난 N일(기본 7일) 동안 가장 활동이 많은 행위자의 프로필을 출력합니다. 모든 호출은 GET이며 Tenable에 아무것도 기록되지 않습니다.

4. MCP 클라이언트를 통한 방법

모든 MCP 클라이언트가 동작합니다. 채팅 클라이언트 없이 도구를 대화형으로 사용해 보려면:

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

또는 Claude Desktop / Claude Code(위)에 연결한 다음 예시 질문 중 하나를 물어보세요. check_permission_prereqs가 첫 호출로 적합합니다 - 서버가 시작되었고, 자격 증명을 찾았으며, 감사 로그에 도달할 수 있는지 확인해 줍니다.

로컬 상태 확인

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

state.db를 삭제하면 기준선이 재설정되고, 다음 detect_anomalies 호출 시 다시 구축됩니다.

알려진 제한 사항

  • Administrator 역할이 필요합니다. audit-log/v1/events를 읽으려면 API 키를 소유한 사용자에게 Administrator 역할 또는 명시적인 audit-log 읽기 권한이 있는 사용자 지정 역할이 필요합니다. 그보다 낮은 권한은 HTTP 403을 반환합니다. 먼저 check_permission_prereqs를 실행하세요. 정확히 이 문제를 해결 텍스트와 함께 보고합니다.

  • 이상 감지 기능은 이력이 있어야 유용합니다.state.db에 대한 첫 detect_anomalies 호출은 창 이전 30일의 데이터를 기준으로 기준선을 구축한 다음 이를 비교합니다. 사전 활동이 거의 없거나 전혀 없는 행위자는 new_actor로 표시되므로 초기 실행 결과는 이후 실행보다 노이즈가 더 많습니다.

  • 역할 확인은 최선 노력입니다. get_actor_profile은 사용자 디렉터리에서 행위자의 Tenable 역할을 확인하려고 시도합니다. 키가 사용자를 나열할 수 없으면 프로필은 여전히 반환되며, 역할 라벨만 없습니다.

  • 업무 외 시간 감지는 고정 UTC 대역을 사용합니다. 업무 외 시간 창은 20:00-06:00 UTC이며 테넌트의 작업 시간대에 맞춰 조정되지 않습니다. 분산 팀은 단순히 다른 지역의 업무 오전에 해당하는 업무 외 시간 결과를 보게 됩니다.

  • 기준선은 서버를 실행하는 머신에 국한됩니다. state.db는 설치 간에 공유되지 않으므로 각자 복사본을 실행하는 두 운영자는 독립적인 기준선을 구축하고 동일한 창에 대해 다른 결론에 도달할 수 있습니다.

  • 넓은 창은 설계상 부분 결과를 반환합니다. 하나의 도구 호출은 최대 20페이지 / 100,000개 이벤트를 처리합니다. 해당 상한에 도달하면 재개에 필요한 next_token과 함께 명시적으로 보고되므로 조용한 잘림이 절대 발생하지 않지만, 매우 넓은 창은 여러 번의 호출이 필요합니다.

  • 처음 1,000개 이벤트만 인라인으로 반환됩니다. list_activity_events는 인라인 events 배열을 1,000개로 제한하고, 그렇게 할 때 inline_truncated를 설정합니다. summary 블록은 여전히 가져온 모든 이벤트를 포함하므로 인라인 목록이 잘려도 집계 수치는 정확하게 유지됩니다.

  • get_actor_profile은 최대 365일을 되돌아봅니다. 그리고 감사 로그 자체가 보관하는 것보다 더 과거를 볼 수 없습니다.

참고 사항

  • mcp==2.0.0을 기준으로 구축되었으며, 이 버전에서 SDK가 FastMCPMCPServer로 이름을 바꿨습니다. server.py는 설치된 SDK가 제공하는 이름을 임포트하므로 mcp 1.x에서도 작동합니다.

  • 이벤트 가져오기는 pyTenable의 TenableIO 세션(audit_log.events(..., return_json=True))을 통해 이루어져, 유지 관리되는 라이브러리에서 인증과 연결 처리를 유지하면서 pagination.next 커서를 우리가 볼 수 있게 합니다. pyTenable을 사용할 수 없으면 X-ApiKeys: accessKey=...;secretKey=... 헤더를 사용하는 동등한 requests 전송이 대신합니다.

  • 타임스탬프는 업무 외 시간 대역을 포함해 모든 곳에서 UTC입니다.

  • state.db는 행위자별 이력을 누적합니다. 삭제하면 모든 기준선이 재설정되고, 다음 detect_anomalies 호출이 이를 다시 구축합니다.

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