AI-first MCP server for Elgato Stream Deck profile management. The default server writes directly to the Stream Deck desktop app's native profile files, and the original USB-direct server is still available as a legacy fallback.
The default packaged entrypoint is the profile writer. It edits ProfilesV3 when present, then falls back to ProfilesV2.
uvx streamdeck-mcp{
"mcpServers": {
"streamdeck": {
"command": "uv",
"args": [
"--directory",
"/path/to/streamdeck-mcp",
"run",
"profile_server.py"
]
}
}
}If you still want direct hardware control that bypasses the Elgato app entirely, keep using the legacy server:
{
"mcpServers": {
"streamdeck-usb": {
"command": "uv",
"args": [
"--directory",
"/path/to/streamdeck-mcp",
"run",
"server.py"
]
}
}
}Or use the packaged legacy entrypoint:
uvx --from streamdeck-mcp streamdeck-mcp-usb| Tool | What it does |
|---|---|
streamdeck_read_profiles |
Lists desktop profiles and page directories from the active ProfilesV3 or ProfilesV2 store |
streamdeck_read_page |
Reads a page manifest and returns simplified button details plus the raw manifest |
streamdeck_write_page |
Creates a new page or rewrites an existing page manifest |
streamdeck_create_icon |
Generates a PNG icon from a Material Design Icons name (e.g. mdi:cpu-64-bit) or from text (but not both). shape="button" (72x72, default) for keypad keys and encoder dial faces; shape="touchstrip" (200x100) for Stream Deck + / + XL dial segment backgrounds. ~7400 MDI icons are bundled offline; unknown names return close-match suggestions |
streamdeck_create_action |
Creates an executable shell script in ~/StreamDeckScripts/ and returns an Open action block |
streamdeck_restart_app |
Restarts the macOS Stream Deck desktop app after profile changes |
streamdeck_install_mcp_plugin |
Installs the bundled streamdeck-mcp Stream Deck plugin into the user's Elgato Plugins directory. streamdeck_write_page auto-installs it when an encoder button needs it, so direct use is rarely necessary |
ProfilesV3is preferred when it exists because page UUIDs map cleanly to directories.ProfilesV2is still supported, but existing pages should be targeted bydirectory_idorpage_indexbecause Elgato stores opaque page directory names there.streamdeck_write_pagecan accept raw native action objects, or use convenience fields likepath,action_type,plugin_uuid, andaction_uuid.- Generated icons are stored in
~/.streamdeck-mcp/generated-icons/. - Generated shell scripts are stored in
~/StreamDeckScripts/. - The bundled streamdeck-mcp Stream Deck plugin is installed into the Stream Deck Plugins directory (e.g.,
~/Library/Application Support/com.elgato.StreamDeck/Plugins/on macOS,%APPDATA%\Elgato\StreamDeck\Plugins\on Windows) once installed. It's a minimal shell whose only job is to declare encoder support so per-instanceEncoder.Icon/Encoder.backgroundwrites survive an Elgato app restart.streamdeck_write_pageinstalls it automatically the first time an encoder button needs it.
The Elgato desktop app keeps every profile in memory and rewrites the on-disk manifests from that snapshot when it quits, so any edit made while the app is running is wiped the next time it closes. The profile writer enforces a quit → write → relaunch cycle:
- Ensure the Elgato app is not running, or pass
auto_quit_app: truetostreamdeck_write_pageto have it quit the app for you (AppleScript first,killallfallback). - Make as many
streamdeck_write_pagecalls as you need — the app stays quit across them. - Call
streamdeck_restart_appwhen you are done. The device re-reads the manifests on launch and your changes appear.
streamdeck_write_page raises a StreamDeckAppRunningError when the app is running and auto_quit_app is not set, so you cannot accidentally write changes that will be silently discarded.
If your Elgato app is installed somewhere other than /Applications/Elgato Stream Deck.app, set STREAMDECK_APP_PATH to the bundle path.
streamdeck_create_actionis the safest way to build shell-command buttons because it writes a standalone script and returns the native Open action block for it.- The profile writer does not require exclusive USB access.
The original USB-direct server is preserved for backwards compatibility. It still provides:
streamdeck_connectstreamdeck_infostreamdeck_set_buttonstreamdeck_set_buttonsstreamdeck_clear_buttonstreamdeck_get_buttonstreamdeck_clear_allstreamdeck_set_brightnessstreamdeck_create_pagestreamdeck_switch_pagestreamdeck_list_pagesstreamdeck_delete_pagestreamdeck_disconnect
Use that mode only when you want the MCP server to own the hardware directly and the Elgato desktop app is not running.
uv venv
uv pip install -e ".[dev]"
uv run pytest tests/ -v
uv run ruff check .To audit this repo against the shared Very Good Plugins MCP standards:
../mcp-ecosystem/scripts/audit-server.sh .For issues, questions, or suggestions:
Built with 🧡 by Very Good Plugins