# Tenable OT MCP Server (Enterprise Manager Edition)

> MCP server exposing Tenable OT Security data to AI clients; this EM fork adds relay routing and site-based queries.

- Type: MCP server
- Author: John Walley (OneClearPath, Incorporated)
- License: Apache-2.0
- Trust tier: contributed (passed automated validation and a baseline maintainer review)
- Last reviewed: 2026-09-01
- Source repository: https://github.com/dpstorey/EM-MCP
- Repo state: not archived
- Last push: 2026-11-05T17:51:00Z
- Stars: 0 (a popularity signal, not a safety signal)
- Forks: 0 (a popularity signal, not a safety signal)
- Open issues: 0
- Language: Python
- Health checked at: 2026-11-05T20:35:15.821Z
- Integrations: Tenable
- Domains: ot-iot-security
- Tags: tenable, ot-security, ics, scada, vulnerability-management
- Date added: 2026-08-31
- Transport: http
- Runtime: python
- Auth method: token
- Compatible clients: Claude Desktop, Claude Code, Cursor, Windsurf, ChatGPT, VS Code Copilot
- Tools:
  - `query_assets`: Query OT assets
  - `get_asset`: Get one OT asset
  - `get_asset_vulnerabilities`: Get vulnerabilities for one asset
  - `list_custom_fields`: List configured custom fields
  - `query_attack_pathways`: Query attack-pathway data (relational, not computed)
  - `query_vulnerability_clusters`: Query vulnerability clusters (relational join, not computed)
  - `query_temporal_patterns`: Query temporal patterns (event sequence, not motif analysis)
  - `get_asset_intelligence`: Get asset intelligence bundle (joined data, not narrative)
  - `list_paired_icps`: List paired ICP appliances via EM
  - `query_events`: Query OT events
  - `get_event`: Get one OT event
  - `list_asset_groups`: List asset groups (active)
  - `list_archived_asset_groups`: List archived asset groups
  - `get_asset_group`: Get an asset group by id
  - `list_email_groups`: List email groups
  - `get_email_group`: Get an email group by id
  - `find_email_groups_using_smtp_server`: Find email groups that route through a given SMTP server
  - `list_schedule_groups`: List schedule groups
  - `list_archived_schedule_groups`: List archived schedule groups
  - `get_schedule_group`: Get a schedule group by id
  - `list_tag_groups`: List tag groups
  - `get_tag_group`: Get a tag group by id
  - `list_eligible_tags`: Discover tags eligible for a tag group
  - `list_rule_groups`: List rule groups
  - `list_archived_rule_groups`: List archived rule groups
  - `get_rule_group`: Get a rule group by id
  - `list_port_groups`: List port groups
  - `list_archived_port_groups`: List archived port groups
  - `get_port_group`: Get a port group by id
  - `list_protocol_groups`: List protocol groups
  - `list_archived_protocol_groups`: List archived protocol groups
  - `get_protocol_group`: Get a protocol group by id
  - `list_user_groups`: List user groups (ICP-level)
  - `list_archived_user_groups`: List archived user groups (ICP-level)
  - `get_user_group`: Get a user group by id (ICP-level)
  - `list_em_user_groups`: List user groups (Enterprise Manager level)
  - `list_em_archived_user_groups`: List archived user groups (Enterprise Manager level)
  - `get_em_user_group`: Get a user group by id (Enterprise Manager level)
  - `create_asset_group`: Create an asset group (tag-like grouping)
  - `update_asset_group`: Update an asset group's metadata or membership
  - `archive_asset_group`: Archive (soft-delete) an asset group
  - `bulk_set_asset_group_display_tag`: Bulk toggle display-tag flag on asset groups
  - `create_email_group`: Create an email group (alert recipient list)
  - `update_email_group`: Update an email group (rename, change SMTP server, or replace recipients)
  - `archive_email_group`: Archive (delete) an email group
  - `create_schedule_group`: Create a schedule group (policy window)
  - `update_schedule_group`: Update a schedule group
  - `archive_schedule_group`: Archive (delete) a schedule group
  - `create_tag_group`: Create a tag group (PLC controller-tag rollup)
  - `update_tag_group`: Update a tag group
  - `archive_tag_group`: Archive (delete) a tag group
  - `create_rule_group`: Create a rule group (IDS rule bundle)
  - `update_rule_group`: Update a rule group
  - `archive_rule_group`: Archive (delete) a rule group
  - `create_port_group`: Create a port group (port-range bundle for PortPolicy)
  - `update_port_group`: Update a port group
  - `archive_port_group`: Archive (delete) a port group
  - `create_protocol_group`: Create a protocol group (protocol+port-range bundle)
  - `update_protocol_group`: Update a protocol group
  - `archive_protocol_group`: Archive (delete) a protocol group
  - `create_user_group`: Create a user group (ICP-level)
  - `edit_user_group`: Edit a user group (ICP-level)
  - `archive_user_group`: Archive (delete) a user group (ICP-level)
  - `set_user_groups`: Reassign a user's group memberships (ICP-level)
  - `create_em_user_group`: Create a user group (Enterprise Manager level)
  - `edit_em_user_group`: Edit a user group (Enterprise Manager level)
  - `archive_em_user_group`: Archive (delete) a user group (Enterprise Manager level)
  - `set_em_user_groups`: Reassign an EM user's group memberships
  - `list_detection_policies`: List detection policies
  - `query_policy_findings`: Query policy findings
  - `list_policy_exclusions`: List policy exclusions
  - `list_active_scans`: List active scans
  - `get_active_scan`: Get one active scan
  - `get_active_scan_executions`: Get past executions of an active scan
  - `define_active_scan`: Define an active scan (NEW — does not run it)
  - `edit_active_scan`: Edit an active-scan definition
  - `enable_active_scan`: Enable an active scan
  - `disable_active_scan`: Disable an active scan
  - `delete_active_scan`: Delete an active-scan definition
  - `define_port_scan`: Define a port-scan job (NEW — does not run it)
  - `edit_port_scan`: Edit a port-scan job
  - `define_snmp_scan`: Define an SNMP scan job (NEW — does not run it)
  - `edit_snmp_scan`: Edit an SNMP scan job
  - `define_controller_discovery_scan`: Define a controller-discovery scan (NEW — does not run it)
  - `edit_controller_discovery_scan`: Edit a controller-discovery scan job
  - `define_asset_discovery_scan`: Define an asset-discovery scan (NEW — does not run it)
  - `edit_asset_discovery_scan`: Edit an asset-discovery scan job
  - `define_inactive_probing_scan`: Define an inactive-probing scan (NEW — does not run it)
  - `edit_inactive_probing_scan`: Edit an inactive-probing scan job
  - `edit_subnets_discovery_scan`: Edit the subnets-discovery scan
  - `list_sensors`: List sensors
  - `tenable_ot_status`: Check Tenable OT connection
  - `summarize_environment`: Summarize the OT environment
  - `list_segments_and_zones`: List network segments and zones
  - `get_communication_paths`: Get communication paths for an asset
  - `query_vulnerability_findings`: Query vulnerability findings
  - `query_vulnerabilities`: Query OT vulnerabilities
  - `get_vulnerability`: Get one vulnerability
  - `hide_asset`: Hide an OT asset (filter from default views)
  - `restore_asset`: Restore a hidden OT asset
  - `bulk_hide_assets`: Bulk-hide assets matching a filter
  - `bulk_restore_assets`: Bulk-restore assets matching a filter
  - `remove_assets_by_address`: Remove asset entries by IP address
  - `recalculate_asset_risk`: Recalculate one asset's risk score
  - `recalculate_all_risk`: Recalculate risk across the deployment
  - `update_asset`: Edit an OT asset's properties
  - `bulk_edit_assets`: Bulk-edit OT assets matching a filter
  - `reset_asset_metadata`: Reset one asset's operator-set metadata
  - `create_custom_field`: Create a custom-field slot
  - `rename_custom_field`: Rename a custom-field slot
  - `delete_custom_field`: Delete a custom-field slot
  - `enable_detection_policy`: Enable a detection policy
  - `disable_detection_policy`: Disable a detection policy
  - `archive_detection_policy`: Archive a detection policy
  - `enable_detection_policies`: Bulk enable detection policies
  - `disable_detection_policies`: Bulk disable detection policies
  - `archive_detection_policies`: Bulk archive detection policies
  - `create_activity_exclusion`: Create activity exclusion
  - `create_conversation_exclusion`: Create conversation exclusion
  - `delete_exclusion`: Delete policy exclusion
  - `resolve_findings`: Resolve detection findings
- Listing page: https://exchange.tenable.com/mcp-servers/tenable-ot-mcp-em-edition
- Source file: https://github.com/tenable/cyberagents-exchange/blob/main/mcp-servers/tenable-ot-mcp-em-edition.md

An open-source [Model Context Protocol](https://modelcontextprotocol.io) server that exposes [Tenable OT Security](https://www.tenable.com/products/tenable-ot) data to any MCP-compatible AI client. This listing is for the **Enterprise Manager (EM) edition**: a fork maintained by Dominic Storey (Tenable) that adds EM-specific routing and query capabilities on top of the original open-source project created by John Walley of OneClearPath, Incorporated.

Note: the Exchange also lists a separate `tenable-ot-security-mcp-server` entry based on the same underlying open-source project under a different account; this listing covers the Enterprise Manager-specific fork maintained by Dominic Storey (Tenable), distinct from that one.

## What it does

Translates MCP tool calls into live queries and actions against a Tenable OT Security deployment — either a direct Industrial Control Platform (ICP) or, in this fork, an Enterprise Manager relay fronting multiple sites. It exposes 121 tools spanning asset inventory and edits, vulnerability and policy findings, detection-policy management and exclusions, sensor status, scan definitions, network topology, and attack-pathway correlation. Every read tool supports paginated, filterable queries; a smaller set of write tools covers tuning actions like hiding/restoring assets, creating exclusions, and enabling or disabling detection policies.

### Enterprise Manager–specific enhancements in this fork

- **Site routing** — read/write tools accept `site_uuid` / `site_name` to route calls through the EM relay to the correct paired ICP
- **EM root queries** — `list_paired_icps` queries the EM directly, bypassing relay routing
- **Machine ID caching** — automatic site name → machine ID resolution, cached for subsequent calls
- **Subnet queries** — assets can be filtered by CIDR subnet
- **Shortened tool descriptions** — trimmed for faster tool-list loading in MCP clients with limited context budgets

## How it works

A stateless container built on FastMCP's Streamable HTTP transport. A setup wizard issues a static bearer token that gates the `/mcp` endpoint (no OAuth flow — the server advertises RFC 9728 protected-resource metadata purely so clients that expect it can discover the bearer-token requirement). The server wraps the Tenable OT Security REST API, translating each MCP tool call into one or more authenticated HTTP requests, then returns results in a client-friendly shape with cursor-based pagination for large result sets.

This is the Markdown version of one of 140 listings on CyberAgents Exchange. The same listing as JSON: https://exchange.tenable.com/api/mcp-servers/tenable-ot-mcp-em-edition.json. The full index and how to read it: https://exchange.tenable.com/llms.txt
