MCP Hub
Back to servers

FL Studio MCP Server

Enables AI assistants to control FL Studio on Windows through a local MCP server without cloud dependencies. Bridges MCP clients to FL Studio's Python scripting environment via file-based IPC for project management, transport control, and UI workflow automation.

glama
Updated
Apr 4, 2026

mcp-flstudio

Official release label: Pré-BETA Complete MCP-serveur-FL-Studio2025

A canonical local-core MCP (Model Context Protocol) server for FL Studio on Windows: no cloud relay for the published core surface, explicit extension boundaries for non-local capabilities, and a public CLI/runtime that can be packaged and shipped cleanly.

Works with Claude Desktop, VS Code Copilot, Codex, and any other MCP-compatible client.


Architecture

┌─────────────────────────────────────────────────────────┐
│  MCP Client  (Claude Desktop / VS Code / Codex)         │
└────────────────────┬────────────────────────────────────┘
                     │ JSON-RPC over stdio
┌────────────────────▼────────────────────────────────────┐
│            MCP Server  (Node.js / TypeScript)            │
│                                                         │
│  ┌──────────────────┐  ┌──────────────────────────────┐ │
│  │ WindowsDesktop   │  │  LocalMailbox Bridge          │ │
│  │ Bridge           │  │                               │ │
│  │ PowerShell COM   │  │  inbox/  ←── requests (.json) │ │
│  │ (fallback only)  │  │  outbox/ ──→ responses (.json)│ │
│  └──────────────────┘  └──────────────┬───────────────┘ │
│  ┌──────────────────────────────────┐  │                 │
│  │ LocalHelper Backend (optional)   │  │                 │
│  │ PowerShell — render / playlist   │  │                 │
│  └──────────────────────────────────┘  │                 │
└────────────────────────────────────────┼────────────────┘
                                         │ file IPC
┌────────────────────────────────────────▼────────────────┐
│         FL Studio  (Python MIDI script companion)        │
│         FLMcpBridge.py — runs inside FL Studio process   │
│         Reads inbox → executes FL API → writes outbox    │
└─────────────────────────────────────────────────────────┘

Three-tier bridge — fallback flow

flowchart TD
    Client([MCP Client]) -->|stdio JSON-RPC| Server[MCP Server]

    Server --> D{FL Studio running?}
    D -- No --> ERR1[Error: FL_NOT_RUNNING]

    D -- Yes --> C{Companion active?\nheartbeat fresh}

    C -- Yes --> MB[LocalMailbox Bridge\ninbox → outbox file IPC]
    MB -->|timeout| CACHE[Return cached state\nfrom last heartbeat]

    C -- "No, desktop-capable cmd" --> DB[WindowsDesktop Bridge\nPowerShell SendKeys]
    DB --> FL[FL Studio process]

    C -- "No, mailbox-only cmd" --> ERR2[Error: COMPANION_NOT_RUNNING]

    MB --> HELPER{Helper configured?}
    HELPER -- Yes --> HP[LocalHelper Backend\nPowerShell render / playlist]
    HELPER -- No --> MB2[Mailbox result only]
    HP --> ENRICH[Enriched response]

Mailbox IPC — request lifecycle

sequenceDiagram
    participant S as MCP Server
    participant FS as File System
    participant C as FL Companion

    S->>FS: write inbox/<uuid>.json (atomic)
    loop OnIdle / OnMidiIn callback
        C->>FS: scan inbox/ for .json files
        FS-->>C: inbox/<uuid>.json found
        C->>C: execute FL Studio API
        C->>FS: write outbox/<uuid>.json (atomic)
    end
    loop poll every 150 ms
        S->>FS: check outbox/<uuid>.json
        FS-->>S: response found
    end
    S->>FS: delete outbox/<uuid>.json
    S-->>S: return response to client

Components

ComponentRuntimeLocation
MCP ServerNode.js ≥ 20src/dist/
Python CompanionPython 3.x (FL Studio built-in)companion/fl_studio/FLMcpBridge.py
Helper Script (optional)PowerShelluser-defined, set via FL_MCP_HELPER_SCRIPT

Installation

Prerequisites

  • Windows 10 / 11
  • FL Studio (any recent version with MIDI scripting)
  • Node.js ≥ 20
  • PowerShell 5+ (pre-installed on Windows)

1 — Build the MCP server

git clone https://github.com/your-org/mcp-flstudio
cd mcp-flstudio
npm install
npm run build

The compiled public CLI is:

node dist/cli/index.js help

or, once installed from npm:

mcp-flstudio help

2 — Install the Python companion in FL Studio

Deploy the companion into the FL Studio MIDI scripts folder:

npm run deploy:companion

or with the public CLI:

node dist/cli/index.js deploy-companion

This installs:

Documents\Image-Line\FL Studio\Settings\Hardware\FLMcpBridge\device_FLMcpBridge.py
Documents\Image-Line\FL Studio\Settings\Hardware\FLMcpBridge\FLMcpBridge.py

The deployed bootstrap now uses this runtime root by default:

Documents\Image-Line\FL Studio\Settings\Hardware\FLMcpBridge\runtime

The Node server auto-detects that deployed runtime before falling back to %LOCALAPPDATA%\FLStudioMcpBridge, so FL_MCP_BRIDGE_DIR is now an override rather than a requirement.

Then in FL Studio:

  1. Open Options → MIDI Settings
  2. Create or select a virtual MIDI port named FLMcpBridge (loopMIDI is the recommended local setup)
  3. Set Input = FLMcpBridge, Controller type = FLMcpBridge, Port = 10
  4. Prefer Output = (none) for the FLMcpBridge script device. If you need an FL Studio MIDI output, use a second dedicated loopMIDI port instead of reusing the same one.
  5. Click Update MIDI scripts / Mettre a jour scripts MIDI
  6. Restart FL Studio if the script does not reload immediately

The companion now keeps MIDI master sync disabled by default to avoid transport feedback loops when the same loopMIDI port is used for both input and output.

If playback makes the BPM dip or fluctuate, inspect the FL Studio MIDI routing first: repeated OnMidiIn activity while transport starts usually means the loopback port is still receiving transport or clock data. The most reliable setup is one input-only script port for FLMcpBridge, with no FL output assigned to that same virtual port.

The play/pause loop reported during validation is now resolved in the default deployed runtime: inbound MIDI callbacks are swallowed by the script, and mailbox servicing stays on OnIdle / OnUpdateMeters.

The companion writes its mailbox state and heartbeat to:

Documents\Image-Line\FL Studio\Settings\Hardware\FLMcpBridge\runtime\state.json

3 — Configure your MCP client

Claude Desktop (%APPDATA%\Claude\claude_desktop_config.json):

{
  "mcpServers": {
    "flstudio-local": {
      "command": "node",
      "args": ["C:/path/to/mcp-flstudio/dist/cli/index.js", "serve"]
    }
  }
}

VS Code (.vscode/mcp.json — already included in this repo):

{
  "servers": {
    "flstudio-local": {
      "type": "stdio",
      "command": "node",
      "args": ["${workspaceFolder}/dist/cli/index.js", "serve"]
    }
  }
}

See config/ for additional examples (Codex, PowerShell helper).


Configuration

All settings are environment variables. Copy .env.example to .env and adjust. The server and CLI now load .env automatically from the working directory, or from FL_MCP_ENV_FILE when set.

VariableDefaultDescription
FL_MCP_BRIDGE_DIRauto-detect deployed Hardware\FLMcpBridge\runtime, then %LOCALAPPDATA%\FLStudioMcpBridgeRoot directory for all bridge files
FL_MCP_HELPER_DIR<bridge_dir>\helperRoot directory for helper request and snapshot files
FL_MCP_LOG_FILE<bridge_dir>\bridge.logStructured JSON log path
FL_MCP_LOG_LEVELinfodebug / info / warn / error
FL_MCP_SAFE_MODEtrueEnables operation guards
FL_MCP_RESPONSE_TIMEOUT_MS8000Default mailbox timeout (ms)
FL_MCP_HEARTBEAT_TIMEOUT_MS15000Companion considered dead after (ms)
FL_MCP_STALE_REQUEST_AGE_MS300000Auto-cleanup age for orphaned requests
FL_MCP_WINDOW_TITLEFL StudioWindow title for focus automation
FL_MCP_HELPER_SCRIPT(unset)Path to optional PowerShell helper script
FL_MCP_HELPER_TIMEOUT_MS45000Helper script timeout (ms)

Available Tools

The live server only registers implemented tools. The canonical catalog remains the source of truth, and any non-local command stays out of the published local-core registry.

Compatibility aliases kept across 1.x:

  • fl_save_project -> session_save_project
  • fl_undo -> session_undo
  • fl_redo -> session_redo

session_clear_undo_history is retained as an extension-only compatibility utility and is not part of the canonical published surface.

Status & diagnostics

ToolDescription
fl_pingCheck whether FL Studio and the companion are reachable
fl_get_statusFull status: process, companion, health, transport
fl_get_versionFL Studio version and build number
fl_get_project_nameCurrent project name
fl_get_project_pathCurrent project file path
fl_get_project_modified_stateWhether there are unsaved changes
fl_get_active_windowTargeted FL Studio window title
fl_get_focus_stateWhether FL Studio is focused
fl_get_last_errorLast recorded bridge error
fl_get_environment_infoRuntime environment summary
fl_get_timebaseProject PPQ / timebase
fl_get_ui_stateCurrent FL Studio UI visibility summary

Project overview

ToolDescription
project_get_infoProject name, tempo, channel/mixer/playlist counts
project_get_summaryFull project state snapshot
project_get_statsDerived statistics (muted channels, clip counts…)
project_get_structureDerived arrangements / sections / markers
project_get_selectionCurrent playlist selection
project_get_current_arrangementActive arrangement metadata
project_get_open_windowsActive FL window + UI state
project_get_markersPlaylist markers
project_get_channel_inventoryAll channels with state
project_get_mixer_inventoryAll mixer tracks with state
project_get_playlist_inventoryPlaylist clips, tracks, and markers
project_get_recent_actionsLatest MCP actions in this session

Transport

ToolInputsDescription
transport_playStart playback
transport_stopStop playback
transport_pausePause playback
transport_get_statusPlaying / paused / stopped / recording
transport_get_song_positionPosition in ticks
transport_set_song_positionticksMove playhead
transport_jump_to_barbarJump to bar number
transport_jump_to_ticktickJump to exact tick
transport_get_tempoCurrent BPM
transport_set_tempobpm (10–300)Set tempo
transport_nudge_tempodelta_bpmOffset current BPM
transport_rewindamount_ticks?Move playhead backward
transport_fast_forwardamount_ticks?Move playhead forward
transport_start_from_beginningplay_after?Reset to bar 1 and optionally play
transport_get_time_signatureCurrent time signature

Channels

ToolInputsDescription
channel_listAll channels with name, volume, mute state
channel_getchannel_indexSingle channel summary
channel_find_by_namenameCase-insensitive channel lookup
channel_set_volumechannel_index, value (0–1)Set channel volume
channel_mutechannel, mutedMute / unmute
channel_unmutechannel_indexUnmute channel

Mixer

ToolInputsDescription
mixer_list_tracksAll mixer tracks
mixer_get_tracktrack_indexSingle mixer track summary
mixer_set_volumetrack_index, value (0–1)Set track volume
mixer_mutetrack, mutedMute / unmute

Playlist

ToolInputsDescription
playlist_get_clipsPlaylist inventory enriched by the helper backend when available
playlist_list_tracksDerived playlist track list
playlist_get_tracktrack_indexSingle playlist track summary

Piano Roll

ToolInputsDescription
pianoroll_get_noteschannel?All notes in the current piano roll
pianoroll_add_notepitch, start, length, velocity?, channel?Add a note
pianoroll_quantizechannel?, amount? (0–1)Quantize notes

Plugins

ToolInputsDescription
plugin_set_parametertarget, parameter, value (0–1)Set a plugin parameter

Session management

ToolInputsDescription
fl_save_project / session_save_projectSave the current project
fl_undo / session_undoUndo last action
fl_redo / session_redoRedo
session_save_checkpointlabelNamed state snapshot
session_list_checkpointsAll checkpoints
session_delete_checkpointcheckpoint_idDelete a checkpoint
session_get_undo_historyRecent undo/redo entries
session_clear_undo_historyRemove undo/redo from audit log
session_get_audit_loglimit?Full audit log
session_clear_audit_logClear audit log
session_begin_transactionlabel?Open a logical transaction
session_commit_transactiontransaction_idCommit
session_abort_transactiontransaction_idAbort
session_get_transaction_statetransaction_idTransaction status

Render

ToolInputsDescription
render_preview_wavoutputPath?Trigger a local WAV render via the helper backend

Resources (MCP)

URIDescription
fl://status/currentCurrent FL Studio status (JSON)
fl://project/currentCurrent project summary (JSON)
fl://channels/listChannel list (JSON)
fl://mixer/{track}Mixer track detail (JSON)
fl://catalog/toolsFull tool catalog
fl://catalog/domain/{domain}Tools for one domain
fl://catalog/tool/{name}Single tool definition
fl://catalog/coverageGenerated coverage report: canonical / published / alias / missing

Prompts (MCP)

NameArgsDescription
arrange-trap-beatstyle, barsInspect session and propose an arrangement
audit-session-before-renderfocusPre-render checklist
clean-up-low-endbassBusLow-end cleanup workflow

Health states

fl_get_status → health field
StateMeaning
readyFL Studio running + companion active and sending heartbeats
degradedFL Studio running, companion detected but heartbeat stale (> 15 s)
offlineFL Studio process not found

Diagnostics

# Print the resolved configuration
npm run debug:config
# or
node dist/cli/index.js debug-config

# Inspect current bridge state (companion heartbeat, pending requests)
npm run debug:state
# or
node dist/cli/index.js debug-state

# Print canonical catalog coverage vs live registry
npm run catalog:coverage

# Verify the companion end-to-end
npm run verify

# Generate the full tool-by-tool checklist
npm run functional:checklist

# Run the scripted smoke scorecard and publish a Markdown report
npm run evaluate:functional

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

Log output is written to bridge.log in newline-delimited JSON:

# Tail the live log for the resolved bridgeDir (PowerShell)
$bridgeDir = (node dist/cli/index.js debug-config | ConvertFrom-Json).bridgeDir
Get-Content (Join-Path $bridgeDir 'bridge.log') -Wait -Tail 40

Functional validation

Public validation assets now live under docs/validation/:

  • docs/validation/bridge-runtime-changes.md documents the runtime and deployment fixes
  • docs/validation/mcp-tool-test-checklist.md lists every registered MCP call and now includes the dated manual validation snapshot from the guided FL Studio campaign
  • docs/validation/functional-evaluation.plan.json defines the scripted smoke suite
  • docs/validation/functional-evaluation.latest.md is the latest generated Markdown scorecard
  • docs/validation/functional-evaluation.latest.html is the visual dashboard
  • docs/validation/functional-evaluation.latest.summary.svg is the release summary visual
  • docs/validation/functional-evaluation.latest.domains.svg is the domain score visual
  • docs/validation/functional-evaluation.latest.coverage.svg is the domain coverage visual

The manual snapshot currently records confirmed validation for selection, mute/unmute, solo/unsolo, pan, volume, color, rename, channel-to-mixer routing, mixer enable/disable, and safe transport_play / transport_stop, along with known failures such as channel_set_pitch, transport_toggle_metronome, and the still-inconsistent transport_toggle_loop.

Public command-reference assets now live under docs/reference/:

  • docs/reference/tool-catalog.en.md is the English command catalog
  • docs/reference/tool-catalog.fr.md is the French command catalog
  • docs/reference/tool-catalog.csv is the spreadsheet-friendly export of all commands
  • docs/reference/tool-catalog.json is the machine-readable command inventory
  • docs/reference/tool-catalog.domains.svg is the command count by domain graph
  • docs/reference/tool-catalog.coverage.svg is the automated coverage by domain graph
  • docs/reference/tool-status-board.md is the working vs incoming/planned status board
  • docs/reference/tool-status-board.fr.md is the dedicated French status board
  • docs/reference/tool-status-board.csv is the spreadsheet export of the status board
  • docs/reference/tool-status-board.json is the machine-readable status board
  • docs/reference/tool-status-board.svg is the status distribution graph

Recommended workflow:

npm run functional:checklist
npm run evaluate:functional
npm run docs:catalog
npm run docs:status

The automated plan now covers:

  • companion health and transport smoke checks
  • channel_mute with automatic state restoration
  • mixer_set_volume with automatic state restoration
  • safe plugin_* inspection calls driven by live target discovery
  • safe session_* checkpoint and transaction flows

Limitations

  • Windows only — requires PowerShell and FL Studio
  • transport_stop desktop fallback is a play/pause toggle; companion required for exact stop
  • transport_get_song_position may return UNSUPPORTED_COMMAND on FL Studio builds that do not expose bar/beat conversion in the MIDI scripting API
  • Piano roll quantize exposes full-amount quantize only (FL scripting API limitation)
  • Mixer effect plugins are not individually addressable (channel plugins only)
  • render_preview_wav requires the optional helper backend script

Development

npm run dev           # Run from TypeScript source (tsx, no build needed)
npm run build         # Compile TypeScript → dist/
npm run check         # Type-check only (no emit)
npm run typecheck     # Type-check gate used by CI/prepack
npm run lint          # ESLint
npm run lint:fix      # ESLint with auto-fix
npm run format        # Prettier
npm run functional:checklist
npm run evaluate:functional
npm test              # Vitest
npm run test:coverage # With coverage report
npm run ci:check      # build + typecheck + lint + test + npm pack --dry-run

Project structure

mcp-flstudio/
├── src/
│   ├── index.ts               # MCP server entry point — tool/resource registration
│   ├── config.ts              # Environment variable parsing
│   ├── configValidation.ts    # Config validation with detailed errors
│   ├── logger.ts              # Structured JSON logger (stderr + file)
│   ├── errors.ts              # BridgeRuntimeError + toBridgeError()
│   ├── types.ts               # Shared TypeScript types
│   ├── env.ts                 # Optional .env loading
│   ├── publicApi.ts           # snake_case public payload normalization
│   ├── server.ts              # MCP bootstrap
│   ├── serverRuntime.ts       # Shared runtime helpers / tool execution
│   ├── bridge/
│   │   ├── flStudioBridge.ts      # Orchestrator — routes across the three tiers
│   │   ├── localMailboxBridge.ts  # File-based IPC (inbox/outbox)
│   │   ├── windowsDesktopBridge.ts # PowerShell COM fallback
│   │   └── helperBackend.ts       # Optional PowerShell helper (render, playlist)
│   ├── catalog/
│   │   └── loadCatalog.ts     # YAML catalog loader + coverage report builder
│   ├── registry/
│   │   ├── definitions.ts     # Canonical tool definitions by domain
│   │   └── register.ts        # MCP registration factory
│   ├── services/
│   │   └── sessionState.ts    # Audit log, checkpoints, transactions
│   ├── cli/
│   │   └── index.ts           # Public CLI: serve / debug / verify / deploy
│   └── __tests__/
│       ├── configValidation.test.ts
│       ├── env.test.ts
│       ├── publicApi.test.ts
│       ├── catalog.test.ts
│       ├── packageManifest.test.ts
│       ├── logger.test.ts
│       └── sessionState.test.ts
├── companion/
│   └── fl_studio/
│       ├── device_FLMcpBridge.py   # Publishable bootstrap, no hardcoded repo path
│       └── FLMcpBridge.py          # FL Studio MIDI script companion runtime
├── config/                    # Client configuration examples
├── .github/workflows/ci.yml   # Required build/test/package gates
├── dist/                      # Compiled output (git-ignored)
└── tools_scoop_mvp_v3         # YAML tool catalog (V3)

License

MIT

Reviews

No reviews yet

Sign in to write a review