FL Studio MCP Server
An MCP server that lets an AI assistant control FL Studio: transport, mixer, channels, patterns, the piano roll, plugins, presets, genre packs, vocal chains and audio files. It runs locally next to FL Studio (stdio) and talks to it through FL's own Python scripting API over virtual MIDI ports, plus, on macOS, the screen and keyboard for the things the API cannot do.
Fork of karl-andres/fl-studio-mcp, with thanks. The original provided the transport/mixer/channel/plugin/piano-roll foundation (MIT license, retained). This fork extends it: session-safe note writing (roll handshake + title OCR), full pattern/channel/file management, in-engine UI automation, one-call track/song building, and a request-id protocol with audit + controller rollback.
Status: alpha. Built and tested on macOS with FL Studio 2026 Producer Edition. Windows is untested beyond the original tools. See the project page for releases and the changelog.
Features
29 tools, each with several actions (fl_help(domain) prints the parameters of one). Highlights:
- Transport and mixer: play/stop/record, tempo, time signature, swing, loop; volume, pan, sends, routing, effects, peak meters, automatic clipping fix.
- Channels and patterns: list, add instruments, clone, group, rename, route; create, clone, select and resize patterns; step-sequencer rows with per-step velocity/pitch/pan.
- Piano roll, safely: notes and chords from text (
"Am F C G"), melodies as note tokens, MIDI import, capture of what you played. Every write first proves which roll is open by reading its on-screen title. - Plugins and presets: list and set parameters, load presets by name, built-in echo/reverb/chorus; JSON beat and melody presets (drop in a file, no code).
- One-call setups: 16 genre packs with drum kits (
fl_genre), a vocal chain with buses and sends (fl_vocal), a whole song folder (fl_preset load_song), multi-step recipes with undo (fl_recipe). - Audio files (
fl_audio): tempo, key, chords and 808 root note; cut a section, isolate left/right, load into a new Sampler. - Seeing and recovering:
fl_screen(OCR), FL's own keyboard shortcuts (fl_shortcut),fl_connectdoctor/recover/tidywhen FL gets stuck. - Optional Claude skills with FL workflows and a music-theory knowledge base (see Skills).
Important Limitations
- macOS-only UI automation. Adding instruments and effects, loading samples, exporting audio and selecting the piano-roll script are done by driving FL's menus (OCR, System Events), because FL's scripting API cannot do them. FL must be in front and the mouse left alone while they run. Needs Accessibility and Screen Recording permission.
- No playlist clips. The API cannot place patterns on the playlist, so songs are built one pattern per section. Markers can be added and listed, not deleted or renamed.
- Never jump onto an empty pattern by other means than
fl_pattern(action="select"): FL opens a modal "Pattern N name" dialog that blocks the controller until a human closes it.fl_pattern createnames the next free slot without jumping. - The piano-roll script selection resets on every FL launch. The server redoes it automatically on
the first note write (
fl_select_scriptis the manual call). - One call at a time. The server and FL share one command/response file pair; never run two FL tool calls in parallel.
- FL Studio itself is not included, and other editions may lack features the automation relies on.
Requirements
- FL Studio 20.7+ (MIDI Controller Scripting API)
- Python 3.10+
- ffmpeg on your PATH (
brew install ffmpeg), used byfl_audioand the sample tools - macOS or Windows
- macOS: IAC Driver (built-in, needs to be enabled)
- Windows: loopMIDI
- The fork's UI automation is macOS-only (roll-title OCR via Vision, System
Events clicks/keys, automatic piano-roll script selection,
fl_screen,fl_shortcut,fl_channel add). On Windows only the original transport/mixer/channel/plugin tools are expected to work (untested).
- Screen Recording + Accessibility permission for the process running the server (macOS)
Which AI Clients Work With This?
This is a standard MCP server that talks to clients over stdio — it isn't hardcoded to any one AI vendor. In principle, any MCP-compatible client can connect: Claude Desktop, Claude Code, Cursor, Windsurf, Gemini CLI/Gemini's MCP support, OpenAI's Codex CLI/Agents SDK MCP support, etc.
What's actually tested and auto-configured: only Claude Desktop and Claude Code, via scripts/install_mcp_for_claude.sh (macOS/Linux) and scripts/install_mcp_for_claude.ps1 (Windows). Other clients (Gemini, OpenAI-based tools, etc.) are not tested against this server and have no installer support — you'd need to manually add an equivalent MCP server entry to that client's own config, pointing at:
{
"command": "uv",
"args": ["run", "--directory", "/path/to/fl-studio-mcp", "fl-studio-mcp"]
}
(adjust /path/to/fl-studio-mcp to your local clone). If you try this with a non-Claude client, please open an issue with what worked/didn't — the protocol should support it, but it hasn't been verified here.
Quick Installation
The easiest way to install is using the provided setup script for your platform.
macOS / Linux
# Clone the repository
git clone https://github.com/jagdeepsinghdev/fl-studio-mcp.git
cd fl-studio-mcp/fl-studio-mcp # the server lives in this subfolder
# Run the one-command installer
./install.sh
Windows
# Clone the repository
git clone https://github.com/jagdeepsinghdev/fl-studio-mcp.git
cd fl-studio-mcp/fl-studio-mcp # the server lives in this subfolder
# Allow running local scripts for this user (one-time)
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned -Force
# Run the one-command installer
.\install.ps1
install.ps1 is the Windows counterpart to install.sh — same steps, PowerShell instead of bash, and it installs Python 3.12 specifically (required for prebuilt python-rtmidi wheels on Windows).
Both installers will:
- Install uv if not present
- Install Python dependencies
- Guide you through enabling virtual MIDI ports (IAC Driver on Mac, loopMIDI on Windows)
- Install the FL Studio MIDI controller script
- Install the Piano Roll script (ComposeWithLLM)
- Configure Claude Desktop or Claude Code automatically (
scripts/install_mcp_for_claude.sh/scripts/install_mcp_for_claude.ps1)
Windows piano-roll auto-trigger note: the Piano Roll script is launched by sending FL Studio a keystroke (
Ctrl+Alt+Y). On Windows this requires briefly foregrounding the FL Studio window, so FL Studio will pop to the front for a moment each time a note-writing tool runs. This is expected. See Piano Roll script not triggering if it doesn't fire at all.
Manual Installation
1. Install Python Dependencies
# Using uv (recommended)
uv sync
# Or using pip
pip install -e .
2. Enable Virtual MIDI Ports
macOS (IAC Driver)
- Open Audio MIDI Setup (search in Spotlight)
- Press Cmd+2 or go to Window > Show MIDI Studio
- Double-click on IAC Driver
- Check "Device is online"
- Click Apply
macOS without a working IAC Driver (macOS 26 "Tahoe")
On macOS 26 the IAC Driver can stay Offline in the new MIDI Studio view, and the server then fails with "No MIDI output ports found". You don't need IAC: any process can create virtual CoreMIDI ports (macOS starts its MIDI server on demand), and FL Studio lists them like any other device.
- Start the loopback helper (creates
FL Studio MCP,FL Studio MCP Bus,FL Studio MCP Out):.venv/bin/python fl_controller/fl_midi_loop.py &
Virtual ports exist only while this process runs. Start it before launching FL Studio, and keep it running. - In FL Studio: Options > MIDI settings > Input > select
FL Studio MCP Bus> Controller type FL Studio MCP Controller > turn Enable on. (Saved by FL; you do this once.) - The server picks the port named exactly
FL Studio MCPautomatically. - If the helper restarts while FL is open, FL's port connection goes stale (commands time out). Click Refresh device list in the MIDI settings.
To start the helper at login, use a LaunchAgent (RunAtLoad + KeepAlive) that runs the command above with
WorkingDirectory set to this repo. Keep the plist minimal: no EnvironmentVariables block needed.
Windows (loopMIDI)
- Download and install loopMIDI
- Create a virtual port (any name works)
- Keep loopMIDI running while using FL Studio
3. Install FL Studio Scripts
Copy the controller script to FL Studio's Hardware folder:
# macOS
mkdir -p ~/Documents/Image-Line/FL\ Studio/Settings/Hardware/FLStudioMCP
cp fl_controller/device_FLStudioMCP.py ~/Documents/Image-Line/FL\ Studio/Settings/Hardware/FLStudioMCP/
# Windows
mkdir "%USERPROFILE%\Documents\Image-Line\FL Studio\Settings\Hardware\FLStudioMCP"
copy fl_controller\device_FLStudioMCP.py "%USERPROFILE%\Documents\Image-Line\FL Studio\Settings\Hardware\FLStudioMCP\"
Copy the Piano Roll script:
# macOS
cp scripts/ComposeWithLLM.pyscript ~/Documents/Image-Line/FL\ Studio/Settings/Piano\ roll\ scripts/
# Windows
copy scripts\ComposeWithLLM.pyscript "%USERPROFILE%\Documents\Image-Line\FL Studio\Settings\Piano roll scripts\"
4. Configure FL Studio
- Restart FL Studio (if it's running)
- Go to Options > MIDI Settings
- Under Input, find your virtual MIDI port (e.g., "IAC Driver Bus 1")
- Set the Controller type to FLStudioMCP
- Enable the port (click to highlight it)
5. Configure Claude (or another MCP client)
Add to your Claude Desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"fl-studio": {
"command": "uv",
"args": ["run", "--directory", "/path/to/fl-studio-mcp", "fl-studio-mcp"]
}
}
}
Or for Claude Code, add to your MCP settings (~/.claude.json, or run claude mcp add).
Using a different MCP-compatible client (Gemini, an OpenAI-based tool, Cursor, etc.)? The same command/args pair above is all any MCP host needs — add it to that client's own MCP config in whatever format it expects. See Which AI Clients Work With This? for what's actually been tested.
Skills (optional)
The server is complete without them. The repo also ships an optional skill pack for Claude
in skills/: FL workflows and gotchas (setup, patterns, piano roll,
mixing, plugins, genres, whole-song building) and a standalone music-theory skill (harmony,
rhythm, 808 writing, form, ragas, ear training). None are installed by default. Pick them by name:
../skills/install.sh # list them with descriptions
../skills/install.sh fl-studio fl-melody music-theory # -> ~/.claude/skills (symlinks)
The table in skills/README.md says what each one adds and when to install it.
Usage
Running the server manually
uv run fl-studio-mcp # from this folder; MCP clients normally start it for you
Writing notes
Ask for notes in plain words ("a minor 4-bar hook on the piano channel"). The server selects the right piano-roll script once per FL launch, opens the target channel's roll, checks the roll title on screen, writes the notes, and reads them back. If notes do not land, see Troubleshooting.
Available Tools
Every domain tool takes an action; fl_help(domain) shows its parameters. The full generated list of
tools, skills and presets is in INVENTORY.md.
| Tool | What it does |
|---|---|
fl_state |
read-only snapshot: tempo, transport, patterns, channels, selected channel, piano-roll notes |
fl_transport |
play, stop, record, set_bpm, set_timesig, set_speed, set_swing, loop, position |
fl_mixer |
set_vol, set_pan, route, sends, add_fx, get_info, get_sends, get_peaks, fix_clipping, get_eq, set_eq |
fl_channel |
list, add, clone, group, rename, route, mute, solo, set_vol, set_pan, set_steps, get_steps, get_step_param, set_step_param, load_sample |
fl_pattern |
create, select, rename, set_len, clone, chain |
fl_notes |
write_steps, write_chords, read_steps, clear, clear_queue, import_midi, capture |
fl_select_script |
select the piano-roll script (automatic on the first note write) |
fl_plugin |
list_params, set_param, load_preset, echo, reverb, chorus, get_fx |
fl_preset |
list, load_beat, load_melody, load_song |
fl_genre |
list, show, load, load_kit: one call per genre |
fl_vocal |
setup, apply, buses, loudness, recipes, show, status, learn, run, onboard |
fl_audio |
analyze, extract, split, load, recorder (needs ffmpeg) |
fl_recipe |
validate, plan, apply, status, undo, export |
fl_file |
save, save_as, export, open |
fl_delete |
destructive: channel, pattern, pattern_data, fx, roll_notes |
fl_batch |
many controller actions in one MIDI round trip |
fl_connect |
FL lifecycle: status, open, close, save, force, dismiss_modal, doctor, recover, tidy |
fl_screen / fl_shortcut |
see the screen (look, ocr, find, hint, click_text) / press FL's own shortcuts, guarded |
fl_launchpad |
8x8 grid controller to step sequencer |
fl_edison / fl_slice_audio |
Edison audio-region flow / slice a file into onset or grid samples |
fl_variations / fl_list_generated |
rule-based beat variations / list generated presets |
fl_probe / fl_ui_screen / fl_ui_script / fl_connection_status / fl_help |
discovery, allowlisted ui.* calls, UI routines, connection check, docs |
The older single-purpose tools (fl_play, fl_set_bpm, fl_send_notes, ...) are legacy: they are
registered only with LEGACY_TOOLS=1.
Example Workflows
Say these to your assistant; the tool calls are what it runs.
A beat and a hook in one go
fl_genre(action="load", genre="trap") # tempo, kit, beat, Keys + Bass, chords, levels
fl_notes(action="write_chords", text="Am F C G", channel_index=5)
Drums by hand
fl_pattern(action="set_len", pattern=1, beats=4)
fl_channel(action="set_steps", index=0, steps=[1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0])
A melody on a new instrument
fl_channel(action="add", plugin="FLEX", name="Piano")
fl_notes(action="write_steps", channel_index=<piano idx>, melody=[["C4","E4","G4","E4"]])
Mix check
fl_mixer(action="get_peaks", track=0)
fl_mixer(action="fix_clipping") # lowers the master fader just enough
Know a sample before you use it
fl_audio(action="analyze", path="loop.wav") # tempo (+ whether the estimators agree), key, chords, root
Troubleshooting
"Not connected to FL Studio"
- Ensure FL Studio is running
- Check that the FLStudioMCP controller is enabled in MIDI Settings
- On Mac, verify IAC Driver is enabled in Audio MIDI Setup, or (macOS 26) that
fl_controller/fl_midi_loop.pyis running (see above) - On Windows, verify loopMIDI is running
- Restart FL Studio after enabling the controller
"Timeout waiting for FL Studio response"
- If you use the virtual-port loopback: it restarted after FL started, or FL was launched before it. Click Refresh device list in FL's MIDI settings (or restart FL). Also check the server opened
FL Studio MCP, notFL Studio MCP Out(fl_connection_status). - Make sure FL Studio is in focus
- Check the Script output window in FL Studio (View > Script output)
- Verify the controller is receiving MIDI (look for activity in MIDI Settings)
Piano Roll script not triggering
- The server selects the script itself on the first note write after each FL launch. If notes still do not land, run
fl_select_script(channel_index=N)and checkfl_stateshows the channel's notes - On macOS: grant Accessibility permissions when prompted
- On Windows: the MCP server foregrounds the FL Studio window automatically before sending the hotkey — if FL Studio isn't running or is minimized to the system tray, the trigger can't find it and will fall back to a warning telling you to press the hotkey manually
- Try pressing Cmd+Opt+Y (macOS) or Ctrl+Alt+Y (Windows) manually to confirm the hotkey itself is bound to the script in FL Studio
- If you just updated the server code (e.g. pulled a fix to the trigger logic), fully restart your MCP client (Claude Desktop/Code) — reconnecting the MCP server alone does not respawn the underlying process, so it can keep running stale code
No MIDI ports available
- macOS: Enable IAC Driver in Audio MIDI Setup
- Windows: Install and run loopMIDI
Architecture
This MCP server uses a hybrid approach:
┌─────────────────┐ ┌─────────────────────────────────────────┐
│ MCP Client │────▶│ FastMCP Server │
│ (Claude, etc) │ │ │
└─────────────────┘ │ ┌─────────────────┐ ┌──────────────┐ │
│ │ MIDI + JSON │ │ Piano Roll │ │
│ │ Tools │ │ Tools (JSON) │ │
│ └────────┬────────┘ └──────┬───────┘ │
└───────────┼──────────────────┼──────────┘
│ │
MIDI + JSON JSON Files +
│ Keystroke
▼ ▼
┌─────────────────────────────────────────┐
│ FL Studio │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │FLStudioMCP │ │ Piano Roll Script│ │
│ │(MIDI Ctrl) │ │ (ComposeWithLLM) │ │
│ └──────────────┘ └──────────────────┘ │
└─────────────────────────────────────────┘
How It Works
-
Transport/Mixer/Channels/Plugins:
- MCP server writes command to JSON file
- Sends MIDI trigger note to FL Studio
- FL Studio controller script reads JSON, executes API, writes response
- MCP server reads response
-
Piano Roll:
- MCP server writes note requests to JSON file
- Sends keystroke (Cmd+Opt+Y on macOS, Ctrl+Alt+Y on Windows) to trigger FL Studio script — on Windows, the FL Studio window is foregrounded first so the keystroke actually reaches it
- Piano Roll script reads JSON and modifies notes
Development
Prerequisites
- Python 3.10+
- uv (recommended)
Setup
# Install all dependencies including dev extras
uv sync --dev
# Or with pip
pip install -e ".[dev]"
Available Commands
| Command | Description |
|---|---|
uv run fl-studio-mcp |
Run the MCP server |
uv run ruff check . |
Lint the codebase |
uv run ruff check --fix . |
Lint and auto-fix |
uv run pytest |
Run tests |
Project Structure
fl-studio-mcp/
├── src/fl_studio_mcp/
│ ├── server.py # FastMCP entry point, registers the tools
│ ├── tools/ # one module per domain tool (transport_v2.py, mixer_v2.py, notes_v2.py, ...)
│ ├── audio/ # numpy tempo/key/chord analysis, slicer
│ └── utils/ # connection, UI automation, roll session, loaders
├── fl_controller/ # runs INSIDE FL: device_FLStudioMCP.py, fl_midi_loop.py (macOS MIDI ports)
├── scripts/ # setup.sh, install-midi-loop.sh, install_mcp_for_claude.*, ComposeWithLLM.pyscript
├── presets/ # beats, melodies, genres, kits, vocal (JSON; drop in a file, no code)
├── recipes/ shortcuts/ ui_routines/ docs/ tests/
└── install.sh / install.ps1
The repository root also has the optional skills/, CHANGELOG.md, INVENTORY.md and the CI/release
workflows: see the project page.
Credits
This project is a fork of, and builds directly on:
- karl-andres/fl-studio-mcp (MIT) by Karl Andres — the original FL Studio MCP server: transport, mixer, channel, plugin and piano-roll tools, the MIDI controller script, and the ComposeWithLLM piano-roll integration. Thanks for the foundation!
- The original project's demo video: see its README.
- calvinw/fl-studio-mcp — upstream reference the original is based on (Piano Roll integration approach)
Other dependencies:
- FL Studio API Stubs - API documentation
- FastMCP - MCP server framework
- mido - MIDI library for Python
- Image-Line - FL Studio
License
MIT
Metadata
Release files for mcp-flstudio 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mcp_flstudio-0.1.0.tar.gz | 462.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_flstudio-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 796.2 kB
Release files / mcp_flstudio-0.1.0.tar.gz
| Download URL | mcp_flstudio-0.1.0.tar.gz |
|---|---|
| Size | 462.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1723cc101bda801f886bee61566926aa0e26412cffad594aa2b79694a6b3eef3
|
|
BLAKE2b-256 checksum How to use checksums |
69ed3cd19a7941c9bb23f96b1fe2b217dadb3ac2d5751ffc4770c691c94f6aca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mcp_flstudio-0.1.0-py3-none-any.whl
| Download URL | mcp_flstudio-0.1.0-py3-none-any.whl |
|---|---|
| Size | 333.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e168c61b0aaaca896b4afd63175f4c2778345a998776dc014f7772518d8c42d9
|
|
BLAKE2b-256 checksum How to use checksums |
fa06caa2bc2e889cb2ac652a669aeeb49cffc7ed262b30f006f56b1a7575d562
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for mcp-flstudio 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.