An MCP (Model Context Protocol) server that enables AI assistants to control FL Studio through MIDI communication and Piano Roll scripts.
dont mind the scuffed audio, i had to clip with my mic bc apple wouldnt let me record desktop audio lol
scuffed.mp4
If you wanted to hear the better audio
beat_with_claude_instrument.mov
- Play, pause, stop playback
- Toggle recording
- Set playback position
- Get song length and position
- Control loop mode (pattern/song)
- Adjust playback speed
- Get/set track volume and pan
- Mute/solo tracks
- Arm tracks for recording
- Set track names and colors
- Stereo separation control
- List all channels
- Get/set channel properties (volume, pan, name, color)
- Mute/solo channels
- Route channels to mixer tracks
- Trigger MIDI notes in real-time
- Step sequencer control (get/set grid bits)
- List plugin parameters
- Get/set parameter values
- Navigate presets (next/previous)
- Query plugin info
- Add notes to the piano roll with precise timing
- Add chords with a single command
- Delete specific notes by MIDI number and time
- Clear all notes from the piano roll
- Read piano roll state to see all existing notes
- Auto-triggering via keystroke (Cmd+Opt+Y on macOS, Ctrl+Alt+Y on Windows)
The FL Studio scripting API does not support loading new VST/AU plugins. You can only control parameters of plugins that are already loaded in your project.
There is no API to programmatically create new patterns. You can only work with existing patterns.
- FL Studio 20.7+ (MIDI Controller Scripting API)
- Python 3.10+
- macOS or Windows
- macOS: IAC Driver (built-in, needs to be enabled)
- Windows: loopMIDI
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.
The easiest way to install is using the provided setup script for your platform.
# Clone the repository
git clone https://github.com/karl-andres/fl-studio-mcp.git
cd fl-studio-mcp
# Run the one-command installer
./install.sh# Clone the repository
git clone https://github.com/karl-andres/fl-studio-mcp.git
cd fl-studio-mcp
# Allow running local scripts for this user (one-time)
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned -Force
# Run the one-command installer
.\install.ps1install.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 tool likefl_send_notesruns. This is expected. See Piano Roll script not triggering if it doesn't fire at all.
# Using uv (recommended)
uv sync
# Or using pip
pip install -e .- 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
- Download and install loopMIDI
- Create a virtual port (any name works)
- Keep loopMIDI running while using FL Studio
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\"- 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)
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.
# Using uv
uv run fl-studio-mcp
# Or after installation
fl-studio-mcp- Open FL Studio and select a channel
- Open the Piano Roll (F7 or double-click the channel)
- The first time, manually run the script: Tools > Scripting > ComposeWithLLM
- After that, the MCP tools will auto-trigger the script
| Tool | Description |
|---|---|
fl_connect |
Connect/reconnect to FL Studio |
fl_connection_status |
Get connection status |
| Tool | Description |
|---|---|
fl_play |
Start/pause playback |
fl_stop |
Stop playback |
fl_record |
Toggle recording |
fl_get_transport_status |
Get playback/recording state |
fl_set_song_position |
Set playback position |
fl_get_song_length |
Get song duration |
fl_set_loop_mode |
Switch between pattern/song mode |
fl_set_playback_speed |
Adjust playback speed (0.25x-4x) |
| Tool | Description |
|---|---|
fl_get_mixer_track_count |
Get number of mixer tracks |
fl_get_mixer_track_info |
Get track details |
fl_get_all_mixer_tracks |
List all tracks |
fl_set_track_volume |
Set track volume |
fl_set_track_pan |
Set track pan |
fl_mute_track |
Mute/unmute track |
fl_solo_track |
Solo/unsolo track |
fl_arm_track |
Arm track for recording |
fl_set_track_name |
Rename track |
fl_set_track_color |
Set track color |
fl_set_stereo_separation |
Adjust stereo width |
| Tool | Description |
|---|---|
fl_get_channel_count |
Get number of channels |
fl_get_channel_info |
Get channel details |
fl_get_all_channels |
List all channels |
fl_get_selected_channel |
Get selected channel |
fl_select_channel |
Select/deselect channel |
fl_select_one_channel |
Select channel exclusively |
fl_trigger_note |
Trigger MIDI note (real-time) |
fl_set_channel_volume |
Set channel volume |
fl_set_channel_pan |
Set channel pan |
fl_mute_channel |
Mute/unmute channel |
fl_solo_channel |
Solo/unsolo channel |
fl_set_channel_name |
Rename channel |
fl_set_channel_color |
Set channel color |
fl_route_channel_to_mixer |
Route to mixer track |
fl_get_grid_bit |
Get step sequencer step |
fl_set_grid_bit |
Set step sequencer step |
fl_get_step_sequence |
Get full pattern |
fl_set_step_sequence |
Set full pattern |
| Tool | Description |
|---|---|
fl_is_plugin_valid |
Check if plugin exists |
fl_get_plugin_name |
Get plugin name |
fl_get_plugin_param_count |
Get parameter count |
fl_get_plugin_params |
List all parameters |
fl_get_plugin_param_value |
Get parameter value |
fl_set_plugin_param_value |
Set parameter value |
fl_get_preset_count |
Get preset count |
fl_next_preset |
Next preset |
fl_prev_preset |
Previous preset |
fl_get_plugin_color |
Get plugin color |
| Tool | Description |
|---|---|
fl_send_notes |
Add notes to the piano roll |
fl_send_chord |
Add a chord (multiple notes at same time) |
fl_delete_notes |
Delete specific notes |
fl_clear_piano_roll |
Clear all notes |
fl_get_piano_roll_state |
Read current piano roll notes |
fl_trigger_script |
Manually trigger the FL Studio script |
fl_get_piano_roll_info |
Get piano roll system info |
fl_clear_request_queue |
Cancel pending queued changes |
"Set the volume of mixer track 1 to 80% and pan it slightly left"
"Create a basic kick pattern on channel 0 with kicks on steps 0, 4, 8, and 12"
"Add a C major arpeggio starting at beat 0: C4, E4, G4, C5 - each note quarter duration"
"Add a C major chord at beat 0, then F major at beat 2, then G major at beat 4"
"List the parameters of the plugin on channel 0 and set the filter cutoff to 50%"
- 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
- On Windows, verify loopMIDI is running
- Restart FL Studio after enabling the controller
- 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)
- First time: manually run Tools > Scripting > ComposeWithLLM in FL Studio
- 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
- macOS: Enable IAC Driver in Audio MIDI Setup
- Windows: Install and run loopMIDI
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) │ │
│ └──────────────┘ └──────────────────┘ │
└─────────────────────────────────────────┘
-
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
- Python 3.10+
- uv (recommended)
# Install all dependencies including dev extras
uv sync --dev
# Or with pip
pip install -e ".[dev]"| 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 |
fl-studio-mcp/
├── fl_controller/
│ └── device_FLStudioMCP.py # FL Studio MIDI controller script (runs inside FL Studio)
├── scripts/
│ ├── setup.sh # FL Studio script installer
│ ├── install_mcp_for_claude.sh # Claude config installer (macOS/Linux)
│ ├── install_mcp_for_claude.ps1 # Claude config installer (Windows)
│ └── ComposeWithLLM.pyscript # Piano Roll script (runs inside FL Studio)
├── src/fl_studio_mcp/
│ ├── server.py # FastMCP server entry point
│ ├── tools/ # MCP tool implementations
│ │ ├── channels.py
│ │ ├── mixer.py
│ │ ├── piano_roll.py
│ │ ├── plugins.py
│ │ └── transport.py
│ └── utils/
│ ├── connection.py # FL Studio connection wrapper
│ ├── fl_trigger.py # Piano roll keystroke trigger
│ └── midi_connection.py # MIDI + JSON communication layer
├── install.sh # One-command installer (macOS/Linux)
└── install.ps1 # One-command installer (Windows)
- FL Studio API Stubs - API documentation
- FastMCP - MCP server framework
- mido - MIDI library for Python
- calvinw/fl-studio-mcp - Piano Roll integration approach
- Image-Line - FL Studio
MIT