zeros-mcp
Click on "Install 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., "@zeros-mcpGo to cue 5 on playback 1"
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.
zeros-mcp
An MCP server for controlling Zero 88 lighting consoles running ZerOS over OSC. It exposes playbacks, cues, the grand master, blackout and user macros as MCP tools.
Implements the OSC surface documented in ZerOS & OSC ("Open Sound Control"), which requires ZerOS 7.14 or later — OSC did not exist before that release.
Zero 88 document OSC for FLX, FLX S24/S48 and ZerOS Server. The 7.14 release notes also list ORB, Solution, SCD and Leap Frog under products affected, and the OSC section carries no console qualifier — but the manual's variant filter does not include them, so treat OSC on those desks as unconfirmed and try it rather than assuming either way.
This drives real lights. Commands take effect immediately on whatever the console is connected to. Point it at a desk with nothing patched, or one that isn't in front of an audience, until you trust it.
The thing to understand first
ZerOS receives OSC. It never sends any. The console has a Receive Port Number and no transmit port; there is no feedback, no acknowledgement, and no way to read the desk's state from here. This is not a gap in this server — it is the shape of the protocol.
Two consequences run through everything below:
No queries about the console exist, or can. There is no
get_active_cue. The only reads areget_command_journal(what this server sent) andget_connection_health(whether the link looks alive). Both say so in their own output, so a model reading them cannot quietly promote "I sent 50%" into "the desk is at 50%".ok: truemeans the packet left this machine, nothing more. Over UDP that is all it can ever mean, because UDP happily accepts writes addressed to a switched-off console. Every success result carriesconfirmed_by_console: falsepermanently.
If you want the console to talk back, it can't. If you want to know whether it's there, set
ZEROS_TRANSPORT=tcp — see Transports.
Related MCP server: Eos MCP
How it works
One outbound path:
commands -> ZEROS_PORT (console's "Receive Port Number")
zeros-mcp ─────────────────────────────────────────────────────► ZerOS console
(nothing comes back, ever)ZerOS takes its arguments in the address path — /zeros/cue/go/1/5 fires cue 5 on
playback 1 — rather than as OSC arguments. Every message this server sends therefore has an
empty argument list, which also sidesteps the fact that Zero 88 never document which OSC type
tag the console expects. It does mean every tool argument is interpolated into an address, so
validating them is load-bearing: a / slipping through wouldn't error, it would fire a
different command.
zeros_mcp/
├── app.py FastMCP instance
├── server.py entry point: logging, mcp.run()
├── config.py ZerosConfig, validated from the environment
├── journal.py what this server sent - not console state
├── errors.py ZerosConfigError / ZerosValidationError / ZerosSendError
├── logging_setup.py stderr logging (stdout carries the MCP protocol)
├── osc/
│ ├── address.py validates anything interpolated into an OSC address
│ ├── slip.py RFC 1055 framing for the TCP transport
│ └── client.py ZerosClient - lazy socket, UDP or TCP, structured errors
└── tools/ one module per area of the consolePrerequisites
A ZerOS console running 7.14 or later
uv— no separate Python install or clone needed;uvfetches Python and the server itself.
Setup
1. Enable OSC on the console. Setup → Triggers → OSC:
Setting | Value |
OSC | Enabled |
Receive Port Number |
|
Protocol | UDP (or TCP (SLIP) — see below) |
Receive Port Number must match this server's ZEROS_PORT, and the protocol must match
ZEROS_TRANSPORT. There is no transmit side to configure, which removes the most common
setup failure on other consoles — and replaces it with a quieter one: because nothing is ever
returned, a wrong port over UDP looks exactly like a working setup from this end. Commands
report ok: true and the rig does nothing.
A console that is not set to DHCP ships on a static 192.168.1.10 / 255.255.255.0.
2. Add it to your MCP client.
For Claude Desktop, add this to claude_desktop_config.json
(Settings → Developer → Edit Config):
{
"mcpServers": {
"zeros": {
"command": "uvx",
"args": ["--from", "git+https://github.com/MaybeItsAdam/zeros-mcp", "zeros-mcp"],
"env": {
"ZEROS_IP": "192.168.1.10",
"ZEROS_PORT": "8830"
}
}
}
}uvx fetches and caches the server straight from GitHub on first launch — nothing to clone or
install by hand. Restart Claude Desktop after editing the config. Any MCP client that launches a
command works the same way; drop the command/args/env above into its config format.
To pin to a specific commit instead of tracking main, append @<commit-sha> to the repo URL.
The server also publishes a system_instructions prompt covering the no-feedback rule, the
macro escape hatch, and when to confirm before acting.
Configuration
All optional. Defaults suit a console on the same machine.
Variable | Default | Description |
|
| Console address. A desk on factory settings is |
|
| Match the console's Receive Port Number. |
|
|
|
|
|
|
Invalid values are rejected at startup with a message naming the variable. Note there is one port here, not the TX/RX pair an Eos-style server needs — inventing a second would misdescribe the protocol.
Transports
UDP is the default and matches ZerOS's own default. It is fire-and-forget: nothing can be learned about the console from it at all.
TCP (SLIP) carries the same messages under RFC 1055
framing. It is worth choosing for one reason: a TCP connection either establishes or it does
not, which is the only evidence of the console's existence available anywhere in this
protocol. With it, get_connection_health can distinguish "something is listening on that
address" from "the packet left this machine". Without it, that question is unanswerable.
The TCP path is written from Zero 88's documented "TCP (SLIP)" option and is covered by tests against a local listener, but it has not been verified against a real console. UDP is the tested-in-anger default. If TCP misbehaves on your desk, please open an issue.
Tools
Every tool returns a structured result with an ok field. ok: false means the command never
left this machine, and error says why. ok: true means it did — and, as above, never more
than that.
Cues — fire_cue, go_cue, set_pending_cue
fire_cue takes a cue and an optional playback, and supports point cues such as 1.5.
set_pending_cue is ZerOS's "Next": it moves the standby cue without firing it.
The Master Playback is playback 0. Playback numbers start at 0, not 1. If a cue will not
fire, try omitting the playback — an FLX S48 user reported /zeros/cue/go/0/4 being ignored
where /zeros/cue/go/4 worked, so the cue-only form is worth trying before concluding the
console isn't listening.
Playbacks — pause_playback, release_playback, view_playback, set_playback_level
go_cue, pause_playback and release_playback all take an optional playback number.
Omitting it targets whichever playback the console currently considers active — which this
server has no way to know, so naming the playback is the safer call.
Omitting fade_seconds on a level is not the same as passing 0: ZerOS then uses the
playback's own raise and lower times, moving rather than snapping.
Whole rig — set_grand_master, set_blackout
Both affect everything at once, and because nothing is reported back you will not be able to tell that you have blacked out a show.
Macros — fire_macro
This is the escape hatch, and it is the answer to most "can it…?" questions. The documented OSC surface has no command line, no channel or colour control, and no way to record anything. Anything outside the list above is done by recording a user macro at the desk once, and firing it by number from here. So "set channel 1 to 50%" is not impossible — it is a macro.
This server — get_connection_health, get_command_journal
Neither reports console state, because none is observable. get_command_journal returns this
server's own history of sent messages, bounded to the most recent 50; an operator moving a
fader by hand a second after you sent a command leaves no trace in it.
Argument ranges are declared in each tool's schema, so out-of-range input is rejected before it reaches the console.
Troubleshooting
Start with get_connection_health. Over TCP it can tell you whether anything is listening,
which narrows the list below considerably. Over UDP it cannot, and it says so rather than guess.
Commands report ok: true but nothing happens. The likeliest failure, and the one with no
signal to go on. Check, in this order:
ZerOS version is 7.14 or later. Older software ignores OSC entirely while looking perfectly healthy — nothing in the UI indicates the feature is absent.
OSC is enabled under Setup → Triggers → OSC.
Receive Port Number equals
ZEROS_PORT.The console's protocol setting (UDP / TCP (SLIP)) matches
ZEROS_TRANSPORT. A UDP sender talking to a console expecting TCP produces exactly this symptom.
To confirm the packets are at least leaving this machine, listen for them yourself:
python3 -c "import socket;s=socket.socket(2,2);s.bind(('',8830));print(s.recvfrom(9999))"Point ZEROS_IP/ZEROS_PORT at that listener and fire a tool. If the datagram arrives, the
send path is fine and the problem is at the console.
Commands return ok: false with a send error. The console is unreachable at ZEROS_IP.
Check the address and that both machines are on the same network. Over TCP this is also what a
refused connection looks like, which is more informative than UDP's silence.
Firewall. On Windows, allow the Python interpreter through for the port you configured.
Nothing works and there is no log output. Set ZEROS_LOG_LEVEL=DEBUG. Logs go to stderr;
your MCP client may hide them.
Development
git clone https://github.com/MaybeItsAdam/zeros-mcp
cd zeros-mcp
uv sync --all-groups
uv run pytest # test suite; no console required
uv run ruff check .
uv run ruff format .
uv run mypyTo point a client at your local checkout instead of GitHub, use
"command": "uv", "args": ["--directory", "/absolute/path/to/zeros-mcp", "run", "zeros_server.py"]
in place of the uvx block above.
The integration tests bind real sockets on ephemeral ports and assert on the bytes that arrive, including the SLIP frame over TCP, so message construction and framing are covered without hardware. There is no receive path to test.
Two rules the test suite enforces mechanically:
Never write to stdout. Under the stdio transport stdout carries JSON-RPC frames; a stray
print()corrupts the session. Usezeros_mcp.logging_setup.get_logger. (tests/test_no_stdout.py)Validate anything interpolated into an OSC address. On ZerOS the address carries the arguments, so a
/in a tool argument silently becomes a different command. Use the helpers inzeros_mcp/osc/address.py.
A third is enforced by convention and worth stating: no tool may imply the console confirmed
anything. tests/test_schemas.py pins the set of get_* tools for that reason — a new one
would mean inventing a feedback path that does not exist.
Related
eos-mcp — the same idea for ETC Eos family consoles. Eos publishes its state over OSC, so that server mirrors the console live and has a far larger tool surface. The difference is the protocol, not the effort.
Licence
MIT — see LICENSE.
Available Tools
12 toolsfire_cueA
Fires a specific cue.
Naming the playback is the clearer call, but the cue-only form is worth knowing about: an FLX S48 user reported the playback-qualified address being ignored where the cue-only one worked. If a cue will not fire, try omitting the playback before concluding the console is not listening.
| Name | Required | Description | Default |
|---|---|---|---|
| cue | Yes | Cue number. Point cues such as "1.5" are supported. | |
| playback | No | Playback number. The Master Playback is 0. Omit to fire the cue on the console's current playback. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses a specific behavioral quirk (playback-qualified address ignored on FLX S48) and provides a workaround, which goes beyond the schema. It does not mention side effects or permissions, but the disclosed quirk is valuable.
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 concise, front-loading the core purpose in the first sentence. The anecdote about the FLX S48 user adds credibility but is slightly verbose; still, it earns its place by providing concrete troubleshooting advice.
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?
Given the simple 2-parameter tool and the presence of an output schema, the description covers the key behavior and a notable exception. It doesn't explain return values, but the output schema covers that. The description is sufficient for an agent to use the tool 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?
The schema already describes both parameters well, but the description adds meaningful context about the playback parameter, explaining that omitting it can be more reliable in certain cases. This goes beyond the schema's basic descriptions.
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 clearly states the tool fires a specific cue, using a specific verb and resource. It also mentions the cue-only form and its utility, but does not explicitly differentiate from sibling tools like go_cue or set_pending_cue, so it lacks sibling distinction.
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 practical guidance on when to omit the playback parameter, suggesting a fallback for when a cue won't fire. However, it does not explicitly state when to use this tool over alternatives, leaving the usage context implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fire_macroA
Runs a user macro stored on the console.
What the macro does is whatever was recorded into it at the desk; this server cannot see its contents, so ask the user what a macro number does rather than guessing from its number.
| Name | Required | Description | Default |
|---|---|---|---|
| number | Yes | User macro number as stored on the desk |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses the critical behavioral limitation: the macro's behavior is opaque to the server, and the number provides no meaningful info about its effect. This prevents the agent from making incorrect assumptions.
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 concise sentences: the first states the core purpose, the second adds an essential caveat. No wasted words, and the key information is front-loaded.
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 parameter and an output schema exists, so the description does not need to explain return values. It covers the essential operational detail (opaque macro contents) and gives practical advice for the agent, making it sufficiently complete.
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 input schema already fully describes the single parameter ('User macro number as stored on the desk'). The description adds no additional semantic detail about the number beyond what schema provides, so a baseline of 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 clearly states the tool's action ('Runs a user macro stored on the console') with a specific verb and resource. It distinguishes itself from sibling tools (e.g., fire_cue) by focusing on macros.
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 provides clear context on how to use the tool: since the server cannot see macro contents, the agent should ask the user what a macro does rather than guessing. This is helpful guidance, though it does not explicitly contrast with alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_command_journalA
Returns what this server has sent to the console.
This is your own history, not the console's state. Every entry means "this message left this machine"; none of them means the desk received it, acted on it, or is still in that state. Someone may have moved a fader by hand a second later and this server would never know.
Use it to retrace what you did, never to answer what the rig is doing.
| 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?
With no annotations, the description carries the full burden and excels: it explains that entries mean messages left this machine, not that the desk received or acted on them, and warns about manual fader movements that the server wouldn't know. This reveals crucial behavioral limitations beyond a simple 'returns' statement.
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 front-loaded with the core purpose, then uses two further paragraphs that each add essential caveats about data interpretation and usage. Every sentence earns its place without being wordy, and the structure is logical (function, meaning, guidance).
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?
Despite being a zero-parameter tool with an output schema, the description provides all necessary context: what the data represents, its limitations, and when to use it. It sufficiently covers the semantics of the returned journal without needing to detail return fields.
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 has zero parameters, so the empty schema already provides complete coverage. The description appropriately avoids inventing parameters, and no further parameter-level explanation is needed, matching the baseline 4 for parameterless tools.
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 clearly states that the tool returns this server's sent console messages, using a specific verb ('returns') and resource ('what this server has sent to the console'). It actively distinguishes this from the console's actual state, setting it apart from sibling tools that query or modify 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 description gives explicit positive guidance ('Use it to retrace what you did') and negative guidance ('never to answer what the rig is doing'). It also clarifies that entries do not imply receipt or action, which is a clear exclusionary instruction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_connection_healthA
Reports what can be determined about the link to the console.
How much that is depends entirely on the transport. Over TCP a connection either establishes or it does not, which is real evidence. Over UDP there is none to be had: nothing is ever returned, and a successful send only means the packet left this machine.
Either way, a healthy link is not evidence that any individual command was understood. ZerOS acknowledges nothing.
| 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?
With no annotations, the description carries the full burden of disclosure. It excellently explains transport-dependent behavior, the limits of UDP, and the fact that a healthy link does not verify command acknowledgment—offering deep transparency about what the result means.
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 appropriately sized and well-structured: it opens with a clear purpose, then explains transport nuances, and ends with an important caveat. Every sentence contributes value without fluff.
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 diagnostic tool with an output schema, the description fully covers the necessary context: what the tool does, how to interpret results, and its limitations. No further details are needed.
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 has zero parameters, so schema coverage is 100%. The description adds useful context about interpreting results based on the transport, but there are no parameter semantics to clarify. Baseline 4 is appropriate given no parameters.
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 clearly states the tool reports on what can be determined about the link to the console, using a specific verb and resource. This distinguishes it from sibling tools that control playback or macros, making its diagnostic purpose evident.
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 provides clear context on when the tool is reliable (TCP) and when it is not (UDP), and explicitly warns not to use it as evidence that commands were understood. While it does not name alternative tools, it gives strong situational guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
go_cueA
Presses Go, advancing to the next cue.
With no playback given this drives whichever playback the console currently considers active, which this server has no way to know. Naming the playback is the safer call whenever you know which one you mean.
| Name | Required | Description | Default |
|---|---|---|---|
| playback | No | Playback to advance. Omit to use the console's current playback. The Master Playback is 0. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations were provided, so the description carries the full burden. It discloses important behavioral nuance: the server cannot know which playback is active when playback is omitted. This adds valuable context about potential ambiguity. It does not discuss side effects or reversibility, but for a simple Go action this is reasonable.
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 sentences: the first states the core action, the second provides a concise caveat about playback selection. It is front-loaded, efficient, and free of fluff.
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 tool with one optional parameter and an output schema, the description is quite complete. It covers the main behavior and the key edge case of omitted playback. It does not describe return values, but that is not required when an output schema exists. Minor gaps like error handling are not critical for this simple action.
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 has 100% coverage for the single parameter. The description enhances the schema by explaining why omitting playback is risky and that providing it is safer. This adds meaningful context beyond the structured definition.
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 clearly states the tool's action: 'Presses Go, advancing to the next cue.' This is a specific verb and resource. It does not explicitly name sibling tools to differentiate, but the action of pressing Go to advance to the next cue is distinct from sibling tools like fire_cue, which likely targets a specific cue.
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 explicit usage guidance for the playback parameter: when omitted, it uses the console's current active playback, and it recommends naming the playback as the safer choice. It does not, however, discuss when to choose this tool over siblings like fire_cue.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pause_playbackA
Pauses a running fade.
| Name | Required | Description | Default |
|---|---|---|---|
| playback | No | Playback to pause. Omit to pause the console's current playback. The Master Playback is 0. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
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 only states the basic effect, without disclosing error behavior, idempotency, or side effects on playback status. For a mutation-like control tool, this is a significant gap.
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 clear sentence with zero wasted words. It is front-loaded with the action and effectively communicates the core purpose.
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?
Given the tool's simplicity (one optional parameter, output schema present), the description is adequate for the core function but lacks edge-case context (e.g., what happens if no fade is running). It does not need to explain return values due to the output schema, so this is a reasonable middle ground.
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 schema's description of the 'playback' parameter is detailed (e.g., 'Omit to pause the console's current playback'). The tool description adds no extra parameter information, so the baseline of 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 'Pauses a running fade' clearly identifies the action (pauses) and the resource (a running fade). This distinguishes it from sibling tools like release_playback (which releases) and fire_cue (which initiates cues). The word 'fade' adds specificity beyond the tool name, making its function 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 description implies usage when a fade is running, but it does not explicitly state when to use this tool versus alternatives (e.g., release_playback), nor does it mention what happens if no fade is running. This falls between 'implied usage' and 'no guidance'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
release_playbackA
Releases a playback, returning the channels it holds to the stack below.
| Name | Required | Description | Default |
|---|---|---|---|
| playback | No | Playback to release. Omit to release the console's current playback. The Master Playback is 0. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It explains the primary effect (channels returned to the stack below), which is valuable, but it does not mention any side effects, prerequisites, or error conditions (e.g., what happens if the playback is not running). The behavior is not fully transparent, but the core action is disclosed.
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, well-structured sentence that immediately states the action and its consequence. There is no wasted language or repetition, making it highly concise and easy to parse.
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?
Given the tool's low complexity (one optional parameter, output schema present), the description provides sufficient coverage of purpose and core behavior. It could be more complete by explicitly addressing when to use this over pause_playback, but the existing context is adequate for this simple 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?
The input schema already provides exhaustive documentation for the single parameter, including its default value (null) and the meaning of 0 (Master Playback). Since schema description coverage is 100%, the description adds nothing beyond the schema, matching the baseline of 3.
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 ("releases") with a clear resource ("playback") and immediately distinguishes the action by explaining the consequence ("returning the channels it holds to the stack below"). This clearly differentiates it from sibling tools like pause_playback or view_playback.
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 provides clear context for when to use the tool: it describes the core behavior of releasing a playback and freeing its channels, implying it is appropriate when a playback no longer needs to hold channels. However, it does not explicitly state when not to use it or name alternatives, such as using pause_playback to temporarily hold channels.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_blackoutA
Turns the console's blackout on or off.
ZerOS accepts several spellings for the argument ("1", "on", "true" and so on); this sends "1" and "0", which are the least ambiguous.
| Name | Required | Description | Default |
|---|---|---|---|
| enabled | Yes | True to black out the rig, False to restore it. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden. It states the core action and adds a useful behavioral detail about sending '1'/'0' spellings. However, it does not mention any side effects, reversibility, or what blackout means for the rig output beyond the schema parameter description.
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 remarkably concise: one clear main sentence and one clarifying sentence about argument handling. Every sentence earns its place, and the purpose is front-loaded.
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 boolean setter, the description combined with the schema and output schema is nearly complete. It lacks only broader usage guidance or notes about interaction with other console states, but these are not critical for such a straightforward 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 description coverage is 100% and the single boolean parameter is well described in the schema ('True to black out the rig, False to restore it'). The description's note about accepted spellings adds peripheral context but does not enhance the semantic meaning of the parameter itself.
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 clearly identifies the tool's action: 'Turns the console's blackout on or off.' It uses a specific verb and resource, and this tool is distinct from all siblings (which handle macros, cues, playbacks, etc.).
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?
No guidance is provided about when to use this tool versus alternatives, or about any prerequisites or exclusions. The description simply states what it does, leaving usage context entirely implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_grand_masterA
Sets the grand master level, optionally fading to it.
The grand master scales the entire rig, so this is one of the few commands here that can black out a show on its own. Confirm before sending it during a performance.
| Name | Required | Description | Default |
|---|---|---|---|
| level | Yes | Level as a percentage, 0-100 | |
| fade_seconds | No | Time to fade over. Omit to change immediately. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly states that the tool can black out a show and advises confirmation during performance, which is valuable risk-related context. It does not describe return values or persistence, but the output schema exists and the warning covers the most critical behavioral trait.
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 sentences with the purpose stated first, followed by a crucial safety note. Every sentence earns its place and no words are wasted.
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 setter with a complete output schema, the description adequately covers the tool's purpose and the most important behavioral caveat (blackout risk). It could mention prerequisites like connection state or that the effect applies globally, but the existing content is sufficient for an agent to invoke it safely and 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?
The input schema already provides 100% coverage with descriptions for both 'level' and 'fade_seconds', including the default and meaning of null. The description adds 'optionally fading' which aligns with fade_seconds but does not add new meaning beyond the schema. Thus the baseline score of 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 ('Sets the grand master level') and immediately clarifies its unique scope ('scales the entire rig'). This distinguishes it from sibling tools like set_playback_level and set_blackout by highlighting its master-level impact.
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 provides a caution ('Confirm before sending it during a performance') but gives no explicit guidance on when to use this tool versus alternatives like set_blackout or set_playback_level. The usage context is implied by the name and the risk warning, but no positive or negative selection criteria are offered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_pending_cueA
Sets which cue is next, without firing it.
This is ZerOS's "Next" command. Use it to jump the standby cue somewhere
else in the stack, then go_cue to run it.
| Name | Required | Description | Default |
|---|---|---|---|
| cue | Yes | Cue number to make pending. Point cues such as "1.5" are supported. | |
| playback | No | Playback number. The Master Playback is 0. Omit to use the console's current playback. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden for behavioral disclosure. It clearly states the key behavior: the tool does NOT fire the cue (critical to distinguish from go_cue/fire_cue). It also explains the 'standby' concept and the intended workflow. However, it does not mention edge cases like invalid cue numbers, overwriting of current pending cue, or any limitations, which would make it fully transparent. The core behavior is well covered, so a 4 is appropriate.
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 concise—two sentences—and front-loaded with the core purpose. Every sentence adds value: the first states what it does, the second explains when/how to use it. No filler or redundancy.
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?
Given the tool's simplicity, the schema's richness, and the presence of an output schema, the description is largely complete. It explains the setting, the non-firing behavior, and the intended sequence with go_cue. However, since there are no annotations and no explicit mention of when to prefer this over fire_cue or go_cue, a small gap remains. For a simple tool, this is nearly complete, so a 4 is warranted.
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 input schema already has 100% description coverage, with clear parameter details (e.g., cue supports point cues, playback defaults to null and references the master playback). The tool description itself adds no additional parameter semantics beyond what the schema provides, so the baseline of 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 clearly states the tool's function: 'Sets which cue is next, without firing it.' This is a specific verb and resource, and the phrase 'without firing it' distinguishes it from fire_cue and go_cue. The reference to ZerOS's 'Next' command adds helpful domain context.
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 provides clear usage context: use it to 'jump the standby cue somewhere else in the stack, then `go_cue` to run it.' This implicitly contrasts with immediate-firing tools and names go_cue as the follow-up action. However, it does not explicitly mention alternatives like fire_cue or when not to use the tool, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_playback_levelA
Sets a playback's fader level, optionally fading to it.
Omitting the fade time is not the same as fading in zero seconds: ZerOS then
uses the playback's own raise and lower times, moving rather than snapping.
Pass fade_seconds=0 if you want an instant change.
| Name | Required | Description | Default |
|---|---|---|---|
| level | Yes | Level as a percentage, 0-100 | |
| playback | Yes | Playback number. The Master Playback is playback 0 | |
| fade_seconds | No | Time to fade over. Omit to use the playback's raise/lower time. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses a critical behavioral nuance: omitting fade_seconds uses the playback's own raise/lower times, resulting in a moving not snapping change. This is valuable beyond the schema. It does not discuss side effects or permissions, but the most surprising behavior is highlighted, so a 4 is warranted.
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 concise and front-loaded. The first sentence states the core purpose; the second paragraph is a focused warning. Every sentence carries useful information with no redundancy or fluff. It is well structured for quick parsing.
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?
Given the tool's simplicity, the schema coverage, and the presence of an output schema, the description is largely complete. It explains the essential behavior and parameters. The only gap is the absence of explicit guidance on when to choose this tool over siblings, but this is a minor omission given how distinct the tool's purpose is.
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 input schema covers 100% of parameters, so the baseline is 3. The description adds significant semantic value by clarifying that omitting fade_seconds is not equivalent to a zero-second fade and explicitly advises passing 0 for an instant change. This goes beyond the schema's 'Omit to use the playback's raise/lower time' by emphasizing the practical implication.
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 clearly states a specific verb (sets) and resource (a playback's fader level), and adds the optional fading capability. This distinguishes it from sibling tools like set_grand_master or fire_cue, which target different controls. The scope 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 description provides clear operational context: set a playback's fader level with optional fade. It includes important guidance on the distinction between omitting fade_seconds and passing 0, which affects behavior. However, it does not explicitly mention when to use this tool over siblings or mention exclusions, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
view_playbackA
Brings a playback into view on the console's screen.
Changes what the operator sees and nothing about the lighting output.
| Name | Required | Description | Default |
|---|---|---|---|
| playback | Yes | Playback number. The Master Playback is playback 0 |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. The explicit statement that it changes only the operator's view and 'nothing about the lighting output' is a valuable, transparent side-effect guarantee. It does not disclose additional behavior like whether it persists or resets selection, but for a simple view tool this is adequate.
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 compact sentences: the first states the action, the second preemptively eliminates a common misconception about side effects. Every word adds value, and the structure is front-loaded with the primary purpose.
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 tool with one parameter, an output schema, and no annotations, the description adequately covers what the tool does and its non-effect on lighting output. The parameter is well-documented in the schema, and the description resolves the critical ambiguity about whether this alters lighting.
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 input schema already fully documents the single parameter (playback integer, with an example that Master Playback is 0), giving 100% coverage. The description adds no parameter-specific details beyond the schema, so the baseline score of 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?
The description states a specific action ('Brings a playback into view') and the target resource ('on the console's screen'), clearly distinguishing it from siblings by explicitly noting it changes nothing about lighting output. This differentiates it from tools like set_playback_level or go_cue that affect lighting.
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 clear context: this is for viewing/selecting a playback without affecting the lighting output. However, it does not explicitly name alternative tools or state when not to use it, so it falls short of the highest bar but offers strong implied usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Most tools have clearly distinct purposes: set_ commands target different parameters, get_ commands retrieve different information, and playback controls are separated by action (pause, release, view, level). The only potential overlap is between fire_cue and go_cue, but the descriptions clarify that one runs a specific cue while the other advances to the next cue.
Tool names follow a consistent verb_noun pattern with useful prefixes (set_, get_, fire_). Minor deviations exist, such as go_cue versus fire_cue and pause_playback/release_playback/view_playback, but the overall naming is predictable and readable.
With 12 tools, the server is well-scoped for controlling a lighting console. It covers cue firing, playback management, levels, blackout, macros, and diagnostics without unnecessary bloat.
The set covers the essential live-control operations (cues, playbacks, grand master, blackout, macros) plus useful diagnostics. The main gap is the inability to read console state—only command history is available—but this is a documented protocol limitation, so it's an acceptable minor gap.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for Zooza — class scheduling, attendance, and booking for activity businesses.
MCP server for Linear project management and issue tracking
The MCP server for Azure DevOps, bringing the power of Azure DevOps directly to your agents.
Related MCP Servers
- AlicenseBqualityBmaintenanceAn MCP server that lets AI assistants control grandMA2 lighting consoles via Telnet, exposing 41 high-level tools for cue management, fixture control, preset management, executor control, macro editing, appearance assignment, bulk operations, console state queries, show file management, read-back verification, and music show workflows.10014Apache 2.0
- AlicenseNot gradedqualityCmaintenanceTransforms an ETC Eos lighting console into a service controllable by AI assistants and automation tools via MCP and OSC, enabling cue management, preset recall, and channel level control.1AGPL 3.0
- AlicenseAqualityDmaintenanceMCP server for controlling Behringer X-Air digital mixers via OSC, with symbolic naming and dB-to-float conversion.191Apache 2.0
- AlicenseBqualityBmaintenanceAn MCP server for controlling Voicemeeter (Basic, Banana, or Potato) on Windows: strip and bus gains, mutes, output routing, live levels, macro buttons, presets, and audio-engine restarts.17MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/MaybeItsAdam/zeros-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server