OpenWRT-MCP Server

Secure MCP (Model Context Protocol) server for OpenWRT router management and diagnostics

Documentation

OpenWRT-MCP

CI Docker Python 3.14+ License: MIT

Read-only MCP (Model Context Protocol) server for OpenWRT router management and diagnostics. Enables AI assistants (Claude Desktop, LibreChat, Cline) to observe and analyze an OpenWRT router without any write access.

Requirements

  • Python 3.14+ (for local use) or Docker
  • OpenWRT router with SSH enabled (Dropbear or OpenSSH)
  • SSH key pair for authentication

Quick Start

1. Generate SSH Key

ssh-keygen -t ed25519 -f openwrt_id_ed25519 -C "openwrt-mcp"
ssh-copy-id -i openwrt_id_ed25519.pub [email protected]

2. Configure

cp .env.example .env
# Edit .env with your OPENWRT_HOST and SSH key path

3. Run with Docker

Option A — with docker compose:

# After editing .env, for Docker add MCP_UNSAFE_PUBLIC_ACCESS_CONFIRMED=1 to .env
docker compose up -d

Option B — with plain docker run:

docker run -d \
  --name openwrt-mcp \
  -p 9094:9094 \
  -p 9095:9095 \
  -p 9096:9096 \
  -e OPENWRT_HOST=192.168.0.1 \
  -e OPENWRT_SSH_KEY=/app/keys/openwrt_id_ed25519 \
  -e MCP_UNSAFE_PUBLIC_ACCESS_CONFIRMED=1 \
  -v $(pwd)/keys:/app/keys:ro \
  ghcr.io/paulomac1000/openwrt-mcp:latest

Building locally:

git clone https://github.com/paulomac1000/openwrt-mcp.git
cd openwrt-mcp
docker build -t openwrt-mcp .
# Then run with the same docker run command above

4. Run locally (Python 3.14+)

pip install -e ".[dev]"
OPENWRT_HOST=192.168.0.1 OPENWRT_SSH_KEY=/path/to/key openwrt-mcp

Ports

PortProtocolPurposeEndpoint
9094HTTPHealth checkGET /health
9095SSEMCP transport (SSE)/sse, /messages
9096HTTPREST API/api/*

Verify

# Health check
curl http://localhost:9094/health

# List all MCP tools
curl http://localhost:9096/api/tools

# Call a tool
curl -X POST http://localhost:9096/api/tools/get_router_info \
  -H "Content-Type: application/json" \
  -d '{}'

# Get tool manifest
curl http://localhost:9096/api/tools/get_router_info/manifest

Available Tools (24)

Tools are categorized by risk level: [READ] tools are safe — they query the router with no side effects. [WRITE] tools can modify router state and require ENABLE_WRITE_OPERATIONS=1 in .env. [DESTRUCTIVE] tools are irreversible (reboot) and require explicit confirmation.

CategoryToolRiskDescription
Connectiontest_router_connectionREADVerify SSH connectivity
Systemget_router_infoREADBoard info, memory, uptime, release
get_router_contextREADUnified context snapshot (system, wifi, DHCP, health)
describe_router_capabilitiesREADServer introspection — tools, manifests, collectors
Networkget_router_wifi_statusREADWiFi radios, SSIDs, connected clients
get_router_dhcp_leasesREADActive DHCP leases
diagnose_router_connectivityREADPing, DNS, and gateway tests
ping_hostREADPing a specific host
traceroute_hostREADTraceroute to a host
nslookup_hostREADDNS lookup from the router
wifi_scanREADScan neighboring WiFi networks
Securityget_router_firewall_rulesREADiptables / nftables / fw4 rules
read_router_uci_configREADRead UCI configuration sections
Diagnosticsget_router_logsREADRecent system logs
search_router_logsREADFiltered log search
Packageslist_router_packagesREADInstalled OPKG packages
DHCPget_dhcp_static_leasesREADStatic DHCP reservations
search_dhcp_logsREADSearch DHCP events in logs
get_device_dhcp_detailsREADFull device info (lease, reservation, logs)
Writeuci_setWRITESet a UCI configuration value
uci_commitWRITECommit UCI changes permanently
restart_interfaceWRITERestart a network interface
reload_networkWRITEReload network services
reboot_deviceDESTRUCTIVEReboot the router (irreversible)

Configuration

All configuration is via environment variables. See .env.example for a complete template.

Required

VariableDescriptionExample
OPENWRT_HOSTRouter IP address192.168.0.1
OPENWRT_SSH_KEYPath to SSH private key/app/keys/openwrt_id_ed25519

Optional

VariableDefaultDescription
OPENWRT_PORT22SSH port
OPENWRT_USERrootSSH username
MCP_SSE_PORT9095MCP SSE transport port
REST_API_PORT9096REST API port
HEALTH_PORT9094Health check port
SSH_TIMEOUT30SSH connection timeout (seconds)
MCP_UNSAFE_PUBLIC_ACCESS_CONFIRMEDSet to 1 for Docker port forwarding
ENABLE_WRITE_OPERATIONSfalseSet to 1 to enable write tools (uci_set, reboot, and others)
OPENWRT_PASSWORDNoneSSH password (not recommended — use SSH keys)
ENABLE_AUDIT_LOGGINGtrueLog all executed commands
AUDIT_LOG_FILE/app/log/openwrt_mcp.logAudit log path
LOG_LEVELINFOLogging level
OPENWRT_KNOWN_HOSTSPath to SSH known_hosts file for host key verification

Security Model

  • Read-only by default — All SSH commands are whitelisted; write operations (uci set, ifdown, ubus reboot) require ENABLE_WRITE_OPERATIONS=1
  • Command whitelist — Explicit read-only patterns (ubus call, uci show, cat /proc/*, logread, ping, and others)
  • Write command whitelist — Separate execute_write() path for write operations (ifdown, ifup, uci set/commit, /etc/init.d/network, ubus reboot)
  • Blocked patternsrm, reboot, wget, curl, uci set (in read path), shell metacharacters (;, |, &&, $, and others)
  • Key-based authentication — Password login discouraged
  • SSH host key verification — Optional via OPENWRT_KNOWN_HOSTS (set to path of known_hosts file)
  • Audit logging — All commands logged with timestamps for accountability
  • Localhost binding — All ports bind to 127.0.0.1 by default; set MCP_UNSAFE_PUBLIC_ACCESS_CONFIRMED=1 for Docker

Standards Compliance

This server follows two AI-First standards:

StandardDocumentVersionDescription
AFDSdocs_standards.mdv1.0Documentation structure, frontmatter schema, controlled language
MCP Coremcp-server-standards.mdv1.1.0Tool design, response contracts, testing hierarchy, security

Compliance level: L3-ready (all L1-L3 rules met; Risk Consistency Matrix enforced by automated tests).

Testing

pip install -e ".[dev]"
pytest tests/unit/ tests/integration/ -q       # 268 tests (requires .env for integration)
pytest tests/unit/ --cov=openwrt_mcp -q         # 80%+ coverage
ruff check . && ruff format --check .           # lint
mypy src/openwrt_mcp/ --strict                  # type check
bandit -r src/openwrt_mcp/ -ll                  # security

Quick Reference

MetricValue
Python3.14+ (Docker: 3.14)
Tools24 (19 READ + 4 WRITE + 1 DESTRUCTIVE)
Tests296 (215 unit + 53 integration + 10 smoke + 18 e2e)
Coverage86%
Lint0 errors (ruff + mypy --strict + bandit)
Dockerghcr.io/paulomac1000/openwrt-mcp:latest
StandardsAFDS v1.0 + MCP Core v1.1.0 — L2+
LicenseMIT

License

MIT