sos-microtik-mcp
# sos-microtik-mcp
An MCP server that lets Claude (Claude Code CLI, Claude Code desktop, or Claude Desktop) discover, audit and configure **MikroTik RouterOS** routers over SSH, for technicians working on site.
The server runs **locally on the technician's computer** and talks to routers on the same network. Router passwords are entered in a local popup and are never sent to the chat.
> ⚠️ **This tool changes the configuration of network equipment.** Test it on a spare router before using it on a client's network. Use at your own risk.
---
## Contents
- [Features](#features)
- [How it works](#how-it-works)
- [Requirements](#requirements)
- [Installation](#installation)
- [Connect it to Claude](#connect-it-to-claude)
- [Interactive panel (Claude Desktop)](#interactive-panel-claude-desktop)
- [Recommended: auto-approve read-only tools](#recommended-auto-approve-read-only-tools)
- [Router preparation](#router-preparation)
- [Addresses and keys: you always provide them](#addresses-and-keys-you-always-provide-them)
- [Usage](#usage)
- [Where files are saved](#where-files-are-saved)
- [Updating and uninstalling](#updating-and-uninstalling)
- [Troubleshooting](#troubleshooting)
---
## Features
| Area | Tools |
|---|---|
| Connection | `discover_routers` (finds MikroTiks on the LAN, like Winbox Neighbors), `connect`, `reconnect`, `list_sessions`, `disconnect` |
| Information | `router_overview`, `run_command` (read-only), `collect_info` (full export plus status, saved per site) |
| Wi-Fi | `configure_wifi`: SSID, password, WPA2/WPA3, country. Supports the legacy `wireless`, new `wifi` (7.13+) and `wifiwave2` drivers |
| Bridge | `setup_bridge_with_wifi_subnet`: LAN ports and Wi-Fi in a bridge, Wi-Fi on its own subnet with DHCP, optional isolation from the LAN |
| Security | `audit_security` (read-only report), `harden_services`, `firewall_baseline` |
| Validation | `validate_network`: checks any address/subnet you enter (`/24` or `255.255.255.0`) and shows mask, network, broadcast, usable range and overlaps |
| WireGuard (v7) | `wireguard_status`, `wireguard_create_interface`, `wireguard_add_peer` (optional client `.conf` / QR), `wireguard_update_peer`, `wireguard_remove_peer`. Keys are never generated by the server |
| Site-to-site tunnels (v7) | `tunnel_setup` (WireGuard + iBGP/OSPF/static, hub and spokes; generates a CLI script when the other router is unreachable), `tunnel_verify` (handshake, ping both ways, routing, login to every router through the tunnel). See [docs/runbook-tunnels.md](docs/runbook-tunnels.md) |
| Changes | `apply_changes` (custom commands), `confirm_changes`, `rollback_now` |
## How it works
- **SSH only.** The router just needs SSH enabled. The API and HTTP services can stay disabled.
- **Dry run by default.** Every tool that changes something first returns the plan and the exact commands. It only applies them when you approve.
- **Automatic rollback ("commit confirmed").** Before applying a change, the server:
1. saves the current config to your computer,
2. saves a backup on the router (`mcp-pre.backup`),
3. starts a timer on the router, 5 minutes by default.
If you don't confirm the change in time (for example, because it locked you out), the router restores the backup and reboots.
- **No assumed values.** The server has no default IP addresses, subnets or WireGuard keys. Claude asks you for every one of them and validates what you enter.
- **Secrets stay local.** Router passwords, Wi-Fi passwords, and WireGuard private and preshared keys are entered in local popups or saved to files on your computer. They are never shown in the chat.
## Requirements
**On the technician's computer**
- Windows, macOS or Linux
- One of: [Claude Code](https://code.claude.com/docs) (CLI or desktop app), or Claude Desktop
- [uv](https://docs.astral.sh/uv/) (recommended install method), or Python 3.10+
- Network access to the router (plugged into its LAN)
**On the router**
- RouterOS v6 or v7 (WireGuard features require v7)
- SSH service enabled
- A user with sufficient permissions (see [Router preparation](#router-preparation))
---
## Installation
### Option A: uv (recommended)
**1. Install uv** (once per computer)
Windows (PowerShell):
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```
macOS / Linux:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
Close and reopen your terminal afterwards so `uv` is on your PATH.
**2. Install the server from GitHub**
```bash
uv tool install git+https://github.com/howlerdevone/sos-microtik-mcp
```
This creates the command `sos-microtik-mcp` with all its dependencies included. To find its full path (you may need it later):
```bash
uv tool dir --bin
```
Typical locations:
- Windows: `C:\Users\<you>\.local\bin\sos-microtik-mcp.exe`
- macOS / Linux: `~/.local/bin/sos-microtik-mcp`
> **Private repository?** Make sure `git` can access it first, for example by signing in with [GitHub CLI](https://cli.github.com/) (`gh auth login`) or by using an SSH URL:
> `uv tool install git+ssh://git@github.com/howlerdevone/sos-microtik-mcp.git`
### Option B: Python virtual environment (manual)
Windows (PowerShell):
```powershell
git clone https://github.com/howlerdevone/sos-microtik-mcp C:\tools\sos-microtik-mcp
cd C:\tools\sos-microtik-mcp
python -m venv venv
.\venv\Scripts\pip install .
```
The command will be at `C:\tools\sos-microtik-mcp\venv\Scripts\sos-microtik-mcp.exe`.
macOS / Linux:
```bash
git clone https://github.com/howlerdevone/sos-microtik-mcp ~/tools/sos-microtik-mcp
cd ~/tools/sos-microtik-mcp
python3 -m venv venv
./venv/bin/pip install .
```
The command will be at `~/tools/sos-microtik-mcp/venv/bin/sos-microtik-mcp`.
On Linux, also install Tk for the password popups: `sudo apt install python3-tk` (Debian/Ubuntu).
---
## Connect it to Claude
Register the server under the name **`mikrotik`**. The permission settings below depend on that name.
### Claude Code (CLI)
```bash
claude mcp add mikrotik --scope user -- sos-microtik-mcp
```
If you get "command not found", use the full path from `uv tool dir --bin` instead:
```powershell
# Windows example
claude mcp add mikrotik --scope user -- C:\Users\<you>\.local\bin\sos-microtik-mcp.exe
```
`--scope user` makes the server available in every project.
Verify:
```bash
claude mcp list
```
`mikrotik` should show as connected. Inside a `claude` session, `/mcp` lists the server and its tools.
### Claude Code (desktop app, Code tab)
Servers added with `claude mcp add --scope user` are normally picked up by the Code tab as well. Fully quit and reopen the app, then type `/mcp` to check.
If it doesn't appear, add it through the Connectors settings as a local server, using the full path to `sos-microtik-mcp` as the command.
### Claude Desktop (Chat tab)
The chat side of Claude Desktop uses its own config file:
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"mikrotik": {
"command": "C:\\Users\\<you>\\.local\\bin\\sos-microtik-mcp.exe"
}
}
}
```
Use the full path, since desktop apps don't always see your terminal's PATH. Then fully quit and restart Claude Desktop.
---
## Interactive panel (Claude Desktop)
In the **Chat tab of Claude Desktop**, the server shows an interactive panel (in Spanish) right inside the conversation, using the [MCP Apps](https://modelcontextprotocol.io/extensions/apps/overview) extension. Claude Code (CLI and Code tab) doesn't render panels; everything works the same there as text.
| Panel | Shown by | What you can do |
|---|---|---|
| **Plan de cambios** | Any change tool in dry-run mode (Wi-Fi, bridge, firewall, hardening, WireGuard, custom changes) | Review the validations and exact commands, then click **Aplicar cambios**, which asks for a second confirmation |
| **Cambios aplicados** | After applying | See each command's result and a **rollback countdown**, then click **Todo funciona: confirmar** or **Revertir ahora** |
| **Auditoría de seguridad** | `audit_security` | See findings by severity (filterable) with the fix for each, and re-run the audit |
| **WireGuard** | `wireguard_status` | See interfaces, firewall status, and peers with a connection indicator (green / yellow / red), handshake and traffic, and refresh |
When you apply, confirm or revert from the panel, the panel tells Claude, so it doesn't repeat the action. Note that **Aplicar cambios** runs the change directly from the panel (after its own second confirmation); it does not go through a separate approval in the chat, so read the plan before clicking. Secrets are never typed into the panel: router passwords, Wi-Fi passwords and WireGuard private and preshared keys still go through the local popup window on your computer.
<p>
<img src="docs/panel-plan.png" width="49%" alt="Plan de cambios">
<img src="docs/panel-applied.png" width="49%" alt="Cambios aplicados con cuenta regresiva">
</p>
<p>
<img src="docs/panel-audit.png" width="49%" alt="Auditoría de seguridad">
<img src="docs/panel-wireguard.png" width="49%" alt="Estado de WireGuard">
</p>
To see the panel, register the server in the Chat side of Claude Desktop (`claude_desktop_config.json`, see [Claude Desktop (Chat tab)](#claude-desktop-chat-tab)) and fully restart the app.
**For developers:** the panel source is `ui/panel.html`. It embeds the official MCP Apps client ([@modelcontextprotocol/ext-apps](https://github.com/modelcontextprotocol/ext-apps), Apache-2.0, vendored in `ui/vendor/`) so it also works offline at client sites. After editing the panel, regenerate the embedded copy:
```bash
python scripts/build_ui.py
```
This writes `mikrotik_ui.py`. Commit that file too, so that installing from GitHub doesn't need a build step.
---
## Recommended: auto-approve read-only tools
Claude Code asks permission before every tool call. You can let the read-only tools run freely while changes still require approval.
Edit `~/.claude/settings.json` (Windows: `C:\Users\<you>\.claude\settings.json`):
```json
{
"permissions": {
"allow": [
"mcp__mikrotik__discover_routers",
"mcp__mikrotik__connect",
"mcp__mikrotik__reconnect",
"mcp__mikrotik__list_sessions",
"mcp__mikrotik__router_overview",
"mcp__mikrotik__run_command",
"mcp__mikrotik__collect_info",
"mcp__mikrotik__audit_security",
"mcp__mikrotik__wireguard_status"
]
}
}
```
Keep the change tools (`configure_wifi`, `setup_bridge_with_wifi_subnet`, `harden_services`, `firewall_baseline`, `wireguard_*` changes, `apply_changes`, `confirm_changes`, `rollback_now`) off this list. That way you approve each change in Claude on top of the tool's own dry run.
---
## Router preparation
**1. SSH enabled** (on by default on most routers):
```
/ip service print
/ip service enable ssh
```
If SSH is restricted by address, include your laptop's subnet:
```
/ip service set ssh address=192.168.88.0/24
```
**2. A user with the right permissions.** The built-in `full` group (used by `admin`) works for everything. Minimums:
| Use | Policies needed |
|---|---|
| Audit / collect info only | `ssh,read,sensitive` |
| Configuration changes + rollback | `ssh,read,write,policy,sensitive,reboot` |
Example of a read-only user:
```
/user group add name=readonly-ssh policy=ssh,read,sensitive,!write,!policy
/user add name=audit group=readonly-ssh password=...
```
**3. Firewall** must allow TCP 22 from your laptop.
**4. For discovery only:** neighbor discovery must be enabled on the interface you're plugged into (it is by default on LAN interfaces). Your laptop's firewall must allow UDP 5678. Windows will ask the first time; allow it on private networks.
Factory-default routers are usually at `192.168.88.1`, user `admin`, with either no password (older units) or the password printed on the sticker (newer units).
## Addresses and keys: you always provide them
The server never invents network settings. Claude asks you for each value, and the server checks it before anything is applied.
**IP addresses and subnets.** You can use either mask format, and they can be mixed:
| You type | Understood as |
|---|---|
| `192.168.20.1/24` | 192.168.20.1, mask 255.255.255.0 |
| `192.168.20.1 255.255.255.0` | same |
| `192.168.20.1/255.255.255.0` | same |
| `10.10.10.2/32, 192.168.50.0 255.255.255.0` | a list (WireGuard allowed addresses) |
What gets checked:
- **Valid IP and mask.** Non-contiguous masks are rejected, and Cisco-style wildcard masks like `0.0.0.255` are caught, with the correct subnet mask suggested.
- **No network or broadcast address** used as a router or gateway address. A correct host address is suggested instead.
- **Host bits on a subnet.** For example, `192.168.50.1/24` used as a route is corrected to `192.168.50.0/24`, with a note.
- **No overlap** with subnets already on the router, between the LAN and Wi-Fi, or between WireGuard peers.
- **DHCP range** stays inside the subnet and excludes the gateway.
- **WireGuard peer addresses** don't use the router's own tunnel IP, and a warning appears if they're outside the tunnel subnet.
- **Lockout check:** management restrictions that wouldn't include your own computer are refused.
You can also just ask, for example: *"Check if 172.16.4.1 255.255.252.0 is OK for the Wi-Fi network."*
**WireGuard keys.** The server **never generates keys**.
| Key | Where it comes from |
|---|---|
| Router interface key | RouterOS generates it, **or** you enter an existing private key in a local popup. Claude will ask which. |
| Remote peer's public key | You provide it, in chat or in a popup. It's taken from the WireGuard app on the phone or laptop, or from the remote router. |
| Preshared key (optional) | Entered in a local popup only |
| Client private key (optional, for a complete client `.conf` / QR code) | Entered in a local popup only. If you skip it, a template `.conf` is saved instead. |
Key checks:
- **Format:** the key is 44 characters of base64.
- **Not the router's own key:** catches the common mistake of pasting the router's key as the peer's key.
- **No duplicates:** the key isn't already used by another peer on the same interface.
- **Matching pair:** if you enter a client private key, it must match the public key you gave. Otherwise nothing is changed.
For client configs, Claude also asks which networks the client should route through the VPN (`0.0.0.0/0` for all traffic, or specific subnets) and the public IP or hostname the client connects to.
---
## Usage
Just ask Claude in plain language. Examples:
```
Find the MikroTik routers on this network and connect to the main one.
```
```
Collect the full config and info for site "Acme Office", then run a security audit.
```
```
Set the Wi-Fi SSID to "Acme-Staff" with WPA2/WPA3 and country Costa Rica.
```
```
Put all LAN ports and the Wi-Fi in one bridge, with Wi-Fi gateway 192.168.20.1 255.255.255.0, isolated from the LAN.
```
```
Apply the baseline firewall and harden the services.
```
```
Show the WireGuard status.
```
```
Add a WireGuard peer for Juan's phone. I'll give you the phone's public key and tunnel IP.
```
**Typical flow for a change**
1. Claude runs the tool as a **dry run** and shows you the plan and the commands.
2. You approve. Claude applies the change, and the rollback timer starts.
3. You verify that the internet, Wi-Fi and LAN still work.
4. Claude calls `confirm_changes`. If something is wrong, it calls `rollback_now`, or you simply wait for the timer.
**Tips**
- Run `collect_info` at the start of every site visit so you always have a "before" copy.
- When changing bridges, Wi-Fi or firewall rules, connect through a **LAN cable**, not Wi-Fi.
- Right after `connect`, Claude tells you whether your PC is on the router's network and gets its IP from the router's DHCP. If you then change that network's IP/subnet, your PC loses the connection. After applying, release/renew its IP (Windows: `ipconfig /release`, then `ipconfig /renew`), have Claude `reconnect` to the router's new IP, and confirm before the rollback timer ends. The LAN DHCP server must also be moved to the new subnet, or the renew won't get a valid address. In the panel, this warning appears in the plan notes before you click **Aplicar cambios**.
- On many non-CRS3xx models (hAP, hEX, RB4011...), the single-bridge VLAN mode turns off hardware offloading, so switching goes through the CPU. Ask for `mode=separate_bridge` if LAN throughput matters.
---
## Where files are saved
Everything is stored on the technician's computer under `~/mikrotik-sites/` (Windows: `C:\Users\<you>\mikrotik-sites\`):
```
mikrotik-sites/
├── <site>/<date_time>/ # collect_info: export.rsc, interfaces, routes, leases...
├── <site>/audit/<date_time>/ # security_audit.txt
├── <site>/wifi/<date_time>/ # generated Wi-Fi passwords
├── <site>/wireguard/<date_time>/ # client .conf files (complete or template) + QR codes
└── _changes/<router-ip>/<date_time>/
├── description.txt
├── commands.rsc
├── before.rsc # config before the change
├── result.txt
└── after_confirmed.rsc # config after confirm_changes
```
> 🔒 These files contain **passwords and private keys** (exports use `show-sensitive`). Keep this folder on an encrypted disk (BitLocker / FileVault) and don't sync it to shared drives.
---
## Updating and uninstalling
**Update** (Option A):
```bash
uv tool upgrade sos-microtik-mcp
```
If it doesn't pick up the latest commit, reinstall it:
```bash
uv tool install --force git+https://github.com/howlerdevone/sos-microtik-mcp
```
Then restart Claude Code or Claude Desktop.
**Update** (Option B): `git pull`, then `pip install .` again inside the venv.
**Uninstall:**
```bash
claude mcp remove mikrotik --scope user
uv tool uninstall sos-microtik-mcp
```
Also remove the `mikrotik` entry from `claude_desktop_config.json` if you added one there.
---
## Troubleshooting
| Problem | Fix |
|---|---|
| Panel doesn't appear in Claude Desktop | The panel only shows in the Chat tab (not in Claude Code). Update Claude Desktop, check the server is in `claude_desktop_config.json`, and fully restart the app. The tools still work as text without the panel. |
| `claude mcp list` shows **failed** | Run `sos-microtik-mcp` by hand in a terminal. If it waits silently, it works (press Ctrl+C). Otherwise it prints the real error. Use the full path when registering. |
| Server not listed in Claude Desktop | Use the full path to the command in the config, then fully quit the app (including from the tray/menu bar) and reopen it. |
| Password popup doesn't appear | It may be behind other windows. It opens on the computer running Claude, so it won't work if Claude Code runs over SSH on another machine. On Linux, install `python3-tk` and use Option B. |
| `discover_routers` finds nothing | Make sure you're on the router's LAN, allow UDP 5678 in your laptop's firewall, and check `/ip neighbor discovery-settings`. You can still connect directly by IP. |
| `discover_routers` says the address is in use | Winbox (or another tool) is already listening on UDP 5678. Close Winbox and try again. |
| Connection timed out | Check that SSH is enabled, the port is correct, the `/ip service` address restriction includes you, and the firewall allows TCP 22. |
| "not enough permissions" | The router user's group is missing policies. See [Router preparation](#router-preparation). |
| Lost connection during a change | Wait for the rollback timer (default 5 min), or if the router's IP changed on purpose, ask Claude to `reconnect` to the new IP and then confirm. |
| WireGuard tools say v7 required | WireGuard only exists on RouterOS v7. Upgrade the router first. |
---
## Disclaimer
Provided as-is, without warranty. The automatic rollback reduces risk but doesn't remove it. Always keep an independent way back into the router (console cable, MAC-Winbox, or physical reset) and test on lab hardware first.
Licensed under the [MIT License](LICENSE). The vendored MCP Apps client in `ui/vendor/` is Apache-2.0 (see `ui/vendor/LICENSE-ext-apps.txt`).
TDQS
Scored across 22 tools
Most tools have clearly distinct purposes (e.g., configure_wifi vs firewall_baseline vs wireguard_create_interface). However, there is some overlap between run_command, apply_changes, and collect_info, and between connect, reconnect, and disconnect, which could cause minor confusion. The descriptions help clarify boundaries.
All tool names follow a consistent snake_case verb_noun pattern. Examples include discover_routers, configure_wifi, validate_network, apply_changes, and wireguard_add_peer. There are no naming inconsistencies.
22 tools is slightly on the higher side but appropriate for the breadth of functionality (session management, Wi-Fi, firewall, WireGuard, auditing, etc.). Each tool appears to serve a distinct purpose, though some could potentially be merged (e.g., connect/reconnect).
The tool set covers a wide range of MikroTik management tasks: discovery, connection, configuration, security, and WireGuard. Some areas might be missing, such as user management, logging, or advanced routing, but core workflows are well-supported.