内容
<p align="center">
<img src="docs/assets/librenmsctrl-social-preview.jpg" alt="librenmsctrl banner" width="900">
</p>
<p align="center">
<a href="https://lidless.dev"><img src="docs/assets/marks/librenmsctrl-circle.png" width="48" alt="Lidless Labs"></a>
</p>
<h1 align="center">librenmsctrl</h1>
<p align="center">
<strong>一个用于 LibreNMS 的操作控制命令行工具:通过 API 令牌身份验证,检查设备、端口、端口健康状况、警报和事件。</strong>
</p>
<p align="center">
<a href="https://lidless.dev/librenms-mcp"><strong>网站 → lidless.dev/librenms-mcp</strong></a>
</p>
<p align="center">
<img src="https://shieldcn.dev/npm/@solomonneas/librenms-mcp.svg" alt="npm 版本">
<img src="https://shieldcn.dev/badge/ctrl-CLI-2563EB.svg" alt="控制命令行工具">
<img src="https://shieldcn.dev/badge/MCP-compatible-8A2BE2.svg" alt="MCP 兼容">
<img src="https://shieldcn.dev/badge/license-MIT-green.svg" alt="MIT 许可证">
</p>
librenmsctrl 是一个用于 [LibreNMS](https://www.librenms.org/) 的本地操作控制命令行工具,这是一个开源的网络监控系统。它为 shell、cron 和 CI 提供了一个键入的命令表面,用于读取被监控的网络:设备、端口、端口健康状况、警报、警报历史和事件日志,通过 LibreNMS API 令牌身份验证。
同一个包仍然与 MCP 兼容,用于代理工作流。`librenmsctrl mcp` 启动 stdio [模型上下文协议](https://modelcontextprotocol.io) 适配器,并且现有的 `librenms-mcp` 二进制文件继续适用于已经使用它的启动器和配置。MCP 适配器只能在您传递明确的 `confirm: true` 时确认或静音警报。它与指向原始 LibreNMS REST API 的代理不同,在一个重要的方面:每个写入都经过验证,每个参数在离开主机之前都经过模式验证,并且您的令牌从所有输出中被删除,因此幻觉的工具调用不会意外地更改您的监控状态。
> **状态:正在进行。** v1 发布了读取工具(第 1 层)和确认门控安全写入(第 2 层)。破坏性操作(第 3 层),例如设备删除、警报规则删除和批量端口重置,被故意推迟,直到写入门控模式有更多现场时间。请将其视为早期但可用的;读取路径和两个写入门控已测试。
## 功能
librenmsctrl 将 LibreNMS 实例转换为网络监控和可观察性工作的可脚本控制表面:列出 LibreNMS 正在通过 SNMP 轮询的设备,拉取单个设备或端口,检查端口健康状况和利用率,读取当前警报和警报历史,并跟踪事件日志。它通过 LibreNMS API 令牌进行身份验证,在幕后与 LibreNMS `/api/v0` REST API 通信,并且可以发出人类可读的表格或原始 JSON 用于管道传输。
对于 MCP 客户端,`mcp` 子命令将相同的 LibreNMS 客户端核心暴露为结构化工具输出,代理可以对其进行推理。包名称仍为 `@solomonneas/librenms-mcp`,并且后兼容的 `librenms-mcp` 二进制文件被故意保持稳定。
写入操作分为三个层级:
- **第 1 层(读取)**:开放。无需确认标志。状态、设备和端口列表、单个设备或端口、端口健康状况、警报列表、警报历史、事件日志。
- **第 2 层(安全写入)**:需要明确的 `confirm: true` 参数,并在每个写入工具的 JSON 模式中记录。确认警报、取消静音警报或将设备置于维护窗口中。缺少确认标志的工具调用在任何 HTTP 流量离开主机之前抛出 `WriteGateError`。
- **第 3 层(破坏性)**:未在 v1 中实现。当添加时,设备删除和警报规则删除等操作将额外需要 `destructive: true`。模型不能从幻觉调用中绕过任一门控。
每个工具调用都针对其发布的 TypeBox `inputSchema` 进行验证,然后工具运行。ID、端口 ID、设备 ID、限制和 `type`/`state` 过滤器都经过边界和枚举检查,因此畸形或注入样式的参数被提前拒绝,永远不会到达 LibreNMS URL 路径或查询字符串。插值路径和查询值还额外进行 URL 编码作为防御深度。API 令牌在启动时注册到编辑器,并从所有日志和错误输出中掩盖。
## 快速入门
发布到 npm 作为 [`@solomonneas/librenms-mcp`](https://www.npmjs.com/package/@solomonneas/librenms-mcp)。安装包以获取 `librenmsctrl` 操作命令行工具和后兼容的 `librenms-mcp` MCP 启动器。
```bash
# 通过兼容的 `librenms-mcp` 二进制文件按需启动 MCP 适配器
npx -y @solomonneas/librenms-mcp
# 安装全局 `librenmsctrl` 和 `librenms-mcp` 二进制文件
npm install -g @solomonneas/librenms-mcp
```
它需要 Node 20+ 和两个环境变量,`LIBRENMS_URL` 和 `LIBRENMS_TOKEN`。
```bash
export LIBRENMS_URL=https://librenms.example.local
export LIBRENMS_TOKEN=<your-api-token>
librenmsctrl status
librenmsctrl alerts list --state 1
librenmsctrl --json ports health --metric errors_in --limit 10
```
MCP 适配器使用 stdio 通信。一种快速确认它启动的方法是给它一个 MCP `tools/list` 请求:
```bash
export LIBRENMS_URL=https://librenms.example.local
export LIBRENMS_TOKEN=<your-api-token>
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | npx -y @solomonneas/librenms-mcp
```
您应该会得到一个包含上述 13 个工具的 JSON 列表。在正常使用中,您将一个 MCP 客户端指向同一个命令。
## 工具
MCP 适配器暴露了 13 个工具:10 个读取工具,3 个确认门控安全写入工具。此列表是从服务器在 [`mcp-server.ts`](mcp-server.ts) 中的工具注册生成的。
**读取工具(10 个,开放):**
| 工具 | 功能 |
|---|---|
| `librenms_status` | LibreNMS 实例状态检查。 |
| `librenms_list_devices` | 列出被监控的设备。 |
| `librenms_get_device` | 获取单个设备信息。 |
| `librenms_list_ports` | 列出设备上的端口。 |
| `librenms_get_port` | 获取单个端口详细信息。 |
| `librenms_port_health` | 端口健康状况和利用率视图。 |
| `librenms_list_alerts` | 列出当前警报。 |
| `librenms_get_alert` | 获取单个警报信息。 |
| `librenms_alert_history` | 历史警报记录。 |
| `librenms_event_log` | 读取设备事件日志。 |
**安全写入工具(3 个,需要 `confirm: true`):**
| 工具 | 功能 |
|---|---|
| `librenms_ack_alert` | 确认活动警报。 |
| `librenms_unmute_alert` | 静音先前静音的警报。 |
| `librenms_set_maintenance` | 将设备置于维护窗口中。 |
## 配置
设置以下环境变量。两个凭证变量都是必需的。
| 变量 | 必需 | 默认值 | 备注 |
|---|---|---|---|
| `LIBRENMS_URL` | 是 | - | LibreNMS 实例的基本 URL。尾部斜杠被剥离。 |
| `LIBRENMS_TOKEN` | 是 | - | LibreNMS API 令牌。在启动时注册到编辑器并从所有输出中掩盖。 |
| `LIBRENMS_TLS_INSECURE` | 否 | `false` | 跳过自签名证书的 TLS 证书验证。接受 `true`/`1`/`yes`,不区分大小写。 |
## 命令行工具
`librenmsctrl` 是用于 shell、cron 和 CI 的只读操作 **控制命令行工具**。它与 MCP 适配器共享 LibreNMS 客户端核心,并通过令牌身份验证与相同的 `/api/v0` API 通信。它仅公开读取工具(第 1 层);确认门控写入(`ack`、`set_maintenance`、`unmute`)在命令行工具中不公开。
```bash
# 全局安装为 `librenmsctrl`,或通过 `npx -p @solomonneas/librenms-mcp librenmsctrl ...`
librenmsctrl status # 实例健康状况(如果没有系统数据,则退出 1)
librenmsctrl devices list --type down
librenmsctrl devices get core-sw1
librenmsctrl ports list core-sw1
librenmsctrl ports get 42
librenmsctrl ports health --metric errors_in --limit 10
librenmsctrl alerts list --state 1 # 0=ok, 1=active, 2=ack
librenmsctrl alerts get 7
librenmsctrl alerts history --device-id 3 --limit 25
librenmsctrl events list --limit 50
librenmsctrl --json status # 原始 JSON 用于管道传输
```
运行 `librenmsctrl help` 获取完整的标志列表。它读取与服务器相同的 `LIBRENMS_URL`、`LIBRENMS_TOKEN` 和 `LIBRENMS_TLS_INSECURE` 环境变量。退出代码:`0` 成功,`1` 运行时错误(LibreNMS 不可达,调用失败,或 `status` 没有系统数据),`2` 用法错误(未知命令/标志或错误值)。
### 启动 MCP 服务器
`librenmsctrl mcp`(或兼容的 `librenms-mcp` 二进制文件)启动 stdio MCP 服务器。如果启动器直接引用文件路径 `dist/mcp-server.js`,请将其指向 `dist/mcp-bin.js`(或 `dist/cli.js mcp`);使用 `librenms-mcp` 二进制文件名的启动器无需更改。
## MCP 客户端配置
将以下内容复制到您的 MCP 客户端。这是在 Claude Desktop 和 Claude Code 中使用的规范 `mcpServers` 形状。`LIBRENMS_URL` 和 `LIBRENMS_TOKEN` 都是必需的。
```json
{
"mcpServers": {
"librenms": {
"command": "npx",
"args": ["-y", "@solomonneas/librenms-mcp"],
"env": {
"LIBRENMS_URL": "https://librenms.example.local",
"LIBRENMS_TOKEN": "<your-api-token>",
"LIBRENMS_TLS_INSECURE": "false"
}
}
}
}
```
### Claude Code
```bash
claude mcp add librenms -s user -- npx -y @solomonneas/librenms-mcp
```
然后在您的 shell (`~/.bashrc`、`~/.zshrc`) 或在 `claude mcp add` 行上使用 `--env` 标志导出 `LIBRENMS_URL` 和 `LIBRENMS_TOKEN`。
### Claude Desktop
将上面的 `mcpServers` 块添加到 `~/Library/Application Support/Claude/claude_desktop_config.json`(macOS)或 `%APPDATA%\Claude\claude_desktop_config.json`(Windows)。
### Codex CLI
`~/.codex/config.toml`:
```toml
[mcp_servers.librenms]
command = "npx"
args = ["-y", "@solomonneas/librenms-mcp"]
[mcp_servers.librenms.env]
LIBRENMS_URL = "https://librenms.example.local"
LIBRENMS_TOKEN = "<your-api-token>"
LIBRENMS_TLS_INSECURE = "false"
```
### OpenClaw
插件安装后会自动加载。配置放置在您的 `~/.openclaw/openclaw.json` 下的 `plugins.entries.librenms`(或使用捆绑的 `openclaw.plugin.json`):
```json
{
"plugins": {
"entries": {
"librenms": {
"package": "@solomonneas/librenms-mcp",
"activation": { "onStartup": true }
}
}
}
}
```
`~/.openclaw/workspace/.env` 中的环境变量由插件继承。
## 安全
MCP 使用三层写入门控模式:
- **第 1 层(读取)**:开放。无需确认标志。
- **第 2 层(安全写入)**:需要明确的 `confirm: true` 参数。该 JSON 模式在每个写入工具上都有文档记录。缺少确认标志的工具调用在任何 HTTP 流量离开主机之前抛出 `WriteGateError`。
- **第 3 层(破坏性)**:未在 v1 中实现。当添加时,设备删除和警报规则删除等操作将额外需要 `destructive: true`。
**输入验证:** 每个工具调用都针对其发布的 TypeBox `inputSchema` 进行验证,然后工具运行。ID、端口 ID、设备 ID、限制和 `type`/`state` 过滤器都经过边界和枚举检查,因此畸形或注入样式的参数被提前拒绝,永远不会到达 LibreNMS URL 路径或查询字符串。插值路径和查询值还额外进行 URL 编码作为防御深度。
**API 令牌范围:** 使用 LibreNMS 中的“只读”令牌角色(设置 > API > 新 API 令牌 > 只读)开始,并验证只读工具是否按预期工作。将令牌升级到“普通用户”或“全局读写”仅在确认编辑器在转录中屏蔽令牌并且模型遵守确认门控后。
**TLS:** `LIBRENMS_TLS_INSECURE=true` 切换开关适用于自签名证书的家庭实验室环境。在具有真实 CA 签名证书的任何环境中,请将其设置为 `false`。
参见 [SECURITY.md](SECURITY.md) 获取漏洞报告策略。
## 为什么不直接将代理指向 LibreNMS API?
您可以将通用 HTTP 工具和 LibreNMS API 令牌交给代理,对于只读探索来说这样做是有效的。但是,当可能进行写入操作时,差异就会显现出来:
- **无写入门控。** 通用 HTTP 工具将愉快地 `PUT` 或 `DELETE` 模型决定的任何内容。librenms-mcp 除非调用带有 `confirm: true`,否则拒绝所有写入操作,并完全拒绝 v1 中的破坏性操作。
- **无输入验证。** 原始 API 工具将模型生成的任何内容直接传递到 URL 中。librenms-mcp 在构建任何请求之前,根据已发布的模式检查边界和枚举每个参数,并对插值值进行 URL 编码作为防御深度。
- **令牌泄露。** 通用工具将请求和响应详细信息(包括您的令牌)回显到转录中。librenms-mcp 在启动时将令牌注册到编辑器,并在所有日志和错误输出中将其掩盖。
- **成形工具优于一个巨大的端点。** 十三个命名、描述的工具为模型提供了一个更好的推理表面,而不是一个具有自由格式路径参数的“调用此 REST API”工具。
## 什么是 librenms-mcp?
- 它不是 LibreNMS 替代品或轮询器。它通过 API 读取现有的 LibreNMS 实例;它不收集 SNMP 数据本身。
- 它不是一个仪表板。输出是用于代理的结构化工具数据,而不是 UI。对于 NOC 仪表板视图,请参见 [watchtower](https://github.com/solomonneas/watchtower)。
- 它不删除设备、不删除警报规则或进行批量端口重置。破坏性操作(第 3 层)在 v1 中故意不存在。
- 它不是托管服务。它在本地运行,通过 stdio 通信,仅与您配置的 LibreNMS URL 通信,并且不启动任何守护进程。
## 贡献
欢迎提交补丁。请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 了解容易实施的内容、 [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) 以及 `.github/` 下的问题和 PR 模板。所有公共输出都应清除个人主机名、令牌和真实 IP 地址。
## 许可证
[MIT](LICENSE).
---
<p align="center"><a href="https://lidless.dev">Lidless Labs</a> · 眼睛不会闭上</p>
<p align="center"><sub><strong>网络:</strong> <a href="https://github.com/lidless-labs/n8nctrl">n8nctrl</a> · <a href="https://github.com/lidless-labs/watchtower">watchtower</a> · <a href="https://github.com/lidless-labs/portgrid">portgrid</a> · <a href="https://github.com/lidless-labs/cutsheet">cutsheet</a> · <a href="https://github.com/lidless-labs/eero-cli">eero-cli</a></sub></p>
<p align="center"><sub><a href="https://lidless.dev">所有工具</a> · <a href="https://github.com/lidless-labs">Lidless Labs on GitHub</a></sub></p>