cyberbrick-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CB_CDP_HOST | No | Host for the Chrome DevTools Protocol connection. Defaults to 127.0.0.1. | 127.0.0.1 |
| CB_CDP_PORT | No | Port for the Chrome DevTools Protocol connection. Defaults to 9223. | 9223 |
| CB_APP_BINARY | No | Path to the CyberBrick desktop app binary used by cb_launch. Defaults to /Applications/CyberBrick.app/Contents/MacOS/CyberBrick. | /Applications/CyberBrick.app/Contents/MacOS/CyberBrick |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| cb_healthA | Check CyberBrick app health: CDP endpoint live, app version, renderer bridge access, device count. Call this first. |
| cb_launchA | Launch the CyberBrick desktop app with the CDP debug port (9223). Reuses a reachable CDP endpoint. If the app is already running without the debug port, it fails unless kill_existing=true (the app enforces a single-instance lock) — killing it discards unsaved work, so get the user's OK first. NOTE: must run from an unsandboxed shell. |
| app_logsA | Read the CyberBrick app's renderer console, captured by this MCP server since it attached (ring buffer, 5000 lines; lines that mention tokens/keys/PINs/certs are never stored). Poll with since= to follow long tasks such as flash_config with hardwareMappings (upgrade → send config → pairing). Per-message B0 traffic and keepalives are hidden unless includeNoise. Read-only. |
| device_listB | List devices known to the CyberBrick app (zustand deviceListStore). Read-only. |
| device_detailB | Get detailed status for one device: connect state, loader mode, connection-pool entry. Read-only. |
| device_pool_stateB | Inspect the internal Bluetooth connection pool (size + ids). Read-only. |
| device_requestA | Call a read-only window.app.local method: isInLoader, getDeviceById, or sendGetMessage with a read-only B0 command (DEVICE_STATUS, GET_DEVICE_CONFIG, GET_BOARD_INFO, GET_BOARD_TYPE, GET_DEVICE_WIFI_MAC, SYSTEM_VERSION, MPY_PROJECT_INFO, MPY_CHECKSUM_INFO). Any other method or command is refused. |
| board_infoA | Aggregated board info for one device: firmware/loader versions, hardware string, project string, SN, board type — read via B0 SYSTEM_VERSION + GET_BOARD_INFO + GET_BOARD_TYPE. |
| device_statusC | ADC / channel status vector (DEVICE_STATUS, 10 bytes). Read-only. |
| device_config_getB | Board config file metadata (GET_DEVICE_CONFIG reqType=GET_FILE_INFO). file_size=0 means no config stored. Read-only. |
| device_config_blockA | Fetch one board-config file block (GET_DEVICE_CONFIG reqType=GET_FILE_BLOCK). Use after device_config_get reports file_size>0. Read-only. |
| device_config_readA | Read back the whole board config file (GET_FILE_INFO + every GET_FILE_BLOCK), trimmed to file_size, with its MD5 (compare with flash_config's md5) and the parsed config JSON. Read-only. |
| device_ble_stateA | Live BLE link state per device: GATT connected, store vs. manager status, pool membership, loader mode and the BluetoothDevice connectionCount. connectionCountOk=false means every reconnect (enterLoader during upgrades, BLE drops) will fail with RECONNECTION_INTERRUPTED — fix with device_ble_heal. Read-only. |
| device_ble_healA | Reset a non-finite (NaN/undefined) BluetoothDevice.connectionCount to 0 on live devices — the state markBluetoothDevice would have set — so the app's reconnect logic works again without power-cycling the board. No BLE I/O. Run before upgrades/pairing when device_ble_state shows connectionCountOk=false. |
| connect_scan_portsA | Enumerate Web Serial ports and Web Bluetooth devices currently available to the CyberBrick app. Read-only — does not pair or connect. Use this to tell the user what hardware can be connected right now. |
| connect_bluetoothA | Drive the app's real add-device flow (BluetoothDeviceManager.requestDevice — the same one the MyDeviceDialog UI uses): starts a BLE scan filtered to CyberBrick devices (companyIdentifier 17882, manufacturer data prefix [99]), then auto-selects the matching device so the chooser resolves without UI. After it resolves, the app marks the device and the caller can verify with device_list. MUTATING (pairs a device). |
| connect_serialA | Ask the app's main process to auto-select a Web Serial (USB-C) port (window.electron.ipcRenderer.autoSelectSerialPort, strategy "first") and return its metadata plus the BLE-connected board it belongs to (USB serial number = chip MAC, matched against each board's GET_DEVICE_WIFI_MAC). In this app the serial link only serves the USB flash (rescue flasher) feature — config, pairing, upgrades and every other device tool go over Bluetooth, so this does not make a board usable by the other tools. Opens nothing on the board. |
| firmware_config_getA | Read the current firmwareConfig from the app store (window.app.useFirmwareConfigStore). This is what would be burned to the board. Read-only. |
| firmware_edit_actionsA | Semantic documentation for the firmware-config store actions (window.app.useFirmwareConfigStore) — the surface behind firmware_config_edit. Returns enums (receiverKey, actuator, device, configType), grouped action names, and per-action arg signatures. Pass action= to get the doc for one action. Read-only, no app connection required. |
| firmware_config_setA | Replace the whole firmware config via the app store's setFirmwareConfig. Immediately applies to the app store (and the next burn). MUTATING — writes to the app's firmware config. |
| firmware_config_editA | Call a single firmware store action on the app store (e.g. updateReceiverChannel, updateSenderChannel, changeSwitchState). Immediately applies to the editor config. MUTATING. Use firmware_edit_actions first to get the exact arg signature (positional args, enums like receiverKey/actuator) for the action you want. |
| firmware_config_resetA | Clear the firmware config to empty defaults via the app store's resetFirmwareConfig. Immediately applies. MUTATING. |
| firmware_config_load_templateA | Replace the editor config with one of the app's built-in project templates (same data as project_create, in the app's UI language). By default keeps the loaded project's id/name so project_save overwrites it; keepIdentity=false loads it as an unsaved new config. Marks the editor modified; nothing is written to the project list or board until project_save / flash_config. MUTATING. |
| flash_configA | Write a firmwareConfig to the board. Default: the app's SET_DEVICE_CONFIG file protocol (FILE_INFO(md5,size) → chunked FILE_BLOCK via sendGetMessage) — works for a lone receiver, burns firmwareConfig if given else the current editor config, to exactly one target device (ambiguous or unmatched targets are refused). The device must be connected (else DEVICE_NOT_CONNECTED → call connect_bluetooth). Returns {ok, verified, bytes, chunkSize, blocks, md5, readback} — verified=true when the board reports the written size — or {stage, ...} on failure. Passing hardwareMappings switches to the app's runSendConfigTask (burns a saved project, needs a sender board; never creates a project). That path can also upgrade firmware / MPY / loader first — preview with flash_check and pass confirm=true only after the user approved those upgrades. Executes immediately — OVERWRITES the board's stored config. MUTATING / writes to hardware. |
| flash_checkA | Dry-run of flash_config's hardwareMappings path: calls the app's checkDeviceConfigSync and reports, per board, which firmware / MPY / loader upgrades runSendConfigTask would run before sending the config and pairing. Nothing is written. Use it to get the user's consent for upgrades first. upgradeTargets is exactly what the run executes (the app's log may still mention a loader upgrade it then skips). Read-only. |
| flash_mpyA | Run a MicroPython firmware update via the app's updateLoaderFirmwareMpy (START_MPY_UPDATE). Writes mpy.img and REBOOTS the board. DESTRUCTIVE — requires confirm=true after explicit user approval. Default path upgrades to the built-in RC MPY (mpyType=1); passing userMpyConfig targets a design MPY. Experimental: the built-in path still needs live validation. |
| flash_firmwareA | Run a full system firmware flash (SYSTEM_UPGRADE) via the app's updateLoaderFirmwareMpy with shouldUpgradeFirmware=true. Executes immediately — multiple reboots, CAN BRICK the device if interrupted. Requires firmwareBinaryB64: the MCP does not replicate the app's cloud package fetch (auth headers + certificate decryption are out of scope), so you must supply the .bin yourself (base64). Requires confirm=true after explicit user approval. DESTRUCTIVE. |
| flash_testA | Send a control/test command to a connected device via the app's sendTestCommand. Executes immediately — drives an actuator/output on the board. MUTATING. |
| project_stateA | Read the app's current context: active route (hash), project list summary, and editor state (isModified, configType). Returns a nextTools list of the tools relevant right now — call this first when working with CyberBrick projects, then act. Read-only. |
| project_listC | List CyberBrick projects via the app store's getShowList(): configId, type, configName, designLink, lastModifiedTime. Pass include=full to fetch one project's complete config body via getFirmwareById. Read-only. |
| project_createA | Create a new CyberBrick project from a built-in template (the app's createProjectFromTemplate flow: template config + addFirmware). Templates: forklift, truck, forklift_and_truck, ball_car, official_remote, none, custom. MUTATING (adds a project to the app's list). |
| project_importA | Import a project from its JSON content (the app's importProjectFromFileContent flow): validates config_version (rejects files newer than the app supports), forces design_id/region to app defaults, adds to the project list. Pass the file content as a string — read the file yourself first. MUTATING (adds a project). |
| project_exportA | Export a project's config as JSON content — the same serialization the app's export uses (runtime fields stripped, version stamped). No save dialog; write the returned content to a file yourself. Read-only. |
| project_renameB | Rename a project via the app store's renameFirmware. MUTATING. Max 31 chars (app validation). |
| project_deleteA | DESTRUCTIVE: permanently deletes the project via the app store's deleteFirmware. This cannot be undone — the project config is removed from the app's persisted list. No confirmation is added by MCP. |
| project_loadA | Load a project's config into the app's firmware editor store (setFirmwareConfig(getFirmwareById(id)) + setConfigType), the same thing the app does when you open a project. After loading, use firmware_config_edit to change parameters, then project_save to persist. MUTATING (replaces the current editor config). |
| project_saveA | Persist the current editor config into the project list (the app store's updateFirmware: updates by id, adds if new) and mark the editor as saved. MUTATING (writes the project list). |
| project_open_editorA | Open the project editor (the app's openProjectEditor): loads the config into the editor store, then opens /project/edit?firmwareId= either in a new app window (default, via the app's createWindowWithPath) or by navigating the current window. MUTATING (loads config, opens window). |
| window_listA | List the CyberBrick app's open windows: |
| window_closeA | Close a CyberBrick app window by its windowId (from window_list). Uses the app's own closeSubWindow (window:close-sub-window IPC) — the same path as the window's close button; unsaved changes trigger the app's own confirm dialog, which the MCP does not bypass. The MCP-connected window cannot be closed (REFUSE_CLOSE_CURRENT). Each project_open_editor with target="new" opens one of these — close them to avoid window buildup. MUTATING. |
| window_close_othersA | Close every CyberBrick app window except the one this MCP session is connected to. Use to clean up editor windows accumulated from project_open_editor. Unsaved changes surface the app's own confirm dialogs. MUTATING. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 41 tools
Most tools have clearly distinct purposes, with explicit warnings for destructive and mutating operations. Some overlap exists among device inspection tools (device_detail vs. board_info vs. device_status) and firmware/config editing paths (firmware_config_set vs. firmware_config_edit vs. project_save), but the descriptions generally clarify boundaries.
All names use snake_case, but the structural conventions are mixed: some tools are resource_action (project_rename, device_list), others action_resource (flash_mpy, connect_bluetooth), and some have unique prefixes (cb_health, app_logs, board_info). The grouping is readable, but there is no single predictable naming pattern.
At 41 tools, the surface is very heavy for an MCP server, even for a complex app-plus-hardware integration. Several tools are specialized or low-level, and the count exceeds the typical comfortable range without strong evidence that all are required for common agent workflows.
The tool set covers the domain broadly: project lifecycle, firmware config editing, device inspection, BLE/serial connection, flashing, health checks, logs, and window management. Minor gaps exist, such as explicit disconnect/unpair operations and higher-level device session cleanup, but core workflows are well supported.