MikroBLOCK
Production-grade MCP server for MikroTik RouterOS with secure AI-native network automation.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
AI-native network automation for MikroTik RouterOS. MikroMCP exposes RouterOS as a typed, auditable Model Context Protocol server so Claude, Cursor, Codex, and other MCP clients can inspect, diagnose, and safely operate MikroTik routers in natural language.
[](https://github.com/AliKarami/MikroMCP/actions/workflows/ci.yml) [](https://github.com/AliKarami/MikroMCP/actions/workflows/release.yml) [](package.json) [](LICENSE) [](package.json) [](https://help.mikrotik.com/docs/display/ROS/REST+API) [](https://modelcontextprotocol.io) [](https://github.com/AliKarami/MikroMCP/wiki/Available-Tools) [](https://glama.ai/mcp/servers/AliKarami/MikroMCP)
MikroMCP exists because raw router CLI access is the wrong abstraction for AI agents. RouterOS is powerful, but asking an LLM to improvise shell commands against production network gear is risky. MikroMCP gives agents a controlled tool surface: strict schemas, idempotent writes, dry-run previews, per-router circuit breakers, retry
52a3285b5d24OBSERVED · 2026-10-08Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add mikromcp -- npx -y [email protected]
Exposed tools (122)
62 read · 25 write · 35 destructive. Blast radius: 35 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
apply_plan | write | Execute write operations in order, stopping on first failure. Each step is snapshotted and journaled individually. Non-admin identities need a confirmationToken (same two-step flow as other destructive tools). Undo individual steps via rollback_change with the returned journal IDs. |
bandwidth_test | write | Run a RouterOS bandwidth test from the router to a remote host running a RouterOS btest server. Returns TX and RX throughput in Mbps. Duration capped at 20 seconds. Saturates the link — not auto-retried. |
bulk_execute | write | Fan out a single-router tool to many routers in parallel (up to |
bulk_read | read | Fan out a read-only single-router tool (list_*, get_* and others annotated read-only) to many routers in parallel (up to |
check_router_health | read | Probe a device: RouterOS routers via system/resource, SwOS switches via sys.b. Returns health status, firmware version, uptime, and (RouterOS only) CPU load and memory info. Unlike other tools, this never throws — unreachable devices are reported as healthy=false. |
create_backup | write | Create a binary configuration backup on a MikroTik router. The backup is saved as <name>.backup on the router |
delete_file | destructive | Delete a file from the router filesystem by name. Idempotent: returns not_found gracefully if the file does not exist. |
export_config | read | Export the router configuration as a RouterOS script. When no file is specified, returns the script text inline. When a file is specified, saves it as <file>.rsc on the router |
fetch_url | write | Send an HTTP/HTTPS request from the router using /tool/fetch. Response body is returned inline (capped at 64 KB with [TRUNCATED] marker). Use outputFile to save to router filesystem instead. Not read-only: POSTs have side effects and outputFile writes to the router. |
get_container_config | read | Read global container configuration: registry URL, RAM high-water mark, and veth interface. |
get_dns_settings | read | Read DNS resolver configuration: upstream servers, cache size, cache TTL, and whether remote DNS requests are allowed. |
get_file_content | read | Read a text file |
get_log | read | Read and filter the system log from a MikroTik router. Supports filtering by topic, message prefix, and a time window (last N minutes) measured against the router |
get_ntp_settings | read | Retrieve NTP client settings from a MikroTik router. |
get_ovpn_server | read | Get the OpenVPN server configuration on a MikroTik router. Throws NOT_FOUND if the OpenVPN package is not installed. |
get_snmp_settings | read | Retrieve SNMP settings from a MikroTik router. |
get_swos_endpoint | read | Fetch and decode a single SwOS |
get_swos_status | read | Retrieve status from a MikroTik SwOS switch (SwOS or SwOS Lite): identity, model, firmware, uptime, per-port link state/speed/duplex, PoE mode/state/power, and SFP modules. |
get_system_clock | read | Read the current date, time, and timezone from a MikroTik router. Focused single-purpose alternative to the clock section in get_system_status. |
get_system_status | read | Retrieve system status information from a MikroTik router including resource usage, identity, license, routerboard details, health sensors, and clock. |
get_upgrade_status | read | Read the current RouterOS package upgrade status and routerboard firmware versions. Shows installed version, latest available version, update channel, and firmware upgrade availability. |
list_address_list_entries | read | List firewall address list entries on a MikroTik router. Supports filtering by list name and address. |
list_arp_entries | read | List ARP table entries on a MikroTik router. |
list_bgp_peers | read | List BGP sessions on a MikroTik router (RouterOS 7+). Returns state, remote AS, prefix counts, and uptime. |
list_bridge_ports | read | List bridge port entries (interface membership, PVID, STP role and status) on a MikroTik router. Supports filtering by bridge and interface, with pagination. |
list_bridges | read | List bridge interfaces and their port members on a MikroTik router. |
list_certificates | read | List certificates on a MikroTik router. |
list_connections | read | List active connection tracking entries from the router firewall table. Filters are applied client-side. Useful for diagnosing NAT and firewall behavior. |
list_container_envs | read | List container environment variable entries, optionally filtered by container name. |
list_container_mounts | read | List container volume mount definitions with source path, destination path, and mount name. |
list_containers | read | List RouterOS container instances with status, image, and network information. |
list_dhcp_clients | read | List DHCP client configurations on a MikroTik router. Shows which interfaces obtain their IP via DHCP, current status, and assigned address. |
list_dhcp_leases | read | List DHCP leases on a MikroTik router with optional filtering by server, status, lease type (dynamic/static), and MAC address. Supports pagination. |
list_dhcp_servers | read | List DHCP servers on a MikroTik router. |
list_dns_entries | read | List static DNS entries on a MikroTik router with optional filtering by name and type. |
list_files | read | List files on a MikroTik router filesystem. Supports filtering by name and type. |
list_firewall_rules | read | List firewall rules from the filter or nat table on a MikroTik router. Supports filtering by chain and disabled state, with pagination. |
list_interface_list_members | read | List interface list memberships (which interface belongs to which list, e.g. WAN/LAN) on a MikroTik router. Supports filtering by list and interface, with pagination. |
list_interface_lists | read | List all interface lists defined on the router. |
list_interfaces | read | List network interfaces on a MikroTik router with optional filtering by type and status. Supports pagination and optional traffic counters. |
list_ip_addresses | read | List IPv4 addresses assigned to interfaces on a MikroTik router, including dynamic ones (DHCP client, PPP). Supports filtering by interface and disabled state, with pagination. |
list_ip_pools | read | List IP address pools on a MikroTik router. Supports filtering by name and pagination. |
list_ip_services | read | List IP services on a MikroTik router (api, api-ssl, ssh, telnet, www, www-ssl, winbox, ftp) with their port numbers and enabled/disabled status. |
list_ipsec_peers | read | List IPSec peers on a MikroTik router. |
list_ipsec_policies | read | List IPSec policies on a MikroTik router. |
list_log_actions | read | List RouterOS logging action targets (system/logging/action) with optional type filter. |
list_log_rules | read | List RouterOS logging rules (system/logging) with optional topic substring and action exact-match filtering. |
list_mangle_rules | write | List firewall mangle rules on a MikroTik router in evaluation order. Supports filtering by chain, action, and disabled state. |
list_neighbors | read | List discovered neighbors (CDP/LLDP/MNDP) on a MikroTik router. |
list_netwatch_entries | read | List Netwatch monitoring entries on a MikroTik router. |
list_ospf_neighbors | read | List OSPF neighbors on a MikroTik router (RouterOS 7+). Returns neighbor state, interface, DR/BDR, and uptime. |
list_ovpn_clients | read | List OpenVPN client interfaces on a MikroTik router. Shows name, remote server, and connection status. |
list_packages | read | List installed RouterOS packages with version and enabled status. |
list_ppp_profiles | read | List PPP profiles including the built-in default and default-encryption profiles. |
list_pppoe_clients | read | List PPPoE client interfaces on a MikroTik router. Shows name, parent interface, ISP username, and connection status. |
list_queues | read | List simple queues on a MikroTik router. |
list_routes | read | List static routes on a MikroTik router with optional filtering by active status and dynamic status. Supports pagination. |
list_routing_rules | write | List policy routing rules on a MikroTik router in evaluation order. Supports filtering by table and disabled state. |
list_routing_tables | read | List custom routing tables on a MikroTik router. |
list_scheduled_jobs | write | List RouterOS scheduler entries on a MikroTik router with next-run time, interval, and disabled state. |
list_scripts | read | List RouterOS scripts on a MikroTik router. Supports optional name filter. |
list_swos_endpoints | read | List the SwOS/SwOS Lite |
list_user_groups | read | List local user groups on a MikroTik router. |
list_users | read | List local users on a MikroTik router. Passwords are never returned. |
list_vrrp_instances | read | List VRRP instances on a MikroTik router. |
list_wifi_clients | read | List currently connected WiFi clients (stations) with signal strength and transfer rates. |
list_wifi_interfaces | read | List WiFi/wireless interfaces on a MikroTik router. Uses /interface/wifi on ROS 7.x, /interface/wireless on older versions. |
list_wireguard_interfaces | read | List WireGuard interfaces and their status on a MikroTik router. |
list_wireguard_peers | write | List WireGuard peers with last handshake time and transfer statistics. |
manage_address_list_entry | destructive | Add or remove a firewall address list entry. Idempotent by list name + address. Supports dry-run mode. |
manage_bridge | destructive | Create or remove a bridge interface on a MikroTik router. Idempotent: create returns already_exists if bridge with same name exists. |
manage_bridge_port | destructive | Add or remove an interface from a bridge on a MikroTik router. Idempotent: add returns already_exists if the port assignment already exists. |
manage_certificate | destructive | Remove, trust, or untrust a certificate. Idempotent: trust/untrust return early if already in the target state. |
manage_container | destructive | Create, start, stop, or remove a RouterOS container. create needs a pre-configured veth interface; start/stop are no-ops when already in the target state; remove throws NOT_FOUND when absent. Supports dry-run. |
manage_container_config | write | Update global container settings. Idempotent: returns no_change if nothing differs. |
manage_container_env | destructive | Add or remove a container environment variable. Idempotent by name+key. add returns already_exists if the entry exists with the same value; throws CONFLICT if the value differs. |
manage_container_mount | destructive | Add or remove a container volume mount. Idempotent by name: add returns already_exists if the mount exists with matching src/dst; throws CONFLICT if name exists with different paths. |
manage_dhcp_client | destructive | Add, remove, enable, or disable a DHCP client on an interface. Idempotent by interface name: add returns already_exists if a DHCP client is already configured on the same interface. |
manage_dhcp_lease | destructive | Convert a dynamic DHCP lease to static (make-static) or remove a lease. Idempotent by MAC address. |
manage_dhcp_server | destructive | Add, remove, enable, or disable a DHCP server. Idempotent by name: add returns already_exists if a server with the same name, interface, and address pool already exists. |
manage_dns_settings | write | Update DNS resolver settings (upstream servers, cache size, cache TTL, allow-remote-requests). Idempotent: returns no_change if nothing differs. |
manage_interface_list | destructive | Add or remove an interface list. Idempotent by name. Removing a list that has members is blocked by RouterOS — the error is surfaced as-is. |
manage_interface_list_member | destructive | Add or remove an interface from an interface list. Idempotent by list+interface composite key. add returns already_exists if the membership exists. remove returns not_found gracefully. |
manage_ip_address | destructive | Add, update, or remove an IP address on a MikroTik router interface. Performs idempotency checks for add operations and supports dry-run mode for all actions. |
manage_ip_pool | destructive | Add or remove an IP address pool. Idempotent by name: add returns already_exists if a pool with the same name and ranges already exists. |
manage_ip_service | write | Enable or disable a RouterOS IP service (api, api-ssl, ssh, telnet, www, www-ssl, winbox, ftp). Port number changes are intentionally not supported to prevent accidental lockout. |
manage_ipsec_peer | destructive | Add, remove, enable, or disable an IPSec peer. Idempotent by name: add returns already_exists if a peer with the same name and address already exists. |
manage_ipsec_policy | destructive | Add, remove, enable, or disable an IPSec policy. Idempotent by composite key (srcAddress + dstAddress + tunnel). |
manage_log_action | destructive | Add or remove a RouterOS logging action target. Idempotent by name. |
manage_log_rule | destructive | Add, remove, enable, or disable a RouterOS logging rule. Idempotent by topics+logAction (add → already_exists on match; remove → not_found handled gracefully; enable/disable throw NOT_FOUND when absent). Supports dry-run. |
manage_netwatch_entry | destructive | Add, remove, enable, or disable a Netwatch monitoring entry. Idempotent by host+port: add returns already_exists if an entry with the same host and port already exists. |
manage_ntp_client | write | Update NTP client settings on a MikroTik router. Idempotent: returns already_set if no changes are needed. |
manage_ovpn_client | destructive | Add, update, or remove an OpenVPN client interface. Idempotent by name (already_exists on matching name+connectTo; CONFLICT on differing connectTo; no_change when an update differs in nothing). Password is always written when provided since RouterOS does not return it on GET. |
manage_ovpn_server | write | Enable, disable, or configure the OpenVPN server (a per-router singleton). Throws NOT_FOUND if the OpenVPN package is not installed. The set action requires at least one configuration field. |
manage_package | write | Enable or disable a RouterOS package. Changes take effect only after a router reboot — use the reboot tool to apply. Idempotent: no-op if already in the target state. |
manage_ppp_profile | destructive | Add, update, or remove a PPP profile. Idempotent by name. update returns no_change when requested values match. Built-in profiles (default, default-encryption) cannot be removed — RouterOS blocks this and the error is surfaced. |
manage_pppoe_client | destructive | Add, update, or remove a PPPoE client interface. Idempotent by name (already_exists on matching name+interface+user; CONFLICT on differing config; no_change when an update differs in nothing). Password is always written when provided since RouterOS does not return it on GET. |
manage_queue | destructive | Add, remove, enable, or disable a simple queue. Idempotent by name: add returns already_exists if a queue with the same name and target already exists. |
manage_route | destructive | Add or remove a static route on a MikroTik router. Performs idempotency checks for add operations and supports dry-run mode for all actions. |
manage_routing_rule | destructive | Add, remove, enable, or disable a policy routing rule. Idempotent by srcAddress+dstAddress+interface+table composite key; a repeated add with an explicit, different ruleAction is a CONFLICT. Supports dry-run mode. |
manage_routing_table | destructive | Create or remove a custom routing table. Idempotent by table name. Supports dry-run mode. |
manage_scheduled_job | destructive | Add, update, remove, enable, or disable a RouterOS scheduler entry. onEvent is arbitrary RouterOS script run with the router user |
manage_script | destructive | Add, update, or remove a RouterOS script. Idempotent by name. add throws CONFLICT if the name already exists; update throws NOT_FOUND if it does not. Supports dry-run. |
manage_upgrade | write | Trigger a RouterOS package update check or install. |
manage_user | destructive | Add, remove, enable, disable, or set the password for a local RouterOS user. Idempotent by name: add returns already_exists if a user with the same name and group already exists. |
manage_user_group | destructive | Add, update, or remove a local RouterOS user group. Idempotent by name: add returns already_exists if a group with the same name and policy already exists. |
manage_vlan | destructive | Add, remove, enable, or disable a VLAN interface. Idempotent by name: add returns already_exists when a VLAN with matching name, vlan-id, and parent interface exists. Supports dry-run mode. |
manage_vrrp_instance | destructive | Add, remove, enable, or disable a VRRP instance. Idempotent by name: add returns already_exists if an instance with the same name, interface, and VRID already exists. |
manage_wifi_interface | write | Enable, disable, or update SSID settings on a WiFi interface. At least one of disabled or ssid must be provided. |
manage_wireguard_interface | destructive | Add, remove, enable, or disable a WireGuard interface. Idempotent by name. RouterOS generates the private key on create — it is never passed in. The public key is returned after creation. |
manage_wireguard_peer | destructive | Add or remove a WireGuard peer. Idempotent by public key: add returns already_exists if a peer with the same public key already exists on the interface. |
ping | write | Send ICMP echo requests from the router to a target address. Returns per-packet RTT and summary statistics. 100% packet loss is a valid result, not an error. |
plan_changes | write | Preview a sequence of write operations: each step runs with dryRun=true against live state, returning affected paths and the predicted action per step. Use apply_plan to execute the same steps for real. |
reboot | write | Trigger a controlled router reboot with an optional delay. Supports dry-run. Use this tool instead of run_command for reboots — run_command |
rollback_change | write | Restore device state to before a write, identified by its journal ID. RouterOS: reads the before-snapshot, diffs against live state, and applies the reverse. SwOS: re-POSTs the exact pre-write |
run_command | write | Execute an arbitrary RouterOS console command via SSH. Guarded by an allow/deny policy (built-in deny list blocks destructive commands; tighten via cmdAllow in routers.yaml or MIKROMCP_CMD_ALLOW). Prefer dedicated tools (reboot, etc.) where available. Output capped at 4000 characters. |
run_script | write | Execute a named RouterOS script. Fire-and-forget — the script runs asynchronously and its output is written to the router system log. Use get_log after calling this tool to see results. |
set_system_clock | write | Set the system date, time, and/or timezone on a MikroTik router. Idempotent: returns already_set if the values already match. Supports dry-run. |
test_read | read | test |
torch | read | Capture a real-time traffic snapshot on a router interface. RouterOS runs the capture for |
traceroute | read | Trace the network path from the router to a target address. Returns an ordered hop list with RTT per hop. Timeouts and partial results are valid responses. Not auto-retried. |
write_swos_blob | write | Mutate a SwOS |
Trust audit
BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (6 observation(s))
- Network
- declared (4 observation(s))
- Shell
- declared (1 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (25)
# rejectUnauthorized: false # Self-signed cert — fingerprint strongly recommended
console.log(chalk.green(`\n Generated token: ${chalk.bold(rawToken)}`));delete_file, manage_address_list_entry, manage_bridge, manage_bridge_port, manage_certificate, manage_container, manage_container_env, manage_container_mount, manage_dhcp_client, manage_dhcp_lease, ma
return createHash("md5").update(input).digest("hex");const ha1 = createHash("md5").update(`${user}:${REALM}:${password}`).digest("hex");const ha2 = createHash("md5").update(`${method}:${fields.uri}`).digest("hex");? createHash("md5"): createHash("md5").update(`${ha1}:${fields.nonce}:${ha2}`).digest("hex");const WIKI_DIR = resolve(__dirname, "../../docs/wiki");
import type { MikroMCPErrorData } from "../../types.js";import type { RouterOSRestClient } from "../../adapter/rest-client.js";import type { RouterOSRecord, RouterOSValue, RestorePlan } from "../../types.js";import { isTrue, normalizeWireValue } from "../../adapter/response-parser.js";**Example prompt:** "Fetch http://10.0.0.1/status from router core-sw and show me the response body"
**Example prompt:** "Fetch http://10.0.0.1/status from router core-sw and show me the response body"
curl -sk https://10.0.0.1/rest/system/resource \
curl -sk https://10.0.0.1/rest/system/resource \
expect(requestMock.mock.calls[0][0]).toBe("http://192.0.2.1:80/rest/interface");tls: { enabled: true, rejectUnauthorized: false },tls: { enabled: true, rejectUnauthorized: false },const opts = buildAgentOptions({ enabled: true, rejectUnauthorized: false });rejectUnauthorized: false,
astro, @astrojs/starlight, sharp
@inquirer/prompts, @modelcontextprotocol/sdk, basic-ftp, bcryptjs, chalk, commander, dotenv, nanoid
@astrojs/sitemap, astro
Gates applied: no_behavioural_pass.
52a3285b5d24full audit observations/trust-audit/mcp-server/alikarami__mikro.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | 52a3285b5d24 | BLOCK | D | 69 | first audit |
Questions
What is the Mikro MCP server?
Production-grade MCP server for MikroTik RouterOS with secure AI-native network automation.
What tools does Mikro expose?
122 in total: 62 read-only, 25 that write, and 35 that can delete or overwrite (delete_file, manage_address_list_entry, manage_bridge, manage_bridge_port, manage_certificate). Every one is listed on this page with its risk.
Is Mikro safe to connect to an agent?
No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 35 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Mikro need?
It reads MIKROMCP_CONFIRMATION_SECRET, MIKROMCP_ITEST_PASSWORD, ROUTER_CORE01_PASS, ROUTER_ITEST_PASS and ROUTER_R1_PASS from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Mikro run?
It speaks sse, stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as mikromcp-site at 0.1.0.
How current is this page?
The grade is for one exact copy of the source (52a3285b5d24), read on 2026-10-08. The repository is watched and re-audited when it changes.