Writes are disabled until you set the flag, so the first thing you can do is inventory and status — "which doors are unlocked, what is on in the basement, what are the setpoints" — with no risk of changing anything. Turn writes on and the allow and deny lists let you keep specific devices, the garage door being the obvious one, out of reach. Session memory is what makes the follow-up phrasing work rather than needing device ids every time.
A Control4 bridge that turns your project's rooms and devices into a tool surface, over STDIO for desktop clients or HTTP for scripts. It talks to the Director directly, validates every input, and enforces safety rules before anything changes state.
- Rooms, devices and control types discovered by name, category and room — `c4_list_rooms`, `c4_list_devices`, `c4_list_controls`, `c4_list_typenames`
- Lighting by name or level, including whole-room operations that avoid catching fans and outlets — `c4_light_set_by_name`, `c4_light_set_level`, `c4_light_ramp`, `c4_room_lights_set`, `c4_light_get_state`
- Locks read and operated, with a state check before and after — `c4_lock_get_state`, `c4_lock_lock`, `c4_lock_unlock`, `c4_lock_set_by_name`
- Thermostats: current state, target temperature, heat and cool setpoints, HVAC mode, fan mode and hold — `c4_thermostat_get_state`, `c4_thermostat_set_target_f`, `c4_thermostat_set_heat_setpoint_f`, `c4_thermostat_set_cool_setpoint_f`, `c4_thermostat_set_hvac_mode`, `c4_thermostat_set_fan_mode`, `c4_thermostat_set_hold_mode`
- TVs and media: what is playing, remote sequences, launching apps, and per-room audio and video source selection — `c4_tv_watch`, `c4_tv_off`, `c4_media_now_playing`, `c4_media_remote_sequence`, `c4_media_launch_app`, `c4_room_select_audio_device`, `c4_room_select_video_device`
- Scenes, macros, announcements and schedules — `c4_macro_execute_by_name`, `c4_announcement_execute_by_name`, `c4_scheduler_list`, `c4_scheduler_set_enabled`
- Alarm state read, armed away or stay, and disarmed — `c4_alarm_get_state`, `c4_alarm_arm_away`, `c4_alarm_arm_stay`, `c4_alarm_disarm`
- Session memory so follow-ups work: "now dim those lights" resolves against the previous target — `c4_lights_set_last`, `c4_tv_off_last`, `c4_memory_get`, `c4_memory_clear`
- Structured ambiguity instead of a guess: when a name matches several rooms or devices, it returns the candidates so the client can ask
A Control4 Director on your network and an account for it. Credentials come from a local `config.json` pointed to by `C4_CONFIG_PATH`, or from `C4_HOST`, `C4_USERNAME` and `C4_PASSWORD` directly. Installed from PyPI as `c4-mcp` 0.1.0 and run over STDIO, or hosted on a NAS over LAN HTTP. State-changing tools stay off until `C4_WRITES_ENABLED` is true; `C4_WRITE_GUARDRAILS`, `C4_WRITE_ALLOWLIST` and `C4_WRITE_DENYLIST` narrow what writes can reach. MIT licensed.
