DLI Power Switch MCP Server
Overview
This project implements a Model Context Protocol (MCP) server that allows an AI agent to control **Digital Loggers (DLI)** Web Power Switches. The system provides tools for discovering hardware, querying outlet status, and performing power operations (On/Off/Cycle).
Crucial Constraint: This system interacts with physical hardware. Strict safety protocols are enforced to prevent accidental power loss to critical infrastructure.
Key Files
server.py: The main entry point. Contains the FastMCP server implementation, tool definitions, and hardware interaction logic using the `power-switch-pro` library.switches_config.json: The source of truth for device configuration. Defines IP addresses, authentication, outlet aliases, and safety types (standard,critical,prohibited).requirements.txt: Python dependencies (power-switch-pro).tests/: Unit tests for the server logic.
Architecture & Performance
This server is designed for responsiveness and safety:
- Asynchronous Core: Built on Python's
asyncioto handle multiple operations efficiently. - Non-Blocking I/O: Interactions with physical hardware (which can be slow) are offloaded to background threads, ensuring the main server loop remains responsive.
- Parallel Discovery: The
get_inventorytool fetches status from all configured switches concurrently, significantly reducing latency in systems with multiple devices.
Installation
Install this server from PyPI using pip:
pip install dli-mcp-server
Configuring with Gemini CLI (and Antigravity)
Once installed, register the server with the Gemini CLI (or Antigravity) using the mcp add command. This ensures the server starts automatically.
gemini mcp add dli-mcp-server dli-mcp-server -e DLI_MCP_CONFIG="/path/to/your/config.json"
Parameters:
- The first
dli-mcp-serveris the name you assign to this server instance. - The second
dli-mcp-serveris the command that runs the server (made available bypip install). -e DLI_MCP_CONFIG="...": (Optional) Sets the environment variable for the configuration file path. If omitted, it defaults toswitches_config.jsonin the current directory.-s useror-s project: (Optional) Sets the configuration scope. Defaults toproject.
Command-Line Usage
The server.py script can be used directly from the command line to control the power switches.
`inventory`
Lists all switches and their outlet statuses.
python server.py inventory
`power_action`
Performs a power action (on, off, cycle) on a specific outlet.
python server.py power_action <switch_id> <outlet_id> <action> [--confirmation YES]
switch_id: Alias or IP address of the switch.
outlet_id: Index or name of the outlet.action:on,off, orcycle.--confirmation: Required for critical outlets.
`group_power_action`
Performs a power action on a group of outlets.
python server.py group_power_action <group_id> <action>
`sync_config_from_hardware`
Synchronizes outlet names from the hardware.
python server.py sync_config_from_hardware <switch_id>
`list_outlets`
Lists all outlets on a given switch.
python server.py list_outlets <switch_id>
`add_switch`
Adds a new DLI power switch to the configuration. If the configuration file does not exist, it will be automatically created.
python server.py add_switch <ip_address> <username>
ip_address: IP address of the new switch.
username: Username for the new switch.password: Password for the new switch.
`remove_switch`
Removes a DLI power switch from the configuration.
python server.py remove_switch <switch_id>
switch_id: Alias or IP address of the switch to remove.
`update_outlet`
Updates the definition of an outlet.
python server.py update_outlet <switch_id> <outlet_id> [--name <new_name>] [--description <new_description>] [--type <new_type>]
switch_id: Alias or IP address of the switch.
outlet_id: Index or name of the outlet (e.g., "Modem" or "1").--name: New name for the outlet.--description: New description for the outlet.--type: New type for the outlet (standard,critical, orprohibited).
| Type | Agent Permission | Behavior |
|---|---|---|
standard |
Full Access | Can be turned On, Off, or Cycled immediately. |
critical |
Restricted | "Off" or "Cycle" actions require explicit user confirmation (confirmation="YES"). |
prohibited |
No Access | NEVER modify this outlet. The server will raise a PermissionError. |
Available Tools
1. `get_inventory()`
- Purpose: The "eyes" of the agent. Call this first to see what switches and
Tools 1
get_inventoryLists all switches and their outlet statuses.Environment Variables
DLI_MCP_CONFIGPath to the switches_config.json configuration file.