Nanoleaf

Nanoleaf MCP Documentation

The Nanoleaf Model Context Protocol (MCP) server allows AI agents to control your Nanoleaf devices.

Pre-requisites

The Nanoleaf MCP requires that you are signed into the Nanoleaf Desktop App and that it is running. The MCP forwards all commands to the desktop app in order to execute them on your devices.

Setup

Claude

Install the Nanoleaf MCP through the Claude connectors marketplace. Search for Nanoleaf and add it to Claude.

ChatGPT

Install the Nanoleaf MCP through the ChatGPT plugin directory. Search for Nanoleaf and install it.

Others

For manual setup with a client that supports the HTTP transport with OAuth, use the URL https://integrations.nanoleaf.me/mcp.

Supported Devices

The following devices are supported: (Note that a firmware update may be required)

The following devices are not supported:

Available Tools

ToolDescription
list_devicesList the Nanoleaf devices in the user's home.
get_device_infoGet static info (serial, model, hardware/firmware versions) and the supported colour-temperature range for one or more devices, all in parallel. Returns a per-device result so partial failures are reported.
get_light_stateQuery the current state per fixture (on/off, brightness, colour, colour temperature, colour mode, and the currently playing scene) for one or more devices, all in parallel. Returns a per-device result so partial failures are reported.
identify_deviceFlash one or more devices briefly so the user can locate them, all in parallel. Returns a per-device result so partial failures are reported.
set_light_stateTurn devices on/off, set brightness, colour (hue/saturation), or colour temperature. Provide one entry per device; each gets its own settings and they are all applied in parallel. To turn some devices on and others off, include both in a single call. Returns a per-device result so partial failures are reported. A colour temperature the device cannot reach is clamped to its nearest supported value; when that happens the result carries colourTemperature {applied, requested} — tell the user which devices differ from what they asked for.
get_scene_capabilitiesList what scenes each device can actually run: the motions it supports, each motion's options with their valid ranges and defaults, the maximum palette size, how many scenes it can store, and which palette types it accepts. Also returns a "common" block holding the intersection across every device listed — use that when authoring one scene for several devices at once, since models differ in which motions they have and how large a palette they accept. Call this before display_scene or save_scene.
get_layoutGet the physical layout of one or more devices, all in parallel. Call this before authoring a static scene — it reports the exact ids that a static scene must colour. Panel devices (light panels and USB) return "geometry":"panels" with one entry per paintable panel: its id, its x/y position in the device's own coordinate space, its orientation in degrees, and its shape, plus the bounding box of the whole layout. Non-light elements such as controllers and power supplies are already excluded. 1D light strips return "geometry":"zones" with a zoneCount, meaning the paintable ids are 0 to zoneCount-1 running along the strip; firmware new enough to expose the fixture endpoints adds per-fixture LED counts. Devices that cannot display static scenes return "geometry":"none". Layouts differ per device, so a static scene must be built separately for each one.
list_scenesList the scenes stored on one or more devices, all in parallel. Returns a per-device result so partial failures are reported.
play_scenePlay a stored scene by name on one or more devices, all in parallel. Returns a per-device result so partial failures are reported.
display_scenePreview a scene on one or more devices, all in parallel. A scene is either a motion + colour palette, or a static scene that sets every panel or zone to its own fixed colour via staticData. Returns a per-device result so partial failures are reported.
show_temporary_colourShow one or more colours on one or more devices for a set number of seconds, all in parallel. This is the tool to use for any request like "flash my lights red", "blink the lights green when the build fails" or "make everything blue for a minute" — prefer it over identify_device, set_light_state and display_scene for those. The device fades through the colours given, one every secondsPerColour, for a total of seconds: one colour holds steady, a colour plus black flashes, and several colours cycle. It plays a temporary scene, so when the time is up the device goes back on its own to whatever it was showing before — nothing needs to be restored afterwards and no scene is saved. Returns a per-device result so partial failures are reported.
save_sceneSave a scene to the stored scene list of one or more devices so it can be selected later, all in parallel. A name is required. A scene is either a motion + colour palette, or a static scene that sets every panel or zone to its own fixed colour via staticData. To edit an existing scene, save with the same name (or the same effectId from list_scenes) — it overwrites the existing scene instead of creating a duplicate. Returns a per-device result so partial failures are reported.
rename_sceneRename a stored scene on one or more devices, all in parallel. Returns a per-device result so partial failures are reported.
delete_sceneDelete a stored scene by name (from list_scenes) from one or more devices, all in parallel. Returns a per-device result so partial failures are reported.
get_circadian_lighting_configGet whether circadian lighting is enabled per fixture, plus the ramp config, for one or more devices, all in parallel. Returns a per-device result so partial failures are reported.
set_circadian_lighting_configSet the circadian lighting ramp configuration (white-point targets in Kelvin + ramp times) on one or more devices, all in parallel. Uses sunrise/sunset offsets by default; supply both riseTimeOfDayMinutes and fallTimeOfDayMinutes for explicit clock times. Call set_device_time first, and set_device_location as well when using sunrise/sunset offsets: a device that does not know its clock, or its position, refuses the write. Returns a per-device result so partial failures are reported.
set_circadian_lightingEnable or disable circadian lighting on one or more devices, all in parallel. Turning it on needs a ramp config already stored (set_circadian_lighting_config) and the clock set (set_device_time); a device missing either refuses. Turning it on also switches the fixture on, since the ramp only sets a white point and would otherwise leave it dark. Returns a per-device result so partial failures are reported.
get_device_timeGet the current clock (UTC) and timezone offset for one or more devices, all in parallel. Returns a per-device result so partial failures are reported.
set_device_timeSet the clock (UTC) and optionally the timezone offset on one or more devices, all in parallel. Defaults to the current time. Required for circadian features. Returns a per-device result so partial failures are reported.
get_device_locationGet the configured location (latitude/longitude) for one or more devices, all in parallel. Returns a per-device result so partial failures are reported.
set_device_locationSet the physical location (latitude/longitude) on one or more devices, all in parallel. Used for sunrise/sunset-based circadian lighting. Returns a per-device result so partial failures are reported.
get_power_drawGet the current power draw in watts for one or more devices, all in parallel. Light-panel devices answer with a live measurement; every other model returns a hard-coded estimate, and the result's source field ("measured" or "estimated") says which — tell the user when a value is an estimate. Returns a per-device result so partial failures are reported.
get_4d_modeGet the 4D screen-mirror mode (off/1D/2D/3D/4D) for one or more NL69 4D-controller devices, all in parallel. Only supported on NL69. Returns a per-device result so partial failures are reported.
set_4d_modeSet the 4D screen-mirror mode on one or more NL69 4D-controller devices, all in parallel. Modes: "off", "1D", "2D", "3D", "4D". Only supported on NL69. Returns a per-device result so partial failures are reported.
get_4d_rhythmGet whether rhythm (music-reactive) screen mirror is enabled for one or more NL69 4D-controller devices, all in parallel. Only supported on NL69. Returns a per-device result so partial failures are reported.
set_4d_rhythmEnable or disable rhythm (music-reactive) screen mirror on one or more NL69 4D-controller devices, all in parallel. Only supported on NL69. Returns a per-device result so partial failures are reported.
get_4d_camera_parametersGet the 4D camera image parameters (contrast, exposure, gain, gamma, hue, saturation, white balance, relative brightness) for one or more NL69 4D-controller devices, all in parallel. relativeBrightness is what users call "dynamic range". Only supported on NL69. Returns a per-device result so partial failures are reported.
set_4d_camera_parametersSet 4D camera image parameters on one or more NL69 4D-controller devices, all in parallel. Per device, either name a preset ("cinematic" for natural colour, "vivid" for punchier colour and brightness) or supply a custom subset of parameters. A preset resets the camera to factory defaults first. Users refer to relativeBrightness as "dynamic range". Only supported on NL69. Returns a per-device result so partial failures are reported.
reset_4d_camera_parametersReset the 4D camera image parameters to factory defaults on one or more NL69 4D-controller devices, all in parallel. Only supported on NL69. Returns a per-device result so partial failures are reported.
get_sync_plus_configRead the Sync+ configuration (bounding box + participating devices and their positions/enabled state) from a Sync+ controller, all in parallel. Pass the NL69 4D-controller serial as the Sync+ controller. Only supported on NL69. Returns a per-device result so partial failures are reported.
set_sync_plus_configGenerate and apply a Sync+ configuration on a Sync+ controller (NL69) from device positions, all in parallel. Intended for the photo-to-config flow: the AI supplies each receiver's serial and its position in the TV's frame of reference (x = left→right, y = floor→ceiling, z = depth/distance-from-TV, all 0-100) and whether it participates; the MCP fetches each device's pairing id, IP, auth token, and layout and derives everything else. Estimate positions as if facing the TV. Only supported on NL69. Returns per-device results (applied count + skipped receivers with reasons).
set_sync_plus_device_enabledTurn Sync+ on or off, all in parallel. Sync+ runs whenever at least one receiver is enabled, so this is how Sync+ is started and stopped: pass enabled true to start it and false to stop it. Pass the NL69 controller serial. Leave deviceIds out to apply to every receiver in the controller's configuration, or pass specific ids (from get_sync_plus_config) to change only those. Only supported on NL69. Returns a per-device result so partial failures are reported.
get_playlistsList the playlists saved for the user's home, via the Nanoleaf desktop app. A playlist is a named, ordered set of scene names shared across the whole home — it is not tied to a single device, so a playlist's scene names may not all exist on any one device. Each playlist has a uuid and a type: type 4 (user) is a playlist the user created, and is the only type that can be changed with save_playlist or removed with delete_playlist; the other types (1 all, 2 colour, 3 rhythm) are built in and read-only. Requires the desktop app to be running and signed in.
save_playlistCreate or update a playlist in the user's home, via the Nanoleaf desktop app. Omit uuid to create a new playlist; pass the uuid of an existing user playlist (from get_playlists) to overwrite it instead. This can only create or edit user playlists (type 4) — the built-in playlists returned by get_playlists (all, colour, rhythm) cannot be created or edited this way. A playlist is shared across the whole home, so effectNames may reference scenes from any device in the home, not just the one it will later be played on — when played on a device that doesn't have one of these scenes, that scene is silently skipped for that device with no error and no report of what was skipped. Before saving, use list_scenes on the devices you expect to play this playlist on and compare against effectNames, so you can warn the user up front about any scenes that won't play everywhere. Requires the desktop app to be running and signed in.
delete_playlistDelete a playlist from the user's home, via the Nanoleaf desktop app. The built-in playlists (all, colour, rhythm) cannot be deleted. Requires the desktop app to be running and signed in.
play_playlistPlay a playlist on one or more devices, via the Nanoleaf desktop app. Requires the desktop app to be running and signed in. Only light panels can play playlists. Returns a per-device result so partial failures are reported.
get_screen_mirror_statusCheck whether the Nanoleaf desktop app is currently mirroring the computer's screen to the user's devices, and which mode it is set to. This reports the desktop app, not an individual device, so it takes no device serial. Always call this before start_screen_mirror or stop_screen_mirror, because starting when it is already running or stopping when it is already stopped is an error. Requires the desktop app to be running and signed in.
start_screen_mirrorStart screen mirroring on the Nanoleaf desktop app, which streams the computer's screen to the devices the user has configured there. This controls the desktop app, not an individual device, so it takes no device serial — do not use it to set a device's own 4D mode (that is set_4d_mode). The mode picks how the screen is translated to light: "4D" mirrors the screen edges, "Tranquility", "Flow", and "Chameleon" are ambient modes that follow the screen's overall colour. Call get_screen_mirror_status first: starting when screen mirroring is already running is an error, so stop it with stop_screen_mirror before starting it in a different mode. Requires the desktop app to be running and signed in.
stop_screen_mirrorStop screen mirroring on the Nanoleaf desktop app. This controls the desktop app, not an individual device, so it takes no device serial — to turn off a device's own 4D mode use set_4d_mode with "off". Call get_screen_mirror_status first: stopping when screen mirroring is not running is an error. Requires the desktop app to be running and signed in.

Troubleshooting