Skip to main content
Glama
netmiko-mcp-linksys

netmiko-mcp-linksys

by WackEarl

netmiko-mcp-linksys

stdio MCP server for a single Linksys LGS-series switch (developed against the LGS328PC CLI).

This project is based on netmiko and netmiko-mcp. The show tool reuses netmiko-mcp's command filter (netmiko_mcp.security.validate_command) and the same allow/deny list format (commands.yml). Configuration tools send only fixed command sequences built by this wrapper; the model never supplies free-form config.

This is 0.1.0. Validation and sequence building are covered by offline tests. A live SSH test against a switch has not been run yet. See Untested assumptions.

Install and run

The intended way to run this server is the packaged entrypoint, pinned to a tag:

uvx --from git+https://github.com/WackEarl/netmiko-mcp-linksys@v0.1.0 netmiko-mcp-linksys

From a local checkout:

uvx --from /path/to/netmiko-mcp-linksys netmiko-mcp-linksys

The process speaks MCP over stdio. It does not open an SSH session at startup; a connection is made only when a tool is called.

paramiko==4.0.0 is intentional. The target switch speaks ssh-rsa with SHA-1; paramiko 5.x rejects that host-key algorithm.

A compatibility shim, lgs_mcp.py, exists only for the older hub invocation python /config/netmiko/lgs_mcp.py. That file is not a standalone implementation: it imports netmiko_mcp_linksys. Prefer the uvx --from ... netmiko-mcp-linksys entry above. If you must keep the old command, add --with git+https://github.com/WackEarl/netmiko-mcp-linksys@v0.1.0 so the package is installed in that environment.

Related MCP server: cisco-mcp

Environment variables

Variable

Required

Description

SWITCH_HOST

yes (at tool call)

Switch IP or hostname.

SWITCH_USER

yes (at tool call)

SSH username.

SWITCH_PASSWORD

yes (at tool call)

SSH password. Never logged or returned.

SWITCH_DEVICE_TYPE

no

netmiko device type. Default: cisco_s300.

SWITCH_KNOWN_HOSTS

yes (at tool call)

Path to an OpenSSH known_hosts file with the switch host key. System host keys are not used.

SWITCH_PROTECTED_PORTS

yes before any disable / PoE-off

Comma-separated ports (e.g. 0/24,0/25) that may not be shut down or have PoE disabled. If this variable is unset, empty, or contains an invalid port, disable and PoE-off fail closed (every port is refused). Enabling a port is still allowed.

NETMIKO_MCP_COMMAND_FILE

yes for show and port_overview

Path to a commands.yml allow/deny list. See examples/commands.yml. Restart the server after edits (lru_cache).

SWITCH_AUDIT_LOG

no

If set, append one JSON line per tool call. The file is created with mode 0600. Passwords are redacted from parameters and results.

Python 3.12 or newer is required.

mcp-hub entry snippet

Secrets stay in hub template variables. save_config is gated by the hub unlock feature (0.12+); maxMinutes: 0 means every call needs a fresh approval. Fill SWITCH_PROTECTED_PORTS after the first read test — until it is set to a valid list, disable and PoE-off are refused.

{
  "switch": {
    "command": "uvx",
    "args": [
      "--python", "3.12",
      "--from", "git+https://github.com/WackEarl/netmiko-mcp-linksys@v0.1.0",
      "netmiko-mcp-linksys"
    ],
    "env": {
      "SWITCH_HOST": "192.0.2.10",
      "SWITCH_USER": "${SWITCH_USER}",
      "SWITCH_PASSWORD": "${SWITCH_PASSWORD}",
      "SWITCH_DEVICE_TYPE": "cisco_s300",
      "SWITCH_KNOWN_HOSTS": "/config/netmiko/known_hosts",
      "SWITCH_PROTECTED_PORTS": "<uplink and management ports, e.g. 0/24>",
      "NETMIKO_MCP_COMMAND_FILE": "/config/netmiko/commands.yml",
      "SWITCH_AUDIT_LOG": "/data/netmiko/audit.log",
      "UV_CACHE_DIR": "/data/uv-cache",
      "UV_PYTHON_INSTALL_DIR": "/data/uv-python",
      "UV_TOOL_DIR": "/data/uv-tools",
      "PATH": "/usr/local/bin:/usr/bin:/bin",
      "HOME": "/home/node"
    },
    "unlock": { "tools": ["save_config"], "maxMinutes": 0 }
  }
}

Copy examples/commands.yml to NETMIKO_MCP_COMMAND_FILE. Create SWITCH_KNOWN_HOSTS yourself from a verified host key; do not use examples/known_hosts as-is (it is a placeholder, not a real key).

Tools

Tool

Effect

Saved?

show(command)

Allow-listed show command via netmiko_mcp.security.validate_command, then send_command. Pipe, semicolon, and newlines are rejected. Deny wins.

n/a

port_overview()

Read-only bundle of show system information, show vlan, show power inline, and show interfaces, each passed through the same command filter.

n/a

port_set_admin_state(port, enabled)

interface gigabitethernet 0/N then no shutdown / shutdown.

no

poe_set(port, enabled)

interface gigabitethernet 0/N then power inline enable / power inline disable. PoE ports: 0/1–0/24.

no

port_set_description(port, text?)

description <text> or no description when text is omitted.

no

save_config()

Privileged exec save only. Gate this in the hub with unlock.

yes

There are no VLAN, reboot, or reset tools.

Port format: 0/1 … 0/28 (no leading zeros). PoE: 0/1 … 0/24. Descriptions: 1–32 characters from [A-Za-z0-9 ._-].

Security model

  • Default deny for show. Only commands listed in allowed_commands run; denied_commands always wins. The allow list does not expand abbreviations (sh ver is not show version). See the netmiko-mcp 0.3.0 validator docs. The wrapper also rejects |, ;, and newlines before that filter runs (allow_pipe is not honoured).

  • No free-form config. Interface commands are built only by this package.

  • No VLAN, reboot, or reset tools.

  • Protected ports, fail-closed. SWITCH_PROTECTED_PORTS blocks port_set_admin_state(enabled=False) and poe_set(enabled=False) on those ports. Enabling is still allowed. If the variable is unset, empty, or contains an invalid port identifier, every disable / PoE-off is refused.

  • Host-key pinning. ssh_strict=True, system_host_keys=False, use_keys=False, allow_agent=False, key file from SWITCH_KNOWN_HOSTS.

  • No connection at startup. Missing or dummy environment is enough for initialize and tools/list.

  • One session per tool call, serialized with a process-wide lock.

  • No automatic save. Running-config changes die on reboot until save_config. In the hub, save_config must be gated by unlock.

  • Audit log records time, tool, parameters, allow/deny, and a short result. Passwords are redacted from parameters, results, and error text.

  • paramiko 4.0.0 for ssh-rsa/SHA-1 host keys. Do not bump to 5.x without a live SSH check.

Untested assumptions

These need a live test on the real switch before relying on the config tools:

  • netmiko cisco_s300 prompt handling, paging, and fast_cli=False against this firmware.

  • Whether the login user is already in privileged exec, or an enable secret is required (SWITCH_ENABLE is not implemented).

  • send_config_set(..., exit_config_mode=True, cmd_verify=True) and the configure terminal / end dance the cisco_s300 driver uses.

  • Read-back commands show interfaces gigabitethernet 0/N and show power inline gigabitethernet 0/N (syntax and useful fields).

  • Device error text actually contains %, Invalid, or Error (the rejection heuristic).

  • save as a single privileged exec command, and its output.

  • 28 ports and PoE on 0/1–0/24 (true for LGS328PC; other LGS models differ).

  • paramiko 4.0.0 still negotiates ssh-rsa/SHA-1 with this switch.

  • Timing, SSH banners, and the first-login prompt.

  • Hub unlock behaviour for save_config.

Development

uv sync --extra dev
uv run --extra dev pytest

Pinned runtime dependencies: netmiko==4.8.0, paramiko==4.0.0, netmiko-mcp==0.3.0, mcp==2.3.0.

Available Tools

6 tools
poe_setA

Enable or disable PoE on a copper port (0/1..0/24). Does not save.

Inputs: port (required), enabled (required). Returns: result

port_overviewA

Read a bundle of allow-listed status commands in one session each.

Read-only: runs only the hardcoded show commands through the same netmiko-mcp command filter as the show tool. Never sends config.

Inputs: no named parameters. Returns: result

port_set_admin_stateA

Enable or disable a switch port (no shutdown / shutdown). Does not save.

Inputs: port (required), enabled (required). Returns: result

port_set_descriptionA

Set an interface description, or clear it when text is omitted. Does not save.

Inputs: port (required), text. Returns: result

save_configA

Copy running-config to startup-config by sending the privileged exec command 'save'.

Inputs: no named parameters. Returns: result

showA

Run an allow-listed show command on the switch (no TextFSM parsing).

Inputs: command (required). Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 6 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes: show, port_overview, port_set_admin_state, poe_set, port_set_description, and save_config target different actions. The only mild overlap is between show and port_overview, both read-only visibility tools, but the descriptions clarify single-command versus bundled status behavior.

    Naming Consistency3/5

    All names use snake_case, but the ordering conventions are mixed: bare verb (show), noun-first (port_overview, port_set_admin_state, poe_set, port_set_description), and verb-first (save_config). The names remain readable, but the pattern is not predictable across the set.

    Tool Count5/5

    Six tools is well-scoped for a focused switch-control server. Each tool appears to earn its place: visibility, port overview, port admin state, PoE control, description management, and saving configuration.

    Completeness3/5

    The server covers read-only inspection plus basic port admin state, PoE, descriptions, and config saving. However, common switch-management operations such as VLAN assignment, speed/duplex settings, and broader configuration retrieval are not represented, leaving notable gaps.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables SSH interactive session management through MCP, supporting commands, menus, and session lifecycle operations.
      1
      -
    • F
      license
      A
      quality
      D
      maintenance
      Enables LLMs to run read-only show commands on Cisco IOS/IOS-XE and Nexus switches over SSH, with a two-account model for privilege separation and a fail-closed allowlist for safety.
      25
      -
    • F
      license
      Not graded
      quality
      C
      maintenance
      Enables MCP-capable AI agents to observe, troubleshoot, and configure Aruba CX (AOS-CX) switches through REST and SSH, with safety controls, inventory management, and verification workflows.
      -
    • A
      license
      A
      quality
      B
      maintenance
      Enables MCP agents to run RouterOS commands on MikroTik routers over SSH, with configurable profiles, secure authentication, and a read-only safety guard.
      3
      24 npm
      MIT