This fork was largely vibe-coded with AI pair-programming. It has NOT been through upstream code review or formal QA. Do NOT submit PRs to upstream from this fork.
For the official QLC+ project, go to: mcallegari/qlcplus
This fork adds an MCP (Model Context Protocol) server that lets AI agents (Copilot, Claude, Cursor, etc.) design and control lighting shows via natural language.
mcp/directory: Self-contained MCP server — 47 tools, 3 prompts, 230 unit tests- Streamable HTTP transport on
http://localhost:9696/mcp(auto-starts with app)- Function Wizard for QML UI
- Launchpad controller integration support
- Audio capture / BPM detection for scripts
Download the latest DMG from Actions artifacts. After mounting the DMG and dragging QLC+ to
/Applications:sudo xattr -cr /Applications/QLC+.app # clear quarantine (ad-hoc signed) open /Applications/QLC+.appmkdir build && cd build cmake -Dqmlui=ON -Dmcp_server=ON .. make -j$(sysctl -n hw.ncpu) ./qmlui/qlcplus-qml # MCP auto-starts on port 9696Disable MCP with
--no-mcp, or change port with--mcp-http <port>.Copilot CLI / VS Code — add to
~/.copilot/mcp.json:{ "servers": { "qlcplus": { "url": "http://localhost:9696/mcp" } } }Claude Code — run:
claude mcp add qlcplus --transport http http://localhost:9696/mcpClaude Desktop — add to
claude_desktop_config.json:{ "mcpServers": { "qlcplus": { "url": "http://localhost:9696/mcp" } } }Cursor — add to
.cursor/mcp.json:{ "mcpServers": { "qlcplus": { "url": "http://localhost:9696/mcp" } } }
Category Tools Query query_fixtures,query_available_fixtures,query_functions,query_fixture_channels,query_palettes,query_universes,query_input_profiles,query_midi_devices,query_osc_status,query_channel_modifiers,query_feedback_profilePatch patch_fixturesFunctions create_scenes,create_chasers,create_sequences,create_efxs,create_collections,create_rgb_matrices,create_scripts,create_fixture_groups,update_scene_from_dmx,delete_functionsPalettes create_palettes,delete_palettesChannels configure_channels,read_dmx_values,set_channel_modifiers,convert_degrees_to_dmx,set_grand_masterI/O configure_universes,configure_plugin_params,configure_osc,configure_beat_source,configure_launchpad,set_input_profile,vc_configure_feedbackVirtual Console vc_create_pages,vc_create_widgets,vc_query_pages,vc_query_widgets,vc_update_widgets,vc_delete_widgets,vc_reparent_widgetsVC Input vc_map_inputs,vc_set_key_sequences,vc_detect_overlapsVC Layout vc_reflow_framePrompts:
design_dj_show,debug_channel_conflict,setup_launchpadAll tools are batch-based (arrays in, arrays out) and idempotent (upsert by name). See
mcp/MCP-ARCHITECTURE.mdfor full documentation.
create_scriptsaccepts raw JavaScript executed by QJSEngine in a dedicated thread. Scripts are validated before saving — syntax errors are rejected with line numbers.Full Engine API (25 methods)
Function Control:
Method Returns Description Engine.startFunction(id)bool Start any QLC+ function Engine.stopFunction(id)bool Stop a running function Engine.isFunctionRunning(id)bool Check if function is active Engine.waitFunctionStart(id)bool Block until function starts Engine.waitFunctionStop(id)bool Block until function stops Engine.stopOnExit(bool)bool Auto-stop started functions on script exit Fixture Control:
Method Returns Description Engine.setFixture(fxID, ch, val)bool Set fixture channel (0-255) Engine.setFixture(fxID, ch, val, fadeMs)bool Set with fade time Engine.getChannelValue(universe, ch)int Read live pre-GM DMX value Timing:
Method Returns Description Engine.waitTime(ms)bool Pause execution (ms) Engine.waitTime("2s.500")bool Pause using time string Engine.random(min, max)int Random integer in [min,max] Engine.random("1s.0", "5s.0")int Random ms from time strings BPM & Beat:
Method Returns Description Engine.setBPM(bpm)bool Set beat generator BPM Engine.getBPM()int Current BPM (internal/MIDI/audio) Engine.getBeatDuration()int Beat period in ms Engine.isBeat()bool True if current tick is on a beat Audio Input:
Method Returns Description Engine.getAudioLevel()int Overall volume 0-255 Engine.getAudioFrequency(band, numBands)int Frequency band 0-255 (3=bass/mid/high, 16=detailed) Envelope (from parent Chaser/Collection):
Method Returns Description Engine.getOwnID()int This script's function ID Engine.getElapsed()int Ms since script started Engine.getEnvelopeDuration()int Allocated duration from parent (ms, 0 if standalone) Engine.getEnvelopeFadeIn()int Fade-in from parent (ms, 0 if not set) Engine.getEnvelopeFadeOut()int Fade-out from parent (ms, 0 if not set) Function Attributes:
Method Returns Description Engine.getFunctionAttribute(id, idx)float Read function attribute Engine.setFunctionAttribute(id, idx, val)bool Modify running function attribute Engine.setFunctionAttribute(id, "Name", val)bool By name (e.g. "Width", "Intensity") System:
Method Returns Description Engine.setBlackout(bool)bool Toggle global blackout Engine.systemCommand("prog args")bool Run external process (detached) Example patterns
// Candle flicker — Gaussian random, warm colors function gaussRand(mean, std) { var u1 = Math.random(), u2 = Math.random(); return mean + std * Math.sqrt(-2*Math.log(u1)) * Math.cos(2*Math.PI*u2); } for (var tick = 0; tick < 200; tick++) { for (var c = 0; c < 6; c++) { Engine.setFixture(c, 0, Math.max(100, Math.min(255, Math.round(gaussRand(210, 25))))); } Engine.waitTime(Engine.random(30, 120)); } // Envelope-adaptive buildup — reusable across different chaser step durations var totalMs = Engine.getEnvelopeDuration(); if (totalMs <= 0) totalMs = 5000; var steps = Math.round(totalMs / 25); for (var i = 0; i <= steps; i++) { Engine.setFixture(0, 0, Math.round(255 * i / steps)); Engine.waitTime(25); } // Audio-reactive — bass drives brightness, mid drives color for (var tick = 0; tick < 500; tick++) { var bass = Engine.getAudioFrequency(0, 3); var mid = Engine.getAudioFrequency(1, 3); Engine.setFixture(0, 0, bass); Engine.setFixture(0, 1, mid); Engine.waitTime(25); }
(Often abbreviated as "QLC+")
Open-source lighting control for DMX, Art-Net, sACN and more.
Designed for live shows, theatre, architectural installations, and venues.
QLC+ is powerful and user-friendly software to control lighting. QLC+ supports a huge amount of hardware, runs on Linux, Windows (10+), macOS (10.12+), and Raspberry Pi. Whether you're an experienced lighting professional or just getting started, QLC+ empowers you to take control of your lighting fixtures with ease. The primary goal of this project is to bring QLC+ to the level of available commercial software.
We have a dedicated page to help you find support, please check out SUPPORT.md. To learn about a specific feature of QLC+, take a look at the official documentation. To give feedback, submit new fixtures and get new ideas, go to the forum
Click the badge below to see the currently confirmed issues with QLC+. Perhaps you can find a solution?
Compilation guides and platform-specific instructions are available in our GitHub Wiki.
If you're regularly updating QLC+ sources with git pull, you may encounter compiler warnings, errors, or unresolved symbols. We strive to keep the master branch free of critical errors; however, dependencies between objects can sometimes cause issues, requiring a full package recompilation rather than just updating recent changes.
We welcome contributions from the community to help make QLC+ even better. If you're working on something major, start a thread in the Development Forum first. Make sure you read the CONTRIBUTING.md document for more.
If you're reading this we already appreciate you. If you're just getting started with lighting you have absolutely no obligation to give us money. When QLC+ opens up revenue opportunities for you, we'd be very thankful for your support. GitHub sponsors is the preferred option.
If you're interested, QLC+ also has an official store where you can purchase clothing, themes, the Raspberry Pi image or one-on-one consultation with an expert.
QLC+ owes its success to the dedication and expertise of numerous individuals who have generously contributed their time and skills. The following list recognizes those whose remarkable contributions have played a pivotal role in building QLC+.
QLC+ 5
- Eric Arnebäck (3D preview features)
- Santiago Benejam Torres (Catalan translation)
- Luis García Tornel (Spanish translation)
- Nils Van Zuijlen, Jérôme Lebleu (French translation)
- Felix Edelmann, Florian Edelmann (fixture definitions, German translation)
- Jannis Achstetter (German translation)
- Dai Suetake (Japanese translation)
- Hannes Bossuyt (Dutch translation)
- Aleksandr Gusarov (Russian translation)
- Vadim Syniuhin (Ukrainian translation)
- Mateusz Kędzierski + smaks6 (Polish translation)
QLC+ 4
- Jano Svitok (bugfix, new features and improvements)
- David Garyga (bugfix, new features and improvements)
- Lukas Jähn (bugfix, new features)
- Robert Box (fixtures review)
- Thomas Achtner (ENTTEC wing improvements)
- Joep Admiraal (MIDI SysEx init messages, Dutch translation)
- Florian Euchner (FX5 USB DMX support)
- Stefan Riemens (new features)
- Bartosz Grabias (new features)
- Simon Newton, Peter Newman (OLA plugin)
- Janosch Frank (webaccess improvements)
- Karri Kaksonen (DMX USB Eurolite USB DMX512 Pro support)
- Stefan Krupop (HID DMXControl Projects e.V. Nodle U1 support)
- Nathan Durnan (RGB scripts, new features)
- Giorgio Rebecchi (new features)
- Florian Edelmann (code cleanup, German translation)
- Heiko Fanieng, Jannis Achstetter (German translation)
- NiKoyes, Jérôme Lebleu, Olivier Humbert, Nils Van Zuijlen (French translation)
- Raymond Van Laake (Dutch translation)
- Luis García Tornel (Spanish translation)
- Jan Lachman (Czech translation)
- Nuno Almeida, Carlos Eduardo Porto de Oliveira (Portuguese translation)
- Santiago Benejam Torres (Catalan translation)
- Koichiro Saito, Dai Suetake (Japanese translation)
Q Light Controller
- Stefan Krumm (Bugfixes, new features)
- Christian Suehs (Bugfixes, new features)
- Christopher Staite (Bugfixes)
- Klaus Weidenbach (Bugfixes, German translation)
- Lutz Hillebrand (uDMX plugin)
- Matthew Jaggard (Velleman plugin)
- Ptit Vachon (French translation)
Licensed under the Apache 2.0 License. See COPYING for details.
Copyright © Heikki Junnila, Massimo Callegari