Comprehensive Model Context Protocol server for managing Home Assistant through AI assistants.
CyberBrick is installed from its publisher's own source and answers where it runs, so this marketplace is not in the path of a single call. There is no address here to send one to, and a panel that pretended otherwise would be showing you an answer we made up. Install it and call it from your own client — the Installation tab has the entry for each one.
What it does
Drive the Bambu Lab CyberBrick desktop app: connect devices, edit firmware config, flash.
Quickstart
# 1 — add it to Claude Code
claude mcp add --scope user cyberbrick-mcp '--' npx -y cyberbrick-mcp
# 2 — ask your agent for something these tools do
# connect_scan_ports, connect_bluetooth, connect_serial and 38 more
CyberBrick costs nothing on mcprush: there is no plan to choose here, no cap to set and nothing mcprush can bill you for.
Collected from a public index. Nobody has claimed this account, so nothing here was written by its author — claim it if it is yours.
Where are you running it?
Every route below installs the same thing and ends at the same approval screen. This one runs on your machine: your client starts CyberBrick as a process under your own user, with your files and your network, so the tool surface below is what it can do to your computer rather than to a server somewhere else. Its scan result is on the Security tab — read the surface before you approve it.
This is a public server: you run it yourself and this marketplace is not in the path. You need Node.js — the current LTS (24) is the safe choice; npx comes with it. Claude Code registers it in one command; --scope user makes it available in every project. The '--' is in quotes so that PowerShell passes it on.
claude mcp add --scope user cyberbrick-mcp '--' npx -y cyberbrick-mcpReconnect, or start a new session, and the tools appear in the model’s tool list.
Nothing is required, but it can take CB_CDP_HOST (Host of the CyberBrick app's CDP endpoint (default 127.0.0.1)), CB_CDP_PORT (Port of the CyberBrick app's CDP endpoint (default 9223)), CB_APP_BINARY (CyberBrick executable that cb_launch starts (default /Applications/CyberBrick.app/Contents/MacOS/CyberBrick)) if you want to set them.
One config entry your client uses to start the process locally. A local server runs with your file system and your network, which is why it is priced without metering.
41 tools, with what each one reads, writes and reaches shown before you agree — the same list on every route above. Read the tool surface.
Tool surface
What the model actually sees. Descriptions are diffed on every release — see version history.
Read from its source code. A server that builds its tool list when it starts can list more tools than this.
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.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| includeKnownDevices | boolean | no | Also list B0-known (paired/known) receivers from the app device list. |
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…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| deviceName | string | no | Prefer a device whose advertised name matches this substring (case-insensitive). If omitted, the first discovered CyberBrick device is selected. |
| deviceId | string | no | Select the board with this deviceId (from device_list; on macOS a Chromium pseudo-address, not the chip MAC). Takes precedence over deviceName — use it for boards that share a name or were renamed (pa |
| timeoutMs | integer | no | How long to wait for the chooser to resolve before cancelling. The B0 probe after selection has its own budget. |
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…
No parameter schema on file.
List devices known to the CyberBrick app (zustand deviceListStore). Read-only.
No parameter schema on file.
Get detailed status for one device: connect state, loader mode, connection-pool entry. Read-only.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| device_id | string | yes | Device identifier as reported by device_list. |
Inspect the internal Bluetooth connection pool (size + ids). Read-only.
No parameter schema on file.
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.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| method | string | yes | Method name on window.app.local, e.g. getDeviceById. |
| args | array | no | JSON-serializable arguments. |
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.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| device_id | string | yes | Device identifier (bluetoothDeviceId) from device_list. |
ADC / channel status vector (DEVICE_STATUS, 10 bytes). Read-only.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| device_id | string | yes | Device identifier (bluetoothDeviceId) from device_list. |
Board config file metadata (GET_DEVICE_CONFIG reqType=GET_FILE_INFO). file_size=0 means no config stored. Read-only.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| device_id | string | yes | Device identifier (bluetoothDeviceId) from device_list. |
Fetch one board-config file block (GET_DEVICE_CONFIG reqType=GET_FILE_BLOCK). Use after device_config_get reports file_size>0. Read-only.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| device_id | string | yes | Device identifier (bluetoothDeviceId) from device_list. |
| index | integer | yes | Block index (0-based). |
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.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| device_id | string | yes | Device identifier (bluetoothDeviceId) from device_list. |
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.…
No parameter schema on file.
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…
No parameter schema on file.
Read the current firmwareConfig from the app store (window.app.useFirmwareConfigStore). This is what would be burned to the board. Read-only.
No parameter schema on file.
Semantic documentation for the firmware-config store actions (window.app.useFirmwareConfigStore) — the surface behind firmware_config_edit.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| action | string | no | Return the doc for a single action name instead of the full catalog. |
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.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| config | yes | Full firmware config object (mirror of firmware_config_get). |
Call a single firmware store action on the app store (e.g. updateReceiverChannel, updateSenderChannel, changeSwitchState).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| action | string | yes | Store action name, e.g. updateReceiverChannel. See firmware_edit_actions. |
| args | array | no | Positional arguments for the action, in the documented order. |
Clear the firmware config to empty defaults via the app store's resetFirmwareConfig. Immediately applies. MUTATING.
No parameter schema on file.
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…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| template | string | yes | Built-in template key (same set as project_create). |
| keepIdentity | boolean | no | Keep the current project id/config_name/design_id/region. |
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…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| firmwareConfig | object | no | Config object to burn (defaults to the current editor config). File-protocol path only. |
| hardwareMappings | array | no | Opt into the high-level runSendConfigTask path (requires a sender board). |
| firmwareListId | string | no | runSendConfigTask path only: saved project id to burn (defaults to the editor's current config id; must exist in project_list). |
| confirm | boolean | no | runSendConfigTask path only, required true: set only after the user approved the upgrades flash_check reports. |
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.…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| hardwareMappings | array | yes | — |
| firmwareListId | string | no | Saved project id (defaults to the editor's current config id). |
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.…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| mpyType | integer | no | 0 = user_mpy (design MPY, requires userMpyConfig), 1 = cb_rc (built-in RC MPY). |
| designId | string | no | — |
| region | string | no | — |
| checksum0 | string | no | MPY checksum for the upgrade check; defaults to empty (built-in path). |
| userMpyConfig | no | Design MPY config {title, microPython:{uniKey, checkSum0}} — required when mpyType=0. | |
| eraseFirmwareConfig | boolean | no | Also erase the board RC config after upgrade (app behavior step 13). |
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…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| firmwareBinaryB64 | string | yes | Base64 of the firmware .bin image. Required — the app fetches its own copies only via its cloud check, which this tool does not replicate. |
| targetVersion | string | no | Target firmware version string (recorded in checkResult.upgradeFirmwareTo). |
| region | string | no | — |
Send a control/test command to a connected device via the app's sendTestCommand. Executes immediately — drives an actuator/output on the board. MUTATING.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| command | object | yes | sendTestCommand payload {config, actuator, set_value, receiver, data}; deviceId is taken from target. |
Check CyberBrick app health: CDP endpoint live, app version, renderer bridge access, device count. Call this first.
No parameter schema on file.
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.…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| kill_existing | boolean | no | Kill a running CyberBrick instance (without the CDP port) before launching. Only with the user's OK — unsaved work is lost. |
| timeout_ms | number | no | Max wait for the CDP endpoint to come up. |
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=<lastSeq> to follow long tasks such as flash_config with hardwareMappings (upgrade → send config →…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| since | integer | no | Return only lines with seq > since (use lastSeq from the previous call). |
| grep | string | no | Case-insensitive regex filter on the line text. |
| levels | array | no | Console levels to keep, e.g. ['error','warning']. |
| limit | integer | no | Max lines returned (the newest matching ones). |
| includeNoise | boolean | no | Include per-message B0 traffic and keepalive lines. |
Read the app's current context: active route (hash), project list summary, and editor state (isModified, configType).
No parameter schema on file.
List CyberBrick projects via the app store's getShowList(): configId, type, configName, designLink, lastModifiedTime.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | string | no | Return the full record for this configId instead of the list summary. |
Create a new CyberBrick project from a built-in template (the app's createProjectFromTemplate flow: template config + addFirmware).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| template | string | yes | Built-in template key. |
| name | string | no | Project name (max 31 chars, as the app validates). Defaults to the template's own name. |
Import a project from its JSON content (the app's importProjectFromFileContent flow): validates config_version
| Parameter | Type | Required | Notes |
|---|---|---|---|
| content | string | yes | Project JSON content (a CyberBrick project file exported by project_export or the app). |
| name | string | no | Project name; defaults to config_name from the content, else "config". ".json" suffix is stripped. |
Export a project's config as JSON content — the same serialization the app's export uses (runtime fields stripped, version stamped).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | string | yes | Project configId (from project_list). |
Rename a project via the app store's renameFirmware. MUTATING. Max 31 chars (app validation).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | string | yes | Project configId (from project_list). |
| name | string | yes | New project name (max 31 chars). |
DESTRUCTIVE: permanently deletes the project via the app store's deleteFirmware.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | string | yes | Project configId (from project_list). |
Load a project's config into the app's firmware editor store (setFirmwareConfig(getFirmwareById(id)) + setConfigType),
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | string | yes | Project configId (from project_list). |
Persist the current editor config into the project list (the app store's updateFirmware: updates by id, adds if new)
No parameter schema on file.
Open the project editor (the app's openProjectEditor): loads the config into the editor store, then opens
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | string | yes | Project configId (from project_list). |
| target | string | no | "new" opens a separate editor window (app default); "current" navigates the main window. |
List the CyberBrick app's open windows: openWindows is the live truth (CDP page list with titles +
No parameter schema on file.
Close a CyberBrick app window by its windowId (from window_list). Uses the app's own closeSubWindow
| Parameter | Type | Required | Notes |
|---|---|---|---|
| windowId | integer | yes | Window id to close (from window_list). Must not be the current window. |
Close every CyberBrick app window except the one this MCP session is connected to. Use to clean up
No parameter schema on file.
- Every tool, no call limit
- No card, and mcprush charges nothing for it
- Source published under MIT
- Runs on your machine — nothing of it reaches our gateway
- Nothing to cap, because mcprush bills nothing
What counts against your monthly calls
| Tool | Unit | Calls used | Out of the allowance |
|---|
Nothing here is billable: mcprush charges nothing to install CyberBrick or to call it, at any volume.
Two independent axes, because powerful and malicious are different questions. The grade is threat only. The capability level is blast radius, and it is never a penalty on the grade — it is priced as one subtract-only term in the score, where you can see it.
| Term | Level | What it prices | Points |
|---|---|---|---|
| capability-exposure | high | capability blast radius (high) — client exposure if the model is manipulated | −6 |
| verification-discount | repo | publisher verification (public source) — no provenance, but the source is public and inspectable | −1 |
| coverage-honesty | source | inspection depth (source) — how much of the target the scan could see | −0 |
What the scan could actually read
A grade is only as meaningful as its coverage, so the scanner publishes its own depth before it publishes its result.
Tools were statically extracted from the published source (41 recovered), not enumerated from a running server. Tool-poisoning, Unicode-smuggling, capability and toxic-flow analysis ran on this inferred surface, but a mis-parsed registration could be missed or mis-attributed, so tool-derived findings are capped below “confirmed”. To grade the real runtime surface, scan the running server: --command "npx -y <package>".
Capability — what it could do if the model were manipulated
Tags derived from each tool’s schema and the implementation, not from what the tool calls itself. high is the level these add up to.
| Tool | Capability tags | Why the tag was assigned |
|---|---|---|
| connect_scan_ports | no tags | |
| connect_bluetooth | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| connect_serial | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| device_list | no tags | |
| device_detail | no tags | |
| device_pool_state | no tags | |
| device_request | no tags | |
| board_info | no tags | |
| device_status | no tags | |
| device_config_get | no tags | |
| device_config_block | untrusted-input | untrusted-input: keyword "fetch" |
| device_config_read | no tags | |
| device_ble_state | no tags | |
| device_ble_heal | state-write | state-write: declares readOnlyHint: false |
| firmware_config_get | no tags | |
| firmware_edit_actions | no tags | |
| firmware_config_set | state-write | state-write: declares readOnlyHint: false |
| firmware_config_edit | state-write | state-write: declares readOnlyHint: false |
| firmware_config_reset | state-write | state-write: declares readOnlyHint: false |
| firmware_config_load_template | state-write | state-write: declares readOnlyHint: false |
| flash_config | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| flash_check | no tags | |
| flash_mpy | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| flash_firmware | untrusted-inputexternal-sink | untrusted-input: keyword "fetch"; external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| flash_test | code-execstate-write | code-exec: parameter "command"; state-write: declares readOnlyHint: false |
| cb_health | no tags | |
| cb_launch | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| app_logs | no tags | |
| project_state | no tags | |
| project_list | untrusted-input | untrusted-input: keyword "fetch" |
| project_create | state-write | state-write: declares readOnlyHint: false |
| project_import | state-write | state-write: declares readOnlyHint: false |
| project_export | no tags | |
| project_rename | state-write | state-write: declares readOnlyHint: false |
| project_delete | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| project_load | state-write | state-write: declares readOnlyHint: false |
| project_save | state-write | state-write: declares readOnlyHint: false |
| project_open_editor | state-write | state-write: declares readOnlyHint: false |
| window_list | no tags | |
| window_close | state-write | state-write: declares readOnlyHint: false |
| window_close_others | state-write | state-write: declares readOnlyHint: false |
Toxic-flow graph
The lethal trifecta, checked as a graph rather than as a checklist: untrusted input, a sensitive source and an external sink have to meet before there is a path worth worrying about.
Supply chain and provenance
This is the first scan of this surface here, so there is nothing yet to compare it against.
Every result on this tab comes from one deterministic pass over the published package — offline, rule by rule, and auditable line by line above. Same methodology version, same bytes, same score.
Release history
Always latest — the install command names no version, so it installs the newest release when it runs; the current release on file is 0.4.0. Pin a release below and the command asks for exactly that one.
No release note was published with this version.
One review per account, from a signed-in account that does not publish this listing. Nothing else is asked — you can say what you think before you install it. Publishers can reply once per review, and a review can be edited or deleted by whoever wrote it.
Any signed-in account that does not publish CyberBrick can review it, once — before installing it or after. A review from an account that has installed it is marked as one.
Nobody has reviewed this listing. The rating on the card is the mean of the reviews written here and nothing else, so there is no rating until somebody writes the first — which takes a signed-in account that does not publish it, and nothing else.