Tenable OT Security MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| TOT_URL | No | Appliance base URL. Alternative: TENABLE_URL. | |
| TENABLE_URL | No | Alternative to TOT_URL. | |
| TOT_API_KEY | No | Service-account API key. Alternative: TENABLE_API_KEY. | |
| TENABLE_API_KEY | No | Alternative to TOT_API_KEY. | |
| TENABLE_OT_HOST | No | Bind address for HTTP transports. | 127.0.0.1 |
| TENABLE_OT_PORT | No | Port for HTTP transports. | 8000 |
| TENABLE_OT_TIMEOUT | No | GraphQL request timeout (seconds). | 30 |
| TENABLE_OT_AUDIT_DIR | No | Directory holding audit.jsonl. | /data |
| TENABLE_OT_LOG_LEVEL | No | Log level. Logs go to stderr. | INFO |
| TENABLE_OT_TRANSPORT | No | Transport: stdio, streamable-http, or sse. The image defaults to streamable-http. | stdio |
| TENABLE_OT_TLS_VERIFY | No | Verify the appliance certificate. Turn on for trusted certificates. | true (compose sets false) |
| TENABLE_OT_TOKEN_LABEL | No | Optional label stamped on audit entries. A label, never the key. | |
| TENABLE_OT_UPLOAD_TIMEOUT | No | File-upload timeout; uploads are parsed server-side and take longer. | 180 |
| TENABLE_OT_WRITE_TOOLS_ENABLED | No | Set to 1/true/yes/on to expose write tools. Anything else keeps them hidden. | 0 |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| tenable_ot_statusA | Report whether this server can reach and authenticate to the configured Tenable OT deployment, with round-trip latency and, on failure, the underlying error. Call this first when other tools are failing, to tell an appliance/credential problem apart from a query problem. READ-ONLY. Never returns the API key. |
| query_assetsA | Returns a list of OT assets in the Tenable OT deployment, filtered by the provided criteria. Returns up to
Filter values use natural OT vocabulary:
• kind: one of ['accesscontrolsystem', 'accesspoint', 'actuator', 'backplanemodule', 'barcodescanner', 'bms', 'camera', 'cnc', 'controller', 'converter', 'cp', 'datalogger', 'dcs', 'domaincontroller', 'drive', 'eng', 'fielddevice', 'fileserver', 'firewall', 'gateway', 'historian', 'hmi', 'hub', 'hvacmodule', 'ied', 'industrialgateway', 'industrialnetworkdevice', 'industrialprinter', 'industrialrouter', 'industrialsensor', 'industrialswitch', 'inverter', 'io', 'iot', 'lightingcontrol', 'medicaldevice', 'mobile', 'networkdevice', 'otdevice', 'otserver', 'otworkstation', 'panel', 'plc', 'powermeter', 'powersupply', 'printer', 'projector', 'radio', 'relay', 'remoteio', 'repeater', 'robot', 'router', 'rtu', 'securityappliance', 'sensor', 'serialethernetbridge', 'server', 'smarthub', 'smartsensor', 'smarttv', 'storagedevice', 'switch', 'tablet', 'tenableem', 'tenableicp', 'tenablesensor', 'threedprinter', 'unknown', 'ups', 'videomanagementsystem', 'virtualserver', 'virtualworkstation', 'voipdevice', 'webserver', 'workstation']
• category: one of 'controller', 'network', 'iot'
• criticality_at_least: one of ['none', 'low', 'medium', 'high']
• vendor: equal-match on the vendor name
• name_contains: substring match on the asset name
• tags: list of exact tag strings; matches an asset carrying ANY of them. Project-file uploads ( |
| get_assetA | Returns the per-asset bundle for one OT asset by id: identity, classification, IPs / MACs, Purdue level, segment membership, criticality, run status, backplane (rack) membership, tags, and aggregate risk. |
| get_asset_vulnerabilitiesA | Returns the open vulnerabilities (Tenable plugins) affecting one OT asset. Each vulnerability includes CVEs, CVSS v3 score and vector, exploit availability flags (CISA KEV, exploit-available, exploited-by-malware), age, public disclosure date, and the official vendor solution. Use |
| list_custom_fieldsA | Returns the asset custom-field schema for this Tenable OT tenant. Custom fields are 10 fixed slots ('customField1'..'customField10'); operators map each slot to a human label (e.g. 'Plant ID', 'CDA Type') and a value type ('PlainText' or 'HyperLink'). Call this before reading or writing custom-field values so the AI knows which labels are configured. Read tools ( |
| get_manual_asset_upload_statusA | Check the processing status of the most recent file uploaded via Tenable OT's Manual Uploads data source ( CAVEAT (confirmed empirically): this field tracks literal CSV-type imports specifically — it stayed null through a live Rockwell .L5X project-file upload that DID create an asset. For project-file / OTD-scan-result uploads, don't treat a null result here as failure — confirm outcome with |
| query_vulnerabilitiesA | Returns Tenable plugins (vulnerabilities) matching the filter criteria. Each result includes CVEs, CVSS v3 score and vector, exploit availability flags (CISA KEV, exploit-available, exploited-by-malware), age, public disclosure date, and the official vendor solution. Call
Filter values use natural OT vocabulary: • severity_at_least: one of 'info', 'low', 'medium', 'high', 'critical' • cve: a CVE substring (e.g. 'CVE-2023-25619' or 'CVE-2023' for a year-bucket) • family / source: exact-match plugin metadata For KEV-only or exploit-available filtering, inspect the projected flags in the response — those live on plugin details and aren't filterable server-side. |
| get_vulnerabilityA | Returns one Tenable plugin (vulnerability) by id, plus the full list of OT assets currently affected. Use this to reason about exposure breadth ('which assets are affected by this exploited-in-the-wild vuln?'). To look up by CVE id, call |
| query_eventsA | Returns OT detection events matching the filter criteria, newest first. Use this to investigate alert windows, policy-firing patterns, source/dest IP context, or events in a specific time window. Each event includes the time, classification, severity, source/dest assets, the firing detection policy, and protocol/IP/MAC context. Call
Filter values use natural OT vocabulary: • severity_at_least: one of 'none', 'low', 'medium', 'high' • event_type: a PolicyEventType name like 'FirmwareVersionChange', 'ConfigurationDownload', 'ProgrammingUpload', 'OperatingMode' • since / until: ISO-8601 timestamps for time-window scope |
| get_eventA | Returns full detail for a single OT event by id. Use after |
| list_detection_policiesA | Returns OT detection policies — the rules that fire events. Each policy has a level (severity), enabled / paused / archived flags, an event-type classification, and aggregate fired-event counts. Use this to audit which policies are configured, which are noisy, or which are paused. Call Note: Tenable OT's |
| get_policyA | Fetch one policy's COMPLETE configuration by id — source/destination asset-group scope (as AND'd rows of OR'd include/exclude conditions), schedule, severity, notification actions (syslog server / email group), and (for Communication/Protocol-schema policies) the protocol/port group. Unlike Call this BEFORE |
| query_policy_findingsA | Returns per-asset findings for one or more detection policies — i.e. the rows of (policy × asset × hit count) that the policies have produced. Use this to see which assets keep tripping a policy (often a tuning gap), or which assets are MITRE-mapped to a specific technique. Each finding has firstHitTime / lastHitTime, activeHits / resolvedHits, status, and joined source / destination assets. Filter values use natural OT vocabulary: • severity_at_least: one of 'none', 'low', 'medium', 'high' • status: a FindingStatus value (e.g. 'Open', 'Resolved') • mitre_technique: a MITRE ATT&CK id (e.g. 'T1565.001') • since: ISO-8601 timestamp; findings last-seen at or after |
| list_segments_and_zonesA | Returns Tenable OT's segmentation: every segment (with VLAN, subnet, asset-type filter, system flag, archived flag) and every zone (a higher-level grouping of asset groups). Use this to answer compliance questions about the IEC 62443 Zone & Conduit model, NERC CIP Electronic Security Perimeters, or NEI 08-09 defense-in-depth. |
| get_communication_pathsA | Returns observed L2 communication links involving one OT asset, with peer asset id, protocols seen, traffic / conversation count, and first/last-conversation times. Peer assets are returned as IDs only — call |
| list_network_configA | Returns the appliance's network CONFIGURATION — what it is set up to watch, as opposed to Reach for this when inventory looks wrong. If an asset is missing from
READ-ONLY. |
| list_sensorsA | Returns every Tenable OT sensor in the deployment with its current status, connection / tunnel status, version, addressing, error state, and whether updates are pending. Use this to verify visibility coverage before drawing conclusions from query_assets / query_events — an offline sensor means absence of evidence, not evidence of absence. The |
| list_asset_groupsA | Page through every active (non-archived) asset group in the deployment. Each entry includes its membership shape — IP list, IP range, asset-id list, filter expression, etc. — and whether it surfaces as a UI tag ( |
| list_archived_asset_groupsA | Page through archived asset groups — those that were soft-deleted via |
| get_asset_groupA | Fetch one asset group's full record by its id. The shape varies by group subtype: an |
| list_email_groupsA | Page through every email group in the deployment. Each entry includes its recipients, the SMTP server it routes through, and last-modified metadata. Email groups are referenced by detection policies' actions to send alert emails. |
| get_email_groupA | Fetch one email group with its recipient list and bound SMTP server details. |
| find_email_groups_using_smtp_serverA | Given an SMTP-server id, return the email groups bound to it. Useful before retiring an SMTP server: any group returned here will lose its delivery path if the server is removed. |
| list_schedule_groupsA | Page through every active schedule group. Each entry surfaces its kind (one-shot TimeInterval, weekly RecurringGroup, or system ScheduleFunction) and the windows it defines. Every policy mutation's |
| list_archived_schedule_groupsC | Soft-deleted schedule groups, paginated. |
| get_schedule_groupA | Fetch one schedule group. Shape varies by kind: |
| list_tag_groupsA | Page through every tag group. Tag groups bundle controller tags (by asset id + tag id) so a TagValuePolicy can fire against all members. |
| get_tag_groupB | One tag group with up to 100 member items. |
| list_eligible_tagsA | List controller tags that could be added to a tag group. Filterable by asset ( |
| list_rule_groupsA | Page through every active rule group. A rule group is a bundle of IDS rule SIDs referenced by IntrusionPolicy. Each entry includes a preview of up to 25 included rules. |
| list_archived_rule_groupsC | Soft-deleted rule groups, paginated. |
| get_rule_groupC | One rule group with the first 25 included rules. |
| list_port_groupsA | Page through every active port group. Port groups are reusable port-range bundles consumed by PortPolicy definitions. |
| list_archived_port_groupsC | Soft-deleted port groups, paginated. |
| get_port_groupC | One port group with up to 100 of its port-range items. |
| list_protocol_groupsA | Page through every active protocol group. Each item carries a protocol (TCP/UDP/MODBUS/S7/IEC104/DNP3/etc.) and optional port range. |
| list_archived_protocol_groupsC | Soft-deleted protocol groups, paginated. |
| get_protocol_groupC | One protocol group with up to 100 of its items. |
| list_user_groupsA | Page through every active user group at the ICP level. Each entry exposes its assigned roles and a sample of member users. |
| list_archived_user_groupsB | Soft-deleted user groups at the ICP level. |
| get_user_groupB | One ICP-level user group with its roles and member preview. |
| list_em_user_groupsA | Page through every active EM-level user group. Each entry exposes |
| list_em_archived_user_groupsD | Soft-deleted EM-level user groups. |
| get_em_user_groupC | One EM-level user group with its roles and member preview. |
| list_active_scansA | Returns Tenable OT active-scan job specifications: name, description, scan operation type (PortScan, AssetDiscovery, SnmpType, etc.), category (IT / OT / Discovery), trigger (Manual / Periodic / System), enabled flag, status, and the asset group the job targets. Use this to audit what scans are configured. Predefined system scans appear with |
| get_active_scanA | Returns the full specification for one active-scan job by id. Use after |
| get_active_scan_executionsA | Returns past execution records for one active scan: start/end time, elapsed time, status (Completed / Failed / Ongoing), who initiated, source (UI / API / system), and any failure explanation. Use this to audit when a scan was last run and whether it succeeded — but the underlying execution is triggered by humans, not this server. |
| summarize_environmentA | Returns a one-shot snapshot of the operator's OT environment — total counts and useful subtotals across assets, events, vulnerabilities, sensors, topology, and policies. Ideal as the first call when the AI doesn't yet know the deployment's shape and scale. Each section is a compact dict; subtotals are best-effort (only those Tenable's filters support are populated). Asset criticality buckets: none / low / medium / high. Plugin severity buckets: info / low / medium / high / critical. Event subtotals split by resolved flag. |
| query_attack_pathwaysA | Returns the asset's 1-hop network neighborhood: the asset itself plus a list of peer-asset IDs it has communicated with, with the protocols and conversation count of each link. Use this AS THE GRAPH the AI walks to reason about attack paths — call again on each peer's id to expand further. The server does NOT compute paths, pick highest-risk routes, or score compromise time. That's the AI's job. Peer assets are returned as IDs only — call |
| query_vulnerability_clustersA | Returns the per-asset → vulnerabilities join the consuming AI uses to spot common CVEs across multiple assets, exploit chains (KEV + exploit-available + high criticality), or single-patch leverage points (one CVE fixing many). Two modes: • Pass Both args may be combined for a per-asset CVE-filtered view. The server does NOT cluster server-side. |
| query_temporal_patternsA | Returns events in a time window, ordered chronologically, with their classification, firing policy, and source/dest IPs joined. The AI uses this raw sequence to detect patterns (e.g. config-download + firmware-change + operating-mode-change within minutes = high-priority investigation). The server does NOT detect motifs, score patterns, or label sequences. |
| get_asset_intelligenceA | Returns one asset's full relational bundle in a single shot: asset core + open vulnerabilities + recent events where the asset is source or destination + 1-hop comms peers. The AI uses this bundle to write a per-asset intelligence narrative if asked. The server does NOT generate the narrative itself. |
| list_policy_relationshipsA | Answers 'what breaks if I change this?' — the impact check to run BEFORE any write that touches a shared object (asset group, schedule group, port/protocol group, baseline). Tenable OT's policy mutations are FULL REPLACES, so an edit lands completely and silently. If a live detection policy scopes to the group you're about to archive or re-scope, that policy's coverage changes with no warning. This tool surfaces those dependants first.
The READ-ONLY. |
| get_schema_enumsA | Read this deployment's own GraphQL schema — enum values, input-object shapes, and the available root query/mutation fields. WHY THIS MATTERS: some filters on this server refuse to run with a It also answers 'does this appliance actually expose query X?' — useful when a topology tool reports that a top-level query was rejected. Arguments: • type_names: specific GraphQL types to dump. Omit to get the types this server still needs. • include_inputs: also dump input-object field shapes (for filter/mutation argument structures). • list_root_fields: also list every root query and mutation name the appliance exposes. READ-ONLY. Touches no OT data — GraphQL reflection only. |
| query_plugin_definitionsA | Returns Tenable plugin DEFINITIONS — the vulnerability checks themselves (id, name, family, severity, VPR score, and how many assets each affects). This is the catalog, NOT per-asset findings: a plugin appears here whether or not anything in your environment is affected. For the vulnerabilities on a specific asset use
READ-ONLY. |
| get_plugin_definitionA | Returns one plugin definition by its NUMERIC plugin id, including the assets it affects. Note the id is an integer (e.g. 500123), not the UUID used for assets. READ-ONLY. |
| export_assetsA | Bulk asset export via Tenable OT's export API. Returns full asset records for offline analysis, inventory reconciliation, or feeding another system. PREFER
READ-ONLY. High latency on large deployments. |
| export_plugin_definitionsA | Bulk plugin-definition export via Tenable OT's export API. Returns full plugin records in bulk. PREFER READ-ONLY. High latency. |
| export_findingsA | Bulk export of FINDING INSTANCES — one record per (vulnerability or policy violation x affected asset) — via Tenable OT's official export API. Choosing between the finding tools:
•
READ-ONLY. High latency on large deployments. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/aqamahn/MCP-server-Tenable-OT-V2'
If you have feedback or need assistance with the MCP directory API, please join our Discord server