Skip to main content
Glama

BandBox Studio

An unofficial local control panel and MCP server for the JBL BandBox Trio, running on macOS. Shape guitar sounds in your browser, or let a local MCP client control presets, effects, mixer levels, and practice tools over Bluetooth.

Experimental: tested with one BandBox Trio. This project is independent of JBL and Harman. Some controls have been verified on hardware; others are implemented from protocol research and covered by offline tests. See validation status.

What it does

Area

Controls

Guitar presets

List, load, create a copy, Save As, rename, and save user presets

Amp and effects

44 models across GAT, COM, WAH, AMP, CAB, MOD, DLY, and RVB; model selection, parameters, and bypass

Mixer

Master and channel levels in the amp's raw 0..32 steps

Practice

Drums, metronome, tuner settings, and guarded looper controls

MCP

21 named tools over local stdio, using the same controller as the GUI

The browser interface uses local HTML, CSS, and JavaScript. The Mac talks directly to the amp through a Swift CoreBluetooth helper. JBL One, an Android phone, and a cloud account are not required at runtime.

Local browser ── GUI server ─┐
                            ├── Shared controller ── Bluetooth ── BandBox Trio
Local MCP client ────────────┘

Related MCP server: garageband-llm-bridge

Setup

You need macOS, Python 3.11 or newer, Xcode Command Line Tools, and a BandBox Trio. Other operating systems and BandBox models are unsupported. If the command line tools are missing, install them with xcode-select --install first.

git clone https://github.com/opethlike/bandbox-studio.git
cd bandbox-studio
python3 install.py
open "BandBox Studio.app"

The installer creates a Python environment, installs dependencies, compiles the native helper, and creates a local app launcher. It does not connect to the amp, change its settings, or register a login service. Keep the repository in a stable local folder: the launcher and generated MCP configuration reference its location.

This is a source distribution. The app is built locally and is not a signed or notarized downloadable release.

Allow Bluetooth access when macOS asks. Turn on your amp, then press Read the amp in the panel. If the amp cannot be found, press its Bluetooth button once, wait for the blue light to pulse, and read again.

The panel opens at http://127.0.0.1:8765. You can also launch it with:

.venv/bin/python gui_launch.py

See the GUI guide for editing, saving, and practice controls.

Connect an MCP client

Setup generates .local/mcp-config.json with the correct absolute paths for this checkout. Copy its jbl-bandbox entry into your client's mcpServers configuration, preserving any other servers already there, then reload that client. Clients with another configuration format need the same executable, arguments, and environment values from that file.

This server uses local stdio. It works with a client that can start a process on the Mac. Publishing this repository does not make the amp accessible to cloud ChatGPT; no remote bridge or public tunnel is included.

Try requests such as:

  • “List my BandBox presets and show the current saved amp settings.”

  • “Create a new blues preset from this saved sound, load it, then show me the available amp models.”

  • “Set the selected user preset's Drive to 40 and save it.”

  • “Read the master volume and metronome tempo.”

The tools provide parameter ranges and control choices through bandbox_effect_catalog and bandbox_list_controls. Clients must use internal preset IDs returned by the tools, which can differ from the preset numbers on the amp's display.

Editing behavior

Reading the amp or opening the page changes no settings. To edit a tone in the GUI, explicitly Load saved sound first. Parameter sliders require Apply; the Active/Bypassed switch takes effect immediately. Save changes commits applied edits to a user preset. Factory presets cannot be overwritten here.

The amp's detail query returns saved settings, which may differ from unsaved knob or JBL One changes. After editing elsewhere, preserve any sound you want to keep on the amp, then load a saved preset again to establish a known starting point. The GUI and MCP coordinate their own writes through shared state, but cannot detect every physical-knob change.

Uncertain writes are reported and never automatically retried. Firmware flashing, factory reset, preset deletion, loop discard, and arbitrary raw-write tools are not exposed. Existing-loop overdubbing is also unavailable. Saving a user preset intentionally overwrites that preset's previous saved sound.

Validation status

Hardware validation has been performed on one Trio and one Mac, not a range of devices or firmware versions.

Area

Evidence

BLE service discovery and reads

Device services, preset inventory, current selection, and saved details read successfully

Drive

41 → 40 → 41, confirmed by device reports and the amp's display

User-preset workflow

New presets created, selected, programmed, saved, and read back; source factory preset preserved

Effects

Model changes, parameter changes, and active/bypass changes exercised while programming those presets; not every model tested

Master mixer

15 → 14 → 15 raw steps, with matching reports and final readback

Drum tempo

90 → 89 → 90 BPM, with matching reports and final readback

GUI

Live reads verified; editing, saving, creation, and practice-control flows browser-tested with a simulated device

Other paths

Save As, rename, remaining catalog models, tuner writes, channel mixer writes, and looper recording/bar changes are not individually hardware-verified

The test suite covers decoding, request validation, state guards, shared-state invalidation, and GUI HTTP boundaries. Offline tests and a matching device report do not establish audio quality or universal firmware compatibility. USB control is not implemented.

Local files and discovery

Runtime state is stored in ~/Library/Application Support/BandBoxStudio/state. It includes the discovered CoreBluetooth identifier and local diagnostics. Generated files, personal device configuration, logs, and build artifacts are ignored by Git.

Variable

Purpose

BANDBOX_RUNTIME_DIR

Override the shared state folder. Use the same value for GUI and MCP.

BANDBOX_DEVICE_UUID

Optionally pin a Mac CoreBluetooth peripheral UUID. This is not a Bluetooth MAC address.

Without a pin, the helper discovers the BandBox by its expected name and checks its control service. Ambiguous multiple-device discovery is refused. A pinned device is not silently replaced by another device if its connection fails.

For a read-only command-line check:

.venv/bin/python server.py current

Other read modes are inspect, state, and presets. Their output can include local device identifiers; redact it before posting an issue. The raw state value maps to battery in JBL One's code but has not been independently compared to the amp's battery display.

Development

.venv/bin/python -m unittest discover -v
.venv/bin/python check_mcp.py

Both commands are offline; the MCP check performs a handshake and catalog checks without contacting the amp. See CONTRIBUTING.md for native tests, protocol changes, and useful bug reports. For connection help, see the GUI guide.

Protocol details and source provenance are in docs/protocol.md and THIRD_PARTY_NOTICES.md. Transport research was informed by OpenJBL's protocol notes; BandBox-specific mappings were identified through JBL One 2.7.9 inspection and device observations.

Licensed under MIT. See SECURITY.md for private vulnerability reporting.

Related MCP Connectors

Related MCP Servers