streamdeck-mcp
Enables AI agents to read and write Elgato Stream Deck desktop profiles, including managing pages, actions, and icons, wrapping shell commands as script-backed keys, and restarting the Stream Deck app to apply manifest changes.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@streamdeck-mcpadd a key for restarting Docker to the top-left of my deck"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
streamdeck-mcp
An MCP server that lets AI agents read and write Elgato Stream Deck desktop profiles — the plain-JSON manifests the Elgato Stream Deck app uses — plus a small toolkit for generating icons, wrapping shell commands in script-backed keys, and restarting the app so changes take effect.
Fork of verygoodplugins/streamdeck-mcp (MIT, Jack Arturo / Very Good Plugins), extended with:
http_service.py— the same tool surface over MCP Streamable HTTP, behind a bearer-token gate, for agents that run on a different machine (the stdio server assumes its client runs where the deck is).deck_status— a one-call health verdict for remote agents.examples/— a launchd service template, an env template, and a read-only end-to-end smoke client.
Ask an agent to "put a key for restarting Docker on the top-left of my deck" and it edits those manifests — no hunting for settings in the app.
The one rule that bites
The Elgato desktop app keeps profiles in memory and rewrites the manifest files from memory when it quits. Edits made behind the app's back are clobbered at the next quit. The correct cycle is:
stop the app (
streamdeck_write_pagerefuses to write while the app is running;auto_quit_app=truestops it for you),make your manifest edits (one or more
streamdeck_write_pagecalls),restart the app (
streamdeck_restart_app) so it reads your layout.
Always back up the profiles directory before writing.
Related MCP server: WebMCP Script
Transports
Transport | When | How |
stdio | the MCP client runs on the deck's machine | the |
Streamable HTTP | the agent runs elsewhere and needs the deck over the network |
|
The HTTP service adds one tool on top of the stdio surface: deck_status.
Quick start — stdio
git clone <this repo>
python3.11 -m venv .venv
.venv/bin/pip install -e .Then point any local MCP host at .venv/bin/streamdeck-mcp (or at the
upstream PyPI release if you don't need the HTTP service).
Quick start — HTTP service
git clone <this repo>
python3.11 -m venv .venv
.venv/bin/pip install -e .
# bearer token (keep it secret; chmod 600)
openssl rand -hex 24 > .token
chmod 600 .token
.venv/bin/streamdeck-mcp-service # listens on 127.0.0.1:18802 by defaultMCP client config (Streamable HTTP):
{
"mcpServers": {
"streamdeck": {
"type": "http",
"url": "http://127.0.0.1:18802/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}For a remote agent on your private/tailnet network, set DECK_MCP_BIND to
a private interface address. The service enforces DNS-rebinding protection
(it only accepts requests whose Host matches the bind address or
loopback), so it is not internet-facing by default; put a
TLS-terminating reverse proxy in front of it if the path between client
and deck crosses an untrusted network.
Smoke-test a running service (read-only):
.venv/bin/python examples/test_client.py http://127.0.0.1:18802/mcp .tokenOn macOS, run it as a launchd service with examples/launchd.plist.tpl
(the template comments cover install, stop, and log locations).
Environment
Variable | Default | Purpose |
|
|
|
|
| bearer token file; re-read per request, so rotation needs no restart |
| auto ( | override the profiles directory |
|
| where |
|
| where |
| — (warnings to stderr) | JSONL audit file, one line per tool call |
Tools
Tool | What it does |
| search installed plugins/actions by text, plugin, controller, or profile usage; each result carries a paste-ready native |
| list profiles (V3/V2), pages, current/default page, device model |
| read one page, button by button, each with its raw native action object |
| create or replace a page manifest; refuses while the app is running unless |
| render one PNG icon from a Material Design Icons glyph and/or text |
| batch-render icons |
| wrap a shell command in a script-backed |
| installed plugins with action/settings schemas (for synthesizing actions) |
| stop + relaunch the Elgato app (macOS) to pick up manifest edits |
| install the bundled in-app |
| app running? profile inventory? uptime? last tool call? |
Authoring a key, in preference order
Paste a native action — copy the
actionobject fromstreamdeck_find_actions, or astreamdeck_read_pagebutton'srawfield, intostreamdeck_write_page. Best for installed plugins whose settings schema is opaque.Synthesize — from
streamdeck_read_plugins:plugin_uuid+action_uuid+settings.Script-backed —
streamdeck_create_actionwrites a shell script and returns anOpenaction; the key then runs your command.
Security model
The HTTP endpoint is bearer-token gated; the token file is re-read on every request and compared in constant time, so rotation needs no restart.
GET /healthis intentionally unauthenticated and returns no profile data (liveness only).DNS-rebinding protection: only requests whose
Hostheader matches the bind host or loopback are accepted; anything else is dropped fail-closed (the connection is closed without a response).The service is not meant to be exposed to the public internet; keep it on a private/tailnet interface, behind TLS if the path is untrusted. No telemetry, no outbound connections.
Troubleshooting
Symptom | Meaning / fix |
| the Elgato app holds the manifests in memory; close it (or pass |
| check |
connection closed with no response | the client's |
keys look stale after a write | the app rewrote the manifests from memory on quit; redo the cycle with the app stopped |
Development
python3.11 -m venv .venv
.venv/bin/pip install -e .[dev]
.venv/bin/pytest # profile engine, stdio server, HTTP service
.venv/bin/ruff check .Tests run on any platform: the profile engine is pure file manipulation and the Stream Deck app is stubbed out.
Layout
profile_manager.py the profile engine (V3/V2 manifests, pages, actions,
icons, app control)
profile_server.py stdio MCP server (9 tools)
server.py legacy USB/streamdeck-python device server (optional)
http_service.py Streamable HTTP service (10 tools, bearer-token gated)
install_skill.py installs the bundled streamdeck-designer skill
streamdeck_assets/ Material Design Icons (Apache-2.0) + designer skill
streamdeck_plugin/ bundled in-app .sdPlugin
tests/ pytest suite (synthetic profile fixtures)
examples/ launchd template, env template, smoke clientAttribution
Forked from verygoodplugins/streamdeck-mcp
(MIT, © Jack Arturo / Very Good Plugins). The HTTP service, deck_status,
the examples and the fork packaging are © Hugo Soares. The bundled
Material Design Icons font is Apache-2.0 (see
streamdeck_assets/MDI-LICENSE).
This server cannot be deployed
Maintenance
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Build, validate, deploy — HTTP APIs, cron jobs, webhooks and MCP tools — from your AI client.
Remote streamable-HTTP MCP server running on a single Cloudflare Worker. Your assistant gets live Airbnb, Amazon, Booking.com, Google Flights, Maps and Reddit data, social search on X, Instagram and TikTok, the Meta Ad Library, and image/video generation without any keys. Connect your own accounts to let it send WhatsApp or Telegram messages, work an IMAP inbox, manage Meta Ads campaigns and publish to X and LinkedIn. OAuth 2.1 with PKCE; stored credentials are AES-256-GCM encrypted.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to remotely search, update, manage files, and run terminal commands on a desktop environment via Streamable HTTP with OAuth 2.0, supporting ChatGPT and web agent integrations.195,946 npm1MIT
- AlicenseBqualityBmaintenanceEnables AI clients to connect locally over stdio, discover and read schemas for native page tools, and execute user-authorized operations supplied by websites and independent user scripts.13MIT
- AlicenseAqualityBmaintenanceEnables an AI agent to take full control of a machine — running shell commands, editing files, managing git, packages and processes, and reaching the network — with batched execution, server-side variables and selectable tool profiles that keep token usage low. It also speaks HTTP so the same agent can operate a remote build box, NAS or VPS.262MIT
- FlicenseNot gradedqualityAmaintenanceExposes a governed suite of 38 tools over a single OAuth-gated MCP endpoint, letting web-based AI clients such as Claude, ChatGPT, and Grok read and edit files, run whitelisted shell commands, search, query SQLite, use Git, automate browsers and DevTools, manage background tasks, reach localhost services, and control the clipboard, notifications, ports, and Postman. This turns remote AI chats into secure operators of a local machine without granting unrestricted shell access.-