{"_id":"@caseman72/wyzer-mcp","_rev":"4-6bbafd74042252fbb1fca7b849efea97","name":"@caseman72/wyzer-mcp","dist-tags":{"latest":"1.2.1"},"versions":{"1.0.1":{"name":"@caseman72/wyzer-mcp","version":"1.0.1","keywords":["wyze","mcp","smart-home","home-assistant"],"license":"MIT","_id":"@caseman72/wyzer-mcp@1.0.1","maintainers":[{"name":"caseman72","email":"casey@manion.com"}],"dist":{"shasum":"056ac84465b7ef7d12a53a53be64dd7e4da5dfb9","tarball":"https://registry.npmjs.org/@caseman72/wyzer-mcp/-/wyzer-mcp-1.0.1.tgz","fileCount":18,"integrity":"sha512-vH0Ad1Cskj/RvLzEKOM7X+aVZvBNQ2+1yj/eYlrChPySxcpgAFvZM10vQWgtEJwBpmhLwdNOhPxeHJ9jZ0Fn2g==","signatures":[{"sig":"MEUCIGN+ZmITNaJJlyAV/ehwlqJR9k9xWBvwUTNfpgWG35QNAiEArnOAn/sBfZXPeodbbDo8DkcuDgWw8HX9LHopCmHgLuA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":75150},"main":"src/index.js","type":"module","gitHead":"a893856e21f0fc5b8979e17a62d45925d4dd808a","scripts":{"start":"node src/index.js","start:http":"node src/index.js --http"},"_npmUser":{"name":"caseman72","email":"casey@manion.com"},"_npmVersion":"11.11.0","description":"MCP server for Wyze smart home devices","directories":{},"_nodeVersion":"25.8.1","dependencies":{"zod":"^3.25.0","@caseman72/wyzer-api":"^1.1.2","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/wyzer-mcp_1.0.1_1773913495716_0.9384602059927323","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@caseman72/wyzer-mcp","version":"1.0.2","keywords":["wyze","mcp","smart-home","home-assistant"],"license":"MIT","_id":"@caseman72/wyzer-mcp@1.0.2","maintainers":[{"name":"caseman72","email":"casey@manion.com"}],"dist":{"shasum":"43963ee2a11c084831e1304dfd269c86fce3efca","tarball":"https://registry.npmjs.org/@caseman72/wyzer-mcp/-/wyzer-mcp-1.0.2.tgz","fileCount":18,"integrity":"sha512-SKc54WGovfm7SLogXgj4sH8LvyPdNOIWjAB+4TcXvbWelCqnePUMgUhQL64S3K3LAMhfwnL/Pe49M8vdyO8GJg==","signatures":[{"sig":"MEQCIBQBAsYKPxiKn5v8IhkvdzkYyp5l8XidVK6d+5lPO3qYAiA9vuery88NAEOzbcf6I9U1Hu9CCMYFjkpP0HgI8WHYGQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":75150},"main":"src/index.js","type":"module","gitHead":"a331ccb4857e3ad0dc9f9a7428ee90ed0caf46a1","scripts":{"start":"node src/index.js","start:http":"node src/index.js --http"},"_npmUser":{"name":"caseman72","email":"casey@manion.com"},"_npmVersion":"11.11.0","description":"MCP server for Wyze smart home devices","directories":{},"_nodeVersion":"25.8.1","dependencies":{"zod":"^3.25.0","@caseman72/wyzer-api":"^1.1.2","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/wyzer-mcp_1.0.2_1773913592751_0.9100825278320555","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@caseman72/wyzer-mcp","version":"1.2.0","keywords":["wyze","mcp","smart-home","home-assistant"],"license":"MIT","_id":"@caseman72/wyzer-mcp@1.2.0","maintainers":[{"name":"caseman72","email":"casey@manion.com"}],"dist":{"shasum":"6024da480f52b6e3888c28cf35022a49da853530","tarball":"https://registry.npmjs.org/@caseman72/wyzer-mcp/-/wyzer-mcp-1.2.0.tgz","fileCount":18,"integrity":"sha512-QQA21KWhqf3mHg00hemlFRHO6j2GRFfIs1SpJdBRzB7sg3t8iL7axkw0MknsadmNd1rkjWcWBFsuB3VkiUJt+w==","signatures":[{"sig":"MEUCIQCtRqJQ3X9fNzNjgLT0dM+wu18Yb0+UlFX4rGAYtKfg1AIgJ1sXk+OiFXDJQyC1iZDTagf+ICia78GiFx+7nWpCQ1g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78628},"main":"src/index.js","type":"module","gitHead":"59fc8c1ced1192a099456f97a9eafdfac82390f3","scripts":{"start":"node src/index.js","start:http":"node src/index.js --http"},"_npmUser":{"name":"caseman72","email":"casey@manion.com"},"_npmVersion":"11.3.0","description":"MCP server for Wyze smart home devices","directories":{},"_nodeVersion":"24.0.2","dependencies":{"zod":"^3.25.0","@caseman72/wyzer-api":"^1.2.0","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/wyzer-mcp_1.2.0_1783386035449_0.43168319784189335","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@caseman72/wyzer-mcp","version":"1.2.1","description":"MCP server for Wyze smart home devices","type":"module","main":"src/index.js","scripts":{"start":"node src/index.js","start:http":"node src/index.js --http"},"keywords":["wyze","mcp","smart-home","home-assistant"],"license":"MIT","dependencies":{"@caseman72/wyzer-api":"^1.2.0","@modelcontextprotocol/sdk":"^1.0.0","zod":"^3.25.0"},"_id":"@caseman72/wyzer-mcp@1.2.1","gitHead":"966b4b191b78424f49be8ad5b19cfaa75197c577","_nodeVersion":"24.0.2","_npmVersion":"11.3.0","dist":{"integrity":"sha512-FAtOD8O7gMNzmtQL3Vbvtr+miY568tEoI3N3lavibPuIrBFf9It53CF56Gfb1UIkd/S9sRhVXCkyOKZWnewkgw==","shasum":"f9728afc3aad7f3bc7d8fb205a9620da1db94e05","tarball":"https://registry.npmjs.org/@caseman72/wyzer-mcp/-/wyzer-mcp-1.2.1.tgz","fileCount":19,"unpackedSize":90726,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCC8R0q14gJ4M+Xj8Fy1BrM5QtCdNPEdz62U7zvY9exngIgaxFKlEOgDKgjSbHLJZ3emiEbpx/R58E9QTSdn8SuhJE="}]},"_npmUser":{"name":"caseman72","email":"casey@manion.com"},"directories":{},"maintainers":[{"name":"caseman72","email":"casey@manion.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/wyzer-mcp_1.2.1_1783390811717_0.7659525856372618"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-19T09:44:55.602Z","modified":"2026-07-07T02:20:11.971Z","1.0.1":"2026-03-19T09:44:55.851Z","1.0.2":"2026-03-19T09:46:32.927Z","1.2.0":"2026-07-07T01:00:35.578Z","1.2.1":"2026-07-07T02:20:11.857Z"},"license":"MIT","keywords":["wyze","mcp","smart-home","home-assistant"],"description":"MCP server for Wyze smart home devices","maintainers":[{"name":"caseman72","email":"casey@manion.com"}],"readme":"# Wyzer MCP Server\n\nA Node.js MCP (Model Context Protocol) server that exposes Wyze smart home devices (plugs, switches, thermostats, air purifiers) for control via Claude Desktop or Home Assistant.\n\n## Features\n\n- **Device Discovery**: Automatically discovers all Wyze plugs, switches, thermostats, and air purifiers\n- **Combined Devices**: Intelligently combines thermostats and plugs with the same nickname for unified control\n- **Online Detection**: Tracks device availability based on last-seen timestamps (2-day threshold)\n- **Dual Transport**: Supports both stdio (Claude Desktop) and HTTP/SSE (Home Assistant)\n- **Request Logging**: Optional logging of all tool calls for debugging\n\n## Installation\n\n```bash\ncd wyzer-mcp\nnpm install\n```\n\n## Configuration\n\n### Wyze Credentials\n\nWyze API credentials are managed by [@caseman72/wyzer-api](https://github.com/caseman72/wyzer-api) via `.env.local`. The file is searched in:\n\n1. Current working directory\n2. `~/.config/wyze/.env.local`\n3. `~/.wyze.env.local`\n\nCreate a `.env.local` file with your Wyze credentials:\n\n```bash\nWYZE_EMAIL=your-wyze-email@example.com\nWYZE_PASSWORD_HASH=your-password-md5-hash\nWYZE_KEY_ID=your-api-key-id\nWYZE_API_KEY=your-api-key\nWYZE_AUTH_API_KEY=your-auth-api-key\n```\n\nVisit the [Wyze Developer Portal](https://developer-api-console.wyze.com/) to create your API credentials. The password hash is the MD5 hash of your Wyze account password.\n\n### Server Configuration (Optional)\n\nCopy `config.example.json` to `config.json` to customize server settings:\n\n```json\n{\n  \"server\": {\n    \"transport\": \"stdio\",\n    \"httpPort\": 8000,\n    \"httpHost\": \"127.0.0.1\"\n  },\n  \"devices\": {\n    \"refreshIntervalMinutes\": 60\n  },\n  \"monitoring\": {\n    \"enabled\": false,\n    \"logFile\": \"./wyzer-mcp-requests.log\"\n  }\n}\n```\n\nEnvironment variable overrides:\n- `WYZER_HTTP_PORT` - HTTP server port (default: 8000)\n- `WYZER_HTTP_HOST` - HTTP server host (default: 127.0.0.1)\n\n## Usage\n\n### stdio Transport (Claude Desktop)\n\n```bash\nnode src/index.js\n```\n\n### HTTP Transport (Home Assistant)\n\nThe HA custom component requires the MCP server to be exposed over HTTP/SSE. Use `mcp-proxy` to bridge the stdio server.\n\n#### Install mcp-proxy\n\n```bash\nbrew install mcp-proxy\n```\n\n#### Start the proxy\n\n```bash\n# Binds to all interfaces so Docker can reach it\nmcp-proxy --port 8081 --host 0.0.0.0 -- node /path/to/wyzer-mcp/src/index.js\n```\n\n### Home Assistant Integration\n\nTested with Home Assistant **2026.1.3**.\n\n1. Copy the custom component to your HA config directory:\n   ```bash\n   cp -r custom_components/wyzer_mcp ~/.home-assistant/custom_components/\n   ```\n\n2. Restart Home Assistant\n\n3. Add the integration: Settings → Devices & Services → Add Integration → \"Wyze MCP\"\n\n4. Enter connection details:\n   - Host: `host.docker.internal` (for Docker) or your Mac's IP\n   - Port: `8081`\n\n#### Optional: Card-Mod and Theme\n\nThis repo includes a [card-mod](https://github.com/thomasloven/lovelace-card-mod) JS file and a clean theme for customizing the HA frontend. To install:\n\n```bash\n# Copy card-mod.js to HA www directory\nmkdir -p ~/.home-assistant/www\ncp card-mod.js ~/.home-assistant/www/\n\n# Copy the clean theme\nmkdir -p ~/.home-assistant/themes\ncp themes/clean.yaml ~/.home-assistant/themes/\n```\n\nThen add to your `configuration.yaml`:\n\n```yaml\nfrontend:\n  themes: !include_dir_merge_named themes\n  extra_module_url:\n    - /local/card-mod.js\n```\n\nThe included `configuration.yaml` shows a complete example with template sensors.\n\n#### Configure Devices\n\nEdit `custom_components/wyzer_mcp/devices.yaml` to define which devices appear in HA:\n\n```yaml\nswitches:\n  # Plugs\n  - id: my_plug\n    name: My Plug\n    device_id: \"XXXXXXXXXXXX\"    # Wyze device ID (MAC address)\n    device_type: plug\n\n  # Wall Switches\n  - id: my_switch\n    name: My Switch\n    device_id: \"LD_SS1_XXXXXXXXXXXX\"\n    device_type: switch\n\npurifiers:\n  # Air Purifiers (fan entity with preset modes + AQI sensor)\n  - id: my_purifier\n    name: My Purifier\n    device_id: \"CO_AP1_XXXXXXXXXXXX\"\n\nthermostats:\n  # Combined thermostat + plug (for space heaters)\n  - id: my_thermostat\n    name: My Thermostat\n    device_id: \"combined_CO_EA1_XXXXXXXXXXXXXXXXXXXXXXXX\"\n    plug_id: \"XXXXXXXXXXXX\"    # Creates a separate heater switch entity\n```\n\n**Notes:**\n- Use the device ID (MAC address) rather than nickname for stability\n- `device_type` must be `plug` or `switch` to call the correct control API\n- For combined thermostats with `plug_id`, a separate \"Heater\" switch entity is created\n\n#### Entity Types\n\nThe integration creates the following entity types:\n\n| Type | Platform | Description |\n|------|----------|-------------|\n| Plugs | `switch` | On/off control for Wyze plugs |\n| Wall Switches | `switch` | On/off control for Wyze wall switches |\n| Thermostats | `climate` | Temperature control, HVAC mode |\n| Heater Switches | `switch` | On/off control for plug in combined devices |\n| Air Purifiers | `fan` | On/off + preset modes (auto/sleep/min/mid/max/turbo), AQI attribute |\n| AQI | `sensor` | Air quality index reading per purifier |\n| API Status | `sensor` | Shows API rate limit info |\n\n#### Device Availability\n\nDevices show as \"Unavailable\" in HA if they haven't reported to Wyze in over 2 days. This is determined by the RSSI timestamp from the Wyze API.\n\n#### Auto-start mcp-proxy with launchd\n\nCreate `~/Library/LaunchAgents/com.wyzer.mcp-proxy.plist`:\n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n    <key>Label</key>\n    <string>com.wyzer.mcp-proxy</string>\n    <key>ProgramArguments</key>\n    <array>\n        <string>/opt/homebrew/bin/mcp-proxy</string>\n        <string>--port</string>\n        <string>8081</string>\n        <string>--host</string>\n        <string>0.0.0.0</string>\n        <string>--</string>\n        <string>/opt/homebrew/bin/node</string>\n        <string>/path/to/wyzer-mcp/src/index.js</string>\n    </array>\n    <!-- Required: allows Wyze API to write token cache -->\n    <key>WorkingDirectory</key>\n    <string>/path/to/wyzer-mcp</string>\n    <key>RunAtLoad</key>\n    <true/>\n    <key>KeepAlive</key>\n    <true/>\n    <key>StandardOutPath</key>\n    <string>/tmp/wyzer-mcp-proxy.log</string>\n    <key>StandardErrorPath</key>\n    <string>/tmp/wyzer-mcp-proxy.err</string>\n</dict>\n</plist>\n```\n\nThen load it:\n```bash\nlaunchctl load ~/Library/LaunchAgents/com.wyzer.mcp-proxy.plist\n```\n\nTo stop/unload:\n```bash\nlaunchctl unload ~/Library/LaunchAgents/com.wyzer.mcp-proxy.plist\n```\n\n#### Managing the service\n\n```bash\n# Check status\nlaunchctl list | grep wyzer\n\n# View logs\ntail -f /tmp/wyzer-mcp-proxy.err\n\n# Restart\nlaunchctl unload ~/Library/LaunchAgents/com.wyzer.mcp-proxy.plist\nlaunchctl load ~/Library/LaunchAgents/com.wyzer.mcp-proxy.plist\n\n# Stop\nlaunchctl unload ~/Library/LaunchAgents/com.wyzer.mcp-proxy.plist\n```\n\n### Claude Desktop Integration\n\nAdd to `~/.claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"wyzer\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/wyzer-mcp/src/index.js\"],\n      \"env\": {}\n    }\n  }\n}\n```\n\n## MCP Tools\n\n### `list_devices`\n\nList all discovered Wyze devices with their current status.\n\n**Parameters:**\n- `type` (optional): Filter by device type - `plug`, `switch`, `thermostat`, `purifier`, `combined`, or `all`\n- `refresh` (optional): Force refresh device list from Wyze API\n\n### `control_plug`\n\nTurn a Wyze plug on or off.\n\n**Parameters:**\n- `deviceId`: Device ID (MAC) or nickname of the plug\n- `state`: `on` or `off`\n\n### `control_switch`\n\nTurn a Wyze wall switch on or off.\n\n**Parameters:**\n- `deviceId`: Device ID (MAC) or nickname of the switch\n- `state`: `on` or `off`\n\n### `control_thermostat`\n\nControl a Wyze thermostat. For combined thermostat+plug devices, `turn_on`/`turn_off` controls the plug (heater power).\n\n**Parameters:**\n- `deviceId`: Device ID (MAC) or nickname of the thermostat\n- `action`: `set_heat`, `set_cool`, `set_mode`, `turn_on`, or `turn_off`\n- `temperature` (optional): Temperature setpoint (required for `set_heat` and `set_cool`)\n- `mode` (optional): Thermostat mode (required for `set_mode`) - `heat`, `cool`, `auto`, or `off`\n\n### `control_purifier`\n\nControl a Wyze air purifier. Set power state and/or fan mode.\n\n**Parameters:**\n- `deviceId`: Device ID (MAC) or nickname of the air purifier\n- `state` (optional): `on` or `off`\n- `fanMode` (optional): `auto`, `sleep`, `min`, `mid`, `max`, or `turbo`\n\nAt least one of `state` or `fanMode` is required.\n\n### `get_device_status`\n\nGet detailed status of any Wyze device. Returns online status, last seen timestamp, and current state.\n\n**Parameters:**\n- `deviceId`: Device ID (MAC) or nickname of the device\n\n**Response includes:**\n- `is_online`: Whether device has reported within 2 days\n- `last_seen`: ISO timestamp of last device report\n- `rssi`: Signal strength (for plugs)\n- `is_on`: Current on/off state\n- Temperature/humidity/setpoints (for thermostats)\n- AQI and fan mode (for air purifiers)\n\n### `get_api_status`\n\nGet Wyze API rate limit status. Returns remaining calls, reset time, and cache info.\n\n## Combined Devices\n\nWhen a thermostat and plug share the same nickname (case-insensitive), they are automatically combined into a single \"combined\" device. This is useful for space heaters controlled by smart plugs with thermostats for temperature sensing.\n\nFor combined devices:\n- `turn_on`/`turn_off` actions control the plug (heater power)\n- `set_heat`/`set_cool`/`set_mode` actions control the thermostat\n\n## Request Monitoring\n\nEnable request logging in config.json:\n\n```json\n{\n  \"monitoring\": {\n    \"enabled\": true,\n    \"logFile\": \"./wyzer-mcp-requests.log\"\n  }\n}\n```\n\nLogs are written in JSON Lines format with timestamps, tool names, parameters, and results.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}