# Mikrotik Mcp

> A Bun-native MCP server that turns one or more MikroTik routers into 706 tools your AI can drive. Firewall · routing · DHCP/DNS · wireless · QoS · and a complete VPN suite — over SSH, with transactional Safe Mode.

- **Type:** MCP server
- **Install:** `agentstack add mcp-ali-master-mikrotik-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ali-master](https://agentstack.voostack.com/s/ali-master)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ali-master](https://github.com/ali-master)
- **Source:** https://github.com/ali-master/mikrotik-mcp
- **Website:** https://mikrotik-mcp.usestrict.dev

## Install

```sh
agentstack add mcp-ali-master-mikrotik-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

A Bun-native MCP server that turns one or more MikroTik routers into 706 tools your AI can drive.
  Firewall · routing · DHCP/DNS · wireless · QoS · and a complete VPN suite — over SSH, with transactional Safe Mode.

  
    
    
    
    
    
  

---

`@usex/mikrotik-mcp` exposes **MikroTik RouterOS** as **706 [Model Context Protocol](https://modelcontextprotocol.io)
tools across 111 modules**, so an AI client (Claude Desktop, Claude Code, any MCP
client) can read and configure your router in plain language. It speaks to the
device over **SSH** — no agent, no API package to install on RouterOS — runs on
**[Bun](https://bun.sh)**, and validates every tool call against a Zod schema.

Every tool is **risk-annotated** (read / write / destructive) so clients can gate
what runs, and risky changes can be wrapped in **Safe Mode** — RouterOS holds them
in memory and auto-reverts if your session drops, so you can't lock yourself out.

```jsonc
// claude_desktop_config.json
{
  "mcpServers": {
    "mikrotik": {
      "command": "mikrotik-mcp",
      "env": {
        "MIKROTIK_HOST": "192.168.88.1",
        "MIKROTIK_USERNAME": "admin",
        "MIKROTIK_PASSWORD": "your-password",
      },
    },
  },
}
```

> _"Show me the firewall input chain, then block SSH from the WAN under safe mode."_
> _"Build an IKEv2 site-to-site tunnel to 203.0.113.5 for 192.168.20.0/24."_
> _"Why can't VLAN 50 reach the internet?"_

## Why it's different

- 🧰 **Breadth** — 706 tools covering the whole device: L2 (bridge, VLAN, wireless,
  PoE), L3 (addressing, routing, DHCP, DNS), security (firewall, NAT, address-lists,
  certificates), QoS (queues), and system ops (users, logs, backups, scheduler).
- 🔐 **A complete VPN suite** — WireGuard, IPsec (IKEv1/IKEv2), L2TP, PPTP, SSTP,
  OpenVPN, plus GRE/IPIP/EoIP/VXLAN tunnels. With a `choose-vpn-solution` prompt
  that picks the right one for you. See the **[VPN guide](docs/vpn-guide.md)**.
- 🛟 **Safe Mode** — a real transactional window (`enable_safe_mode` →
  changes → `commit_safe_mode`/`rollback_safe_mode`) backed by a persistent SSH
  session. Auto-reverts on disconnect.
- 🚦 **Risk-annotated tools** — `readOnlyHint` / `destructiveHint` let clients
  auto-approve reads and prompt on writes.
- 🧱 **Injection-safe by construction** — a command builder quotes/escapes every
  value, so a hostname like `LAN; /system reset` can never split into a second
  command.
- 🖧 **Multiple devices** — define named routers and the AI targets one per call
  (a validated `device` argument). Configure **both ends of a tunnel** from one
  conversation. See **[docs/multi-device.md](docs/multi-device.md)**.
- 🪜 **SSH jump hosts** — reach a router with no exposed port by tunnelling
  through another via `jumpVia` (ProxyJump/bastion) — commands, Safe Mode and
  file upload all ride the hop. No new WAN port.
- ⚡ **Connection pooling** — one persistent SSH session per device, reused
  across tool calls. Saves ~200-500 ms handshake per command (double through
  jump hosts). Idle connections auto-close after 30 s.
- 🤖 **Guided prompts** — 9 built-in workflows (harden, diagnose, guest Wi-Fi, VPNs,
  cross-device tunnels, backup & document) that turn an intent into tool calls.

## Quickstart

```bash
# 1. Install (requires Bun ≥ 1.3 — https://bun.sh)
bun add -g @usex/mikrotik-mcp

# 2. Point it at your router and verify SSH connectivity
MIKROTIK_HOST=192.168.88.1 MIKROTIK_USERNAME=admin MIKROTIK_PASSWORD=•••• \
  mikrotik-mcp auth-check

# 3. List the catalog (name · risk · title)
mikrotik-mcp tools

# 4. Run it (stdio by default — wire it into your MCP client)
mikrotik-mcp serve
```

**Try it without an AI client** — open the official [MCP Inspector](docs/inspector.md)
against the server (from source):

```bash
bun run inspect        # opens the Inspector UI to browse/run all 706 tools
```

**Prefer SSH keys over a password?** Point the server at a key file instead — and
add a passphrase if the key is encrypted:

```bash
MIKROTIK_HOST=192.168.88.1 MIKROTIK_USERNAME=admin \
MIKROTIK_KEY_FILENAME=~/.ssh/id_ed25519 \
MIKROTIK_KEY_PASSPHRASE=•••• \
  mikrotik-mcp auth-check     # prints "Auth mode: SSH key"
```

The key (file via `--key-filename` or inline PEM via `--private-key`) takes
precedence over a password. Full configuration reference:
**[docs/configuration.md](docs/configuration.md)**.

### From source

```bash
git clone https://github.com/ali-master/mikrotik-mcp && cd mikrotik-mcp
bun install
bun run start            # serve from source
bun run build            # bundle to dist/
```

## The tool catalog

**706 tools across 111 modules.** Full, always-current reference (parameters +
risk per tool) is generated from source: **[docs/tools-reference.md](docs/tools-reference.md)**.

| Group                    | Tools | Modules                                                                                                    |
| ------------------------ | ----: | ---------------------------------------------------------------------------------------------------------- |
| **Interfaces**           |    41 | interfaces, VLAN, bridge, wireless, PoE                                                                    |
| **Addressing & Routing** |    46 | IP addresses, IP pools, routing, DHCP, DNS                                                                 |
| **Dynamic Routing**      |    99 | router-id, settings, tables, rules, next-hops, filters, BFD, BGP, OSPF, RIP, PIM-SM, IGMP proxy, GMP, RPKI |
| **Security**             |    34 | firewall filter, NAT, address-lists, certificates, IP services                                             |
| **VPN & Tunneling**      |    96 | WireGuard, IPsec, PPP, L2TP, PPTP, SSTP, OpenVPN, GRE/IPIP/EoIP/VXLAN                                      |
| **QoS**                  |    19 | queue types, queue trees, simple queues                                                                    |
| **System & Ops**         |   102 | system, network tools, scheduler/scripts, users, logs, backup, Safe Mode                                   |

## VPN & tunneling — expert coverage

Every MikroTik VPN technology, modeled the way RouterOS actually layers them (the
PPP-based VPNs share one `/ppp` backend for users and addressing):

| Need                                | Use                     | Build it with                                                                          |
| ----------------------------------- | ----------------------- | -------------------------------------------------------------------------------------- |
| MikroTik ↔ MikroTik, modern clients | **WireGuard**           | `create_wireguard_interface`, `add_wireguard_peer`, `generate_wireguard_client_config` |
| Interop site-to-site / native IKEv2 | **IPsec**               | `create_ipsec_{profile,peer,identity,proposal,policy}`, `get_ipsec_active_peers`       |
| Built-in OS VPN clients             | **L2TP/IPsec**          | `set_l2tp_server`, `create_ppp_secret`, `create_ppp_profile`                           |
| Through restrictive firewalls       | **SSTP** (TLS)          | `set_sstp_server`, `create_sstp_client`                                                |
| Cross-platform OpenVPN              | **OpenVPN**             | `set_ovpn_server`, `create_ovpn_client`                                                |
| Route / L2-bridge between sites     | **GRE/IPIP/EoIP/VXLAN** | `create_gre_tunnel`, `create_eoip_tunnel`, `create_vxlan_tunnel`                       |

Not sure which? Invoke the **`choose-vpn-solution`** prompt and the server
recommends one and outlines the build. Details: **[docs/vpn-guide.md](docs/vpn-guide.md)**.

## Manage multiple devices

Give each router a name and the AI can drive them all from one conversation —
exactly what you need to **set up a tunnel between two MikroTiks and test it from
both ends**. Point the server at a JSON file (or `MIKROTIK_DEVICES`):

```jsonc
// devices.json
{
  "defaultDevice": "site-a",
  "devices": {
    "site-a": { "host": "203.0.113.10", "username": "admin", "keyFilename": "/keys/site-a" },
    "site-b": { "host": "198.51.100.20", "username": "admin", "password": "••••" },
  },
}
```

```bash
mikrotik-mcp serve --config ./devices.json
mikrotik-mcp devices        # site-a (default) · site-b
mikrotik-mcp auth-check     # probes every device
```

When more than one device is configured, **every tool gains an optional `device`
argument** (a validated enum of your names); omit it to use the default. The AI
discovers names with `list_mikrotik_devices`, and **Safe Mode is per-device** so
each router commits independently. The **`setup-tunnel-between-sites`** prompt
drives the whole both-ends flow. Full guide: **[docs/multi-device.md](docs/multi-device.md)**.

```jsonc
// the AI calls a tool against a specific router:
// create_wireguard_interface { "device": "site-a", "name": "wg-to-b", "listen_port": 13231 }
```

**Behind a bastion?** Reach a router with no exposed SSH port by jumping through
another (OpenSSH-style ProxyJump) — `jumpVia` names a configured device to tunnel
through; commands, Safe Mode and SFTP upload all ride the hop:

```jsonc
"home-ax3": { "host": "10.10.30.100", "username": "admin", "jumpVia": "hex" }
```

The bastion router needs SSH TCP forwarding enabled (`/ip ssh set
forwarding-enabled=local`). See **[docs/multi-device.md](docs/multi-device.md#ssh-jump-hosts-bastion--proxyjump)**.

## Built-in prompts

MCP **prompts** are one-click guided workflows. This server ships 9 — authored as
Markdown in [`prompts/`](prompts/), so you can edit or add your own without
touching code:

`harden-router` · `diagnose-connectivity` · `setup-guest-wifi` ·
`choose-vpn-solution` · `setup-wireguard-vpn` · `setup-ipsec-site-to-site` ·
`setup-l2tp-ipsec-roadwarrior` · `setup-tunnel-between-sites` · `backup-and-document`

See **[docs/prompts.md](docs/prompts.md)**.

## Transports

| Transport           | When                              | Run                                                              |
| ------------------- | --------------------------------- | ---------------------------------------------------------------- |
| **stdio** (default) | Claude Desktop, local MCP clients | `mikrotik-mcp serve`                                             |
| **streamable-http** | Remote / shared, behind a proxy   | `mikrotik-mcp serve --transport streamable-http --mcp-port 8000` |
| **sse**             | Legacy HTTP clients               | `mikrotik-mcp serve --transport sse`                             |

HTTP transports expose `POST /mcp` and a `GET /health` check, with DNS-rebinding
protection that reconciles with your bind host automatically. See
**[docs/transports.md](docs/transports.md)**.

## SSH connection pooling

By default the server keeps **one persistent SSH connection per device** and
opens a fresh exec channel for each tool call — eliminating the ~200-500 ms
handshake overhead that a one-shot connection incurs on every command. Through
a jump host the savings double (two handshakes avoided). Idle connections are
closed automatically after 30 s.

```bash
# Disable pooling (revert to one-shot per tool call)
MIKROTIK_SSH__KEEP_ALIVE=false mikrotik-mcp serve

# Tune the idle timeout (ms)
mikrotik-mcp serve --ssh-idle-timeout 60000
```

In a JSON config file:

```jsonc
{
  "ssh": {
    "keepAlive": true, // default — set false to disable
    "keepAliveInterval": 10000, // SSH keepalive packet interval (ms)
    "idleTimeout": 30000, // close idle connections after (ms)
  },
}
```

Connection pooling is SSH-only; MAC-Telnet devices always use one-shot
connections. Safe Mode still uses its own dedicated persistent session.

## Safe Mode

```text
enable_safe_mode → (make changes) → commit_safe_mode    # persist
                                   → rollback_safe_mode  # discard
```

While active, every change is held in memory; if the SSH session drops (e.g. a
firewall rule that locks you out), RouterOS reverts everything automatically.
Commands issued during the window are routed through the same persistent session.
See **[docs/safe-mode.md](docs/safe-mode.md)**.

## Configuration

Connection and transport settings come from `MIKROTIK_*` env vars or matching CLI
flags (highest precedence last: defaults → env → flags).

| Variable                      | Flag                 | Default     | Purpose                                                                                              |
| ----------------------------- | -------------------- | ----------- | ---------------------------------------------------------------------------------------------------- |
| `MIKROTIK_HOST`               | `--host`             | `127.0.0.1` | RouterOS host                                                                                        |
| `MIKROTIK_USERNAME`           | `--username`         | `admin`     | SSH user                                                                                             |
| `MIKROTIK_PORT`               | `--port`             | `22`        | SSH port                                                                                             |
| `MIKROTIK_PASSWORD`           | `--password`         | —           | SSH password _(or use a key →)_                                                                      |
| `MIKROTIK_KEY_FILENAME`       | `--key-filename`     | —           | SSH private-key file path                                                                            |
| `MIKROTIK_PRIVATE_KEY`        | `--private-key`      | —           | Inline private key (PEM)                                                                             |
| `MIKROTIK_KEY_PASSPHRASE`     | `--key-passphrase`   | —           | Passphrase for an encrypted key                                                                      |
| `MIKROTIK_JUMP_HOST`          | `--jump-host`        | —           | SSH bastion to tunnel through ([jump hosts](docs/multi-device.md#ssh-jump-hosts-bastion--proxyjump)) |
| `MIKROTIK_CONFIG_FILE`        | `--config`           | —           | JSON file of named devices ([multi-device](docs/multi-device.md))                                    |
| `MIKROTIK_DEVICES`            | `--devices`          | —           | Inline JSON of named devices                                                                         |
| `MIKROTIK_MCP__TRANSPORT`     | `--transport`        | `stdio`     | `stdio` / `streamable-http` / `sse`                                                                  |
| `MIKROTIK_MCP__PORT`          | `--mcp-port`         | `8000`      | HTTP bind port                                                                                       |
| `MIKROTIK_SSH__KEEP_ALIVE`    | `--ssh-keep-alive`   | `true`      | SSH connection pooling (reuse connections across tool calls)                                         |
| `MIKROTIK_SSH__IDLE_TIMEOUT`  | `--ssh-idle-timeout` | `30000`     | Close idle pooled connections after (ms)                                                             |
| `MIKROTIK_DASHBOARD__ENABLED` | `--dashboard`        | `false`     | Real-time observability dashboard ([docs](docs/observability.md))                                    |

Full table (incl. HTTP host, allow-lists, timeouts, `MIKROTIK_LOG_LEVEL`):
**[docs/configuration.md](docs/configuration.md)**.

### Observability dashboard (optional)

A localhost-only web dashboard that intercepts **every** tool call the LLM makes
— live feed of inputs/outputs (secrets redacted), latency percentiles, error
rate and per-tool/risk/device analytics — persisted to a Bun-native SQLite store
and served on its own port alongside any transport:

```bash
mikrotik-mcp serve --dashboard          # → http://127.0.0.1:9090
```

See **[docs/observability.md](docs/observability.md)**.

## Beyond the catalog

On top of the per-scope tools, the server ships higher-level workflows:

- **[Change Plan & Dry-Run](docs/cha

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ali-master](https://github.com/ali-master)
- **Source:** [ali-master/mikrotik-mcp](https://github.com/ali-master/mikrotik-mcp)
- **License:** MIT
- **Homepage:** https://mikrotik-mcp.usestrict.dev

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-ali-master-mikrotik-mcp
- Seller: https://agentstack.voostack.com/s/ali-master
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
