fl-bridge-mcp
# fl-bridge-mcp ( Made With Fable 5.1)
An MCP server that gives AI assistants (Claude Code, Claude Desktop, Cursor, any MCP client)
**full control of FL Studio** through its scripting API. It connects on its own and never
touches your mouse or keyboard.
- **Zero-setup connection.** On first use it installs its controller script into FL Studio's
settings folder, finds your virtual MIDI port, and probes FL Studio. No native MIDI wheels on
Windows: it talks to loopMIDI through the built-in `winmm` API.
- **57 focused tools covering the whole API** (consolidated so an assistant sees a compact, cheap tool list), built from the official FL Studio API reference
(`docs/fl-api-reference.md`): project save, tempo, time signature, undo, markers, transport,
channels, step sequencer (including per-step pitch/velocity), mixer routing and EQ, effect
slots, plugin parameters and presets, patterns, playlist tracks, windows, snap, level
metering, piano roll note editing (including key/scale and time-signature markers), MIDI
file export, music theory helpers (scales including Indian thaats, chords, progressions,
drum patterns), plus three areas most FL tooling misses:
- **Automatable parameters (REC events).** Read and set any knob FL can automate, the way a
hardware controller does: channel arpeggiator, echo/delay, filter, pitch, master pitch,
shuffle, mixer EQ bands, effect plugin parameters (`fl_param`, `fl_param_scan`, `fl_channel_fx`,
`fl_master`).
- **Edison audio scripts.** Generates ready-to-run Edison scripts (normalize, fade, reverse,
trim, tone, gain, beat regions, or raw `enveditor` code) into FL's Audio scripts folder and
can open Edison on a mixer track.
- **FL's internal Python.** `fl_internal` probes for `flrack`/`flcpt`, the modules
FL's own "Create a chord progression" tool uses to add channels and load assets; when they
are importable, `fl_exec` can use them.
- **Every tool is verified live** by `tests/smoke_live.py` against a running FL Studio; unit tests
cover everything that needs no FL Studio.
- **Slash commands**: MCP prompts `fl_status_check`, `fl_build_track`, `fl_mix_check`, `fl_arrange_chords`
(shown by MCP clients as `/mcp__fl-bridge__...`), plus Claude Code commands `/fl-status`, `/fl-track`,
`/fl-mix`, `/fl-notes` in `.claude/commands/`.
- **`fl_exec` for anything else**: run Python inside FL Studio with `channels`, `mixer`,
`plugins`, `transport`, `patterns`, `playlist`, `arrangement`, `general`, `ui` available.
- **Hands off your PC.** The only keystroke it can ever send is the piano roll script hotkey,
and only when FL Studio is already the active window. Everything else goes through the API.
- Compatible with the older `FL Studio MCP Controller` script if that is what FL Studio is
running: it auto-detects either.
## Requirements
- FL Studio 20.7+ (developed and tested on FL Studio 2026) on Windows or macOS
- A virtual MIDI port: [loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html) on
Windows, or the IAC Driver on macOS
- Python 3.10+ and [uv](https://docs.astral.sh/uv/)
## Install
```bash
git clone https://github.com/MadBlast0/fl-bridge-mcp
cd fl-bridge-mcp
uv sync
```
Register it with your MCP client. The server speaks standard MCP over stdio (default), HTTP or SSE, so it
works with any MCP-capable assistant, not only Claude. Replace the path with your clone.
**Claude Code / Claude Desktop** (`~/.claude.json` or `claude_desktop_config.json`, under `mcpServers`):
```json
"fl-bridge": { "command": "uv", "args": ["run", "--directory", "C:\path\to\fl-bridge-mcp", "fl-bridge-mcp"] }
```
**Cursor** (`.cursor/mcp.json` or global settings), **Windsurf** (`~/.codeium/windsurf/mcp_config.json`),
**Cline / Roo Code** (MCP settings), **Gemini CLI** (`~/.gemini/settings.json`), **Codex CLI** (`~/.codex/config.toml`,
`[mcp_servers.fl-bridge]`), **Zed**, **Continue** all take the same shape: command `uv`, args
`["run", "--directory", "<path>", "fl-bridge-mcp"]`.
**VS Code (GitHub Copilot agent mode)** `.vscode/mcp.json`:
```json
{ "servers": { "fl-bridge": { "type": "stdio", "command": "uv", "args": ["run", "--directory", "C:\path\to\fl-bridge-mcp", "fl-bridge-mcp"] } } }
```
**Clients that connect over HTTP** (ChatGPT connectors, LM Studio, OpenWebUI, LibreChat, n8n, custom agents): start
the server once and point the client at the URL.
```bash
uv run --directory C:\path ol-bridge-mcp fl-bridge-mcp --transport http --port 8765 # http://127.0.0.1:8765/mcp
uv run --directory C:\path ol-bridge-mcp fl-bridge-mcp --transport sse --port 8765 # http://127.0.0.1:8765/sse
```
The server must run on the machine where FL Studio runs; expose the port only on networks you trust.
## One-time step inside FL Studio
The server copies the `FL Bridge` controller script into
`Documents/Image-Line/FL Studio/Settings/Hardware/FLBridge` the first time it runs. FL Studio
must be told to use it once:
1. Start FL Studio (restart it if it was already open when the server first ran).
2. Options > MIDI settings. Under **Input**, select your loopMIDI / IAC port, enable it, and
set **Controller type** to **FL Bridge**.
3. Make sure the same port is *not* enabled under **Output**.
Ask your assistant to call `fl_status`. It reports the port, which controller answered, and
exact setup hints if something is missing.
Piano roll notes (`fl_notes_add`, `fl_notes_edit`) are applied by the `FL Bridge Notes`
script that the server installs into `Settings/Piano roll scripts`. Run it from the piano
roll's Tools > Scripting menu, or bind a hotkey to it in FL Studio.
## Tutorial
Everything below is what you type to your assistant. The tool names in brackets are what it calls under the hood; you
never have to type those.
### 1. First contact (2 minutes)
1. Start loopMIDI (Windows) and FL Studio.
2. In your assistant, say **"check the FL Studio connection"** (or `/fl-status` in Claude Code). The server installs its
scripts and probes FL Studio (`fl_status`).
3. If it says FL Studio is not answering, do the one-time step above (Options > MIDI settings > Input > loopMIDI Port >
Controller type "FL Bridge") and ask again.
4. Say **"what is in this project?"** You get tempo, time signature, channels, mixer tracks with effects, patterns and
markers (`fl_project_state`).
### 2. Build a track from nothing (10 minutes)
Say: **"Build me an emotional Punjabi backing track in D minor at 82 BPM with intro, mukhda, antara and outro."**
(`/fl-track ...` in Claude Code, or the `fl_build_track` prompt in other clients.)
What happens:
1. The assistant plans sections and bars, picks a scale (`fl_music_theory` knows western modes and Indian thaats such
as bhairavi and kafi), a chord progression (`fl_music_progression`) and a drum pattern (`fl_music_drums` has
keherwa, dadra, bhangra, trap, boom bap and more).
2. It writes one multi-track MIDI file with markers (`fl_write_midi_file`) and asks you to **drag it into FL Studio**.
FL creates one channel per track with a General MIDI sound. This is the only manual step, because FL's API cannot
create channels.
3. Tell it "it's in". It then sets the tempo, names and colours channels and mixer tracks, mutes the guide melody, adds
a reverb bus, balances levels, plays a few bars to confirm every instrument makes sound (`fl_get_levels`) and saves
(`fl_save_project`).
Swap the FLEX sounds for your own instruments whenever you like; everything the assistant set up stays.
### 3. Write into the piano roll
Open a channel's piano roll in FL Studio, then say: **"put a Dm Bb F C progression in this piano roll, arpeggiated
in 8ths, 4 bars each"** (`/fl-notes ...`).
The notes are queued (`fl_notes_add`). Apply them by running **Tools > Scripting > FL Bridge Notes** in the piano
roll; bind a hotkey to it in FL if you do this often. The same path handles edits: "transpose everything up 2",
"quantize to 16ths", "humanize the velocities", "make it legato", "add a D minor scale marker" (`fl_notes_edit`,
`fl_notes_marker`). Ask "what is in the piano roll now?" to read it back (`fl_notes_state`).
Drum patterns go straight into the step sequencer without any script: **"put a keherwa groove on channels 9, 10
and 11"** (`fl_music_drums`, `fl_channel_steps`). Melodic step sequences work too, with per-step pitch and velocity
(`fl_channel_step_params`).
### 4. Mix
Say **"check my mix"** (`/fl-mix`). The assistant plays the busiest section, reports silent tracks, peaks over 0 dB,
channels going straight to master and missing sends, then fixes the safe things: track levels and pans
(`fl_mixer_track_set`), sends to a reverb or delay bus (`fl_mixer_send`), the built-in 3-band EQ (`fl_mixer_eq`),
effect slot mix and bypass (`fl_mixer_effect`). Loading a new effect plugin is the one thing it will ask you to click.
Anything FL can automate is reachable too: "open the arpeggiator on the pad channel, chord mode, 1/16", "set the
channel filter cutoff to 40%", "master pitch down a semitone", "more shuffle" (`fl_channel_fx`, `fl_param`,
`fl_master`). Ask "what knobs does this channel have?" to discover them (`fl_param_scan`).
### 5. Everyday commands
| Say | Tool |
|---|---|
| "play from bar 33", "stop", "switch to pattern mode" | `fl_transport`, `fl_goto_bar` |
| "set tempo to 90 and time signature to 6/8" | `fl_project_set` |
| "add a marker called Chorus at bar 17" | `fl_markers` |
| "undo the last 3 changes" | `fl_undo` |
| "rename channel 4 to Bass and colour it purple" | `fl_channel_set` |
| "create a pattern called Verse B, 16 beats" / "clone pattern 2" | `fl_pattern_create` |
| "solo the vocal mixer track" | `fl_mixer_track_set` |
| "what preset is on channel 1? next preset" | `fl_plugin_info`, `fl_plugin_preset` |
| "show the mixer" / "close all windows" | `fl_window`, `fl_ui_action` |
| "save the project" | `fl_save_project` |
| "install an Edison script that normalizes the selection" | `fl_edison_script` (run it inside Edison) |
When nothing fits, the assistant can run any FL scripting call directly (`fl_exec`) and look up the API
(`fl_api_list`, `docs/fl-api-reference.md`).
### 6. When something is off
- **"FL Studio is not answering"**: a modal dialog in FL (a name prompt, a Confirm box) blocks its scripts. Close it.
If FL was restarted, the controller must still be enabled in MIDI settings.
- **Playhead did not move / undo did nothing yet**: FL applies these a moment later. Ask for the status again.
- **The .mid import plays silence**: FL imports MIDI with an empty playlist. In song mode, click the pattern onto
Track 1 of the playlist, or switch to pattern mode.
- **Notes did not appear**: the piano roll script must be run in the piano roll of the channel you want; check
`fl_notes_state` for `pending` operations.
## Tools
| Group | Tools |
|---|---|
| Connection / raw | `fl_status`, `fl_exec`, `fl_api_list`, `fl_project_state` |
| Project | `fl_save_project`, `fl_project_set` (tempo, time signature), `fl_undo` (undo/redo/save point), `fl_markers`, `fl_transport_command` (any FPT_* command), `fl_capture_played_notes` |
| Transport | `fl_transport` (play/pause/stop/record, loop mode, speed, status), `fl_goto_bar`, `fl_get_levels` |
| Channels | `fl_channels`, `fl_channel_set`, `fl_channel_steps` (read/write/fill), `fl_channel_step_params`, `fl_channel_audition`, `fl_channel_window`, `fl_channel_tools`, `fl_channel_fx` (arp, filter, echo) |
| Mixer | `fl_mixer_tracks`, `fl_mixer_track_set`, `fl_mixer_send` (routes), `fl_mixer_eq`, `fl_mixer_effect` (slots) |
| Plugins | `fl_plugin_info`, `fl_plugin_params`, `fl_plugin_set_params`, `fl_plugin_preset`, `fl_plugin_pads` |
| Parameters (REC) | `fl_param`, `fl_param_scan`, `fl_master` |
| Patterns | `fl_patterns`, `fl_pattern_create` (new or clone), `fl_pattern_set` (rename/size/colour/select/clear steps/burn loops) |
| Playlist | `fl_playlist_tracks`, `fl_playlist_track_set`, `fl_playlist_live` |
| UI | `fl_window`, `fl_ui_action`, `fl_options`, `fl_hint`, `fl_open_event_editor`, `fl_send_cc_to_plugin`, `fl_browser` |
| Notes | `fl_notes_add`, `fl_notes_edit`, `fl_notes_marker`, `fl_notes_state`, `fl_write_midi_file` |
| Music | `fl_music_theory`, `fl_music_progression`, `fl_music_drums` |
| Edison / internal | `fl_edison_script`, `fl_internal` |
`fl_exec` example:
```python
# name every used mixer track after the channel routed to it
for i in range(channels.channelCount(True)):
fx = channels.getTargetFxTrack(i, True)
if fx:
mixer.setTrackName(fx, channels.getChannelName(i, True))
result = "done"
```
## What FL Studio's API cannot do
These are limits of FL Studio itself, not of this server:
- It cannot load plugins or add channels directly. `fl_browser(path, load=True)` walks the Browser tree
through the API and activates an item, which works when the browser has a normal selection;
otherwise the assistant tells you what to click.
- It cannot place clips in the playlist or open files. `fl_write_midi_file` is the workaround
for building arrangements: drag the `.mid` into FL Studio and it creates one channel per
track, with markers.
- `patterns.clearPattern()` always opens a confirmation dialog, so `fl_pattern_set(clear_steps=True)`
clears steps instead and piano roll notes are cleared with `fl_notes_edit([{"op": "clear"}])`.
## Testing
```bash
uv run python tests/smoke_live.py # every tool against the running FL Studio
uv run python tests/smoke_live.py --save # also exercises fl_save_project
```
The test writes only to a scratch pattern named "Bridge Smoke", the last mixer insert and
playlist track 40, and restores what it changes. It does not save unless asked.
## How it works
```
MCP client ──stdio──▶ fl-bridge-mcp ──JSON file + MIDI note 127──▶ FL Bridge (inside FL Studio)
◀────────── JSON response ─────────┘
```
The controller script is deliberately tiny: it only knows `ping` and `exec`. Every tool is
Python code sent through `exec`, so new capabilities never require touching FL Studio.
## Credits
Protocol idea inspired by [karl-andres/fl-studio-mcp](https://github.com/karl-andres/fl-studio-mcp)
(MIT). This is an independent rewrite. API reference generated from
[fl-studio-api-stubs](https://github.com/IL-Group/FL-Studio-API-Stubs).
## License
MIT
TDQS
Scored across 57 tools
There are several overlapping tools that could be confused: fl_transport_command vs fl_transport, fl_param_scan vs fl_plugin_params, and fl_channel_tools vs the individual fl_channel_* tools. The presence of fl_param with no description adds further ambiguity.
All tools share the fl_ prefix and mostly use snake_case, but the verb/object order is inconsistent: fl_notes_add vs fl_goto_bar, fl_plugin_params vs fl_param_scan, and many noun-only names like fl_markers, fl_master, and fl_param. The pattern is recognizable but not uniform.
With 57 tools, the server is well above the typical 3-15 range and even beyond the 25+ too-many threshold. Although the FL Studio domain is broad, this many tools feels like an extreme call in a single MCP server.
The tool set covers nearly every FL Studio workflow: project/transport, channels, mixer, playlist, patterns, piano roll, plugins, browser, music theory, MIDI export, and Edison scripting. There are no major gaps for the apparent DAW-automation purpose.