关于 MikroTik RouterOS
MikroTik RouterOS 是通过二进制 API 管理路由器配置的 MCP 服务,面向网络管理员和自动化客户端。它以真实的 .id 标识规则,写入后会读取结果以便核验。
主要功能
- 01通过二进制 API 连接 RouterOS
- 02读取并写入真实 .id
- 03写入后回读核验变更
- 04覆盖防火墙、路由、DNS 等
- 05拒绝使用位置编号进行写入
适用场景
- 01查看路由器系统与接口信息
- 02添加或调整防火墙规则
- 03查询 DHCP 租约和地址列表
- 04核验配置变更是否生效
MCP 相关
它向 MCP 客户端提供 RouterOS 查询与配置工具,涵盖系统信息、接口、IP、过滤规则、NAT、DHCP、DNS、路由和日志。规则写入要求使用读取所得的真实 .id。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx mikrotik-mcpMIKROTIK_HOSTIP address or hostname of the router, e.g. 192.168.88.1MIKROTIK_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+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
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_PORT | 8729 | api-ssl 使用 8729,明文连接使用 8728。 |
MIKROTIK_TLS | true | |
MIKROTIK_TLS_FINGERPRINT | — | 路由器证书的 SHA-256 指纹,用于固定证书。 |
MIKROTIK_TIMEOUT | 10 |
在 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_PORT | 8729 | api-ssl 使用 8729,明文传输使用 8728。 |
MIKROTIK_TLS | true | 关闭此选项会使路由器密码以明文形式通过网络传输。 |
MIKROTIK_TLS_FINGERPRINT | — | 路由器证书的 SHA-256 值。固定该值,才能对 TLS 连接进行身份验证,而不只是加密。 |
MIKROTIK_TIMEOUT | 10 | 秒。 |
无需数据目录:此服务读写的所有数据都在路由器上,因此无需保留本地状态。请勿勾选 为此服务提供数据目录。
权限级别
Hub 只根据每个工具的 readOnlyHint 和 destructiveHint 读取并执行授权级别——高于授权级别的工具不会出现在 tools/list 中,即使被调用也会遭到拒绝。
| 级别 | 可用工具 | |
|---|---|---|
viewer | 17 个工具 | 读取整个配置,不做任何更改。 |
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
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。