Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Manages MikroTik routers via the RouterOS API (port 8728/8729). Use when the user wants to configure, monitor, or troubleshoot a MikroTik router — including interfaces, firewall, DHCP, DNS, routing, queues, VPN, and system management.
.claude/skills/mikrotik-api/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-16 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-17 | ✗→✓ | ▲ Improved | — | — |
| case-18 | ✗→✓ | ▲ Improved | — | — |
| case-03 | ✗→✓ | ▲ Improved | — | — |
Communicate with MikroTik RouterOS devices using the Python routeros-api library over the API port (8728 plain, 8729 SSL).
Install the library if not present:
bashpip3 install --break-system-packages routeros-api
It is highly recommended to use environment variables for credentials to avoid hardcoding.
Set these in your environment or .env file:
MIKROTIK_HOST: Router IP or hostnameMIKROTIK_USERNAME: Router usernameMIKROTIK_PASSWORD: Router passwordpythonimport routeros_api import os # Get credentials from environment variables host = os.getenv('MIKROTIK_HOST') username = os.getenv('MIKROTIK_USERNAME') password = os.getenv('MIKROTIK_PASSWORD') # Fallback to manual input if env vars are missing if not all([host, username, password]): print("Environment variables MIKROTIK_HOST, MIKROTIK_USERNAME, or MIKROTIK_PASSWORD are not set.") # host = input("Enter Host: ") ... conn = routeros_api.RouterOsApiPool( host=host, username=username, password=password, plaintext_login=True, # Required for RouterOS 6.43+ port=8728 # Use 8729 for SSL ) api = conn.get_api() # ... do work ... conn.disconnect()
MIKROTIK_HOST, MIKROTIK_USERNAME, and MIKROTIK_PASSWORD.conn.disconnect() when done.plaintext_login=True for RouterOS v6.43+ and v7.x.pythonconn = routeros_api.RouterOsApiPool( host=host, username=username, password=password, plaintext_login=True, use_ssl=True, ssl_verify=False, # Set True with proper certs ssl_verify_hostname=False, port=8729 )
pythonresource = api.get_resource('/ip/address') items = resource.get() # Get all items = resource.get(interface='ether1') # Filter by param items = resource.get(disabled='false') # Filter by status
pythonresource = api.get_resource('/ip/address') resource.add(address='192.168.1.1/24', interface='ether1') # With comment resource.add(address='192.168.1.1/24', interface='ether1', comment='Management')
pythonresource = api.get_resource('/ip/address') resource.set(id='*1', address='192.168.2.1/24') resource.set(id='*1', comment='Updated via API') resource.set(id='*1', disabled='yes') # Disable entry resource.set(id='*1', disabled='no') # Enable entry
python\nresource = api.get_resource('/ip/address')resource.remove(id='*1')
pythonresource = api.get_resource('/system') resource.call('reboot') # Call with parameters resource = api.get_resource('/ip/firewall/filter') resource.call('move', {'numbers': '*1', 'destination': '*5'})
pythonresource = api.get_resource('/interface') resource.set(id='*1', disabled='yes') # Disable resource.set(id='*1', disabled='no') # Enable
| Task | Resource Path | |------|--------------| | System info (CPU, RAM, uptime) | /system/resource | | Router identity | /system/identity | | System clock | /system/clock | | NTP client | /system/ntp/client | | NTP server | /system/ntp/server | | Scheduler | /system/scheduler | | Scripts | /system/script | | Logging rules | /system/logging | | Log entries | /log | | Packages | /system/package | | Package update | /system/package/update | | Router board info | /system/routerboard | | License | /system/license | | Health (voltage, temp) | /system/health | | History | /system/history | | Users | /user | | User groups | /user/group | | Active users | /user/active | | SSH keys | /user/ssh-keys | | Files | /file | | Backup | /system/backup | | SNMP | /snmp | | SNMP community | /snmp/community | | Certificates | /certificate | | Console | /system/console | | LEDs | /system/leds |
| Task | Resource Path | |------|--------------| | All interfaces | /interface | | Ethernet | /interface/ethernet | | Bridge | /interface/bridge | | Bridge ports | /interface/bridge/port | | Bridge VLANs | /interface/bridge/vlan | | Bridge hosts (MAC table) | /interface/bridge/host | | Bridge MSTi | /interface/bridge/msti | | Bridge settings | /interface/bridge/settings | | VLAN | /interface/vlan | | Bonding (LACP/bonding) | /interface/bonding | | EoIP tunnel | /interface/eoip | | GRE tunnel | /interface/gre | | IPIP tunnel | /interface/ipip | | VXLAN | /interface/vxlan | | VXLAN VTEP | /interface/vxlan/vtep | | WireGuard | /interface/wireguard | | WireGuard peers | /interface/wireguard/peers | | L2TP client | /interface/l2tp-client | | L2TP server | /interface/l2tp-server/server | | SSTP client | /interface/sstp-client | | SSTP server | /interface/sstp-server/server | | OVPN client | /interface/ovpn-client | | OVPN server | /interface/ovpn-server/server | | PPPoE client | /interface/pppoe-client | | PPPoE server | /interface/pppoe-server/server | | PPTP client | /interface/pptp-client | | PPTP server | /interface/pptp-server/server | | LTE | /interface/lte | | LTE APN | /interface/lte/apn | | Wireless (WiFi legacy) | /interface/wireless | | WiFi (new, ROS 7) | /interface/wifi | | WiFi channels | /interface/wifi/channel | | WiFi datapath | /interface/wifi/datapath | | WiFi security | /interface/wifi/security | | WiFi configuration | /interface/wifi/configuration | | WiFi provisioning | /interface/wifi/provisioning | | WiFi registration table | /interface/wifi/registration-table | | WiFi access list | /interface/wifi/access-list | | WiFi interworking | /interface/wifi/interworking | | Interface lists | /interface/list | | Interface list members | /interface/list/member | | Ethernet switch | /interface/ethernet/switch | | Ethernet switch port | /interface/ethernet/switch/port | | Traffic monitor | /interface/monitor-traffic |
| Task | Resource Path | |------|--------------| | IP addresses | /ip/address | | ARP table | /ip/arp | | Routes | /ip/route | | Route rules | /ip/route/rule | | DNS settings | /ip/dns | | DNS static entries | /ip/dns/static | | DNS cache | /ip/dns/cache | | DHCP client | /ip/dhcp-client | | DHCP server | /ip/dhcp-server | | DHCP server network | /ip/dhcp-server/network | | DHCP server leases | /ip/dhcp-server/lease | | DHCP server option | /ip/dhcp-server/option | | DHCP server option sets | /ip/dhcp-server/option/sets | | DHCP relay | /ip/dhcp-relay | | IP pool | /ip/pool | | IP neighbors | /ip/neighbor | | IP neighbor discovery | /ip/neighbor/discovery-settings | | IP services | /ip/service | | IP settings (forwarding) | /ip/settings | | IP proxy | /ip/proxy | | IP proxy access list | /ip/proxy/access | | IP SOCKS | /ip/socks | | IP SSH | /ip/ssh | | IP cloud | /ip/cloud | | IP UPnP | /ip/upnp | | IP UPnP interfaces | /ip/upnp/interfaces | | IP SMB | /ip/smb | | IP traffic flow | /ip/traffic-flow | | IP traffic flow target | /ip/traffic-flow/target | | IP accounting | /ip/accounting | | IP Kid Control | /ip/kid-control | | IP Kid Control devices | /ip/kid-control/device | | IP Hotspot | /ip/hotspot | | IP Hotspot profile | /ip/hotspot/profile | | IP Hotspot user | /ip/hotspot/user | | IP Hotspot user profile | /ip/hotspot/user/profile | | IP Hotspot active | /ip/hotspot/active | | IP Hotspot host | /ip/hotspot/host | | IP Hotspot cookie | /ip/hotspot/cookie | | IP Hotspot IP binding | /ip/hotspot/ip-binding | | IP Hotspot walled garden | /ip/hotspot/walled-garden | | IP Hotspot walled garden IP | /ip/hotspot/walled-garden/ip |
| Task | Resource Path | |------|--------------| | Filter rules | /ip/firewall/filter | | NAT rules | /ip/firewall/nat | | Mangle rules | /ip/firewall/mangle | | RAW rules | /ip/firewall/raw | | Address lists | /ip/firewall/address-list | | Connections (conntrack) | /ip/firewall/connection | | Connection tracking | /ip/firewall/connection/tracking | | Service ports (ALGs) | /ip/firewall/service-port | | Layer 7 protocols | /ip/firewall/layer7-protocol |
| Task | Resource Path | |------|--------------| | IPv6 addresses | /ipv6/address | | IPv6 routes | /ipv6/route | | IPv6 firewall filter | /ipv6/firewall/filter | | IPv6 firewall mangle | /ipv6/firewall/mangle | | IPv6 firewall RAW | /ipv6/firewall/raw | | IPv6 firewall address list | /ipv6/firewall/address-list | | IPv6 ND (Neighbor Disc.) | /ipv6/nd | | IPv6 ND prefix | /ipv6/nd/prefix | | IPv6 DHCP client | /ipv6/dhcp-client | | IPv6 DHCP server | /ipv6/dhcp-server | | IPv6 pool | /ipv6/pool | | IPv6 settings | /ipv6/settings |
| Task | Resource Path | |------|--------------| | Routing tables | /routing/table | | Routing rules | /routing/rule | | OSPF instance | /routing/ospf/instance | | OSPF area | /routing/ospf/area | | OSPF interface template | /routing/ospf/interface-template | | OSPF neighbors | /routing/ospf/neighbor | | OSPF LSA | /routing/ospf/lsa | | BGP connection | /routing/bgp/connection | | BGP template | /routing/bgp/template | | BGP session | /routing/bgp/session | | BGP advertisements | /routing/bgp/advertisements | | BGP networks | /routing/bgp/network | | RIP instance | /routing/rip/instance | | RIP interface template | /routing/rip/interface-template | | Route filter rules | /routing/filter/rule | | Route filter select rules | /routing/filter/select-rule | | Prefix lists | /routing/filter/community-list | | BFD session | /routing/bfd/session | | BFD configuration | /routing/bfd/configuration | | Routing ID | /routing/id | | RPKI | /routing/rpki | | IGMP Proxy | /routing/igmp-proxy | | PIM | /routing/pimsm |
| Task | Resource Path | |------|--------------| | PPP secrets | /ppp/secret | | PPP profiles | /ppp/profile | | PPP active connections | /ppp/active | | PPP AAA settings | /ppp/aaa | | PPP L2TP secret | /ppp/l2tp-secret |
| Task | Resource Path | |------|--------------| | Simple queues | /queue/simple | | Queue tree | /queue/tree | | Queue types | /queue/type | | Interface queues | /queue/interface |
| Task | Resource Path | |------|--------------| | CAPsMAN manager | /caps-man/manager | | CAPsMAN configuration | /caps-man/configuration | | CAPsMAN channel | /caps-man/channel | | CAPsMAN datapath | /caps-man/datapath | | CAPsMAN security | /caps-man/security | | CAPsMAN provisioning | /caps-man/provisioning | | CAPsMAN interface | /caps-man/interface | | CAPsMAN registration table | /caps-man/registration-table | | CAPsMAN access list | /caps-man/access-list | | CAPsMAN remote-cap | /caps-man/remote-cap |
| Task | Resource Path | |------|--------------| | MPLS settings | /mpls | | MPLS interface | /mpls/interface | | MPLS forwarding table | /mpls/forwarding-table | | MPLS LDP | /mpls/ldp | | MPLS LDP interface | /mpls/ldp/interface | | MPLS LDP neighbor | /mpls/ldp/neighbor | | VPLS | /interface/vpls | | Traffic engineering | /mpls/traffic-eng |
| Task | Resource Path | |------|--------------| | Ping | /tool/ping (use call) | | Traceroute | /tool/traceroute (use call) | | Bandwidth test | /tool/bandwidth-test (use call) | | Torch (traffic by IP) | /tool/torch (use call) | | Profile (CPU profile) | /tool/profile | | Netwatch | /tool/netwatch | | E-mail settings | /tool/e-mail | | Fetch (HTTP client) | /tool/fetch | | Graphing interface | /tool/graphing/interface | | Graphing resource | /tool/graphing/resource | | Graphing queue | /tool/graphing/queue | | Sniffer | /tool/sniffer | | SNMP | /snmp | | MAC server | /tool/mac-server | | MAC Winbox | /tool/mac-server/mac-winbox | | MAC Ping | /tool/mac-server/ping | | Bandwidth server | /tool/bandwidth-server | | IP Scan | /tool/ip-scan | | SMS | /tool/sms | | Romon | /tool/romon |
| Task | Resource Path | |------|--------------| | Container config | /container/config | | Containers | /container | | Container mounts | /container/mounts | | Container envs | /container/envs |
| Task | Resource Path | |------|--------------| | IoT Bluetooth | /iot/bluetooth | | IoT Bluetooth scanners | /iot/bluetooth/scanners | | IoT GPIO | /iot/gpio | | IoT MQTT broker | /iot/mqtt/brokers |
| Task | Resource Path | |------|--------------| | ZeroTier | /zerotier | | ZeroTier interface | /zerotier/interface |
pythonresource = api.get_resource('/ip/firewall/filter') rules = resource.get(chain='forward', action='drop')
pythonresource = api.get_resource('/ip/firewall/filter') resource.add( chain='forward', action='accept', src_address='10.0.0.0/8', place_before='*5' # Insert before rule *5 )
Note: Use underscores in Python for hyphenated attributes (e.g., src-address → src_address, place-before → place_before).
pythonresource = api.get_resource('/ip/firewall/filter') resource.call('move', {'numbers': '*A', 'destination': '*1'})
pythonresource = api.get_resource('/ip/firewall/address-list') ips = ['1.2.3.4', '5.6.7.8', '9.10.11.12'] for ip in ips: resource.add(list='blocklist', address=ip, comment='Blocked via API')
pythonresource = api.get_resource('/interface') ifaces = resource.get(name='ether5') if ifaces: resource.set(id=ifaces[0]['id'], disabled='yes')
python# The library always returns all properties; filter in Python: resource = api.get_resource('/interface') for iface in resource.get(): print(iface.get('name'), iface.get('type'), iface.get('running'))
python# Tools that produce output need call() with parameters resource = api.get_resource('/tool') # Note: Some tools (ping, traceroute) run indefinitely. # Use count parameter to limit. result = resource.call('ping', {'address': '8.8.8.8', 'count': '4'}) for r in result: print(r)
python# Create a backup file resource = api.get_resource('/system/backup') resource.call('save', {'name': 'api-backup'}) # Export config to file resource = api.get_resource('/') resource.call('export', {'file': 'api-export'})
pythonresource = api.get_resource('/system') resource.call('reboot') # resource.call('shutdown')
pythonresource = api.get_resource('/system/package/update') resource.call('check-for-updates') result = resource.get() print(result) # resource.call('install') # Install and reboot
RouterOS 7.1+ also supports a REST API over HTTP/HTTPS. Use when the Python library is unavailable.
bash# GET - Read resources curl -k -u user:pass https://<IP>/rest/ip/address # PUT - Create new entry curl -k -u user:pass -X PUT https://<IP>/rest/ip/address \ --data '{"address":"192.168.1.1/24","interface":"ether1"}' \ -H "content-type: application/json" # PATCH - Update entry curl -k -u user:pass -X PATCH https://<IP>/rest/ip/address/*1 \ --data '{"comment":"updated"}' -H "content-type: application/json" # DELETE - Remove entry curl -k -u user:pass -X DELETE https://<IP>/rest/ip/address/*1 # POST - Run any command curl -k -u user:pass -X POST https://<IP>/rest/ip/address/print \ --data '{"_proplist":["address","interface"]}' \ -H "content-type: application/json"
bashcurl -k -u user:pass -X POST https://<IP>/rest/interface/print \ --data '{".query":["type=ether"],"_proplist":["name","type","running"]}' \ -H "content-type: application/json"
pythonimport requests from requests.auth import HTTPBasicAuth base = 'https://<IP>/rest' auth = HTTPBasicAuth('<USER>', '<PASS>') # GET all interfaces r = requests.get(f'{base}/interface', auth=auth, verify=False) print(r.json()) # POST (run commands with parameters) r = requests.post(f'{base}/ip/address/print', auth=auth, verify=False, json={'_proplist': ['address', 'interface']}) print(r.json())
pythonimport routeros_api from routeros_api.exceptions import RouterOsApiCommunicationError try: conn = routeros_api.RouterOsApiPool(host, username=user, password=pw, plaintext_login=True) api = conn.get_api() resource = api.get_resource('/ip/address') resource.add(address='invalid', interface='nonexistent') except RouterOsApiCommunicationError as e: print(f"API Error: {e}") except ConnectionError: print("Cannot reach router") finally: try: conn.disconnect() except: pass
| Code | Meaning | |------|---------| | 0 | Missing item or command | | 1 | Argument value failure | | 2 | Command interrupted | | 3 | Scripting related failure | | 4 | General failure | | 5 | API related failure | | 6 | TTY related failure | | 7 | Value from :return command |
id field in responses (e.g., *1, *A) is the internal MikroTik ID used for set/remove.src-address → src_address.place_before when adding to control position./routing/ospf/instance not /routing/ospf)./ip/service enable api.count or duration parameter.www or www-ssl service enabled on the router.count, duration, once).| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +32 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.