millumin-mcp
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., "@millumin-mcplaunch column 2 and set the video master to 0.8"
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.
millumin-mcp
An MCP server that lets Claude Code, or any MCP client, control Millumin on macOS through its OSC API.
It runs locally over stdio, started by the client. It sends OSC to Millumin and can listen for Millumin's feedback. Tested with Millumin 5.14.
Tools
Tool | Purpose |
| Run |
| Set a property on a target (default |
| Set the |
| Send any OSC address |
| Send |
| Send |
| Read recent feedback, optionally filtered |
Related MCP server: supercollider-mcp
Setup
In Millumin's Device manager (⌘K), OSC tab:
OSC listener on input port 5678.
For feedback: an OSC sender to
127.0.0.1port 5679, with feedback on.
Build the server (Node 20 or later):
git clone https://github.com/jpkelly/millumin-mcp.git
cd millumin-mcp
npm install
npm run buildAdd it to your MCP client:
{
"mcpServers": {
"millumin": {
"command": "node",
"args": ["/path/to/millumin-mcp/dist/server.js"],
"env": { "MILLUMIN_FEEDBACK_PORT": "5679" }
}
}
}Variable | Default | |
|
| Where Millumin runs |
|
| Millumin's OSC listener port |
| unset | Port to receive feedback on; unset turns feedback off |
| unset |
|
Notes
Millumin's OSC API can't create layers, canvases, outputs or routings. Make those in Millumin.
selectedLayerfollows the selection in Millumin's interface. Targetindex:Nwhen the selection may change.Launching a column that is already playing doesn't restart it.
goToTime [0]restarts all media together.Feedback gives layer names in lowercase.
Tests
npm testRuns against a fake Millumin on a loopback port, never a real one.
License
Available Tools
7 toolsmillumin_actionB
Run a Millumin action, e.g. launchColumn [index or name], stopColumn, launchNextColumn, playOrPause, goToTime [seconds], selectLayer [index or name], displayTestCard, hideTestCard.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Action arguments | |
| name | Yes | Action name without the /action/ prefix, e.g. launchColumn |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It lists action names but does not disclose side effects, permissions, reversibility, error behavior, or whether actions are synchronous, which is a significant gap for an action-execution tool.
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 a single front-loaded sentence with no filler, and the examples earn their place by illustrating valid action names and argument forms. The dense list format is efficient, though it could be slightly more structured.
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 two-parameter tool with full schema coverage and no output schema, the description is adequate to call common actions. However, the absence of annotations leaves behavioral details such as side effects, permissions, and error handling undocumented, and sibling differentiation 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?
Schema coverage is 100%, so the baseline is 3, but the description adds useful meaning by showing example action names and their expected arguments, such as launchColumn [index or name] and goToTime [seconds]. This helps the agent understand how the generic 'args' array is used in practice.
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 and resource: 'Run a Millumin action', and gives concrete action names such as launchColumn and goToTime. It is clear what the tool does, though it does not explicitly distinguish itself from siblings like millumin_send_raw or millumin_set.
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 examples imply that this tool runs named Millumin actions, but there is no explicit guidance on when to use it versus alternatives such as millumin_set, millumin_send_raw, or millumin_query. No exclusions or preconditions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
millumin_feedbackA
Return recent feedback messages from Millumin (addresses start with /millumin), optionally filtered by a case-insensitive substring such as "launchedColumn" or "layer:Intro".
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | No | ||
| sinceSeconds | No | Only messages from the last N seconds |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden: it does disclose that matching is case-insensitive and that addresses are namespaced under /millumin, which is genuine added context. However it omits whether reads are non-destructive, whether messages accumulate or are consumed, ordering, and any result-count limit — all relevant for a feedback-buffer read.
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 sentence, front-loaded with the action and resource, with the optional filter trailing. The parenthetical examples are useful rather than padding; no wasted prose.
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 no output schema and no annotations, the description should say something about what a returned message looks like (timestamp, address, value) or how many come back. It covers input-side filtering adequately but leaves the response shape entirely unspecified.
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%, and the description compensates for the undocumented `pattern` parameter by specifying case-insensitive substring semantics plus two concrete example values. `sinceSeconds` is already documented in the schema, so the remaining gap is minor.
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 (return recent feedback messages from Millumin) and narrows scope to /millumin-prefixed addresses. It does not distinguish itself from the sibling millumin_query, which plausibly also reads Millumin state, so an agent may hesitate between the two.
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 by the filtering examples ("launchedColumn", "layer:Intro"), which show the kinds of things to search for, but there is no explicit statement of when to prefer this over millumin_query or millumin_ping, nor any exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
millumin_masterB
Set a master level: video, audio, or dmx. Value is normalized 0..1.
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | ||
| channel | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does not say whether the master applies live to output, whether setting is immediate, what happens to previously set levels, or what is returned - significant gaps for an unannotated mutation.
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, zero filler, and the action and channel set are front-loaded. Nothing needs to be trimmed.
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 two-parameter mutation with no annotations and no output schema, the description is minimally viable: the inputs are covered, but behavior of the write (effect timing, scope across channels, error conditions) is absent.
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 0%, but the description does cover both parameters: the channel enum values (video/audio/dmx) are echoed and 'normalized 0..1' clarifies that 1 means full level rather than an arbitrary float range. That is modest added meaning; the schema already provides the min/max bounds.
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 (Set) and a specific resource (a master level) with its three channels enumerated. It is clear what the tool does, but it never contrasts with the very generically named sibling millumin_set, so an agent could plausibly confuse the two.
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 explicit guidance on when to use this tool versus millumin_set or millumin_action, no prerequisites, and no note on when not to use it. The only usage signal is the implicit 'you want to set a master level'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
millumin_pingB
Send /ping and return the layer and board state Millumin reports back. Requires MILLUMIN_FEEDBACK_PORT and Millumin's OSC "API feedback" enabled and pointed at that port.
| Name | Required | Description | Default |
|---|---|---|---|
| waitMs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose a non-obvious external dependency (env var plus a setting inside Millumin) that an agent could not infer from the schema. It stops short of describing failure behavior — what happens if no feedback arrives, whether the call errors or returns empty — which matters for a network/OSC round-trip tool.
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, zero filler, with the action and its return value front-loaded and the prerequisite following. Every sentence earns its place.
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?
There is no output schema, so the description must carry return semantics; it names the returned data (layer and board state) but not its shape. Combined with the undocumented waitMs and the absence of timeout/failure behavior, a network-dependent tool is left partially specified.
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% and the single parameter waitMs (integer, default 1000, 100–10000) is never mentioned in the description. Its obvious meaning — how long to wait for the feedback reply before giving up — is exactly the kind of semantics the description should supply and does not.
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 — send /ping and return layer and board state — which is concrete and actionable. It does not, however, distinguish itself from siblings like millumin_feedback or millumin_query, which plausibly return overlapping state, so an agent cannot route between them from the description alone.
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 gives a hard prerequisite (MILLUMIN_FEEDBACK_PORT set, Millumin's OSC 'API feedback' enabled and pointed at that port), which implicitly frames this as a connectivity/health check. But it never says when to prefer this over millumin_feedback or millumin_query, nor what to do if the precondition is unmet.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
millumin_queryA
Ask Millumin for the current value of one property by sending address + "/?", then return any feedback that came back. Example address: /layer:Intro/opacity.
| Name | Required | Description | Default |
|---|---|---|---|
| waitMs | No | ||
| address | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose meaningful behavior: it appends "/?" to the address and returns 'any feedback that came back,' hinting the response may be empty. It does not say what happens on timeout, whether feedback is guaranteed, or what a failed query returns — gaps that matter for a read tool with no annotation safety net.
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, front-loaded with the action and followed by the concrete wire-protocol example. No filler, no repetition of schema constraints.
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-address read with no output schema, the description gives enough to construct a call: the address format, the appended suffix, and the shape of the response. The main omission is timeout/empty-response behavior tied to `waitMs`, which an agent would need to interpret a blank result.
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 must compensate. It does well on the required `address` param by giving the format convention and a concrete example (`/layer:Intro/opacity`), but `waitMs` (100–5000, default 500) is never mentioned, leaving a timing control that directly affects whether feedback is captured completely undocumented.
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 current value of one property from Millumin. The protocol detail (address + "/?") and the example address make the operation unambiguous, though it never names the read-vs-write boundary against siblings like millumin_set or millumin_feedback.
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 word 'query' — an agent can infer this is the read path while millumin_set is the write path, but the description never says when to pick this over millumin_feedback or millumin_send_raw, nor any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
millumin_send_rawA
Send an arbitrary OSC message to Millumin. Use only when no typed tool fits. Destructive addresses (/action/quit, /action/saveProject) are refused unless the server was started with MILLUMIN_ALLOW_DESTRUCTIVE=1.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | ||
| address | Yes | OSC address, e.g. /selectedLayer/opacity |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the safety burden and discloses an important guardrail: destructive OSC addresses are refused unless MILLUMIN_ALLOW_DESTRUCTIVE=1. It does not fully describe side effects of non-destructive messages, response behavior, or error handling.
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 three tight sentences with purpose, usage constraint, and safety behavior front-loaded. There is no redundant or filler text.
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?
It covers the critical escape-hatch usage rule and destructive-address guard, which are the main risks. However, with no annotations and no output schema, it leaves gaps around args semantics, return values, and error behavior.
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 only 50%, and the description does not explain the args parameter or how values map to OSC arguments. The address parameter is already documented in the schema, so the description adds little parameter meaning beyond the structured fields.
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 and resource: send an arbitrary OSC message to Millumin. It also distinguishes this escape-hatch tool from the typed tools by saying to use it only when no typed tool fits.
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 gives a clear last-resort rule: use only when no typed tool fits. It also names destructive addresses that are blocked unless an environment flag is set, though it does not explicitly name the alternative typed sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
millumin_setB
Set a property on a target. Target defaults to selectedLayer; other forms are layer:, light:, index:, or an element name. Property examples: opacity, position/x, position/xy, rotation, scale, intensity, media/speed, media/normalizedTime.
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | Value; arrays are sent as multiple args | |
| target | No | Target element, e.g. selectedLayer or layer:Intro | selectedLayer |
| property | Yes | Property path, e.g. opacity or position/xy |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral burden. 'Set' implies mutation and the default target is disclosed, but permissions, side effects, reversibility, error behavior, and return behavior are all omitted.
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 compact and front-loaded: the core operation comes first, followed by target syntax and property examples. Every clause contributes directly to invocation.
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?
It covers target and property syntax well, and the schema fully documents the value parameter. But with no annotations and no output schema, the description leaves mutation side effects, error behavior, and sibling selection guidance unaddressed.
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 100%, so the baseline is 3. The description earns a bump by adding target forms beyond the schema example ('light:<name>', 'index:<n>', element name) and extra property paths such as 'position/x' and 'media/speed'.
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 and resource: 'Set a property on a target.' It adds property examples that clarify the kind of operation, but it never differentiates this tool from siblings such as millumin_action or millumin_send_raw.
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 by the operation name, and the target-default sentence helps invocation. However, the description never states when to choose this over millumin_action, millumin_send_raw, or other siblings, nor does it give prerequisites or exclusions.
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.
7 tool updates
v0.1.0- First observed
millumin_action - First observed
millumin_feedback - First observed
millumin_master - First observed
millumin_ping - First observed
millumin_query - First observed
millumin_send_raw - First observed
millumin_set
TDQS
Scored across 7 tools
The typed tools separate command execution (millumin_action), property setting (millumin_set), and master-level setting (millumin_master) clearly. millumin_query, millumin_feedback, and millumin_ping all expose feedback/state but with distinguishable purposes, while millumin_send_raw overlaps everything as a fallback, keeping this from a perfect score.
All names share the millumin_ prefix and snake_case, which aids readability. However, suffixes mix nouns and verbs (action, master, feedback, ping, query vs set, send_raw) rather than following a single predictable verb_noun convention.
Seven tools is well within the appropriate range for an OSC control bridge. Each tool has a distinct role: typed control, master control, raw fallback, and introspection.
The surface covers core control and introspection: actions, property setting, master levels, targeted queries, recent feedback, ping state, and raw OSC as an escape hatch. Typed discovery/listing of layers, columns, media, or available properties is not provided, though raw OSC can fill those gaps.
Maintenance
Related MCP Connectors
OSC ↔ MIDI bridge for synthesizers and DAWs, with the SynthHub catalogue. A MIDI MCP and OSC MCP.
Remote MCP server for audio stem separation, denoise, reverb, and MIDI export.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
MCP server for OnceAsk, the AI-native current-address layer for people and agents.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables control of a running TouchDesigner instance via MCP protocol, providing tools to manage operators, parameters, and project state through a local HTTP bridge.161-
- AlicenseNot gradedqualityDmaintenanceBridges MCP clients to a running SuperCollider IDE, enabling code evaluation, state queries, post window capture, and screenshots via OSC.GPL 2.0
- FlicenseAqualityDmaintenanceMCP server that enables control of an ETC Eos lighting console over OSC, supporting cues, channel levels, faders, and macros, with safety guards for destructive actions.132-
- AlicenseCqualityCmaintenanceEnables end-to-end control of FL Studio on macOS through MCP clients, including transport, patterns, mixer, piano roll, playlist, live metering, browser navigation, and rendering.160MIT