Desktop bridge
How the MCP server connects to a running CostPad Desktop — live mutations and pulling the user's real product.
When the CostPad Desktop app is running, the MCP server connects to it over a local, auth-free bridge. This unlocks use case 2 — desktop-attached: an assistant can push its changes to the Desktop (panels animate live) and pull the user's real product to analyze actual numbers. With no Desktop running, the server is a normal offline engine — use case 1 — standalone — and never surfaces a connection error.
Local and auth-free
The bridge is loopback-only (127.0.0.1) and gated by a rotating local token in ~/.costpad/desktop.json. It is not account auth — the MCP never talks to costpad.dev.
How it connects
- The Desktop writes a discovery lockfile
~/.costpad/desktop.json={ port, token, pid, version }. - The MCP reads it, opens a WebSocket, and presents the token (
hello→welcome). - While connected, mutations stream to the Desktop and the MCP can pull the current product.
Tools
| Tool | What it does |
|---|---|
bridge_status | Reports connected / offline, the Desktop version, and last sync time — so an assistant knows which use case it's in. |
pull_from_desktop | Loads the Desktop's current product into the session (replacing the simulation), so analysis starts from the user's real numbers. Errors clearly when offline. |
Live mutations
Every state-changing tool (update_*, load_scenario, import_product, reset_state, load_preset) mirrors its change to the Desktop as a section/payload event, so the matching panel re-renders live. Emitting is best-effort: it never blocks or changes a tool's result, and is a no-op when offline.
section | payload |
|---|---|
cogs / tiers / mix / addOns / oneTimePurchases | the resulting array for that section |
product | the full simulation (used for whole-model replacements like load_preset) |
The full wire protocol — discovery, transport, message schemas, ordering, and security — is documented in the package's bridge-protocol.md.