DLI电源开关MCP服务器
概述
该项目实现了 模型上下文协议(MCP) 允许AI代理控制的服务器 数字记录仪(DLI) Web电源开关该系统提供用于发现硬件、查询插座状态和执行电源操作(开/关/循环)的工具。
关键约束: 该系统与物理硬件交互。执行严格的安全协议,以防止关键基础设施意外断电。
关键文件
server.py:主要切入点。包含FastMCP服务器实现、工具定义和使用power-switch-pro图书馆。switches_config.json:设备配置的真实来源。定义IP地址、身份验证、出口别名和安全类型(standard,critical,prohibited).requirements.txt:Python依赖关系(power-switch-pro).tests/:服务器逻辑的单元测试。
架构与性能
此服务器专为响应性和安全性而设计:
- 异步核心: 基于Python构建
asyncio以高效地处理多个操作。 - 非阻塞I/O: 与物理硬件的交互(可能很慢)被卸载到后台线程,确保主服务器循环保持响应。
- 并行发现: 这
get_inventory该工具同时从所有配置的交换机获取状态,显著降低了具有多个设备的系统中的延迟。
安装
使用pip从PyPI安装此服务器:
pip install dli-mcp-server使用Gemini CLI(和反重力)进行配置
安装后,使用Gemini CLI(或Antigravity)注册服务器 mcp add 命令。这可确保服务器自动启动。
gemini mcp add dli-mcp-server dli-mcp-server -e DLI_MCP_CONFIG="/path/to/your/config.json"参数:
- 第一
dli-mcp-server是您为此服务器实例指定的名称。 - 第二
dli-mcp-server是运行服务器的命令(由提供pip install). -e DLI_MCP_CONFIG="...":(可选)设置配置文件路径的环境变量。如果省略,则默认为switches_config.json在当前目录中。-s user或-s project:(可选)设置配置范围。默认为project.
命令行用法
这 server.py 可以直接从命令行使用脚本来控制电源开关。
inventory
列出所有开关及其插座状态。
python server.py inventorypower_action
在特定插座上执行电源操作(打开、关闭、循环)。
python server.py power_action [--confirmation YES]switch_id:交换机的别名或IP地址。
outlet_id:出口的索引或名称。action:on,off,或cycle.--confirmation:关键插座需要。
group_power_action
对一组插座执行电源操作。
python server.py group_power_action sync_config_from_hardware
从硬件同步插座名称。
python server.py sync_config_from_hardware list_outlets
列出给定交换机上的所有插座。
python server.py list_outlets add_switch
在配置中添加新的DLI电源开关。如果配置文件不存在,它将自动创建。
python server.py add_switch
ip_address:新交换机的IP地址。
username:新交换机的用户名。password:新交换机的密码。
remove_switch
从配置中删除DLI电源开关。
python server.py remove_switch switch_id:要删除的交换机的别名或IP地址。
update_outlet
更新插座的定义。
python server.py update_outlet [--name ] [--description ] [--type ]switch_id:交换机的别名或IP地址。
outlet_id:插座的索引或名称(例如“调制解调器”或“1”)。--name:门店的新名称。--description:插座的新描述。--type:新型插座(standard,critical,或prohibited).
| 类型 | 代理权限 | 行为 |
|---|---|---|
standard | 完全访问 | 可以立即打开、关闭或循环。 |
critical | 受限的 | “关闭”或“循环”操作需要用户明确确认(confirmation="YES"). |
prohibited | 禁止进入 | 永不 修改此出口。服务器将引发 PermissionError. |
可用工具
1. get_inventory()
- 目的: 代理人的“眼睛”。首先调用此命令,查看可用的开关和插座及其当前状态(ON/OFF)。
- 退货: 一个包含所有开关、插座、组及其描述的JSON对象。
2. power_action(switch_id, outlet_id, action, confirmation="NO")
- 目的: 控制特定的物理插座。
- 输入:
- switch_id:别名(例如“garage_rack”)或IP。 - outlet_id:名称(例如“调制解调器”)或索引(例如“1”)。 - action:“开”、“关”或“循环”。 - confirmation:只有当用户明确批准了某个危险操作时,才必须设置为“是” critical 出口。
3. group_power_action(target, action)
- 目的: 控制一组逻辑插座(例如,“重新启动网络堆栈”)。
- 行为: 按顺序执行。如果 *任何* 该组的成员是
prohibited,整个操作立即中止。
4. sync_config_from_hardware(switch_id)
- 目的: 更新
switches_config.json文件中包含设备上找到的实际插座名称。 - 注: 这不会覆盖安全类型(
critical/prohibited)或描述。
5. add_switch(ip_address, username, password)
- 目的: 在配置中添加新的DLI电源开关。
- 输入:
- ip_address:新交换机的IP地址。 - username:新交换机的用户名。 - password:新交换机的密码。
6. remove_switch(switch_id)
- 目的: 从配置中删除DLI电源开关。
- 输入:
- switch_id:要删除的交换机的别名或IP地址。
7. list_outlets(switch_id)
- 目的: 列出给定交换机的所有插座及其状态。
- 输入:
- switch_id:交换机的别名或IP地址。
- 退货: 插座信息的JSON数组。
8. update_outlet(switch_id, outlet_id, new_name=None, new_description=None, new_type=None)
- 目的: 更新配置文件中插座的定义,并将新名称写入硬件。
- 输入:
- switch_id:交换机的别名或IP地址。 - outlet_id:名称或索引(例如“调制解调器”或“1”)。 - new_name (可选):插座的新名称。这会写入配置文件和硬件。 - new_description (可选):插座的新描述。这只会写入配置文件。 - new_type (可选):新型插座(standard, critical,或 prohibited).这只会写入配置文件。
- 退货: 成功信息。
代理人操作指南
- 始终先检查库存: 在假设插座存在或知道其状态之前,运行
get_inventory. - 尊重“禁止”网点: 如果用户要求关闭被禁止的设备(例如“安全DVR”),请解释您不能这样做,因为它在配置中受到限制。
- 处理“关键”警告: 如果
power_action返回“安全锁定”消息,停止并询问用户: *“这是一个关键设备。您确定要关闭它吗?”*。只有当他们说“是”时才能继续。 - 使用别名: 更喜欢使用友好的
alias和name(例如,“garage_rack”、“Modem”)在与用户通信时通过IP地址和索引。
测试
该项目包括一套单元测试,以确保服务器逻辑正确。测试位于 tests/ 目录。
要运行测试,请先安装测试依赖项:
pip install -r tests/requirements.txt然后,使用以下命令运行测试:
python tests/test_server.py这些测试旨在在没有物理DLI电源开关的情况下运行。他们使用mocking来模拟硬件及其行为。
自动化测试
该项目使用GitHub Actions进行持续集成。对每个推送和拉取请求都会自动执行测试 main 支。工作流在以下平台上运行:
- 操作系统: Windows、Linux(Ubuntu)和macOS。
- Python版本: 3.10、3.11和3.12。
这确保了跨支持的Python版本的跨平台兼容性和稳定性。
测试覆盖率
要检查测试覆盖率,您可以使用 coverage 包装(包含在 tests/requirements.txt).
运行覆盖率测试并生成报告:
coverage run tests/test_server.py
coverage report -m该项目旨在实现高测试覆盖率,以确保可靠性。
使用Gemini CLI(和反重力)进行配置
您可以使用以下命令在Gemini CLI(或Antigravity)中轻松注册此MCP服务器 mcp add 命令。这可确保服务器自动启动。
窗户:
gemini mcp add dli-mcp-server python "C:\Path\To\dli-mcp-server\server.py" -e DLI_MCP_CONFIG="C:\Path\To\your\config.json" -s userLinux/macOS:
gemini mcp add dli-mcp-server python "/path/to/dli-mcp-server/server.py" -e DLI_MCP_CONFIG="/path/to/your/config.json" -s user参数:
dli-mcp-server:您分配给服务器的名称。python "...":启动服务器的命令。确保提供完整的绝对路径server.py.-e DLI_MCP_CONFIG="...":(可选)设置配置文件路径的环境变量。如果省略,则默认为switches_config.json在服务器的目录中。-s user:将配置保存到用户设置(全局),使其在所有项目中都可用。-s project(默认):将配置保存到当前项目的.gemini/settings.json。如果您希望服务器配置特定于当前工作区,请使用此选项。
配置
默认情况下,服务器使用 switches_config.json 文件在同一目录中。您可以通过设置 DLI_MCP_CONFIG 环境变量到配置文件的路径。
例子:
export DLI_MCP_CONFIG=/path/to/your/custom_config.json
python server.py inventory这对于在不修改主配置的情况下使用不同配置进行测试特别有用 switches_config.json 文件。
交互示例
用户: “关闭路由器。”
代理人行动:
- 呼叫
get_inventory(内部)->看到路由器critical. - 呼叫
power_action("garage_rack", "Router", "off"). - 结果: 返回“安全锁…”。
- 代理响应: “路由器被标记为关键设备。您确定要关闭它吗?”
用户: “是的,做吧。”
代理人行动:
- 呼叫
power_action("garage_rack", "Router", "off", confirmation="YES"). - 结果: “成功…”
- 代理响应: “路由器已关闭。”
发展信息
此MCP服务器是使用Gemini CLI和Gemini 3.0型号开发的。
