A TypeScript-based Model Context Protocol (MCP) server for Plugwise smart home integration with automatic network discovery.
- 🔍 Automatic Network Scanning: Discovers all Plugwise hubs on your network
- 🔐 Credential Management: Stores hub passwords securely from .env file
- 🔌 Device Control: Control thermostats, switches, and smart plugs
- 🌡️ Temperature Management: Set temperatures, presets, and schedules
- 📊 Energy Monitoring: Read power consumption and sensor data
- 🏠 Multi-Hub Support: Manage multiple gateways simultaneously
- 🔄 Real-time Updates: Get current device states and measurements
Install globally to use with any MCP client:
npm install -g plugwise-mcp-serverOr use directly with npx (no installation needed):
npx plugwise-mcp-servergit clone https://github.com/Tommertom/plugwise-mcp-server.git
cd plugwise-mcp-server
npm install
npm run build- Node.js 17 or higher
- npm or yarn
- Plugwise gateway (Adam, Anna, Smile P1, or Stretch)
Test the installation without real hardware using mock mode:
# Test all read operations
npm run test:read-only -- --mock
# Test protocol features
npm run test:features -- --mockOr with real hardware:
# Set up gateway credentials
echo "PLUGWISE_HOST=192.168.1.100" > .env
echo "PLUGWISE_PASSWORD=your-gateway-password" >> .env
# Run tests
npm run test:read-onlySee Quick Test Guide for more options.
When installed via npm:
plugwise-mcp-serverWhen running from source:
npm startServer runs at:
- MCP Endpoint:
http://localhost:3000/mcp - Health Check:
http://localhost:3000/health
The Plugwise MCP server can work with any MCP client that supports standard I/O (stdio) as the transport medium. Here are specific instructions for some popular tools:
To configure Claude Desktop to use the Plugwise MCP server, edit the claude_desktop_config.json file. You can open or create this file from the Claude > Settings menu. Select the Developer tab, then click Edit Config.
{
"mcpServers": {
"plugwise": {
"command": "npx",
"args": ["-y", "plugwise-mcp-server@latest"],
"env": {
"HUB1": "abc12345",
"HUB1IP": "192.168.1.100",
"HUB2": "def67890",
"HUB2IP": "192.168.1.101"
}
}
}
}To configure Cline to use the Plugwise MCP server, edit the cline_mcp_settings.json file. You can open or create this file by clicking the MCP Servers icon at the top of the Cline pane, then clicking the Configure MCP Servers button.
{
"mcpServers": {
"plugwise": {
"command": "npx",
"args": ["-y", "plugwise-mcp-server@latest"],
"disabled": false,
"env": {
"HUB1": "abc12345",
"HUB1IP": "192.168.1.100",
"HUB2": "def67890",
"HUB2IP": "192.168.1.101"
}
}
}
}To configure Cursor to use the Plugwise MCP server, edit either the file .cursor/mcp.json (to configure only a specific project) or the file ~/.cursor/mcp.json (to make the MCP server available in all projects):
{
"mcpServers": {
"plugwise": {
"command": "npx",
"args": ["-y", "plugwise-mcp-server@latest"],
"env": {
"HUB1": "abc12345",
"HUB1IP": "192.168.1.100",
"HUB2": "def67890",
"HUB2IP": "192.168.1.101"
}
}
}
}To configure a single project, edit the .vscode/mcp.json file in your workspace:
{
"servers": {
"plugwise": {
"type": "stdio",
"command": "npx",
"args": ["-y", "plugwise-mcp-server@latest"],
"env": {
"HUB1": "abc12345",
"HUB1IP": "192.168.1.100",
"HUB2": "def67890",
"HUB2IP": "192.168.1.101"
}
}
}
}To make the server available in every project you open, edit your user settings:
{
"mcp": {
"servers": {
"plugwise": {
"type": "stdio",
"command": "npx",
"args": ["-y", "plugwise-mcp-server@latest"],
"env": {
"HUB1": "abc12345",
"HUB1IP": "192.168.1.100",
"HUB2": "def67890",
"HUB2IP": "192.168.1.101"
}
}
}
}
}To configure Windsurf Editor, edit the file ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"plugwise": {
"command": "npx",
"args": ["-y", "plugwise-mcp-server@latest"],
"env": {
"HUB1": "abc12345",
"HUB1IP": "192.168.1.100",
"HUB2": "def67890",
"HUB2IP": "192.168.1.101"
}
}
}
}The server reads hub passwords from environment variables. You can provide these in two ways:
Option 1: MCP Configuration (Recommended)
Add the env field directly to your MCP client configuration as shown in the examples above.
Option 2: .env File
Create a .env file in your project root or set system-wide environment variables:
# Hub passwords (8-character codes from gateway stickers)
HUB1=abc12345
HUB2=def67890
# Optional: Known IP addresses for faster discovery and auto-loading
HUB1IP=192.168.1.100
HUB2IP=192.168.1.101Security Note: When using the MCP configuration env field, credentials are passed securely to the server process. For enhanced security, consider using .env files which are typically excluded from version control.
# Automatically discover and connect to your hubs
node scripts/workflow-demo.jsAutomatically scan your network for Plugwise hubs using passwords from .env.
await mcpClient.callTool('scan_network', {});
// Returns: { discovered: [ { name, ip, model, firmware } ], scanned_ips: 2 }Features:
- Tests known IPs first if
HUBxIPvariables are provided (instant) - Falls back to full network scan if needed (1-2 minutes)
- Stores credentials automatically for later use
Connect to a Plugwise gateway. After scanning, credentials are automatic!
// Auto-connect to first discovered hub
await mcpClient.callTool('connect', {});
// Connect to specific hub (password from scan)
await mcpClient.callTool('connect', { host: '192.168.1.100' });
// Manual connection (without scanning)
await mcpClient.callTool('connect', {
host: '192.168.1.100',
password: 'abc12345'
});Get all devices and their current states.
const result = await mcpClient.callTool('get_devices', {});
// Returns all devices, zones, sensors, and their current valuesSet thermostat temperature setpoint.
await mcpClient.callTool('set_temperature', {
location_id: 'zone123',
setpoint: 21.0
});Change thermostat preset mode.
await mcpClient.callTool('set_preset', {
location_id: 'zone123',
preset: 'away' // Options: home, away, sleep, vacation
});Turn switches/plugs on or off.
await mcpClient.callTool('control_switch', {
appliance_id: 'plug123',
state: 'on' // 'on' or 'off'
});set_gateway_mode: Set gateway mode (home, away, vacation)set_dhw_mode: Set domestic hot water mode (auto, boost, comfort, off)set_regulation_mode: Set heating regulation modedelete_notification: Clear gateway notificationsreboot_gateway: Reboot the gateway (use with caution)
plugwise://devices: Access current state of all devices as a resource
setup_guide: Get comprehensive step-by-step setup instructions
npm run test:allThis runs a complete test of all read-only MCP operations:
- ✅ Server health check
- ✅ MCP protocol initialization
- ✅ Network scanning for hubs
- ✅ Gateway connection and info retrieval
- ✅ Device state reading
- ✅ Resources and prompts
Safe: Only tests read operations, never changes device states.
See Test Documentation for details.
node scripts/workflow-demo.jsThis demonstrates:
- ✅ Network scanning with .env passwords
- ✅ Auto-connection without credentials
- ✅ Device discovery and listing
- ✅ Multi-hub management
node scripts/test-network-scan.jsnode scripts/test-mcp-server.js./scripts/find-plugwise-hub.sh- Adam: Smart home hub with OpenTherm support (thermostat control, floor heating)
- Anna: Standalone thermostat gateway
- Smile P1: Energy monitoring gateway (electricity, gas, solar)
- Stretch: Legacy hub for connecting Circle smart plugs
- Jip: Motion sensor with illuminance detection
- Lisa: Radiator valve (requires hub)
- Tom/Floor: Floor heating controller
- Koen: Radiator valve (requires a Plug as intermediary)
- Plug: Smart plug with power monitoring (Zigbee)
- Aqara Plug: Third-party Zigbee smart plug
- Circle: Legacy Circle/Circle+ plugs (via Stretch only)
- Setup Guide - Detailed setup instructions
- MCP Server Documentation - Complete API reference
- Network Scanning Guide - Network discovery deep dive
- Network Scanning Summary - Feature overview
Run with hot-reload:
npm run devCompile TypeScript to JavaScript:
npm run buildplugwise/
├── src/mcp/ # TypeScript source
│ ├── server.ts # MCP server with tools
│ ├── plugwise-client.ts # Plugwise API client
│ └── plugwise-types.ts # Type definitions
├── build/mcp/ # Compiled JavaScript
├── docs/ # Documentation
├── scripts/ # Test scripts
│ ├── workflow-demo.js
│ ├── test-network-scan.js
│ ├── test-mcp-server.js
│ └── find-plugwise-hub.sh
├── .env # Hub credentials
├── package.json
└── tsconfig.json
- Password Storage: Store passwords in
.envfile only (never in code) - Git Ignore:
.envis in.gitignoreto prevent committing secrets - Network Security: Plugwise uses HTTP Basic Auth (not HTTPS)
- Keep gateways on secure local network
- Use VPN for remote access
- Consider separate VLAN for IoT devices
- API Access: The API has full control over your heating system - restrict access accordingly
- Check
.envfile hasHUB1,HUB2, etc. defined - Verify passwords are correct (case-sensitive, check gateway sticker)
- Ensure gateways are powered on and connected to network
- Confirm you're on the same network as the hubs
- Try:
ping <gateway_ip>to test connectivity
- Verify IP address is correct
- Check firewall isn't blocking port 80
- Test with manual connection:
curl http://<ip>/core/domain_objects - Ensure gateway isn't overloaded with requests
- Add
HUBxIPvariables to.envfor instant scanning - Specify network:
scan_network({ network: '192.168.1.0/24' }) - Check network size (scanning /16 is much slower than /24)
claude mcp add --transport http plugwise-server http://localhost:3000/mcpAdd to .vscode/mcp.json:
{
"mcpServers": {
"plugwise": {
"type": "http",
"url": "http://localhost:3000/mcp"
}
}
}npx @modelcontextprotocol/inspectorConnect to: http://localhost:3000/mcp
// Scan and connect
await mcpClient.callTool('scan_network', {});
await mcpClient.callTool('connect', {});
// Set home mode
await mcpClient.callTool('set_preset', {
location_id: 'living_room',
preset: 'home'
});
// Warm up bathroom
await mcpClient.callTool('set_temperature', {
location_id: 'bathroom',
setpoint: 22.0
});const devices = await mcpClient.callTool('get_devices', {});
for (const [id, device] of Object.entries(devices.data)) {
if (device.sensors?.electricity_consumed) {
console.log(`${device.name}: ${device.sensors.electricity_consumed}W`);
}
}// Discover all hubs
const scan = await mcpClient.callTool('scan_network', {});
// Get devices from each hub
for (const hub of scan.discovered) {
await mcpClient.callTool('connect', { host: hub.ip });
const devices = await mcpClient.callTool('get_devices', {});
console.log(`Hub ${hub.ip}: ${Object.keys(devices.data).length} devices`);
}- Structure Migration Plan - Complete plan for restructuring project
- Structure Comparison - Visual comparison of architectures
- Migration Checklist - Step-by-step migration checklist
- Migration Summary - Quick reference summary
- Architecture Diagram - System architecture overview
- Code Organization - Project structure and conventions
- Reorganization Overview - Historical reorganization notes
- Autoload Hubs - Automatic hub loading implementation
- Network Scanning - Network discovery implementation
- Temperature Tools - Temperature control features
- Sensor & Switch Parsing - Device parsing logic
- Quick Reference - Common commands and patterns
- Autoload Quick Reference - Autoload feature guide
- Temperature Tools Quick Reference - Temperature API guide
- Quick Test Guide - Fast start testing guide
- Test Scripts Documentation - Comprehensive testing documentation
- Test All Script - HTTP-based testing guide
- Multi-Hub Testing - Testing with multiple hubs
- List Devices Script - Device enumeration guide
- Publishing Guide - How to publish to npm
- Setup Guide - Initial setup instructions
- Publish Checklist - Pre-publish verification
Based on the excellent python-plugwise library.
Architectural patterns inspired by sonos-ts-mcp.
MIT License - See LICENSE file for details
Current version: 1.0.2
- ✅ Full MCP protocol support
- ✅ Automatic network scanning
- ✅ Multi-hub management
- ✅ Complete device control
- ✅ Comprehensive documentation
- ✅ Structure migration planning