Skip to main content

Myro:Home Helper MCP server

Lets an AI assistant (Claude Desktop, Claude Code, ChatGPT desktop, anything that speaks MCP) read and control an HAI/Leviton Omni controller through Myro:Home Helper, using the Helper's HTTP API. The assistant sees typed tools with descriptions instead of guessing URL shapes.

What you need

  • Myro:Home Helper (Mac App Store) 4.06 or later on a Mac on your network (4.07 or later for the read tools: list_objects, get_object, helper_log).
  • An API key for your controller: Helper → API tab → Generate.
  • uv on the machine running the assistant (brew install uv or the one-line installer). uvx fetches and runs this server on demand and keeps it updated.

Configure

Claude Desktop (claude_desktop_config.json) or any client that takes the standard MCP config:

{
  "mcpServers": {
    "myrohome-helper": {
      "command": "uvx",
      "args": ["myrohome-helper-mcp"],
      "env": {
        "MHH_URL": "http://192.168.1.76:9393",
        "MHH_API_KEY": "your-api-key"
      }
    }
  }
}

Claude Code:

claude mcp add myrohome-helper -e MHH_URL=http://192.168.1.76:9393 -e MHH_API_KEY=your-api-key -- uvx myrohome-helper-mcp

The controller ID is fetched from the Helper automatically. Set MHH_CONTROLLER_ID only if you want to pin it.

Tools

Read:

Tool What it returns
helper_info Helper version and identity, and which controller the key is for
controller_status Name, model, firmware, connection, power, battery, phone line, energy cost, troubles
controller_property(name) One controller property
list_objects(type?) Every object with decoded state; filter by Zone, Unit, Flag, Output, Thermostat, Auxiliary Sensor, …
get_object(type, number) One object
helper_log(lines) The Helper's recent log lines
ethernet_quality(since?) The controller connection's health record
connection_status Helper 4.07+: live connected/reconnecting state and the panel messages showing now
list_logged_sensors Which sensors record history, with the type and number
sensor_history(type, number, points) Logged readings for one sensor or thermostat
history_window(type, number, start, end, points, remove_outliers, runtime_bucket, time_zone) Helper 4.50+: bounded live/archived samples, statistics before display reduction, and hourly/daily/weekly reported HVAC intervals with unknown coverage and archive warnings
panel_events(...) Helper 4.50+: cached panel history with zone/area/type/month/day filters and user attribution
refresh_panel_events(scope) Helper 4.50+: recent history by default; explicit all reads up to 2000 available panel records. Poll panel_events while refreshing is true; check panelEndReached and refreshError before claiming completeness

The new history/activity tools require adapter 0.4.0 and Helper 4.50. Panel event dates contain no year; receivedAt is download time, not event time. History indexing is incremental: retry when indexing is true. HVAC intervals are estimates from reported action, and unknownSeconds must not be interpreted as equipment being off. These additions do not change the existing security tools. Recent event refreshes are limited to once every 30 seconds per controller; full downloads to once every 10 minutes. A 429 means wait and use the cached panel_events result, not repeat the download immediately.

Write (each changes the physical home; tool descriptions tell the assistant to confirm first):

Tool Effect
set_unit(number, value, timer?) 0 off, 1 or 100 on, 2–99 dimmer level; optional timer 1–99 s for on/off
set_blind(number, value, timer?) Blind/shade 0–100
set_flag(number, value, timer?) Flag to 0–255; optional timer 1–99 s for 0/1
increment_flag(number) / decrement_flag(number) Updated Helper 4.50+: one native counter step, without cached read/modify/write
dim_unit(number, steps?) / brighten_unit(number, steps?) Updated Helper 4.50+: 1-9 native lighting steps (default 1), not percentage points
set_output(number, on, timer?) Output relay on or off; optional timer 1–99 s
set_thermostat(number, mode?, heat_setpoint?, cool_setpoint?, humidify_setpoint?, dehumidify_setpoint?, fan?, hold?) Mode off/heat/cool/auto/emergency, setpoints, fan auto/on, hold
set_area_lights(on, area) All lights in an area on or off (area 0 = all)
run_button(number) Run a controller button (macro)
set_upb_link(number, state) UPB link on / off / store
show_panel_message(number, presentation) Show a programmed message on the keypads: beep_led / led / silent
clear_panel_message(number) Clear one message, or 0 for all
lock_door(number) Lock an access-control lock (unlocking is opt-in, below)
set_user_setting(number, value) User setting 1–255 to a raw value 0–65535
set_energy_cost(level) low / medium / high / critical
send_notification(message) Push to the Myro:Home apps
send_test_notification The Helper's test push, to check delivery
speak(message) Speak on the Mac
log_message(message) Write to the Helper log
log_to_file(filename, message) Append to a file in the Helper's Logs folder
sync_now Re-sync from the controller

Adapter 0.5.0 adds typed /control tools for blinds, thermostats, area lights, buttons, UPB links, messages, locks, user settings and audio transport, plus timers on units, flags and outputs (Helper 4.07 or later). Existing untimed unit/flag/output, audio, energy, notification, speech, log and sync tools retain their existing routes. Timed dim levels, intermediate blind positions and flag counters are rejected because the panel ignores their timer. Thermostat setpoints use the controller's temperature format; Helper enforces that format's range. A controller ACK means acceptance, not physical completion. After an error or timeout, read the state before considering another write; commands are never automatically retried.

Scripts (save, enable and reload need a key with remote script management enabled; listing, reading and validating do not):

Tool What it does
list_scripts Every script: name, id, enabled, schedule
get_script(identifier) One script's full source
scripting_reference(compact) The live scripting API, with your real device names
validate_script(code) Syntax and warnings, without running it
save_script(name, code, script_id, enabled) Create or replace; disabled by default
set_script_enabled(identifier, enabled) Enabling runs the script immediately
reload_scripts Re-runs every enabled script

Helper 4.50 relative controls

Adapter 0.5.0 adds the four relative tools above, requiring an updated Helper 4.50 build with these actions. Earlier 4.50 builds may not support them. Discover the exact Flag or Unit number first. They validate input locally and use the authenticated typed control endpoint; the Helper also checks that the object has the right type. Each counter call requests one step. Lighting steps are not percentage points; device support and resulting levels depend on the panel and lighting technology. The panel defines behavior at counter endpoints 0/255. Flags can trigger panel programs, so confirm intent before changing them.

No automatic retries: an ACK timeout may mean the command already applied. accepted means the panel acknowledged it, not that a particular final value was observed. Check reported state after uncertainty. These additions do not expand security permissions. Older Helpers return explicit failure with an updated 4.50 build requirement; the adapter never substitutes a cached-value write.

Helper 4.50 scripting features

The live scripting_reference exposes MyroLibraries, MyroControllers, and MyroSystem.speakQueued / cancelSpeech / cancelAllSpeech. MCP can generate, validate and save scripts using these APIs through the existing script tools; it does not need a separate tool for every JavaScript method.

Library files must be installed locally in Helper's Scripts/Libraries folder. Cross-controller access requires local Send To and Accept From grants at the respective controllers. MCP cannot upload library files, change grants, or silently switch its controller API key. A grant extends the origin scripts' authority, including remotely managed scripts, so enable it only deliberately. Validation checks the script body without loading dependencies or proving permissions, device state or speech playback. Save disabled and review before enabling. Script-owned speech cancellation does not cancel the separate HTTP speech queue used by MCP's speak tool.

Browser login, themes and live page navigation are UI features, not MCP tools. History queries include archived data automatically; archive deletion policy remains local configuration, not an MCP write capability.

Audio, Lutron and displays:

Tool What it does
list_audio_sources Sources and their cached metadata
audio_source_metadata(source, refresh) What one source is playing
set_audio_zone(zone, power, volume, mute, source) Control a zone
audio_zone_key(zone, transport or key) Russound transport (play, pause, next, …) or a raw audio key 1–40
list_lutron Bridges, devices and Picos
set_lutron_level(bridge_id, level, ...) Set a Lutron device 0-100
activate_lutron_scene(bridge_id, scene_href) Activate a scene
press_lutron_button(bridge_id, integration_id, component) Press a keypad or Pico button
list_displays Vestaboards and LaMetric clocks
`send_to_vestaboard(text lines
send_to_lametric(text, ...) Show a notification on a LaMetric
sync_clock Set the controller's clock from this Mac

Helper Mac:

Tool What it does
beep System beep on the Helper Mac
show_mac_alert(message) Alert dialog on the Helper Mac
set_speech_delays(start_delay_ms, between_delay_ms) Tune the speech queue
play_sound(filename, queue_with_speech) Play a sound from the Helper's Scripts folder
stop_sound(filename) Stop it

Security (all three need an API key with arm/disarm enabled; arm also needs a panel code stored locally):

Tool Effect
arm(mode, area) day, night, away, vacation, day_instant, night_delayed
bypass_zone(zone, bypassed, area) Bypass or restore one zone
restore_all_zones(area) Restore every bypassed zone

arm stays disabled until the owner stores a panel code on the machine running this server. bypass_zone and restore_all_zones work without one on Helper 4.13 or later, running as the panel's Programmed user; with a stored code they run as that user instead. To store or remove the code:

uvx myrohome-helper-mcp security-code set      # prompts; nothing is echoed
uvx myrohome-helper-mcp security-code delete

The code goes into the operating system credential store (macOS Keychain, Windows Credential Locker, Linux Secret Service) under the controller's identity. It is never placed in the MCP config, an environment variable, or a conversation, and it is read only when a security tool is actually called. Helper validates it against the panel itself.

Disarming and unlocking (off by default)

An assistant cannot turn the alarm off or unlock a door unless you allow it, on the computer running this server:

uvx myrohome-helper-mcp allow disarm        # adds the disarm tool
uvx myrohome-helper-mcp allow unlock        # adds the unlock_door tool
uvx myrohome-helper-mcp disallow disarm     # takes it away again

Each asks you to type the word to confirm, and applies only to the controller that API key belongs to. Restart your MCP client afterwards. Until you allow them, the tools are not registered at all, so an instruction hidden in an email, web page or document the assistant reads has nothing to call. Disarm still also needs an API key with arm/disarm enabled and a stored panel code. Revoking takes effect on the next call, without a restart.

AI assistants can be misled by text they read. Allow these only if you understand that, and prefer the Myro:Home app for disarming.

Security

This server runs on your LAN like every other Myro:Home client and holds one controller's API key. Anyone who can run the assistant with this config can do what the key allows. Keep it on trusted machines. The Helper's HTTP API is plain HTTP on the local network; do not expose port 9393 to the internet.

Developing

uv sync
MHH_URL=http://192.168.1.76:9393 MHH_API_KEY=... uv run myrohome-helper-mcp   # stdio server
uv run mcp dev src/myrohome_helper_mcp/server.py                             # MCP inspector

Releasing

Bump version in pyproject.toml and __init__.py, commit, then tag and push: git tag v0.1.0 && git push origin v0.1.0. The GitLab CI job builds and publishes to PyPI through trusted publishing (one-time setup: PyPI project -> Publishing -> add GitLab publisher MyroControl/myrohome-helper-mcp, environment pypi).

MIT licensed. Myro Control, LLC.

Metadata

Release files for myrohome-helper-mcp 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for myrohome-helper-mcp 0.5.0
File Size Uploaded Provenance Actions
myrohome_helper_mcp-0.5.0.tar.gz 90.5 kB Without provenance Details for myrohome_helper_mcp-0.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for myrohome-helper-mcp 0.5.0
File Interpreter ABI Platform Actions
myrohome_helper_mcp-0.5.0-py3-none-any.whl Python 3 none any Details for myrohome_helper_mcp-0.5.0-py3-none-any.whl

Total release size: 116.3 kB

Release files / myrohome_helper_mcp-0.5.0.tar.gz

Download URL myrohome_helper_mcp-0.5.0.tar.gz
Size 90.5 kB
Tags Source
SHA-256 checksum
How to use checksums
31beb13f20b70a2c57aa4dbee7c20f565187c284557aa119e96405f0cdb550c7
BLAKE2b-256 checksum
How to use checksums
0076d44de902a85e90e4e5eb8a2ac46cf53276b6f5c5ff801ef5d980cd561d8e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / myrohome_helper_mcp-0.5.0-py3-none-any.whl

Download URL myrohome_helper_mcp-0.5.0-py3-none-any.whl
Size 25.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
696a7f7179f92e54b904e05c0f2d4d379276d94380a49febfe60113fdda5635f
BLAKE2b-256 checksum
How to use checksums
a7646917b99e121aee62c85f78f9a2a539cc950b25088d083199476fa52d4fb5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for myrohome-helper-mcp 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page