Skip to main content
Glama
twinkly-mcp

twinkly-mcp

by paztek

twinkly-mcp

A Model Context Protocol (MCP) server that gives AI agents control of your Twinkly lights.

Point an MCP-capable assistant (Claude Desktop, Claude Code, etc.) at this server and ask it to turn your lights on, set a color, change brightness, or switch effects — in plain language.

It's built on top of the @twinklyjs/twinkly library, which talks to Twinkly devices over their local network API.

What you can do

Ask your assistant things like:

  • "Turn the Christmas tree lights on / off"

  • "Make the lights warm white at 40% brightness"

  • "Set them to green"

  • "Switch to the sparkle effect"

  • "What are my lights doing right now?"

  • "Discover my Twinkly devices"

Related MCP server: elgato-keylight

Requirements

  • Node.js 20+

  • One or more Twinkly devices on the same local network

  • An MCP client (e.g. Claude Desktop or Claude Code)

Quick start

With Claude Code, one command:

claude mcp add twinkly --env TWINKLY_IP=192.168.1.50 -- npx -y twinkly-mcp

Replace the IP with your device's, or drop --env entirely and use --env TWINKLY_DISCOVERY=true to let the server find your lights on the network.

For other clients, see Connecting an MCP client below. Nothing to clone or build — npx fetches the package on first run.

To hack on the server itself, see Development.

Configuration

The server is configured via environment variables (CLI flags and an optional JSON config file are also supported — see CLAUDE.md).

Devices

Variable

Description

TWINKLY_IP

IP address of a single device (e.g. 192.168.1.50); registered as the device named default.

TWINKLY_DEVICES

JSON map of named devices, e.g. {"tree":"192.168.1.50","window":"192.168.1.51"}.

TWINKLY_DEFAULT_DEVICE

Name of the device to use when a request doesn't specify one.

TWINKLY_DISCOVERY

true to auto-discover devices on the network at startup.

Don't know your device's IP? Enable discovery, or just ask the assistant to "discover my Twinkly devices".

Transport, safety & diagnostics

Variable

Default

Description

TWINKLY_TRANSPORT

stdio

stdio (for local MCP clients) or http (Streamable HTTP on /mcp).

TWINKLY_PORT

3000

Port for the HTTP transport. Binds to 127.0.0.1.

TWINKLY_READONLY

false

true exposes only read tools — no changes to your lights.

TWINKLY_TOOLS

(all)

Comma-separated allow-list of tool groups: discovery,status,power,color,effects,movies,admin.

TWINKLY_ALLOW_ADMIN

false

true exposes the gated admin tools (set_name, set_timer, send_frame). Off by default.

TWINKLY_TIMEOUT_MS

10000

Per-request timeout.

TWINKLY_LOG_LEVEL

info

error | warn | info | debug. Logs go to stderr only.

Tools

Every device-targeting tool takes an optional device argument (a name from list_devices); omit it to use the default device.

Discovery & status (read-only)

Tool

What it does

list_devices

List the devices the server knows about.

discover_devices

Scan the network for Twinkly devices and add new ones.

get_device_details

Hardware/firmware details (product, model, LED count, MAC, uptime…).

get_summary

Quick overview: mode, color, timer, music, filters.

get_state

Current mode, brightness, saturation, and color in one call.

Control

Tool

What it does

set_power

Turn the lights on (movie mode) or off.

set_mode

Set the operation mode directly (off, color, demo, movie, effect, rt, playlist).

set_color

Set a static color (rgb or hsv) and switch to color mode.

set_brightness

Set brightness 0–100.

set_saturation

Set saturation 0–100.

list_effects / set_effect

List predefined effects / play one by id.

list_movies / set_movie

List saved movies / play one by id.

Admin (gated behind TWINKLY_ALLOW_ADMIN=true)

Tool

What it does

set_name

Rename a device.

set_timer

Schedule daily on/off times.

send_frame

Push one realtime frame of per-LED RGB values over UDP.

The riskier device operations the underlying library can do (firmware, WiFi/network, MQTT, mic, factory reset) are intentionally not exposed.

Connecting an MCP client

Claude Desktop, Cursor, and other stdio clients

Add the server to your client's MCP configuration — claude_desktop_config.json for Claude Desktop, .mcp.json in a project for Claude Code, .cursor/mcp.json for Cursor:

{
  "mcpServers": {
    "twinkly": {
      "command": "npx",
      "args": ["-y", "twinkly-mcp"],
      "env": {
        "TWINKLY_IP": "192.168.1.50"
      }
    }
  }
}

Restart the client, and the Twinkly tools will be available to the assistant. Keep the -y — without it npx may stall on an install prompt that the client can't answer.

Any variable from Configuration can go in that env block: TWINKLY_DISCOVERY instead of a fixed IP, TWINKLY_READONLY to expose only the read tools, and so on.

Streamable HTTP

Run the server with the HTTP transport:

TWINKLY_IP=192.168.1.50 TWINKLY_TRANSPORT=http TWINKLY_PORT=3000 npx -y twinkly-mcp

It serves the MCP endpoint at http://127.0.0.1:3000/mcp. Point an HTTP-capable MCP client at that URL.

How it works

AI assistant  ──MCP──>  twinkly-mcp  ──local HTTP/UDP──>  Twinkly device(s)

The server translates natural-language requests into MCP tool calls, which it maps onto the Twinkly device API on your local network. Your device IPs and tokens stay local — nothing is sent to the cloud by this server.

Development

git clone https://github.com/paztek/twinkly-mcp.git && cd twinkly-mcp
npm install
npm run dev          # run in watch mode (tsx)
npm run build        # compile to dist/
npm test             # run the test suite
npm run test:coverage

# Real-device smoke test (read-only; skipped without a device):
TWINKLY_IP=192.168.1.50 npx vitest run src/integration.test.ts

See CLAUDE.md for architecture, the full configuration reference, and the build history.

License

ISC

Available Tools

14 tools
discover_devicesDiscover Twinkly devicesA

Actively scan the local network (UDP) for Twinkly devices and add any newly found ones to the registry. Returns the full device inventory afterwards. Use this when a device is not yet listed by list_devices.

Inputs: no named parameters. Returns: devices

get_device_detailsGet device detailsA
Read-only

Get static hardware/firmware details for a Twinkly device: product, model, LED count and profile, MAC, UUID, firmware family, and uptime. Use get_state for the current mode/color/brightness.

Inputs: device. Returns: mac, name, uuid, model, +9 more

get_stateGet light stateA
Read-only

Get the current state of a Twinkly device in one call: operation mode, brightness, saturation, and color. This is the go-to read tool before changing anything.

Inputs: device. Returns: mode, color, device, brightness, +1 more

get_summaryGet device summaryA
Read-only

Get a quick overview of a Twinkly device: current mode, color, on/off timer, music state, and active filters (brightness/saturation). Available since firmware 2.5.6.

Inputs: device. Returns: mode, color, music, timer, +2 more

list_devicesList Twinkly devicesA
Read-only

List the Twinkly devices this server knows about (from configuration and any prior discovery). Returns each device name, IP, where it came from, and which one is used when a tool omits the device argument. Use these names as the device argument on other tools.

Inputs: no named parameters. Returns: devices

list_effectsList effectsA
Read-only

List the predefined effects available on a Twinkly device (count + unique ids) and which effect is currently selected. Some firmware cannot report a numeric id for the current effect, in which case only currentEffectUniqueId is set. Use set_effect with an effect id to play one.

Inputs: device. Returns: count, device, effectIds, currentEffectId, +1 more

list_moviesList moviesA
Read-only

List the movies (saved animations) uploaded to a Twinkly device — id, name, frames, fps — and which movie is current. Use set_movie with an id to play one.

Inputs: device. Returns: device, movies, currentMovieId

set_brightnessSet brightnessA

Set the overall brightness of a Twinkly device to an absolute level from 0 to 100.

Inputs: value (required), device.

set_colorSet colorA

Set a single static color and switch the device into color mode so it shows immediately. Provide exactly one of rgb ({r,g,b}, 0–255) or hsv ({h,s,v}; hue 0–359, sat/val 0–255).

Inputs: hsv, rgb, device.

set_effectSet effectA

Select a predefined effect by its numeric id and switch the device into effect mode so it plays. Call list_effects first to see how many effects exist (ids start at 0).

Inputs: effectId (required), device.

set_modeSet operation modeA

Set the LED operation mode directly. Modes: off, color (static color), demo (built-in loop), movie (a saved movie), effect (a predefined effect — pass effectId), rt (realtime), playlist. To pick which movie/effect plays, use set_movie / set_effect.

Inputs: mode (required), device, effectId.

set_movieSet movieA

Select a saved movie by its numeric id and switch the device into movie mode so it plays. Call list_movies first to see the available ids.

Inputs: id (required), device.

set_powerTurn lights on or offA

Turn a Twinkly device on or off. "off" stops the LEDs; "on" resumes movie playback (the usual powered-on state). For a specific mode like a static color or the demo loop, use set_mode.

Inputs: on (required), device.

set_saturationSet saturationA

Set the color saturation of a Twinkly device to an absolute level from 0 (black-and-white) to 100 (full color).

Inputs: value (required), device.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 14 tools

    Disambiguation3/5

    Some tools have overlapping purposes (e.g., get_state vs get_summary, set_power vs set_mode, set_color vs set_mode), but descriptions help differentiate them by intent and use case. Most tools target a clear resource and action pair, so ambiguity is limited to a few pairs.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern (get_, set_, list_, discover_) using snake_case. No mixing of styles or vague verbs, making the naming highly predictable.

    Tool Count5/5

    14 tools is well-scoped for a Twinkly device control server, covering discovery, state, effects, movies, and various settings. The count is not excessive or thin, fitting the domain appropriately.

    Completeness4/5

    Core workflows are covered (discover, list, get state, set power/color/brightness/effects/movies). Minor gaps exist, such as no playlist selection or on/off timer control, but these are workable and do not break main use cases.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server that enables AI agents to control Xiaomi Mi Home smart devices through natural language, with support for listing devices, controlling properties, and running scenes.
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      MCP server for controlling Elgato Key Lights. Enables turning lights on/off, adjusting brightness and color temperature, applying presets, and triggering effects via Claude.
      13
      Apache 2.0
    • A
      license
      A
      quality
      B
      maintenance
      A comprehensive MCP server that enables AI assistants to interact with Home Assistant, control smart home devices, query states, execute services, and manage automations via natural language.
      77
      196,503 PyPI
      7,782
      MIT