workspace/skills/percepxion-oob/SKILL.md
Manage Lantronix out-of-band (OOB) infrastructure via Percepxion central management platform: device inventory, serial port inspection via SLC CLI, firmware compliance, config management, security auditing, and closed-loop incident remediation. Use during outages, maintenance windows, compliance cycles, and AI-assisted automation workflows.
npx skillsauth add automateyournetwork/netclaw percepxion-oobInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Out-of-Band (OOB) management is a dedicated secondary path to the console port of every network device in your infrastructure. When a switch, router, firewall, or server becomes unreachable via its production (in-band) network interface, OOB gives you serial console access through an independent control plane, often with a resilient cellular network WAN connection, so you can, Day-0 provision, diagnose, recover, or remediate even when the production network is completely dark.
OOB turns a midnight outage that would require a truck roll into a routine remote session.
Lantronix hardware in this stack:
| Device | Role | Ports | Cellular | Status | |--------|------|-------|--------|--------| | SLC9000 | Console server, current gen. Serial or USB console ports and Ethernet switch ports. Dual power, redundant management interfaces, Percepxion-native, OpenAPI 3.1. | 16-48 | Optional 5G | Announced June 1st, 2026 | | SLC8000 | Console server, previous gen. Still widely deployed in enterprise and carrier networks. Full Percepxion support. | 8-48 | - | Shipping until December 31st, 2026 | | EMG series | Compact console server for small closets or remote edge sites. | 4-8 | Optional 4G | Production |
Percepxion is the SaaS-native management platform that aggregates these devices into a single API surface. It handles device ZTP, authentication, session brokering, firmware lifecycle, configuration management, access logging, and multi-tenant operations across thousands of devices. The Percepxion MCP server exposes 37 tools against this API.
This skill operates on two distinct device types. Confusing them causes wrong tool calls and unwanted outcomes.
| Term | What it is | Examples | How you reference it |
|------|-----------|---------|---------------------|
| OOB device (also: console server) | The Lantronix hardware managed by Percepxion. Has serial ports that cable to managed devices. | SLC9000, SLC8000, EMG7500, EMG8500 | By device_id in most MCP tool calls |
| Managed device (also: attached device, target device) | The network device whose console port is physically cabled to a serial port on the OOB device. NOT managed by Percepxion directly. | Cisco switch, Juniper router, Palo Alto firewall, OOB-connected server | Via get_security_telemetry (full inventory: hostname, model, serial, IP, OS) or get_port_telemetry (single port). list_device_ports returns port state only, not managed-device identity. |
Tool routing for port and managed-device queries:
| Question | Correct tool | Notes |
|----------|-------------|-------|
| What ports does this OOB device have? | list_device_ports | Returns port names, numbers, and connection state. Does NOT return managed-device hostname, model, serial, or IP. |
| What managed devices are attached to this OOB device? | get_security_telemetry | Source of truth for managed-device inventory. Returns per-port dp_info records: hostname, model, serial, IP, OS version, uptime, CPU/memory/flash. Also includes console manager, firmware, network, and audit records. |
| What is on a specific port (e.g. port 2)? | get_port_telemetry | Single-port filtered view. Returns structured managed-device object for that port only. Cheaper than get_security_telemetry for targeted single-port questions. |
| What port is a named managed device on? | list_device_ports with device name as device_id | Searches port index by label/name. Returns parent_device_id and port_number for computing SSH connection string. |
The key distinction for tool calling:
get_device_list, get_device_details, get_device_config, firmware_compliance_report, reboot_device, and send_direct_cli_command, operate on the OOB device. The device_id in every tool call is the OOB device ID from get_device_list or get_device_details.send_direct_cli_command runs commands on the SLC's own management CLI (Linux shell), not on managed devices attached via serial. Valid commands are SLC-native: show deviceport names, show deviceport port N, connect direct deviceport N,show sysstatus, admin version, diag ping <ip>, diag traceroute <ip>. Cisco/Juniper/Arista CLI syntax will not work here. Full CLI command reference in the SLC9000 Users Guide PMD-00347A-SLC9K-UG-release.pdf chapter "18: Command Reference".send_direct_cli_command + get_cli_command_output expose, so anything that screen can do, this MCP already covers. However, the MCP can compute the direct SSH connection string you need, see the "When to ask for clarification" section below. For a fully interactive terminal session rather than a connection string, SSH directly to the SLC (ssh sysadmin@<slc-ip>) and use connect direct deviceport N from the SLC shell. That is a human-in-the-loop operation outside this MCP server's scope.When to ask for clarification:
If the operator says "I need to run a command on the device," ask:
If they mean the SLC, proceed with send_direct_cli_command using SLC CLI syntax.
If they mean an attached managed device, do not stop at "SSH to the SLC directly." Instead, proactively look up the connection details they need:
list_device_ports(device_id=<managed_device_name_or_port_label>), search port records by the managed device name or partial port label. The device_id parameter functions as a search string against the Percepxion port index, the same search the WebUI Device Ports view uses. Results include parent_device_id (which SLC hosts this port) and port_number.parent_device_id and port_number. If the port status shows disconnected or no carrier detect, flag it before returning the connection string.get_device_details(device_id=parent_device_id), retrieve the SLC's management IP address.ssh -p <3000+N> <username>@<slc-management-ip>
The username is typically the operator's Percepxion/SLC credential. If unknown, surface the SLC IP and port and note they will be prompted for credentials on connect.
This saves the operator from logging into Percepxion to find port assignments manually.
This disambiguation drives every tool choice in this skill.
Proactive use is as important as reactive use. The Percepxion MCP is not a break-glass tool, it's the management plane for the OOB infrastructure at all times. Use it before incidents happen, not only during them.
| Trigger | OOB Role | Workflows / Tools |
|---------|----------|-------------------|
| Production network outage, device unreachable | Diagnose via SLC CLI, assess serial port state, capture evidence | W2 preflight + W3 diagnostics + W8 closed-loop |
| Maintenance window, fleet firmware update | Compliance scan + bulk upgrade via Smart Groups | W4: firmware_compliance_report, update_firmware_by_smart_group |
| Proactive compliance run | Config drift detection, template enforcement | W6: get_device_config, clone_device_config, list_templates |
| PagerDuty / Itential event fires | Closed-loop automated remediation with audit trail | W8 full flow |
| Security audit / access review | Who accessed what, when, from where | W5: investigate_audit_logs, get_security_telemetry |
| New site onboarding | Bulk device import and config clone | W7: import_and_assign_devices, clone_device_config |
| AI automation pre/post validation | Verify OOB path is healthy before and after primary-network changes | W2: get_device_details, list_device_ports or send_direct_cli_command |
If a user asks about fleet health, firmware currency, config drift, or access history, pull the relevant Percepxion data immediately. Do not wait for an incident to justify the query.
Never send CLI commands to a managed device or push firmware to an OOB device without explicit operator confirmation. send_direct_cli_command reaches live network infrastructure through a serial port, a wrong port number sends your command to the wrong managed device entirely. update_firmware_by_smart_group pushes firmware to OOB devices and is irreversible while in progress. All mutating actions require human confirmation before invocation.
Always call login_with_env first. Every session requires authentication. No other tool will succeed without an active session. This is not optional, and it applies to every credential provider, the tool authenticates via whichever backend PERCEPXION_CREDENTIAL_PROVIDER selects.
Read before you write. Call get_device_list or get_device_details to confirm the OOB device. Call get_security_telemetry (or get_port_telemetry for a single port) to confirm which port reaches the target managed device and verify it shows a connected managed device. list_device_ports returns port state only, it does not surface managed-device hostname, model, or serial. Never skip these steps.
This skill uses the percepxion-mcp-server, a Python/FastMCP server that wraps the Percepxion REST API.
Install:
git clone https://github.com/Lantronix/percepxion-mcp-server.git
cd percepxion-mcp-server
uv venv && uv pip install -r requirements.txt
Register in openclaw.json (stdio transport):
{
"percepxion": {
"type": "stdio",
"command": "uv",
"args": ["run", "--directory", "/path/to/percepxion-mcp-server", "python", "percepxion_mcp.py"],
"env": {
"PERCEPXION_USERNAME": "${PERCEPXION_USERNAME}",
"PERCEPXION_PASSWORD": "${PERCEPXION_PASSWORD}",
"PERCEPXION_API_URL": "${PERCEPXION_API_URL}"
}
}
}
Version requirement: this skill was written based on percepxion-mcp-server v1.1.0. If not at this version or later, update the server from the repository above, in particular get_cli_command_output (retrieve actual CLI output text) and role-aware organization_id enforcement (see Platform Security Configuration) were both added in v1.1.0 and this skill assumes they're present.
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| PERCEPXION_USERNAME | Yes, when PERCEPXION_CREDENTIAL_PROVIDER=env (the default) | | Percepxion login username. Not read by the vault, aws, or cyberark providers. |
| PERCEPXION_PASSWORD | Yes, when PERCEPXION_CREDENTIAL_PROVIDER=env (the default) | | Percepxion login password. Not read by the vault, aws, or cyberark providers. |
| PERCEPXION_API_URL | No | https://api.percepxion.ai/api | API base URL. Use https://api.gopercepxion.ai/api for the Lantronix internal sandbox. |
| PERCEPXION_CREDENTIAL_PROVIDER | No | env | Credential backend: env (default), vault, aws, or cyberark. With a non-env provider, set that provider's variables instead of username/password, see the provider table in Platform Security Configuration. |
| PERCEPXION_DEFAULT_ORGANIZATION_ID | No | | Default organization ID used when callers omit organization_id. Useful for single-organization deployments. Primary name; PERCEPXION_DEFAULT_TENANT_ID still works as a deprecated alias. |
| PERCEPXION_REQUEST_TIMEOUT | No | 45 | HTTP timeout in seconds. Raise to 120 or higher for large log downloads or slow links. |
| PERCEPXION_FIRMWARE_DIR | No | | If set, firmware uploads are restricted to files in this directory. Recommended for shared or automated deployments. |
Important: Use
https://api.percepxion.ai/api, notapi.gopercepxion.aiwhich is a sandbox environment unless explicitly instructed by the user. The wrong domain causes silent auth failures.
Note on the skill metadata: the
requires.enventry in this skill's frontmatter listsPERCEPXION_USERNAMEandPERCEPXION_PASSWORDbecauseenvis the default credential provider. A deployment usingvault,aws, orcyberarkconfigures that provider's variables on the MCP server process instead, and does not need those two set.
The slc-mcp-server is the direct-to-device companion to percepxion-mcp-server: a separate Python/FastMCP server that talks to a single SLC9000/SLC8000 console server over its REST API, with no cloud round-trip. Use it when the agent has network reach to the SLC's management IP and wants synchronous CLI output in one call (apply_config_commands) instead of the Percepxion job-then-fetch cycle. Workflow 3 as written runs entirely through Percepxion and needs only percepxion-mcp-server; slc-mcp-server is optional and adds device-level capabilities Percepxion doesn't expose.
Which server for which job (there is no capability overlap by design):
| Capability | slc-mcp-server (direct) | percepxion-mcp-server (fleet) |
|---|---|---|
| Serial port status/config | get_slc_port, get_slc_ports | list_device_ports |
| CLI commands, synchronous output in one call | apply_config_commands | - |
| CLI commands, async job + output fetch | - | send_direct_cli_command + get_cli_command_output |
| Firmware update | firmware_update, get_firmware_update_status | update_firmware_by_smart_group |
| Device config backup | export_config_commands | get_device_config |
| User/session management | get_sessions, terminate_session | - |
| Reboot | reboot_device | reboot_device (fleet) |
| Cellular status | get_cellular_status | - |
| Fleet-wide ops (smart groups, templates) | - | Yes |
| Audit logs | - | investigate_audit_logs |
Install:
git clone https://github.com/Lantronix/slc-mcp-server.git
cd slc-mcp-server
pip install -e .
pip install -e . pulls in all dependencies including pyotp, required for 2FA-enabled devices.
Register in openclaw.json (stdio transport):
{
"slc": {
"type": "stdio",
"command": "python3",
"args": ["/path/to/slc-mcp-server/run_server.py"],
"env": {
"SLC_DEFAULT_IP": "${SLC_DEFAULT_IP}",
"SLC_USERNAME": "${SLC_USERNAME}",
"SLC_PASSWORD": "${SLC_PASSWORD}"
}
}
}
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| SLC_DEFAULT_IP | No | | Default device IP, used when device_id isn't in the per-device registry |
| SLC_USERNAME | No | sysadmin | Default username |
| SLC_PASSWORD | No | | Default password |
| SLC_TOTP_SECRET | No | | Default TOTP secret for 2FA-enabled devices |
| SLC_{KEY}_IP / SLC_{KEY}_USERNAME / SLC_{KEY}_PASSWORD / SLC_{KEY}_TOTP_SECRET | No | | Per-device credentials, {KEY} is the device identifier uppercased with non-alphanumeric characters replaced by _ (e.g. device_id slc9000-dc-a becomes SLC_SLC9000_DC_A_IP) |
| SLC_VERIFY_SSL | No | true | Set to false only for lab devices with self-signed certificates. Never disable in production. |
| SLC_CREDENTIAL_PROVIDER | No | env | Credential backend: env (default), vault, aws, percepxion, or cyberark. The percepxion provider looks up device IP from the Percepxion device registry (requires PERCEPXION_API_URL/PERCEPXION_USERNAME/PERCEPXION_PASSWORD above) while SLC credentials still come from SLC_{KEY}_*. |
| SLC_CLI_WRITE_ENABLED | No | false | Allow write commands via apply_config_commands and px client tools |
| SLC_CLI_YOLO | No | false | Disable all CLI policy filtering. Never use in production. |
Read-only commands (show, diag, ping, traceroute, etc.) are always permitted regardless of SLC_CLI_WRITE_ENABLED. A built-in deny list (factory-reset, write erase, erase startup-config, erase flash, reload, reboot, format, shutdown, power off, reset system, init 0, halt) always blocks unless SLC_CLI_YOLO=true.
Every session starts here. You must authenticate before any other tool will succeed.
Tool: login_with_env
Parameters: {}
Returns a session token stored in memory for the server process lifetime. Confirm the response shows "ok": true before proceeding.
Despite the name, login_with_env authenticates via whichever backend PERCEPXION_CREDENTIAL_PROVIDER selects (env, vault, aws, or cyberark). No different tool call is needed for non-env providers; the server fetches credentials from the configured store and logs in the same way.
get_device_list returns OOB devices (the Lantronix console servers), not managed devices. All are optional parameters.
Tool: get_device_list
Parameters: {
"search_query": "*",
"limit": 25,
"sort": "device_name",
"order": "asc"
}
Returns all OOB console servers managed by your Percepxion account. Note device IDs, you'll need them for every subsequent tool call. Use search_query to filter by hostname or model.
If the account manages multiple customer organizations:
Tool: list_organizations
Parameters: {}
(list_tenants still works as a deprecated alias for list_organizations. organization_id is the primary parameter name across all tools; tenant_id still works everywhere as a deprecated alias.)
Then filter by organization:
Tool: get_devices_by_organization
Parameters: {
"organization_id": "org-abc123"
}
If the authenticated account is a Percepxion Project Admin, organization_id is required, not optional, on job/telemetry/content/Smart-Group/audit calls (send_direct_cli_command, get_cli_command_output, search_job_groups, get_job_group, update_device_config, reboot_device, request_device_syslog_upload, smart group and firmware tools, audit tools, and more). A Project Admin's access spans every organization in their project, so Percepxion can't infer a single default the way it does for Tenant Admin/Tenant User accounts (auto-scoped to their one organization, organization_id optional for those). Omitting it as a Project Admin raises a clear error naming the missing parameter (percepxion-mcp-server v1.1.0+); before that fix it surfaced as an opaque 400 ACCESS_DENIED: "Invalid access to tenant." Call list_organizations first if you don't already have the ID to pass. Device-inventory tools (get_device_list, get_device_details, list_device_ports) don't require it for any role. See Platform Security Configuration for the full rule.
Look up by device ID or serial number, at least one is required.
Tool: get_device_details
Parameters: {
"device_id": "device-abc123"
}
Or by serial number if device ID is unknown:
Tool: get_device_details
Parameters: {
"serial_num": "SLC9016-XXXXXX"
}
Returns hostname, firmware version, model, IP address, last check-in time, and status for the OOB device.
Before triggering automated remediation, maintenance tasks, or configuration changes, confirm the OOB device is reachable and the target serial port shows an active connection. A failed preflight stops you before committing to an operation on a dead or misidentified console path.
Tool: get_device_details
Parameters: {
"device_id": "device-abc123"
}
Check status is online and last check-in is recent. If the OOB device is offline, the serial path is unavailable. Stop and alert the operator.
list_device_ports returns port names, numbers, and connection state. get_security_telemetry returns full managed-device inventory per port (hostname, model, serial, IP, OS version). Use both: list_device_ports to enumerate ports and confirm connection state, get_security_telemetry (or get_port_telemetry for a single port) to confirm the right managed device is present on the target port. A list_device_ports result of total: 0 or an empty port status does not mean no managed devices are attached, the telemetry endpoint is authoritative for that question.
Tool: list_device_ports
Parameters: {
"device_id": "device-abc123",
"limit": 100
}
Confirm the port status shows connected. Then verify managed-device identity:
Tool: get_port_telemetry
Parameters: {
"device_id": "device-abc123",
"port_number": 4
}
Or for all ports at once:
Tool: get_security_telemetry
Parameters: {
"device_id": "device-abc123"
}
Confirm the target port's managed_device shows Managed Device Attached: Yes and the hostname or model matches the expected device. If the port shows no device in either tool, the serial cable may be unplugged or the managed device is powered off. Warn the operator and stop unless they explicitly override.
For richer per-port detail (carrier detect state, baud rate, bytes transferred), supplement with a CLI call:
Tool: send_direct_cli_command
Parameters: {
"device_id": "device-abc123",
"command": "show deviceport port 4",
"description": "W2 preflight, detailed port 4 inspection"
}
Poll get_job_group (or search_job_groups) with the returned job_group_id until status reaches "Completed", then call get_cli_command_output with that same job_group_id and device_id for the actual command output text. get_job_group alone returns status and metadata only, never the output text, see the Async Operations section below.
description field of all subsequent tool calls: "description": "Operator authorized: proceeding despite [reason]". This creates an auditable record. The operator's override cannot bypass server-side CLI policy (see Platform Security Configuration).Use send_direct_cli_command to run diagnostic commands on the SLC's own management CLI. This is how you assess port state, check SLC system health, and collect evidence before or during an incident. All commands target the SLC itself, not managed devices attached via serial.
What send_direct_cli_command does: Submits a command to the SLC's native Linux/management shell and returns a job group ID. The SLC executes the command and reports what it observes, including the state of each serial port (carrier detect, baud rate, bytes transferred). The device_id is always the OOB device (SLC) ID.
What it does NOT do: Pass commands through to managed devices (Cisco switch, Juniper router, Arista switch). Commands like show ip interface brief or show ip bgp summary are Cisco IOS syntax and will not work here. If the operator needs to reach a managed device CLI, the MCP can compute the direct SSH connection string (ssh -p <3000+N> <user>@<slc-ip>) using get_device_details and list_device_ports, see "When to ask for clarification" in the Key Terms section. For a fully interactive terminal session, SSH directly to the SLC (ssh admin@<slc-ip>) and use connect direct deviceport N from the SLC shell. That is a human-in-the-loop operation outside this MCP server's scope.
All send_direct_cli_command calls are asynchronous, and returning the actual output text is a two-step follow-up, not one. Poll status first, then fetch output:
Tool: get_job_group
Parameters: { "job_group_id": "<id from send_direct_cli_command response>" }
Once status reaches "Completed":
Tool: get_cli_command_output
Parameters: {
"job_group_id": "<same id>",
"device_id": "<same device_id>"
}
get_job_group alone never returns CLI output text, only job status and metadata (device, command string, timestamps). Calling get_cli_command_output before the job completes returns total_results: 0, not an error, retry after a short delay. (percepxion-mcp-server v1.1.0+; earlier versions had no working way to retrieve CLI output text via the API at all, only job status via MQTT.)
Tool: send_direct_cli_command
Parameters: {
"device_id": "device-abc123",
"command": "show sysstatus",
"description": "SLC health check, pre-incident diagnostics"
}
Tool: get_job_group
Parameters: {
"job_group_id": "<id from send_direct_cli_command response>"
}
Once "status": "Completed":
Tool: get_cli_command_output
Parameters: {
"job_group_id": "<id from send_direct_cli_command response>",
"device_id": "device-abc123"
}
Tool: send_direct_cli_command
Parameters: {
"device_id": "device-abc123",
"command": "show deviceport port 4",
"description": "Port 4 inspection, checking carrier detect and connection state"
}
Poll get_job_group for status, then get_cli_command_output (same job_group_id + device_id) for the actual text. Output includes: baud rate, carrier detect (yes/no), connection state, bytes sent/received since last session. A no carrier result means the attached device is powered off or the cable is disconnected.
Tool: send_direct_cli_command
Parameters: {
"device_id": "device-abc123",
"command": "show portstatus",
"description": "Full port survey, pre-maintenance audit"
}
Poll get_job_group for status, then get_cli_command_output for the actual text. Returns the mode and state of every device port. Useful for inventory checks and preflight before bulk operations.
Tool: send_direct_cli_command
Parameters: {
"device_id": "device-abc123",
"command": "diag ping 192.168.1.50",
"description": "Reachability test to managed device management IP from SLC local network"
}
Poll get_job_group for status, then get_cli_command_output for the actual text. Tests whether the managed device is reachable via its management IP from the SLC's network path. Confirms whether the failure is in-band (unreachable from the SLC too) or isolated to the production network.
After any diagnostic session, capture OOB device logs for the audit trail:
Tool: get_device_syslogs
Parameters: {
"device_id": "device-abc123"
}
Tool: query_device_access_log
Parameters: {
"device_id": "device-abc123",
"query": "session opened"
}
Use before maintenance windows, for quarterly compliance reviews, or when CVEs require a coordinated patch across the fleet.
Tool: get_device_firmware_status
Parameters: {
"device_id": "device-abc123"
}
expected_firmware_version is required. Use model_filter to scope to one device family.
Tool: firmware_compliance_report
Parameters: {
"expected_firmware_version": "9.7.0.0R11",
"model_filter": "SLC9000",
"limit": 1000
}
Returns compliant, non-compliant, and unknown devices for the OOB fleet against the specified version.
Tool: list_firmware_content
Parameters: {}
Returns firmware packages available in Percepxion for your OOB device models (SLC9000, SLC8000, EMG).
Use a query filter string OR an explicit device_ids list, not both. Use temporary: true for one-off operations.
Tool: create_smart_group
Parameters: {
"name": "slc9000-non-compliant-q2",
"query": "firmware_ver:9.7.0.0R7 AND model:SLC9000",
"description": "Non-compliant SLC9000s for Q2 patch cycle",
"temporary": true
}
Returns a smart group ID. Smart groups re-evaluate membership at execution time.
Present: smart group name, member count, current firmware versions, target firmware version, and the local firmware file path that will be uploaded. Wait for explicit confirmation.
update_firmware_by_smart_group uploads a local firmware file to Percepxion and targets one or more smart groups. You must have the firmware file on disk before calling this. smart_group_ids is an array.
Tool: update_firmware_by_smart_group
Parameters: {
"firmware_file_path": "/path/to/SLC9000-9.7.0.0R11.bin",
"smart_group_ids": ["sg-abc123"],
"content_name": "SLC9000-9.7.0.0R11",
"version": "9.7.0.0R11",
"description": "Q2 compliance patch, operator authorized",
"enable": true
}
This is asynchronous and maps to a multipart/form-data upload. Returns a job group ID immediately.
Tool: get_job_group
Parameters: {
"job_group_id": "jg-xyz789"
}
Or search recent jobs:
Tool: search_job_groups
Parameters: {
"query": "firmware update",
"limit": 10
}
Poll until status is completed or failed. On failed, surface the error reason to the operator.
For a per-device breakdown across the Smart Group (which devices succeeded, which failed) rather than just the overall job status, use get_job_results_by_device(job_group_id) instead of, or alongside, get_job_group.
Tool: delete_smart_group
Parameters: {
"smart_group_id": "sg-abc123"
}
Use for post-incident access reviews, compliance audits, or when a security team needs to reconstruct who accessed which OOB devices during a specific window.
device_id is required, this is scoped to one OOB device, not fleet-wide.
Tool: get_security_telemetry
Parameters: {
"device_id": "device-abc123",
"selected": true
}
Returns telemetry statistics useful for security analysis on that OOB device.
investigate_audit_logs has no device_id parameter. Filter by device using search_string. Date parameters are from_date and to_date, not start_time/end_time. If dates are omitted, the default range is effectively all history.
Tool: investigate_audit_logs
Parameters: {
"search_string": "device-abc123",
"from_date": "2026-06-01",
"to_date": "2026-06-02",
"limit": 50,
"order": "desc"
}
To filter by specific users, pass a list to usernames:
Tool: investigate_audit_logs
Parameters: {
"usernames": ["[email protected]", "[email protected]"],
"from_date": "2026-06-01",
"to_date": "2026-06-02",
"limit": 50
}
investigate_user_audit_logs returns user records with last audit action summaries. Filter with user_filter string, there are no date range parameters on this tool.
Tool: investigate_user_audit_logs
Parameters: {
"user_filter": "[email protected]",
"limit": 50,
"order": "asc"
}
For SIEM ingestion or evidence preservation:
Tool: download_device_access_log
Parameters: {
"device_id": "device-abc123"
}
Tool: query_device_access_log
Parameters: {
"device_id": "device-abc123",
"query": "session opened port 8"
}
Use for baseline config distribution, config audit, or onboarding new OOB devices (console servers) with a standard configuration. All tools in this workflow operate on the OOB device, not on managed devices attached to it.
Tool: get_device_config
Parameters: {
"device_id": "device-abc123"
}
Requires operator confirmation. Present the proposed change before applying.
Use either property_name + new_value for a single change, or items for multiple changes at once. apply_now: true (default) saves and immediately creates a config pull job.
Tool: update_device_config
Parameters: {
"device_id": "device-abc123",
"property_name": "syslog_server",
"new_value": "192.168.1.100",
"apply_now": true
}
Multiple changes at once using items:
Tool: update_device_config
Parameters: {
"device_id": "device-abc123",
"items": [
{"name": "hostname", "value": "slc9000-chicago-01"},
{"name": "banner", "value": "Authorized access only. All sessions are logged."}
],
"apply_now": true
}
record_names is required, it specifies which config record names to copy from the source. Read the source config first with get_device_config to identify the record names.
get_device_config on the baseline devicerecord_names from the responseTool: clone_device_config
Parameters: {
"source_device_id": "device-abc123",
"target_device_id": "device-def456",
"record_names": ["network", "services", "authentication"],
"template_name": "Chicago-Baseline-v2"
}
Tool: list_templates
Parameters: {}
For onboarding new Lantronix hardware into Percepxion, offboarding decommissioned OOB devices, or rotating the credentials Percepxion uses to authenticate to each OOB device.
Tool: import_and_assign_devices
Parameters: {
"devices": [
{"device_id": "device-new-001", "device_name": "slc9000-chicago-02", "serial_num": "SLC9016-XXXXXX"},
{"device_id": "device-new-002", "device_name": "slc9000-chicago-03", "serial_num": "SLC9016-YYYYYY"}
],
"organization_id": "org-abc123"
}
Each entry in devices must include device_id, device_name, and serial_num. A fourth optional field device_descriptioncan be used for additional context. organization_id is required here for Project Admin sessions, see Platform Security Configuration.
Requires operator confirmation. A reboot of the OOB device causes a brief loss of serial console access to all managed devices on its ports. Confirm the maintenance window is acceptable.
get_device_detailsTool: reboot_device
Parameters: {
"device_id": "device-abc123",
"description": "Scheduled reboot, maintenance window approved by operator"
}
Irreversible. Confirm before executing.
Tool: remove_device_from_platform
Parameters: {
"device_id": "device-abc123"
}
Or unassign from a tenant without removing from the platform:
Tool: unassign_devices
Parameters: {
"device_ids": ["device-abc123"]
}
Request the OOB device to upload its current syslog buffer for retrieval:
Tool: request_device_syslog_upload
Parameters: {
"device_id": "device-abc123"
}
Trigger: An upstream orchestrator (PagerDuty, Itential FlowAI, monitoring webhook) signals that a device is unreachable via the primary network. This workflow gives the orchestrator a complete OOB response: diagnostic evidence, optional remediation, and a traceable audit trail to close the incident ticket.
Write access prerequisite: Steps 7-8 (remediation commands) require PERCEPXION_CLI_WRITE_ENABLED=true on the MCP server. Steps 1-6 and 9 are read-only and always available.
Tool: login_with_env
Parameters: {}
Skip if already authenticated in this session.
Tool: get_device_list
Parameters: {
"search_query": "<site-name or managed-device-name>"
}
Returns the Lantronix OOB device (SLC console server) managing the affected infrastructure at that site.
Tool: get_device_details
Parameters: {
"device_id": "<oob_device_id>"
}
Critical branch: If the OOB device itself is unreachable (online: false), OOB access is unavailable. Stop and escalate to a human. Do not proceed.
Run Workflow 2 to confirm the managed device is connected at the serial layer. Check show deviceport port <N> via send_direct_cli_command for carrier detect and connection state.
If the port shows no carrier or a disconnected state, log this as a finding in the incident record and decide with the operator whether to continue.
Tool: get_device_syslogs
Parameters: {
"device_id": "<oob_device_id>"
}
Captures the OOB device syslog before any action. This is the before-state evidence.
Tool: send_direct_cli_command
Parameters: {
"device_id": "<oob_device_id>",
"command": "show sysstatus",
"description": "Automated incident response, incident-id: <upstream-incident-id>, diagnostics phase"
}
Run SLC-native diagnostics as needed (show sysstatus, show deviceport port <N>, diag ping <ip>). Always include the upstream incident ID in the description field. Poll get_job_group for status, then call get_cli_command_output with the same job_group_id and device_id for the actual diagnostic text, that's what goes into the incident record, get_job_group alone has no output.
Only if PERCEPXION_CLI_WRITE_ENABLED=true. Present the proposed command to the operator or upstream orchestrator before executing.
Tool: send_direct_cli_command
Parameters: {
"device_id": "<oob_device_id>",
"command": "<recovery-command>",
"description": "Automated remediation, incident-id: <upstream-incident-id>, approved by: <orchestrator-or-operator>"
}
Confirm status via get_job_group, then confirm actual output via get_cli_command_output with the same job_group_id and device_id. Do not report remediation as successful based on job status alone, verify the device's own response text.
Tool: investigate_audit_logs
Parameters: {
"search_string": "<oob-device-name-or-ip>"
}
Confirms the OOB action is in Percepxion's audit trail. Include the audit log excerpt in the incident closure report.
Return a structured outcome to the calling system (Itential, PagerDuty, ServiceNow):
remediated, diagnosed-only, or escalate-to-humanAI-initiated OOB access carries the same audit trail as human access. The description field on every send_direct_cli_command call is the machine's justification. Treat it like a change ticket number. Percepxion logs who authenticated, what commands ran, and when, regardless of whether a human or an AI agent initiated the session.
login_with_env supports four credential backends, selected by the PERCEPXION_CREDENTIAL_PROVIDER environment variable on the server:
| Provider | Env var to set | When to use |
|----------|---------------|-------------|
| env (default) | PERCEPXION_USERNAME + PERCEPXION_PASSWORD | Dev, local testing, simple deployments |
| vault | VAULT_ADDR, VAULT_TOKEN, VAULT_SECRET_PATH | Production, HashiCorp Vault for secret management |
| aws | AWS_SECRET_NAME, AWS_REGION | Production, AWS Secrets Manager |
| cyberark | CYBERARK_URL, CYBERARK_APP_ID, CYBERARK_SAFE, CYBERARK_OBJECT | Enterprise deployments already running CyberArk Central Credential Provider (CCP) |
To switch providers at runtime, use reconfigure_credentials then re-authenticate:
Tool: reconfigure_credentials
Parameters: {
"provider": "vault"
}
Valid values: "env", "vault", "aws", "cyberark". After calling this, always follow with login_with_env to re-authenticate with the new provider. This is NOT per-device credential rotation, it changes which secret store the MCP server itself uses for its Percepxion session credentials.
organization_id Requirement (v1.1.0+)Percepxion's RBAC model has three roles, and their organization_id/tenant_id requirements differ:
| Role | Scope | organization_id on job/telemetry/content/Smart-Group/audit calls |
|------|-------|----------------------------------------------------------------|
| Tenant User | One or more specific organizations, explicitly group-granted | Optional, auto-scoped |
| Tenant Admin | One organization | Optional, auto-scoped |
| Project Admin | Every organization in their project | Required |
A Project Admin's access spans an entire Percepxion project (Percepxion's hierarchy is Project > Portal > Organization), and there's no API endpoint that enumerates a project's member organizations, so the server can't infer a single default the way it does for the other two roles. Omitting organization_id as a Project Admin now raises a clear error naming the missing parameter; before percepxion-mcp-server v1.1.0 this surfaced as an opaque 400 ACCESS_DENIED: "Invalid access to tenant." with no indication why. If a call fails with either error, check the authenticated account's role before assuming a bug, call list_organizations to find the ID to pass. Device-inventory tools (get_device_list, get_device_details, list_device_ports) don't require it for any role.
send_direct_cli_command enforces server-side CLI policy. These are environment variables set on the MCP server, not parameters in the tool call. The AI cannot override these policies at runtime, they must be configured by whoever starts the server.
| Env var | Default | Effect |
|---------|---------|--------|
| PERCEPXION_CLI_WRITE_ENABLED | false | true enables write commands. Read-only (show, get, ping, traceroute) is the default. |
| PERCEPXION_CLI_MAX_LENGTH | 512 | Maximum command length in characters. Automated workflows that build long commands will hit this silently. |
| PERCEPXION_CLI_DENY_COMMANDS | built-in list | Comma-separated commands to block in addition to the built-in deny list |
| PERCEPXION_CLI_PERMIT_COMMANDS | unset | Comma-separated explicit allowlist; if set, only these commands (and their subcommands) are allowed |
| PERCEPXION_CLI_YOLO | false | true disables ALL filtering including the deny list. Use with extreme caution. |
Built-in deny list (always blocked unless YOLO mode): reload, factory-reset, write erase, and similar destructive commands.
Operator override pattern: If an operator explicitly accepts risk and needs to run a write command or a normally-blocked command:
PERCEPXION_CLI_WRITE_ENABLED=true (or PERCEPXION_CLI_YOLO=true for full bypass)description field of every send_direct_cli_command call: "description": "Write access enabled, operator authorized: [reason]"User and device access permissions are configured in the Percepxion UI, not via this MCP server. A send_direct_cli_command failure with a permissions error means RBAC on the platform needs updating, there is nothing to change in the MCP call itself.
Percepxion also supports per-port CLI command filtering configured in the platform UI (separate from the MCP server's CLI policy). If a command is allowed by the MCP server policy but blocked by Percepxion's own filtering, surface the error to the operator and advise reviewing the platform's command filter for that port.
All MCP-initiated sessions are fully logged in Percepxion's audit trail: who authenticated, which commands ran, job group IDs, and session duration. Retrieve via investigate_audit_logs.
The following tools are asynchronous, they return a job group ID immediately and continue in the background:
update_firmware_by_smart_grouprequest_device_syslog_uploadreboot_devicesend_direct_cli_command (always async, not conditional on firmware build)Always follow async calls with:
Tool: get_job_group
Parameters: { "job_group_id": "<id returned by the async call>" }
Poll until status is "Completed" or "Failed". On failure, surface the full error reason to the operator before suggesting next steps.
get_job_group and search_job_groups never return CLI output text, only status and job metadata (device, command string, timestamps). For send_direct_cli_command jobs specifically, once status reaches "Completed", call get_cli_command_output(job_group_id, device_id) for the actual device response text (percepxion-mcp-server v1.1.0+). For a multi-device job (e.g. a Smart Group firmware push or a CLI command sent to several devices at once), get_job_results_by_device(job_group_id) returns a per-device result rollup instead of one device at a time.
description value in every send_direct_cli_command call to create a traceable link between the automation record and the OOB action in Percepxion's audit logTerminology
device_id in all MCP tool calls is the OOB device ID from get_device_list. This is always the Lantronix SLC or EMG, never the managed device (router/switch/firewall) attached to it.Authentication
login_with_env at the start of every session. No other tool works without it.PERCEPXION_USERNAME, PERCEPXION_PASSWORD, VAULT_TOKEN, or session tokens in logs, chat output, or error messages.https://api.percepxion.ai/api as the API URL. api.gopercepxion.ai causes silent auth failures unless the operator has confirmed their instance uses that domain.Preflight before automation
description field of every subsequent tool call.SLC CLI scope
send_direct_cli_command sends commands to the SLC's own management CLI (Linux/management shell), not to managed devices. Valid commands are SLC-native: show sysstatus, show deviceport port <N>, show portstatus, diag ping <ip>, admin version, etc.send_direct_cli_command + get_cli_command_output. The MCP can compute the direct SSH connection string (ssh -p <3000+N> <user>@<slc-ip>), see "When to ask for clarification" in the Key Terms section. For a fully interactive terminal session, direct SSH to the SLC followed by connect direct deviceport <N> from the SLC shell is required. That is a human-in-the-loop operation outside MCP scope.send_direct_cli_command is asynchronous. Poll get_job_group (or search_job_groups) for status, then call get_cli_command_output with the same job_group_id + device_id for the actual output text, get_job_group alone never returns it.organization_id is required (not optional) on send_direct_cli_command, get_cli_command_output, and most other job/telemetry/content/audit tools, see Workflow 1 Step 3 and Platform Security Configuration.PERCEPXION_CLI_WRITE_ENABLED=false). Write commands require server reconfiguration. The AI cannot bypass CLI policy at runtime.Firmware updates (OOB devices)
update_firmware_by_smart_group requires a local firmware file (firmware_file_path) and targets smart_group_ids (array). Confirm the file path, group membership count, and target version before calling.get_job_group or search_job_groups.Credential provider
reconfigure_credentials switches the MCP server's credential provider (env, vault, aws), it does NOT rotate per-device passwords. Always follow it with login_with_env to re-authenticate.Destructive lifecycle operations
remove_device_from_platform and reboot_device, require the operator to confirm the OOB device hostname before executing.reboot_device causes temporary loss of serial console access to all managed devices on the OOB device's ports.Async tracking
send_direct_cli_command, update_firmware_by_smart_group, reboot_device, and request_device_syslog_upload are all asynchronous. Never leave a job untracked, always poll to completed or failed and report the final status.Proactive use
firmware_compliance_report and get_device_config across the fleet without waiting for a problem to surface.Automation pipeline preflight (when OOB coverage exists)
get_device_list for the target device hostname or IP. If no OOB device is found, proceed normally, absent OOB coverage is expected and not a blocker. If an OOB device is found, run W2 preflight. A known OOB path that is unreachable is worth flagging before committing the change; an OOB path that simply doesn't exist is not.Evidence always (W8 and any automated remediation)
get_device_syslogs before and investigate_audit_logs after. This evidence is non-negotiable for compliance and incident closure. Do not skip these steps even if the remediation command fails.tools
Zoom meeting intelligence — correlates a live or referenced Zoom meeting discussion against NetClaw's historical meeting record (via the official Zoom Meetings MCP) and today's actual network state. Use when someone in a Zoom meeting references a past discussion or incident ('didn't we have this issue before?'), or asks to search prior meetings for a topic. Does not itself recognize live in-meeting questions — that happens automatically inside zoom-rtms-mcp's own extractor (spec 118) before this skill is ever invoked.
tools
Federate your NetClaw with other NetClaw operators over the BGP mesh — exchange capability inventories and ask your claw what a peer can do. (US1; remote invocation and chat land in later phases.)
tools
Track token consumption, enforce session budgets, and display cost for every NetClaw interaction.
tools
Review current and historical problems from Zabbix — severity, which host, when it started, how long it has been active, and whether anyone has acknowledged it. Use when someone asks what is broken right now, how long something has been broken, or what happened during a window that has already passed.