mikrotik-swos-mcp
Enables reading and changing MikroTik SwOS / SwOS Lite switches live through their web API, including configuration and status reads, safe dry-run writes with confirmation tokens, VLAN/port/system/SNMP field updates, backups, .swb decoding and diffs, and live or upload-based restore.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
mikrotik-swos-mcp
An MCP server that lets an AI assistant (Claude Code, Claude Desktop or any MCP client)
read and change MikroTik SwOS / SwOS Lite switches live through their web API. You no longer have to download, edit
and upload .swb backups by hand.
No hard-coded field tables. The server downloads each switch's own
engine.jsand learns field ids, names, types, option lists and UI forms from it. The minified names change with every SwOS build, and the parser copes with that.Writes work exactly like the web UI. The server POSTs one UI form to
/<section>.b, and the change applies live without a reboot.Safe by default. Every write first returns a dry-run diff and a token. Nothing changes until the tool is called again with
confirm=<token>, and the token is refused if the live configuration changed in between. After a write the server reads the values back, appends a changelog entry and saves a fresh backup.Backups with real field names. It decodes
.swbfiles and diffs live against file or file against file. A prepared.swbcan be restored live by applying only the forms that differ, without a reboot.Gentle on production switches. One request at a time, at least 0.2 s between requests, a 3 s cache and no background polling.
Verifiable.
verify/renders the switch's own web UI offline on captured data and compares every value it shows with the decoder (see Verification).
Supported devices
Device / firmware | Status |
CSS610-8G-2S+, SwOS Lite 2.21 | Verified against the web UI on 3 production switches: 3,251 displayed values, 0 mismatches. Live write tested (identity round trip, read back, no reboot) |
CSS610-8G-2S+, SwOS Lite 2.18 | Used in production before an upgrade: reads, backups and dry runs; |
CSS610-8G-2S+, SwOS Lite 2.20 | Parser OK on the reference |
CSS610-8P-2S+ (PoE), SwOS Lite 2.20 | Parser OK on the reference |
Full SwOS (CRS305/309/310/326, CSS326) | Not supported yet. Same UI framework, but descriptive keys, variable port count and >32-bit masks. Parser fails on the reference files |
Other SwOS Lite devices probably work because everything is read from the device. Please run verify/ on yours and open
an issue with the result line.
Related MCP server: RouterOS MCP Server
Install
git clone https://github.com/saniyo/mikrotik-swos-mcp
cd mikrotik-swos-mcp
pip install -r requirements.txt # mcp (1.x or 2.x) + requests
cp switches.example.json switches.json # then edit itswitches.json:
{
"user": "admin",
"configs_dir": "configs",
"changelog": "configs/CHANGELOG.md",
"switches": [
{"ip": "192.168.88.1", "name": "core", "password": "", "note": "CSS610 in rack A"}
]
}configs_dirholdscurrent/(the latest backup of each switch),archive/<date>/(superseded backups) andmanual-changes/(prepared.swbfiles forrestore_backup). Relative paths are relative to the config file.Passwords: use the
passwordfield, or the environment variablesSWOS_PASSWORD_192_168_88_1(one switch) orSWOS_PASSWORD(all switches). Environment variables win. Passwords are never printed or written anywhere. An empty admin password only triggers a warning; nothing is blocked.SWOS_CONFIG=/path/to/switches.jsonkeeps the config outside the repository.
Register with your MCP client
Claude Code:
claude mcp add swos --scope user -- /path/to/python /path/to/mikrotik-swos-mcp/server.pyClaude Desktop (claude_desktop_config.json):
{"mcpServers": {"swos": {"command": "/path/to/python", "args": ["/path/to/mikrotik-swos-mcp/server.py"]}}}Use a stable interpreter, not a virtual environment that another tool may rebuild. The server runs over stdio.
Tools
Tool | What it does |
| Configured switches with live identity, version, uptime and a warning for an empty password |
| Config with the web-UI field names. |
| Per port: link, speed, duplex, flow control. Plus uptime, CPU temperature, serial and MAC. |
| Diff of any two of: a live switch, a |
| System > Identity |
| Port name, enabled, VLAN mode / receive / default VLAN ID / force VLAN ID |
| Add, change or remove one VLAN table entry (members, IGMP snooping) |
| Any web-UI field by tab and field name, e.g. |
| Saves |
| Applies a |
A write session looks like this:
> set_identity switch=core identity=CSS610-RACK-A
DRY RUN - 192.168.88.1: identity -> CSS610-RACK-A
[System / General] POST /sys.b (whole UI form, other fields re-sent unchanged, applies live):
System / General: Identity: MikroTik -> CSS610-RACK-A
To apply, call again with confirm="b39d5ed576".
> set_identity switch=core identity=CSS610-RACK-A confirm=b39d5ed576
APPLIED - 192.168.88.1
[System / General] POST /sys.b: HTTP 200, read-back OKHow SwOS Lite talks (read from engine.js, not guessed)
GET /<section>.b(sys.b,link.b,fwd.b,vlan.b,snmp.b,rstp.b,lacp.b,host.b,acl.b; read-only ones start with!, like!stats.b) returns a JavaScript literal withiNNkeys, e.g.{i01:0x03ff,i0a:['506f727431',...]}. Strings are hex, IPv4 is a little-endian 32-bit number, per-port checkboxes are bit masks.The web UI writes one form at a time (one tab block with its own Apply button):
POST /<section>.b,Content-Type: text/plain, and the body holds every writable field of that form in the same literal format. Several tabs sharefwd.b/sys.b, and each posts only its own fields. The change applies immediately. This server posts the same form and re-sends the untouched fields with the values it has just read.Restore Backup = multipart
POST /backup.swb(fieldfile), thenPOST /reboot.A
.swbbackup holds the same data with one-letter keys: index NN becomes'A'+NN, continuing with'a'..after'Z'.HTTP digest auth, HTTP/1.0, one connection at a time.
Field definitions look like
{n:"VLAN Mode",id:"i15",t:G,m:["disabled","optional","strict"]}. The type function names (G) and property names (m) differ between builds, so the parser identifies them by code signatures (for example, the checkbox type is the one whose parser contains>>1&2147483647).
Verification
The decoder is checked against the switch's own web UI, not against a hand-written expectation:
python verify/make_harness.py core # captures each section once (read-only), builds verify/out/<ip>/
python -m http.server 8765 --bind 127.0.0.1 --directory verify/out
# open http://127.0.0.1:8765/<ip>/index.html and wait a few secondsThe page is the switch's real index.html + engine.js, fed with the captured data through a fake XMLHttpRequest, so it
never talks to the switch (POSTs are dropped). It renders every tab and compares each input, select, checkbox and read-only
value with the decoder. The result line reads like ok 870, blank=default 117, mismatch 0, missing 3, extra 0:
blank=default: the UI leaves a field empty when it holds its default value (for example0.0.0.0).missing 3: Root Bridge and Allow From are composite fields that the UI shows as one combined input (8000.aa:bb:cc:dd:ee:ff). They are expected; check them by eye.extra: a UI element the decoder does not know. It should be 0. Anything else is a bug, so please report it.
Keys that the switch sends but no UI field shows (SwOS Lite 2.21): sys.b i02 current IP, i06 version,
i0b build time, i0c upgrade flag, i0d watchdog (shown on 2.18, hidden on 2.21); link.b i09 per-port
counter (lanrat names it port uptime; the unit is unverified); rstp.b i04 matches the STP path cost (4 / 19 / 100 for
1G / 100M / 10M links). The rest are zero and not referenced by engine.js: sys.b i15 i16 i1c-i1f i20 i21 i23-i26 i2b,
link.b i0b i0c, sfp.b i07, stats.b i03.
Comparison with related projects
this project | |||
Type | MCP server (Python) | MCP server (TypeScript, RouterOS + SwOS) | Library, CLI, Ansible (Python) |
Field map | read from each switch's | static tables | static tables per platform |
SwOS Lite / full SwOS | Lite only (for now) | both (SwOS marked experimental) | both, more devices |
Coverage | every web-UI field (generic | sys, link, fwd, VLAN, LACP, SNMP, PoE, upgrade | sys, ports, PoE, LAG, VLAN, SNMP, password |
Write safety | dry run + token, read-back, changelog, backup | dry run, lockout guard, snapshot/rollback | Ansible check mode |
Restore | live (only differing forms) or upload + reboot | upload + reboot | upload |
| yes | no | no |
Verified against the UI | yes ( | no | no |
Not here yet, worth adopting: full SwOS, a hard lockout guard (MikroMCP), PoE convenience tools, firmware upgrade.
Safety notes
Fields that affect management access (IP, Allow From, VLAN changes) produce warnings in the dry run. Unlike some related projects, there is no automatic lockout guard yet, so review VLAN changes on the uplink port yourself.
The admin password is never changed. A live restore never touches the password either.
Static hosts and ACL entries are read and diffed but have no dedicated write tool; use
restore_backupinstead.verify/and all read tools never write. The verify page drops every POST.
Related projects
AliKarami/MikroMCP, lanrat/python-mikrotik-swos (its
webui_reference/and field maps were used as an independent cross-check: every SwOS Lite key they map agrees with ours), tofkamp/mikrotik_swos, probert94/python-switchos.
License
MIT. Use at your own risk: these switches often carry production traffic, so always read the dry run.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Protocol-native energy infrastructure orchestration for AI data centers. Provides 46 MCP tools across 8 grid protocols (IEC-61850, DNP3, Modbus, OCPP, OpenADR, IEEE 2030.5, IEC 60870-5-104, ICCP) with 5 core API primitives: connect, dispatch, settle, comply, and intel. Enables AI agents to programmatically interact with substations, grid interfaces, and energy assets for real-time workload-grid coordination.
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Remote streamable-HTTP MCP server running on a single Cloudflare Worker. Your assistant gets live Airbnb, Amazon, Booking.com, Google Flights, Maps and Reddit data, social search on X, Instagram and TikTok, the Meta Ad Library, and image/video generation without any keys. Connect your own accounts to let it send WhatsApp or Telegram messages, work an IMAP inbox, manage Meta Ads campaigns and publish to X and LinkedIn. OAuth 2.1 with PKCE; stored credentials are AES-256-GCM encrypted.
- DNS-DATA RemoteDeprecatedcom.dns-data
Connect AI assistants to authorized Windows and macOS devices for files, commands, and management.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA bridge between AI assistants and MikroTik RouterOS devices, allowing natural language interaction to manage network configurations including VLANs, firewalls, DNS settings, and more.1MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with MikroTik RouterOS devices through API and SSH connections, supporting network monitoring, configuration management, and diagnostics across multiple routers with automatic connection fallback.3MIT
- AlicenseCqualityAmaintenanceProvides a bridge between AI assistants and MikroTik RouterOS devices, enabling natural language management of VLANs, firewall rules, DNS settings, and more.2341,052 PyPI334MIT
- AlicenseNot gradedqualityCmaintenanceBridges AI assistants with MikroTik RouterOS devices, enabling natural language management of network configurations, firewall, VLANs, VPNs, and diagnostics via ~300 tools.1MIT