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 (or, with Helper 5.0, a NESS / ELK M1 panel) 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.
uvon the machine running the assistant (brew install uvor the one-line installer).uvxfetches and runs this server on demand and keeps it updated.
NESS / ELK (Helper 5.0)
Helper 5.0 adds NESS / ELK M1 panels alongside HAI / Leviton Omni. The tools and
their parameters are the same for both; controller_status reports
controllerFamily ("HAI / Leviton" or "NESS / ELK", derived from the
controller's protocol), and the live scripting_reference is scoped to that
family, so the assistant should read it before writing scripts. On ELK, user
codes may be 4 or 6 digits (security-code set accepts either), there is no
energy-cost level, and audio is a legacy M1XEP integration.
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, controllerFamily |
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 (HAI / Leviton only) |
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.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| myrohome_helper_mcp-0.5.1.tar.gz | 91.7 kB | Without provenance | Details for myrohome_helper_mcp-0.5.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| myrohome_helper_mcp-0.5.1-py3-none-any.whl | Python 3 | none | any | Details for myrohome_helper_mcp-0.5.1-py3-none-any.whl |
Total release size: 118.6 kB
Release files / myrohome_helper_mcp-0.5.1.tar.gz
| Download URL | myrohome_helper_mcp-0.5.1.tar.gz |
|---|---|
| Size | 91.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
829a1b3b4eab9399af79ecab407cfa1c9d35b36b75ffa65ff670361073cf0efe
|
|
BLAKE2b-256 checksum How to use checksums |
7e89ea9bf187357eb522ac8b243f9d779f27c01be743b90bbecc9809bd9fedfc
|
| 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.1-py3-none-any.whl
| Download URL | myrohome_helper_mcp-0.5.1-py3-none-any.whl |
|---|---|
| Size | 26.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dc6206cf82e7b90df348bbc38e5a350cfdd9e2378b79798054fe1ff7f3ad27d0
|
|
BLAKE2b-256 checksum How to use checksums |
e760b5aa21032d5ff169b6d67e19519d22a380f1f64aa495ca96c02e9e2ca887
|
| 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.1
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.