Skip to main content
Glama
MelvinTo

n3 MCP server

by MelvinTo

n3 — Stream Dock N3 without the StreamDock app

Independent, community project. Not affiliated with or endorsed by Mirabox / Hotspot Technology.

Pure-Python control of the Mirabox Stream Dock N3 (USB 6603:1002) over HID. No vendor binaries, no Qt app, no plugins: a CLI for humans and scripts, and an MCP server plus Claude Code skills so an AI agent can drive the deck directly.

n3.py        library + CLI
n3_mcp.py    MCP server (stdio JSON-RPC) — tools n3_info, n3_set_key(s), n3_set_screen,
             n3_brightness, n3_clear, n3_power, n3_wait_event, n3_events
.mcp.json    registers the server for Claude Code when run from this directory
.claude/skills/n3        how to use the CLI/MCP, layout, conventions
.claude/skills/n3-menu   ask the user questions through the physical keys
examples/    keymap.json (watch mode), status.json (layout),
             claude_dashboard.py (live tiles: Claude/Codex quotas, active sessions, ping,
             app launcher, volume/brightness knobs; `--install` runs it as a login agent)

Setup

pip3 install --user hidapi pillow          # package name is 'hidapi' (imports as 'hid'); Python 3.9+
osascript -e 'quit app "StreamDock"'       # the app holds the device exclusively
python3 n3.py info

Optional launcher: ln -s "$PWD/n3.py" ~/bin/n3 (or anywhere on your PATH).

Global MCP registration (instead of the per-project .mcp.json):

claude mcp add n3 -- python3 "$PWD/n3_mcp.py"     # run from this directory

Related MCP server: mcp-divoom-lan

Firmware V3.293N3 stops repainting after a period of silence and only recovers on a USB replug. The StreamDock app never goes quiet (it re-uploads a key image + refresh every second), so the daemon does the same (--keepalive 1.0), plus the 10 s CONNECT heartbeat. n3 daemon owns the device, sends the heartbeat, reconnects on unplug/replug, replays the last layout, and fans out key/knob events. The CLI and the MCP server automatically talk to it over ~/.config/n3/n3d.sock when it is running (macOS opens HID devices exclusively, so the daemon must be the single owner).

n3 daemon --install     # macOS launchd agent local.n3d, starts at login, log ~/Library/Logs/n3d.log
n3 daemon --status
n3 daemon --uninstall
n3 daemon               # or run it in the foreground yourself

CLI

python3 n3.py info [--json]
python3 n3.py brightness 0-100 | +10 | -10   # relative steps use the last level set
python3 n3.py key 1 [2 3 ...] --text "Build\nOK" --bg "#2e7d32" --fg white [--image icon.png] [--size 18]
python3 n3.py screen --text "CI: green" --bg navy [--image bg.png]
python3 n3.py clear [keys... | all]
python3 n3.py layout file.json | -          # whole state in one call
python3 n3.py listen [--json] [--timeout S] [--count N]
python3 n3.py watch examples/keymap.json    # run shell commands on key/knob events
python3 n3.py wake | sleep | refresh
python3 n3.py raw <hex> [--read S]          # protocol experiments

Layout JSON:

{"brightness": 80, "clear": true,
 "keys": {"1": {"text": "Build", "bg": "#1e88e5"}, "2": {"image": "/path/icon.png"}, "3": null},
 "screen": {"text": "main @ 4f2a1c", "bg": "#1a237e"}}

Events are JSON lines: {"type":"key","key":3,"action":"press"}, {"type":"knob","knob":3,"position":"top","action":"left"}.

Platform notes

  • macOS is what this was developed and tested on (Apple Silicon, macOS 26). n3 daemon --install uses launchd.

  • Linux should work with hidapi and a udev rule granting access to 6603:1002 (e.g. SUBSYSTEM=="hidraw", ATTRS{idVendor}=="6603", ATTRS{idProduct}=="1002", MODE="0666"); run n3 daemon under your own service manager. Untested.

  • Windows: untested.

  • Only the N3 variant reporting firmware V3.293N3_PXL... (the app calls it "MBox-N3 ") has been verified. Other Stream Dock models use different sizes and product IDs; see Mirabox's public Device SDK for their tables.

Device layout

Part

Ids

Display

LCD keys

1–6

64×64

Buttons

7–9

none

Knobs

1 bottom-left, 2 bottom-right, 3 top

none

Screen

320×240

Protocol

Recovered from Mirabox's libtransport (their public Device SDK) and verified against firmware V3.293N3_PXL.02.010. Output reports are 1024 bytes, input reports 512 bytes, and GET_REPORT(0) returns the firmware string. Command frames (CRT\0\0 prefix, zero padded):

Frame

Meaning

LIG \0\0 <pct>

brightness (byte 10)

CLE \0\0\0\0 <key or FF>

clear key / all (byte 11)

STP

refresh (show queued images)

DIS / HAN

wake / sleep

CONNECT

heartbeat, every 10 s while a client is attached

CLE\0\0DC

"software disconnected" notice

BAT <u32be len> <key> + JPEG in 1024-byte chunks

key image

LOG <u32be len> 01 + JPEG in 1024-byte chunks

screen image

Input events: ACK\0\0OK\0\0\0 <code> <state>; codes 1–6 keys, 25/30/31 buttons 7–9, 33/34/35 knob press, 90/91 60/61 50/51 knob rotate. The firmware sends no acknowledgement for writes.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Enables programmatic control of Divoom Pixoo LED matrices to display layered pixel art, animations, and hardware-rendered scrolling text. Users can compose complex visual scenes, push images, and manage device settings like brightness and channels through an LLM.
    7
    231 npm
    9
    Apache 2.0
  • A
    license
    B
    quality
    C
    maintenance
    Enables AI clients to control Divoom LAN devices, including watchface management, brightness adjustment, and screen control through natural language.
    18
    41 npm
    4
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables AI agents to control Android TV/Android devices through ADB, including screen capture, remote control, app management, and more.
    24
    3 npm
    MIT