# Workbench Server v2 Design Spec **Date:** 2026-03-30 **Status:** Draft **Repo:** https://git.sethpc.xyz/Seth/workbench-server ## Summary Workbench is an MCP server that lets any AI CLI create and control interactive web pages served over LAN. The AI pushes arbitrary HTML/CSS/JS to a browser page via WebSocket. Use cases: hardware diagnostics, guided procedures, dashboards, data collection — anything that benefits from a visual display surface the AI can control. v2 adds: server persistence (survives AI CLI restarts), pip-installable packaging, AI-guided setup (INSTALL.md/START.md), and a simplified desktop-focused layout (no embedded terminal panel). ## What Changes From v1 | Aspect | v1 | v2 | |--------|----|----| | Server persistence | In-memory only — lost on restart | `.server.json` on disk, reconnect on startup | | Layout | Split: diagnostic panel + sethmux iframe | Full-width display surface, no terminal | | Mobile support | Responsive stacking | Desktop only | | Dependencies | mcp, aiohttp | mcp, aiohttp (unchanged) | | Packaging | Raw script | pip-installable package | | Setup | Manual | AI-guided (INSTALL.md → START.md) | | tmux/sethmux | Embedded iframe | Removed entirely | ## What Stays The Same - MCP server on stdio transport - 6 MCP tools: `workbench_scaffold`, `workbench_state`, `workbench_log`, `workbench_read_log`, `workbench_list`, `workbench_stop` - HTTP + WebSocket per project (aiohttp) - AI pushes arbitrary HTML/CSS/JS — no widget system, full creative freedom - Dual-format session logging (session.md + session.jsonl) - Project directories at `~/workbench//` - LAN-native, no cloud, no auth - Cost tracking (cost-log.jsonl) ## Architecture ``` ┌─────────────────────┐ ┌──────────────────────────────┐ │ AI CLI terminal │ │ Browser (desktop) │ │ │ │ │ │ AI calls MCP tools │ stdio │ ┌────────────────────────┐ │ │ workbench_state ──┼────┐ │ │ AI-generated content │ │ │ workbench_log │ │ │ │ HTML / CSS / JS │ │ │ etc. │ │ │ │ updated live via WS │ │ │ │ ▼ │ │ │ │ │ │ MCP │ │ Schematics, tables, │ │ │ │ server │ │ checklists, dashboards│ │ │ │ │ │ │ — anything the AI │ │ │ │ │ │ │ decides to build │ │ │ │ ▼ │ ├────────────────────────┤ │ │ │ HTTP + │ │ Log feed │ │ │ │ WS on │ └────────────────────────┘ │ │ │ LAN │ ● Connected │ project-name │ └─────────────────────┘ └──────────────────────────────┘ ``` ## Persistence Mechanism ### Problem The MCP server runs as a subprocess of the AI CLI. When the AI restarts, the MCP server restarts, and all in-memory state (running HTTP servers, WebSocket clients) is lost. The AI then calls `workbench_scaffold` again and starts a duplicate server. ### Solution Persist server state to disk. On startup and on each `workbench_scaffold` call, check for an existing running server before starting a new one. **Per-project server file:** `~/workbench//.server.json` ```json { "pid": 12345, "port": 8070, "started": "2026-03-30T10:00:00-04:00" } ``` ### workbench_scaffold flow ``` workbench_scaffold(name, title) │ ├─ Project dir exists? │ ├─ No → create dir, write scaffold HTML, init logs │ └─ Yes → keep existing files │ ├─ .server.json exists? │ ├─ No → start new HTTP server, write .server.json │ └─ Yes → read port from file │ ├─ HTTP GET localhost: returns 200? │ │ ├─ Yes → server is alive, reattach (add to active_projects) │ │ └─ No → server is dead, clean up .server.json, start new server │ └─ PID still running? (fallback check) │ └─ Return {"path": "...", "url": "http://:"} ``` ### MCP server startup (reconnect) When the MCP server process starts (before any tool calls), scan for running servers: ```python for project_dir in ~/workbench/*/: server_file = project_dir / ".server.json" if server_file.exists(): info = json.loads(server_file.read_text()) if is_server_alive(info["port"]): active_projects[name] = {"port": info["port"], ...} ``` This means: AI CLI restarts → MCP server restarts → immediately knows about all running project servers → `workbench_list` and `workbench_state` work without calling `workbench_scaffold` again. ### workbench_stop flow ``` workbench_stop(project) │ ├─ Log session end to cost-log.jsonl ├─ Stop HTTP server (runner.cleanup()) ├─ Delete .server.json └─ Remove from active_projects ``` ## Scaffold HTML (v2) Full-width desktop layout. No split pane, no iframe, no terminal embed. ```html {{TITLE}}

{{TITLE}}

{{DESCRIPTION}}

Waiting for content...

Session Log

Connecting...
``` Key changes from v1: - No split layout, no divider, no term-panel, no iframe - Full-width `#content` area - Flexbox column layout (content grows, log and status at bottom) - No mobile media queries - Same WebSocket reconnect logic - Same localStorage state persistence ## MCP Tools (unchanged API) The 6 tools keep the same interface. Only internal behavior changes for persistence. ### workbench_scaffold Same parameters: `name`, `title`, `description`. New behavior: checks `.server.json` before starting a new server (see Persistence Mechanism above). Returns: `{"path": "...", "url": "http://:"}` (unchanged). ### workbench_state Unchanged. Pushes JSON to browser via WebSocket. `template`, `styles`, `script` fields. ### workbench_log Unchanged. Appends to session.md and session.jsonl, pushes to browser log feed. ### workbench_read_log Unchanged. Returns recent log entries from session.jsonl. ### workbench_list Same return format, but now also checks `.server.json` files to detect servers that survived an MCP restart. ### workbench_stop Same behavior, plus deletes `.server.json` on stop. ## Source Structure ``` workbench-server/ pyproject.toml README.md INSTALL.md LICENSE src/ workbench/ __init__.py __main__.py # python -m workbench cli.py # CLI: mcp, serve, list, help server.py # MCP server + HTTP/WS management + persistence project.py # Project dir management, logging scaffold.html # HTML template tests/ conftest.py test_project.py test_persistence.py test_server.py ``` ## Packaging ```toml [build-system] requires = ["setuptools>=68.0"] build-backend = "setuptools.build_meta" [project] name = "workbench-server" version = "0.1.0" description = "MCP server that lets AI CLIs build interactive web pages served over LAN" requires-python = ">=3.10" dependencies = [ "mcp>=1.26.0", "aiohttp>=3.9.0", ] [project.scripts] workbench = "workbench.cli:main" ``` ## INSTALL.md Same AI-guided pattern as kitty-workbench, but simpler (no terminal detection needed): 1. Clone + pip install 2. Detect platform and browser availability 3. Configure MCP for user's AI CLI 4. SSH ControlMaster setup (if applicable) 5. Smoke test 6. Write `~/workbench/START.md` ## README.md Public-facing. Setup is "paste the URL" or "read INSTALL.md". Desktop browser as the display surface. No mention of kitty or terminal splitting. Examples: hardware diagnostics, guided procedures, data collection. ## CLI Interface ``` workbench mcp # start MCP server (stdio transport) workbench serve # serve a project without MCP (standalone) workbench list # list projects workbench help # usage ```