Mission control for your localhosts. Register every dev server you run, flip them on and off from one dark, fast dashboard — and hand the keys to Claude, which can discover, start, stop and debug them over MCP.
- One board for all your projects: status, port, pid, uptime, CPU/memory
- Start / stop / restart with one click — kills the whole process tree, no orphaned Vite daemons
- Live log tailing (stdout + stderr) streamed over SSE
- Port scanner: see everything listening on your machine, adopt unmanaged servers into the board, or kill them
- Crash detection with exit codes, port-conflict guards, process re-adoption after Switchboard restarts
- Claude integration two ways (HTTP or stdio MCP) plus a plain REST API for everything else
- Zero build step, zero external assets, works offline. Node 18+.
git clone https://github.com/nnnunezr/switchboard.git
cd switchboard
npm install
npm startOpen http://localhost:4200. Register a project (name, directory, start command, port), hit Start.
usage: switchboard [--port N]
env:
PORT preferred port (default 4200, walks upward if taken)
SWITCHBOARD_TOKEN require "Authorization: Bearer <token>" on /api and /mcp
SWITCHBOARD_DATA data directory (default ~/.switchboard)
Switchboard speaks MCP, so Claude can find and administrate your localhosts by itself — "what's running?", "start the backend and tail its logs", "something is squatting port 3000, kill it". Use whichever transport you prefer (the Connect Claude button in the dashboard shows these commands pre-filled):
Claude Code — streamable HTTP (app must be running):
claude mcp add --transport http switchboard http://127.0.0.1:4200/mcpClaude Code — stdio (proxies to the running app, auto-discovers its port):
claude mcp add switchboard -- node /path/to/switchboard/mcp-stdio.jsClaude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"switchboard": {
"command": "node",
"args": ["/path/to/switchboard/mcp-stdio.js"]
}
}
}| Tool | What it does |
|---|---|
list_projects |
Every registered project with live status, port, uptime, URL |
scan_ports |
All TCP listeners on the machine, attributed to projects where possible |
start_project / stop_project / restart_project |
Lifecycle control by name or id |
get_logs |
Tail captured stdout/stderr |
add_project / update_project / remove_project |
Manage the registry |
kill_process |
Signal an unmanaged pid found via scan |
app_info |
Switchboard's own version, URLs, data dir |
Everything the UI and MCP tools do is plain HTTP on http://127.0.0.1:4200:
| Method & path | Purpose |
|---|---|
GET /api/projects?metrics=1 |
List projects (optionally with CPU/mem) |
POST /api/projects |
Register {name, cwd, command, port?, env?, notes?} |
PUT /api/projects/:idOrName |
Update fields |
DELETE /api/projects/:idOrName |
Unregister |
POST /api/projects/:idOrName/start | /stop | /restart |
Lifecycle |
GET /api/projects/:idOrName/logs?lines=200 |
Log tail |
GET /api/scan |
Port sweep |
POST /api/kill |
{pid, signal?} |
GET /api/events |
SSE stream: projects + log events |
GET /api/health, GET /api/info |
Liveness / metadata |
- Projects are spawned through your login shell (
$SHELL -lc) in their own process group, so stopping a project SIGTERMs the entire tree (with SIGKILL escalation after 5s) — dev-server child processes don't survive. - A port probe promotes
starting → runningwhen the project's port opens; a non-zero exit marks itcrashedwith the exit code and captured stderr. - Started pids are persisted, so if Switchboard itself restarts it re-adopts still-running servers instead of losing track of them.
- The registry lives in
~/.switchboard/projects.json— plain JSON, edit it by hand if you like.
- Binds to
127.0.0.1only, and rejects requests whoseHostheader isn't local (DNS-rebinding guard). - Optional bearer auth: set
SWITCHBOARD_TOKEN=...and every/apiand/mcprequest must carryAuthorization: Bearer <token>. The dashboard prompts for the token and keeps it in localStorage. - Switchboard executes the shell commands you register, with your user's privileges. That is its job — but only register commands you trust, and treat
add_projectfrom any connected agent accordingly.
See CHANGELOG.md for the list of bugs found and fixes made.
MIT