mcpField
M
MikroTik RouterOS

MikroTik RouterOS

本地服务
github.com/StefanKnol云与基础设施05 周前更新

关于 MikroTik RouterOS

MikroTik RouterOS 是通过二进制 API 管理路由器配置的 MCP 服务,面向网络管理员和自动化客户端。它以真实的 .id 标识规则,写入后会读取结果以便核验。

主要功能

  1. 01通过二进制 API 连接 RouterOS
  2. 02读取并写入真实 .id
  3. 03写入后回读核验变更
  4. 04覆盖防火墙、路由、DNS 等
  5. 05拒绝使用位置编号进行写入

适用场景

  1. 01查看路由器系统与接口信息
  2. 02添加或调整防火墙规则
  3. 03查询 DHCP 租约和地址列表
  4. 04核验配置变更是否生效

MCP 相关

它向 MCP 客户端提供 RouterOS 查询与配置工具,涵盖系统信息、接口、IP、过滤规则、NAT、DHCP、DNS、路由和日志。规则写入要求使用读取所得的真实 .id。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"stefanknol-mikrotik": {
"command": "uvx",
"args": [
"mikrotik-mcp"
],
"env": {
"MIKROTIK_HOST": "<MIKROTIK_HOST>",
"MIKROTIK_USERNAME": "<MIKROTIK_USERNAME>",
"MIKROTIK_PASSWORD": "<MIKROTIK_PASSWORD>",
"MIKROTIK_PORT": "<MIKROTIK_PORT>",
"MIKROTIK_TLS": "<MIKROTIK_TLS>",
"MIKROTIK_TLS_FINGERPRINT": "<MIKROTIK_TLS_FINGERPRINT>",
"MIKROTIK_TIMEOUT": "<MIKROTIK_TIMEOUT>"
}
}
}
}
启动命令uvx mikrotik-mcp
需要配置的环境变量
MIKROTIK_HOSTIP address or hostname of the router, e.g. 192.168.88.1
MIKROTIK_USERNAMERouterOS user. Use a dedicated account rather than admin; its group must carry the `api` policy, and a group without it is rejected with the same error as a wrong password.
MIKROTIK_PASSWORD密钥Password for that user.
MIKROTIK_PORTAPI port: 8729 for api-ssl (default), 8728 for plaintext.
MIKROTIK_TLSUse the TLS API. Defaults to true; turning it off sends the router password over the network in the clear.
MIKROTIK_TLS_FINGERPRINTSHA-256 of the router certificate. MikroTik's API-SSL certificate is self-signed, so pinning this is what makes the connection authenticated rather than merely encrypted.
MIKROTIK_TIMEOUTConnection timeout in seconds. Defaults to 10.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypimikrotik-mcp0.3.0

工具

34

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

mikrotik-mcp

mcp-name: io.github.StefanKnol/mikrotik-mcp

一个通过 MikroTik RouterOS 二进制 API 提供服务的 MCP 服务,而不是通过 SSH 驱动 CLI。

这一区别正是关键所在。CLI 打印的是位置编号,并非规则的标识。按位置列出规则、再按位置写入的服务,要么会直接失败——where .id=3 什么也匹配不到,因此每次写入都会对明明存在的规则报告“未找到”——要么更糟:顺序变更后,成功写入了另一条规则。在防火墙上,这意味着删除了错误的规则。

二进制 API 在每次读取时都会返回真实的 .id(*7、*1f)。因此:

  • 每次读取都会返回 id,每次写入都要传入 id;
  • 列表结果还会带有 position,它仅用于显示,不接受用于写入,并会返回说明原因的错误;
  • 写入后会读取回写入的内容,因此可以验证变更,而不是想当然;
  • remove_firewall_rule 接受可选的 confirm_comment,并返回已删除的规则。

使用方法

uvx mikrotik-mcp

通过环境变量配置——如果将密码作为标志传入,ps 就会显示密码:

变量默认值含义
MIKROTIK_HOST—路由器地址。必填。
MIKROTIK_USERNAME—必填。
MIKROTIK_PASSWORD—
MIKROTIK_PORT8729api-ssl 使用 8729,明文连接使用 8728。
MIKROTIK_TLStrue
MIKROTIK_TLS_FINGERPRINT—路由器证书的 SHA-256 指纹,用于固定证书。
MIKROTIK_TIMEOUT10

在 MCP 客户端的配置中:

{
  "mcpServers": {
    "mikrotik": {
      "command": "uvx",
      "args": ["mikrotik-mcp"],
      "env": {
        "MIKROTIK_HOST": "192.168.88.1",
        "MIKROTIK_USERNAME": "mcp-agent",
        "MIKROTIK_PASSWORD": "..."
      }
    }
  }
}

在路由器上

/ip service enable api-ssl
/user group add name=mcp policy=api,read,write,test
/user add name=mcp-agent group=mcp password=<strong-password>

api 策略不可或缺;缺少它时产生的登录错误与密码错误完全相同——因此,如果凭据看起来正确但仍无法登录,请先检查用户组。

如果条件允许,请设置 MIKROTIK_TLS_FINGERPRINT。MikroTik 的 API-SSL 证书是自签名的,因此普通 CA 验证无法通过原厂设备的验证;固定证书才能让连接获得身份验证,而不只是加密。

工具

共 34 个工具,涵盖系统信息、接口、IP 寻址、防火墙过滤(IPv4 和 IPv6)、防火墙地址列表、NAT、DHCP 租约、DNS、路由和日志——此外还有 ros_list,它可以读取任意 RouterOS 路径,因此无需专用工具即可覆盖所有内容。

这里刻意没有通用写入入口。

首次调用前,有三点值得了解:

  • 写入必须使用 id(*7),不能使用 position。 每个列表结果中都会同时显示二者。position 表示规则当前在评估顺序中的位置;每当有内容被添加、删除或移动时,它都会变化,而且计数范围是整个表,而非你筛选出的链。传入 position 进行写入时会被拒绝,而不是被猜测处理。
  • IPv4 和 IPv6 使用独立的规则集。 防火墙工具接受 family 参数,默认值为 ipv4,因此设备可能看起来已锁定,但 IPv6 规则表却为空,也就会接受所有流量。出于这个原因,列出 IPv4 规则时也会报告 IPv6 规则数量。
  • 地址列表中保存着配置导出无法显示的状态。 规则在运行时添加的条目带有超时时间,且只存在于内存中。请先通过 list_address_list_entries 查询 count_only:填充满的封锁列表可能包含数万个条目。

与 mcphub 搭配使用

mcphub 将 MCP 服务置于统一登录之后,并按账户授权使用。每台路由器都是一个独立后端,位于各自的 /mcp/<slug>,并在客户端中注册为独立连接器。

添加

通过注册表添加——这是更合适的默认方式。点击 从注册表添加,搜索 mikrotik-mcp,Hub 会根据 server.json 构建设置表单,并在启用后端时启动 uvx mikrotik-mcp。它会在独立进程中运行,无法读取 Hub 为其他用途持有的凭据。通过这种方式添加的后端默认处于禁用状态:打开它,查看工具列表,然后再启用。

作为插件添加——将此软件包安装到 Hub 自身的环境中,mikrotik 就会显示为一种后端类型,并提供带类型的字段和一个测试按钮,该按钮会报告路由器的标识信息和 RouterOS 版本。配置起来更方便,但进程内插件可以读取 Hub 持有的所有凭据。请在构建自己的 Hub 镜像时使用这种方式。

要设置的内容

无论采用哪种方式,都需要设置相同的内容。环境变量如下:

变量默认值
MIKROTIK_HOST—路由器地址。必填。
MIKROTIK_USERNAME—必填。请使用专用用户,而不是 admin;该用户所属组需要 api 策略。
MIKROTIK_PASSWORD—必填。
MIKROTIK_PORT8729api-ssl 使用 8729,明文传输使用 8728。
MIKROTIK_TLStrue关闭此选项会使路由器密码以明文形式通过网络传输。
MIKROTIK_TLS_FINGERPRINT—路由器证书的 SHA-256 值。固定该值,才能对 TLS 连接进行身份验证,而不只是加密。
MIKROTIK_TIMEOUT10秒。

无需数据目录:此服务读写的所有数据都在路由器上,因此无需保留本地状态。请勿勾选 为此服务提供数据目录。

权限级别

Hub 只根据每个工具的 readOnlyHint 和 destructiveHint 读取并执行授权级别——高于授权级别的工具不会出现在 tools/list 中,即使被调用也会遭到拒绝。

级别可用工具
viewer17 个工具读取整个配置,不做任何更改。
user+7 个工具添加规则和条目,并禁用或重新启用它们。
admin+10 个工具删除、就地编辑和重新排序。

viewer — connectivity_check、get_dns_settings、get_firewall_rule、 get_logs、get_nat_rule、list_address_list_entries、list_address_lists、 list_dhcp_leases、list_dns_adlist、list_dns_static、list_firewall_rules、 list_interfaces、list_ip_addresses、list_nat_rules、list_routes、 ros_list、system_info。

user 额外提供 add_address_list_entry、add_dns_static、add_firewall_rule、 add_nat_rule、make_lease_static、set_firewall_rule_enabled、 set_nat_rule_enabled。这些工具都会写入数据,但没有一个会移除任何内容:添加规则属于写入,而非破坏;禁用规则会保留该规则、注释和位置,因此重新启用后会准确恢复原状。禁用规则是一种可逆的方式,可以查明某条规则是否导致了某个问题,因此它属于此级别,而非 admin——否则,user 将完全没有安全测试的方式。

admin 额外提供以下十个破坏性工具:

工具将丢失的内容
remove_firewall_rule该规则。返回的副本是唯一记录。
remove_nat_rule该规则。
remove_dns_static该条目。
remove_address_list_entry该条目。动态条目会在其规则下次匹配时重新出现;静态条目不会。
update_firewall_rule对其设置或清除的任何内容,其之前的值。
update_nat_rule同上。
update_dns_static同上。
move_firewall_rule之前的顺序,而顺序就是防火墙的全部语义。
move_nat_rule同上。
set_interface_enabled磁盘上的内容不会丢失——但如果禁用接收请求的接口,就会切断唯一的返回路径,而此处没有任何工具能远程撤销此操作。

测试会按名称固定上述每项权限分配,因此以后添加的工具会导致测试套件失败,直到有人决定它属于哪个级别。

发布到 MCP 注册表

server.json 是官方 MCP 注册表的清单,并依据已发布的架构进行验证。它声明了 uvx mikrotik-mcp 命令和每个 MIKROTIK_* 变量,并标明哪些是必需项、哪些是机密项——这样,浏览注册表的客户端无需了解此服务,就能生成正确的设置表单。

发布有先后顺序,因为注册表会验证发布条目的人是否确实拥有该条目指向的软件包。

1. 软件包必须已发布到 PyPI。 注册表会获取 pypi.org/pypi/mikrotik-mcp/<version>/json,并拒绝软件包不存在的条目。为版本打标签并让 CI 发布:

git tag v0.1.0 && git push --tags

这需要先设置 PyPI Trusted Publisher。由于此项目尚未发布到 PyPI,因此必须设置为待处理发布者——只有项目存在后,项目专属的 Publishing 选项卡才会出现,这正是本页要解决的先有鸡还是先有蛋的问题:

pypi.org → 账户设置 → Publishing → 添加新的待处理发布者

字段值
PyPI 项目名称mikrotik-mcp
所有者StefanKnol
仓库名称mikrotik-mcp
工作流名称ci.yml
环境名称pypi

环境名称很重要:发布作业声明了 environment: pypi,如果两者不一致,PyPI 就会拒绝上传。

2. README 必须包含所有权令牌。 注册表会在 PyPI 描述中查找 mcp-name: io.github.StefanKnol/mikrotik-mcp,而该描述就是这个文件——它位于文件顶部,单独占一行。这能证明发布注册表条目的人控制着该 PyPI 软件包。

3. 注册表条目会自行发布。 ci.yml 中的 registry 作业会在同一标签对应的 PyPI 上传完成后运行,并通过 mcp-publisher login github-oidc 进行身份验证。GitHub 会签发一个短期有效的 OIDC 令牌,注册表验证该令牌后,会根据仓库所有者授予 io.github.StefanKnol/* 命名空间权限。无需保存机密,也无需在每次发布时进行设备流程登录。

该作业会等待 PyPI 实际提供新版本。注册表会获取 pypi.org/pypi/mikrotik-mcp/<version>/json,并拒绝它无法找到的软件包条目;而该端点会比上传晚几秒更新——直接在上传后发布,时间上可能会撞上。

重新运行是安全的:版本已存在于注册表中,正是该作业要实现的结果,因此作业会报告这一情况并通过,而不会因注册表拒绝重复条目而失败。

手动发布——例如恢复失败的运行,或发布早于该作业创建时间的版本:

curl -sL https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_linux_amd64.tar.gz | tar xz mcp-publisher
./mcp-publisher login github && ./mcp-publisher publish

login github 会启动设备流程并验证你是 StefanKnol,从而无需询问即可授权与 OIDC 路径相同的命名空间。

版本号会出现在四处:pyproject.toml、__version__、server.json,以及该文件中 packages 条目内的版本号。与其手动编辑:

uv run python scripts/release.py 0.2.0 --tag

该命令会设置这四处的版本号、验证它们、提交并打标签。注册表会将每个版本视为单独的条目,并检查 PyPI 上是否存在完全匹配该版本的软件包,因此嵌套的 packages[].version 与顶层版本号同样重要——而它很容易被漏掉,因为缺少它时清单仍然有效。测试会确保这些版本号一致。

开发

uv sync --extra dev
uv run pytest

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。