amaran-mcp
Controls an amaran (Sidus Mesh) light directly over Bluetooth Mesh when amaran Desktop is not running, sending encrypted mesh messages to set power, brightness, white/colour, and effects, and reading the light's status and battery reports.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@amaran-mcpturn on the light, dim it to 30%, and set it to warm white"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
amaran-mcp
A Model Context Protocol server and CLI through which an AI assistant drives an amaran light from a Mac, built for two uses of equal weight. It works with Claude Code, Cursor, GrokBot and any other MCP client that runs a local server.
Studio lighting from a prompt | Music mode |
Describe the shot (a talking head, a corporate interview) or show Claude a photo of the set; it sets colour temperature, tint and level, and a saved scene brings the look back. | The light follows what the Mac plays by the structure of the track rather than its beat: it drifts through the groove, pales when the kick drops out, blooms when a breakdown's chords lift, and opens out at the drop. |
Underneath, Apple's on-device sound classifier separates singing from speech, and a 50/50 blend of gradient-boosted trees and a log-mel CNN, trained on 402 expert-labelled Creative Commons EDM tracks, names the section once a second in 3 ms of numpy: balanced accuracy 0.49 on held-out tracks, against 0.36 for hand-written rules. Everything runs on the Mac.
Play a breakdown: press play on a vocal trance track and watch what music mode does, second by second, in step with the music, next to an expert's reading of the same track.
So what · When to use this · How to use this · Music mode · Studio lighting · Tools · What's next · How it reaches the light · Research
So what
Most music-reactive lights flash on every beat. It looks like a club toy, and in a room you work or listen in it wears thin in minutes. Music mode listens the way a musician does instead: it hears the tempo, the chords, the singing and the sections of a track, so the light drifts through the groove, pales when the kick drops out and blooms when a breakdown's chords lift, then opens out at the drop. It never flashes; colour can only change so fast.
Context matters, and so does the human imagination. Trance music evokes different vibes in everyone. Euphoric trance, however, is euphoric for many who listen, myself included; therefore, a bias towards a calming palette was introduced.
Lighting a talking head well is fiddly in the other direction: white balance, tint and level, set by hand and lost by the next call. Here you describe the shot, or show Claude a photo of the set, and it sets the light; a scene brings the same look back tomorrow. Alone in frame, you can say the change out loud instead of getting up to make it.
Everything runs on the Mac: the audio never leaves it, and the light is reached through amaran Desktop or directly over Bluetooth.
Related MCP server: HueMCP
When to use this
You are | Use | Why |
Listening to a trance or house set at your desk, with the light in view | Music mode ( | The room moves with the track's sections, not its kick drum |
Streaming or recording with music playing on the Mac | Music mode | It follows whatever the Mac plays, AirPlay from an iPhone included |
On a video call, recording a talking head or a corporate interview | Studio lighting from a prompt | White light matched to the camera, no colour on the face |
Hosting a show or recording alone, in frame at the Mac | Voice commands to Claude | Look at the monitor, say the change, stay in your seat |
Setting up the same shot again |
| One name brings back colour temperature, tint and level |
Wanting it to learn your music | The background listener and | Your own sessions become training data, kept on your Mac |
It is not for stage or club lighting: it drives one light, it is slow by design, and it speaks to amaran lights, not DMX.
How to use this
Set it up once
You need a Mac, uv, Xcode's command line tools
(xcode-select --install; music mode compiles its audio helper on first run),
and amaran Desktop with the light paired in it.
Install the command from PyPI (later,
uv tool upgrade amaran-mcpupdates it):uv tool install amaran-mcpWithout uv,
pip install amaran-mcp(Python 3.11 or newer) works too;pip install --upgrade amaran-mcpupdates it. For the newest code before a release, install from GitHub instead:uv tool install git+https://github.com/jtannahill/amaran-mcp.Quit amaran Desktop fully (it keeps running after its window closes, and holds the light), then import the light:
amaran-mcp import amaran-mcp statusConnect your assistant.
Claude Code, as a plugin that updates with
/plugin update:/plugin install amaran --marketplace jtannahill/amaran-mcpOn older versions,
/plugin marketplace add jtannahill/amaran-mcpand then/plugin install amaran@amaran-mcp. Or register the command directly:claude mcp add -s user amaran -- amaran-mcp serve.Cursor, in
~/.cursor/mcp.json, with the full path thatwhich amaran-mcpprints (apps opened from the Dock do not see your shell's PATH):{ "mcpServers": { "amaran": { "command": "/Users/you/.local/bin/amaran-mcp", "args": ["serve"] } } }GrokBot or any other MCP client: the same command,
amaran-mcp serve, by its full path.
Ask for something: "warm white at 40 percent", "a slow violet", "start music mode, deep".
To work on the code instead, clone the repo and put uv run before each
command.
import writes ~/.config/amaran-mcp/light.json (mode 600; it holds the mesh
keys). The first Bluetooth use asks for permission for the app running the
command. If the light was paired with the amaran phone app instead,
amaran-mcp import --account you@example.com fetches the keys from the
amaran account (the password is asked for and never stored; untested).
Then ask for what you want
Say to Claude | What happens |
"Start music mode" or "start music mode, deep" | The light follows what the Mac plays, in that mood |
"Stop music mode" | The light goes back to how it was |
"Corporate interview, camera at 5600K, soft and a touch warm" | White light at the right temperature and level |
"Here's a photo of my set, light my face for a webcam talk" | Claude reads the photo and sets white balance and level |
"Save this as interview A" / "recall interview A" | The look is kept and brought back |
"Warmer, and down ten percent", said aloud while on camera | The same tools, by voice (hands free) |
"Warm white at 40 percent" or "a slow violet" | Direct control, as with any light |
The same works from the terminal (amaran-mcp music --mood deep, and
the other commands under Tools).
Music mode
amaran-mcp music --mood ethereal # or ask Claude: "start music mode"The light follows whatever this Mac plays, AirPlay from an iPhone included. It listens to the Mac's own audio output, not a microphone, so headphones are fine. Everything runs on the Mac.
Built for vocal trance
It was tuned on the euphoric, vocal end of trance, the sound of Armin van Buuren's A State of Trance, Find Your Harmony and Future Sound of Egypt, and the genre's habits are built in:
The music | Music mode |
138 BPM, a bar every 1.74 s, phrases of 8 and 32 bars | Counts in bars at the tempo it hears; the model looks at about one 8-bar phrase at a time |
A rolling offbeat bass that never stops | Hears the kick by its beat, not by the bass level |
The long breakdown: pads, piano, a reverb-soaked vocal | Pale first, then the chords set the colour |
Euphoria from minor-key progressions lifting onto major chords | The bloom is tied to that lift and nothing else |
Snare rolls, risers and filter sweeps in the build | Tension from noise and density, so the colour deepens |
The drop: the kick back under the supersaw anthem | Opens out to full on a real drop, not on a bass swell |
A radio host talking over the mix | Apple's classifier tells speech from singing: talk never blooms |
Why this matters for the model, and what the training data lacks: Vocal trance at 138 BPM.
What listens
Stage | What runs | Where |
Capture | A Core Audio process tap on the system output | Swift helper, macOS 14.2+ |
Voices | Apple SoundAnalysis, the built-in on-device sound classifier: singing, choir, speech, rapping, crowd | Apple's model, no network |
Tempo and chords | Kick-band onset tracking for the beat; chroma matched to 24 chords for the harmony and the minor-to-major lift | numpy |
Sections | A machine-learned model names intro, groove, breakdown, build or drop once a second | numpy, 3 ms a second |
Light | A renderer turns sections, chords and voice into one slow colour | numpy |
Apple's classifier is how music mode tells a vocal from a DJ talking over the mix: singing makes a bloom bigger, speech never blooms.
The section model
Two models, blended 50/50:
Gradient-boosted trees on a 16-second summary of what music mode hears: energy, bass, kick, tempo, harmony, tension, Apple's singing and speech readings, and 11 spectral readings.
A spectrogram CNN, a small convolutional network that reads the last 16 seconds as a log-mel spectrogram (64 bands, 10 frames a second).
Both learned from SSME: 402 Creative Commons EDM
tracks with drops, builds and breaks marked by experts. Training uses
scikit-learn and PyTorch; the shipped model is plain numpy arrays
(src/amaran_mcp/music/sections.npz), so music mode needs neither. Scored on
tracks held out from each model's training (five-fold cross-validation):
Sections | Breakdowns | Builds | Drops | |
Rules | 0.36 | 0.02 | 0.00 | 0.10 |
Trees | 0.48 | 0.05 | 0.08 | 0.19 |
CNN | 0.44 | 0.11 | 0.07 | 0.15 |
Blend (shipped) | 0.49 | 0.09 | 0.07 | 0.20 |
Sections is balanced accuracy, the share of seconds called right averaged over the four sections the model names; the others are F scores for finding a start within a few seconds. Rules are the hand-written logic the model replaced. Trance breakdowns are the weakest spot, which is why it also learns from your own listening (below). The full research, every measurement and how to retrain: docs/research.md.
What the light does
Section | The light |
Intro | Restrained, in the lower third of the brightness range |
Groove | Drifts slowly through the mood's colours and breathes with the energy |
Breakdown | Pale for its first bars, then each chord sets the colour: minor cool, major warm |
Lift | The chords rise from minor to major: the light warms, swells and turns luminous, more with a vocal |
Build | The drift stops, the colour deepens, brightness holds |
Drop | Opens out to full |
Trance gets full colour: saturated blues, violets and orchids that only turn paler at the start of a breakdown, and never grey. Hue turns at most 30 degrees a second, so it never flashes or pulses on the beat.
Mood | Colours |
| Deep blue, violet, teal, orchid |
| Indigo, navy, magenta-violet |
| Lavender, peach, gold, rose |
The same song twice
The sections repeat; the colours do not, on purpose.
Same on a second play? | |
Sections, blooms and when they land | Yes, within about a second. The section calls have no randomness and keep time by the audio itself, but live capture lands on a slightly different grid each play, so a call that sits right at a threshold (the 2 s hold, the 4-bar kick test, a bloom) can occasionally flip |
The colours | No. When the Music app names a new song, the light starts it on a palette stop picked at random from those not showing; from any other source (AirPlay, a browser, SoundCloud, YouTube) the groove's drift carries on from where the last track left it. Either way the same sections come in different colours |
The first 10 to 30 seconds | Yes, after a gap of 3 s or more: tempo, chord and sound tracking start fresh for each song, as training heard every track. In a gapless mix they carry on from the track before |
The demo page | Always. It replays one fixed capture, so the light is identical on every play |
Any other light command stops music mode, except brightness, which moves its range. Needs Xcode's command line tools (the audio helper is compiled on first run); macOS asks once for permission to record system audio.
Teaching it your music
amaran-mcp install-listener # record listening sessions at login
amaran-mcp mark lift # or breakdown, vocal, build, drop
amaran-mcp uninstall-listenerThe listener records while music plays (FLAC, a feature log and your marks, in
~/.config/amaran-mcp/recordings), so a model can be trained on what you
actually listen to. It never touches the light, needs ffmpeg, stops at 30 GB,
and nothing leaves the Mac. Delete the folder to remove the recordings.
Music mode records the same way when the listener is not running. Either one keeps only the music: a session starts when music is recognised (with the ten seconds before it) and ends two minutes after it stops, so a call or a video afterwards is not kept, and the microphone is never recorded. The folder is readable by your user only.
Studio lighting from a prompt
Interviews and talking heads are mostly white light: the right colour temperature, the right level, no cast on the face, and colour, if any, only on the background. Say what the shot is and Claude sets the light with the same tools:
"Corporate interview, daylight from a window on the left, camera at 5600K. Soft key, a touch warm, not too bright."
"Here's a photo of my set. Light my face for a webcam talk."
What you need | How it is set |
Match the camera's white balance |
|
Cancel a green or magenta cast from windows or office lights |
|
Exposure for the face |
|
A background accent, when the look wants one |
|
The same look tomorrow, or per shot |
|
Claude reads a photo of the set the way it reads any picture, so it can see the window, the room's colour and where the light sits, and pick the white balance and level from that. Today that is one light; a key, fill and back light setup is planned as more amaran lights join.
Hands free, on camera
Working solo, the light is out of reach once you are in frame: hosting a show alone, or recording a video from the Mac in front of you. Speak to Claude instead, through the Mac's Dictation or the voice input of the Claude app you use, and the light changes while you keep your eyes on the monitor and stay in place:
"Warmer, and down ten percent."
"The sun's gone in. Bring the level up to match."
"Recall interview A."
Each command is an ordinary tool call, so it takes the moment Claude needs to reply: call changes between takes or segments rather than mid-sentence. On a live show the microphone hears the command too, so mute it for the cue or keep cues to the breaks.
Tools
Tool | Does |
| Power, brightness, mode and, over Bluetooth, battery |
| On or off; brightness in percent |
| Colour temperature in kelvin, with optional green or magenta tint |
| Hue, saturation and brightness |
| Built-in effects such as fire, TV and lightning, and the pixel effects through Desktop |
| Name the current look and bring it back |
| Follow what the Mac plays, in a mood |
| Flag a lift, vocal, build or drop for training |
The same from the terminal:
amaran-mcp on | off | status
amaran-mcp brightness 40
amaran-mcp white 3200 60 # kelvin, brightness, optional tint
amaran-mcp color 30 100 50 # hue, saturation, brightness
amaran-mcp effect fire 70
amaran-mcp music --mood deepNext
Neither of these is built yet.
Plan | What it would do |
The body as well as the music | Layer health wearable data on top of music mode: heart rate from an Apple Watch, strain and recovery from WHOOP. The music still sets the sections and the colour; the body modulates them to some degree, for example a calmer, lower drift as your heart rate settles, or a fuller drop when you are moving |
More lights | Several amaran lights at once: a key, fill and back light for interviews, set together from one prompt |
Keep the shot lit | Watch the camera through a take and hold the face's exposure and skin tone steady, nudging brightness and colour temperature as daylight shifts or the speaker moves |
How it reaches the light
AMARAN_BACKEND=auto (the default) picks one on every call:
amaran Desktop running | Desktop closed | |
Path | Desktop's local OpenAPI WebSocket, | Bluetooth Mesh, directly |
Speed | Tens of milliseconds | A second or more |
Effects | Desktop's full list, pixel effects included | The light's built-in effects |
Battery | Not available | Available, with the light's own status reports |
Set AMARAN_BACKEND=desktop or bluetooth to force one.
The Desktop API wants a token in each request, signed with the key from an
approved amaran OpenAPI application (apply in amaran Desktop's User Center).
Put it in ~/.config/amaran-mcp/openapi_key (mode 600) or
AMARAN_OPENAPI_KEY. Without one the server signs with a random key, as the
Bitfocus Companion module does. amaran Desktop 1.1 accepts any token, so
whether an approved key is used exactly as intended cannot be verified yet.
The light acts as a Bluetooth Mesh proxy. The server connects when a tool
runs, sends encrypted mesh messages (Sidus opcode 0x26), reads the light's
status and battery replies, then disconnects after 30 seconds idle so the
amaran apps can reach the light again.
The mesh keys come from amaran Desktop's local database. The server sends from
its own mesh address and stores its message counter, which only goes up, in
~/.config/amaran-mcp/state.json. Lights ignore any message whose counter is
not higher than the last one they saw from that address, so the counter must
never go back.
Tested on a PT2c: status, brightness, white, tint, colour, the fire effect and power were each confirmed by the light's own status reports.
Limits
One light. Custom per-pixel patterns are not supported; the built-in effects are, including the pixel effects through amaran Desktop.
The light accepts one Bluetooth connection at a time. The auto backend avoids fighting amaran Desktop over it, but a phone app holding it still blocks the Bluetooth backend.
Through amaran Desktop, the active mode is the last one this server set; a change made in the amaran apps shows only its power and brightness.
Re-pairing the light in amaran Desktop changes the keys: run
importagain.
Credits
src/amaran_mcp/sidus/ is vendored unmodified from
neyako/amaran-hacs (MIT), which builds
on wesbos/amaran-BLE-control.
The amaran Desktop message and token format follow
bitfocus/companion-module-amaran-desktop (MIT)
and the amaran OpenAPI docs.
The section model learns from the SSME dataset
(Yadati, Larson, Liem and Hanjalic). The demo tracks stream from SoundCloud.
Available Tools
12 toolsget_lightARead-only
Read the light's power, mode, brightness, colour, effect and battery.
Also lists what this model supports (colour temperature range, effects).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already covers the safety profile, so the bar is lower, and the description still adds real context: the call also enumerates model capabilities (colour temperature range, supported effects). That dual-purpose behavior is not derivable from the annotations or the empty schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the primary function and followed by the secondary capability-listing behavior. No filler, no restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and the description still summarizes them plus the capability discovery feature. For a zero-parameter read tool this is essentially complete; only explicit guidance on when to reach for it over nothing is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4; there is nothing for the description to disambiguate. The description correctly spends no words on argument semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Read the light's power, mode, brightness, colour, effect and battery") and enumerates exactly what comes back, which cleanly separates it from the set_* siblings. It stops short of naming an alternative explicitly, but the read-vs-set distinction is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The read verb implies the natural use case (inspect current state before or after calling setters), but there is no explicit when-to-use or when-not-to-use statement. An agent can infer the workflow, yet nothing routes it explicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_music_momentB
Flag this moment in the music mode recording ("the chords just lifted"), for training. Call it the moment the user says so.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | breakdown, lift, vocal, build, drop or other | |
| note | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=false, so the mutating-but-safe profile is structured data. The description adds that the mark is recorded for later training, which hints at persistence, but it doesn't say whether marks are retrievable later, what happens outside music mode, or whether repeats accumulate. Adequate, not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core action, with no filler. 'For training' is the one slightly wasted clause since it's never explained.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values needn't be explained, and only two parameters exist. However, for a stateful tool tied to music mode, the description omits the key precondition (music mode active) and any note on how marks are later consumed, leaving a real gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: the 'kind' parameter already enumerates breakdown/lift/vocal/build/drop/other, so the description adds nothing there. The undocumented 'note' parameter is only indirectly illustrated by 'the chords just lifted'. That example is helpful but not a substitute for describing what the note field is for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (flag/mark) and a specific object (a moment in the music mode recording), which clearly distinguishes it from siblings like start_music_mode and stop_music_mode. The parenthetical example ('the chords just lifted') makes the resource concrete. Minor vagueness remains in 'for training' – it doesn't say what the marks train or feed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Call it the moment the user says so' gives a trigger condition, but it's implied rather than explicit: there's no statement that music mode must already be active, no handling when it isn't, and no alternative tool named. An agent can infer usage but must guess at prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recall_sceneBIdempotent
Put the light back into a saved scene. get_light lists the saved scenes.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, destructiveHint=false, so the safety profile is covered elsewhere. The description adds little beyond that: it does not say what happens if the name is unknown, whether all light attributes are overwritten, or whether the change applies immediately.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no waste, and the core action is front-loaded before the discovery hint.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter mutation with an output schema and annotations, this covers the essentials (what it does, where to find the name). It omits failure behavior and the scope of state change, which matter for a mutating tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the burden, and it does so usefully by indicating that the sole parameter is the name of a saved scene obtainable via get_light. It stops short of stating whether the name is case-sensitive or must match exactly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: restoring the light to a saved scene. The phrasing 'put the light back' is slightly informal, but combined with the get_light reference it clearly marks this as scene recall rather than scene saving, distinguishing it from save_scene.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies the workflow prerequisite by noting that get_light lists the saved scenes, which tells an agent where to get valid names. It never explicitly contrasts recall with save_scene or states when recall is preferred over setting brightness/color directly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_sceneA
Save the light's current look under a name, replacing any scene with that name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations say readOnlyHint=false and destructiveHint=false; the description adds the critical nuance that an existing scene with the same name is replaced, i.e. silent overwrite with no confirmation. That is real behavioral context beyond the structured fields. It stops short of saying whether the save persists across restarts or what happens on invalid names.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with the verb front-loaded and the overwrite caveat appended where it is most needed. No filler, no restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and there is only one parameter. The definition covers the main risk (overwriting a same-named scene). It is slightly thin on persistence scope (scene stored on device vs. app session) for a stateful feature that pairs with recall_scene.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one parameter with 0% description coverage, so the description must compensate. It does partially: 'under a name' plus 'replacing any scene with that name' establishes that name is the lookup key used for overwrite. It gives no constraints on format, uniqueness, length, or case sensitivity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: 'Save the light's current look under a name' tells the agent exactly what is captured and stored. It implicitly contrasts with sibling recall_scene (storing vs restoring) but never names it, so differentiation is inferred rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Phrasing ('current look') implies the tool is used to snapshot the present state, which is enough to pick it over the set_* tools. However, there is no explicit 'use this when...' guidance, no mention of recall_scene as the counterpart, and no stated prerequisites or limits.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_brightnessAIdempotent
Change brightness only, keeping the current white, colour or effect.
While music mode runs, this moves music mode's brightness range instead.
| Name | Required | Description | Default |
|---|---|---|---|
| brightness | Yes | Brightness, 0-100 % |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare it as a non-read-only, idempotent, non-destructive mutation, so the bar is lower; the description still adds real value by disclosing that other settings are preserved and that under music mode the call mutates the music mode brightness range instead of the static level. It doesn't mention failure modes (e.g., device off/unreachable) or rate limits, which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both load-bearing, with the primary behavior front-loaded and the contextual exception second. No filler or restatement of the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation, and the description covers scope, side effects, and the music-mode edge case. Only minor gaps remain — preconditions and error behavior — which are not decisive for a one-parameter call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single brightness parameter is documented with its 0-100 range in the schema, so the definition already carries the semantics. The description adds no format or unit detail beyond that, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Change) and resource (brightness) plus an explicit scope qualifier: 'brightness only, keeping the current white, colour or effect.' That qualifier is exactly what separates it from siblings like set_white, set_color, and set_effect, so an agent can route correctly without reading schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'keeping the current white, colour or effect' communicates the condition that selects this tool over the color/effect setters, and the music-mode sentence flags a context where the effect differs. It stops short of naming the alternative siblings explicitly or stating preconditions such as the light needing to be on.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_colorAIdempotent
Set a coloured light, by hue and saturation or by a #RRGGBB hex colour.
| Name | Required | Description | Default |
|---|---|---|---|
| hex | No | Colour as #RRGGBB, instead of hue and saturation | |
| hue | No | Hue in degrees: 0 red, 120 green, 240 blue | |
| brightness | No | ||
| saturation | No | Saturation, 0-100 % |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare that this is a mutating, idempotent, non-destructive operation, so the description has a lower burden. It adds little beyond those annotations and does not clarify behavioral questions such as precedence between hex and hue/saturation or whether unspecified parameters retain current values.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no wasted wording. The primary action comes first, followed by the two supported colour specification modes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The existence of an output schema and safety annotations removes the need to explain return values or basic mutation safety. Still, an agent would benefit from knowing how hex and hue/saturation interact, whether brightness is affected, and what defaults apply when no parameters are supplied.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents three of four parameters with ranges and examples, giving a baseline of 3. The description usefully frames hex as an alternative to hue and saturation, but it omits the optional brightness parameter and does not explain parameter interaction rules beyond the basic either/or.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: setting a coloured light. It also distinguishes the two main input modes (hue/saturation vs #RRGGBB), though it does not explicitly contrast with siblings like set_white or set_brightness.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: use this for coloured light rather than white or brightness. However, it gives no explicit guidance on when to prefer hex over hue/saturation, what happens if both are supplied, or how it relates to siblings such as set_effect.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_effectCIdempotent
Start one of the light's built-in effects.
| Name | Required | Description | Default |
|---|---|---|---|
| effect | Yes | An effect from get_light's supports.effects, e.g. fire, tv, lightning | |
| brightness | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false, so the safety profile is covered elsewhere. The description adds nothing beyond that: it does not say whether starting an effect replaces the current effect, how brightness interacts with the effect's own colors, or whether the effect persists after disconnect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler; the verb and resource come first. It is efficient, though its brevity is achieved by omitting rather than by compressing real content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and annotations cover the mutation semantics. Still, for a state-changing tool that interacts with brightness and with other effects, the description omits the prerequisite (valid effect list) and any note about replacing a running effect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 50% and the description adds no parameter semantics at all. The critical constraint — that 'effect' must be drawn from get_light's supports.effects — is only in the schema, and the interaction between the optional 'brightness' parameter and the effect is explained nowhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource pair ("Start ... the light's built-in effects"), which is clearly distinct from the sibling stop_effect. It stops short of naming the sibling or stating scope (e.g., which light, whether it replaces an active effect), so it is clear but not maximally differentiating.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this versus set_color, set_white, or recall_scene, and no mention of the required prerequisite that the effect string come from get_light's supports.effects (that only appears in the schema). The reader is left to infer the usage context from the verb alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_powerAIdempotent
Turn the light on or off. On restores what it was doing before.
| Name | Required | Description | Default |
|---|---|---|---|
| on | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose that the tool is mutating, idempotent, and non-destructive. The description adds meaningful behavioral context beyond those annotations by noting that turning the light on restores its previous state, which is important for understanding the effect of the operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences and is front-loaded with the primary action. Every sentence adds useful meaning without unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter power tool with annotations covering safety and idempotency, and with an output schema present, the description is complete enough. It explains the action and the key state-restoration behavior an agent needs to know.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage for the single `on` boolean parameter is 0%, so the description must carry the semantic burden. It does this well by explaining that the parameter controls on/off state and that `on` restores prior behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise verb and resource: turning the light on or off. This is clearly distinct from sibling commands such as set_brightness, set_color, and set_effect, which adjust other light attributes rather than power state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The on/off use case is implied by the description, but there is no explicit when-to-use guidance, no mention of alternatives like get_light or scene recall, and no stated exclusions. It is adequate but leaves the agent to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_whiteAIdempotent
Set white light by colour temperature. get_light shows this model's range.
| Name | Required | Description | Default |
|---|---|---|---|
| tint | No | Green/magenta offset, 0 neutral | |
| kelvin | Yes | Colour temperature, e.g. 3200 tungsten, 5600 daylight | |
| brightness | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false, establishing that this is a safe, repeatable setter. The description adds the practical note to check get_light for the supported range, but says nothing about what happens to the tint or brightness defaults or whether it overrides color settings.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, with the core action front-loaded and the range-lookup hint second. Every sentence earns its place and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, with one required parameter and an output schema available, so the description does not need to explain return values. The main gap is the lack of a warning about interaction with set_color or set_brightness, but the definition is otherwise complete enough for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 67%, and the schema itself provides examples for kelvin (tungsten, daylight) and explains tint and brightness ranges. The description only restates 'colour temperature' and adds no detail on how the parameters combine or what valid values exist beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('set white light by colour temperature'), which distinguishes it from siblings like set_color and set_brightness. It is clear what the tool does, though the distinction from the nearby set_color and set_effect tools is only implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides one useful pointer, telling the agent to use get_light to discover the model's supported range. However, it gives no guidance on when to use this instead of set_color or how it interacts with set_brightness, leaving alternatives to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_music_modeA
Start music mode: the light follows what this Mac is playing (including AirPlay from an iPhone) with slow, ethereal colour. Moods: ethereal, deep, dawn.
| Name | Required | Description | Default |
|---|---|---|---|
| mood | No | ethereal (default), deep or dawn | ethereal |
| record | No | save the session on this Mac for training (default on) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only state readOnlyHint=false and destructiveHint=false; the description adds that the mode reacts to audio playback and uses slow ethereal color. However, it omits session lifecycle details, such as that the mode continues until stopped via stop_music_mode, and it does not surface the default recording-for-training behavior that the schema mentions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences with zero waste. The core behavior is front-loaded, and the mood list is appropriately appended as supporting detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. The description covers the mode's behavior and mood options; the main remaining gap is lifecycle information (how to stop it) and the privacy implication of recording, though the latter is documented in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are fully documented in the schema. The description repeats the available mood names but adds no selection guidance or interpretation beyond what the schema already provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('start') and resource ('music mode') and explains the distinctive behavior: the light follows what the Mac is playing, including AirPlay from an iPhone. It is clearly distinguishable from static effect tools like set_effect, though it does not explicitly name siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it (when you want music-reactive lighting) but gives no explicit when-to-use/when-not guidance or alternatives. It does not mention stop_music_mode or explain how this differs from set_effect beyond the reactive behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop_effectAIdempotent
Stop the running effect and return to the last steady white or colour.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-readonly, idempotent, non-destructive behavior, so the bar is lower. The description adds genuinely useful post-condition context — the light reverts to the previous steady white or colour — which is not captured by any structured field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with no waste; the action is front-loaded and the outcome follows immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and zero parameters, the description need only explain the action and its side effect, which it does. Minor gap: it does not state what happens if no effect is running, though idempotentHint covers most of that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. There is nothing parameter-related for the description to compensate for, and it correctly does not pad with argument detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("stop the running effect") plus the resulting state ("return to the last steady white or colour"). This implicitly separates it from set_effect and stop_music_mode, though it never names a sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied — an agent can infer it applies when an effect is active, but there is no explicit when/when-not guidance or reference to alternatives such as stop_music_mode. Adequate but leaves selection logic to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop_music_modeA
Stop music mode and return the light to how it was.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a non-read-only, non-destructive mutation, and the description usefully clarifies that the prior light state is restored rather than left at the music-mode values. It does not say whether the restoration is instant, whether it fails if music mode is not active, or what the response contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence with the action front-loaded and the side effect trailing. Zero waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter state-changing tool with an output schema and annotations covering the safety profile, the description covers what the tool does and its restoration effect. Only the no-op/error condition is unstated, a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so the baseline is 4; the schema is empty and there is nothing the description could add.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Stop music mode') plus the observable effect ('return the light to how it was'). The inverse sibling start_music_mode makes the pairing obvious, though the description never names it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the name and the start_music_mode sibling; there is no explicit statement of when to call this versus stop_effect or set_power. An agent can infer the pairing but must do so itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v0.1.1- First observed
get_light - First observed
mark_music_moment - First observed
recall_scene - First observed
save_scene - First observed
set_brightness - First observed
set_color - First observed
set_effect - First observed
set_power - First observed
set_white - First observed
start_music_mode - First observed
stop_effect - First observed
stop_music_mode
TDQS
Scored across 12 tools
Each tool has a distinct verb targeting a different aspect of the lamp's state (power, brightness, white, colour, effect, scene, music mode), and descriptions explicitly clarify boundaries, e.g. set_brightness noting it only adjusts brightness while preserving the current mode. The only mild conceptual overlap, start_music_mode vs set_effect, is resolved by describing music mode as a separate behaviour. An agent can pick the right tool from names alone.
All twelve tools follow a strict snake_case verb_noun pattern (get_light, set_power, stop_effect, save_scene, start_music_mode), with natural mirrored pairs like start_music_mode/stop_music_mode and save_scene/recall_scene. No mixed casing or inconsistent verb styles.
Twelve tools is well within the ideal 3-15 range for a single-device lighting controller. Every tool maps to a real capability (state read, each light attribute, effects, scenes, music mode) without redundant entries.
The surface covers the full lifecycle for light control: read state, set power/brightness/colour/white, start and stop effects, save and recall scenes, and music mode. The main gap is scene management beyond save/recall — there is no delete_scene or rename, so saved scenes can only be overwritten, not removed.
Maintenance
Related MCP Connectors
Yeelight device discovery, state, control, and scene execution.
Control Unreal Engine to browse assets, import content, and manage levels and sequences. Automate…
Turns a phone into a camera+Bluetooth remote so AI assistants can see and control any PC.
Connect your AI assistant to Blender for 3D modeling, Geometry Nodes, materials, lighting, animation, rendering and export. Inspect real scenes and viewport images, refine the result and restore checkpoints. OAuth connects your chat to Blender Bridge Desktop on an online Windows 10/11 x64 computer running Blender 4.2+. The chat can run on another device. Requires an active Blender Bridge account; 7-day trial available. AI model access is separate.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables users to control Govee LED devices using the Govee API, with features for turning devices on/off, setting colors, and adjusting brightness through a CLI or MCP clients.6MIT
- AlicenseAqualityDmaintenanceEnables discovery and control of Philips Hue lighting devices via a local bridge using the CLIP v2 API, without any cloud dependency.10MIT
- AlicenseAqualityDmaintenanceEnables control of Philips Hue lights via Bluetooth LE directly from Claude, without requiring a Hue Bridge or internet connection.81MIT
- AlicenseNot gradedqualityDmaintenanceEnables control of Apple Music on macOS, including playback, track info, volume, and more.12 npmMIT