One tray toggle for all your AI coding agents' MCP servers — at once, no restarts.
Patchbay is a Windows system-tray app + a local MCP gateway that lets you toggle MCP servers on/off from the tray — live, for ALL your CLI coding agents at once (Claude Code, Codex, Antigravity, Kilo), with no agent restart and no per-agent config edits after a one-time wiring.
It speaks the Model Context Protocol over
Streamable HTTP on http://127.0.0.1:39100/mcp (bound strictly to localhost).
Point every agent at that single URL once; from then on you flip servers on and
off in the Patchbay tray and every connected agent picks it up instantly.
- One URL for every agent. Point Claude Code, Codex, Google Antigravity and
Kilo at
http://127.0.0.1:39100/mcponce — never edit their configs again. - Live toggle. Tick/untick a server in the tray; its tools appear or
disappear for every connected agent instantly (agents that honor
tools/list_changed; Codex needs a session restart — its limitation, not Patchbay's). - Per-agent identity. An agent is identified by its self-reported name or,
better, by an
X-Patchbay-Clientheader you set, so you can tell a personal and a work profile of the same tool apart. - Per-agent permissions. Give any agent its own independent on/off list ("Custom permissions"), separate from the global checkboxes.
- Approval gate. Optionally require a one-time Allow/Deny Windows dialog the first time a brand-new identity connects (off by default).
- Honest errors. Calling an unpatched server returns a clear message to the
agent instead of a mystery failure. A Patchbay restart invalidates every
agent's MCP session (in-memory only, unavoidable) — a spec-compliant client
(Claude Code included) silently reconnects on its very next tool call, no
visible disruption; an agent that never called
initializeat all gets an explicit instruction instead of a confusing error. - Manage Patchbay from an agent. Built-in tools
patchbay__add_jack,patchbay__remove_jack,patchbay__list_jacks,patchbay__toggle_jacklet a connected agent add/remove/flip servers without you touching the config file. - Secrets encrypted at rest. API keys, bearer tokens and env vars are DPAPI-encrypted (tied to your Windows user account) the moment they're saved — no master password, no plaintext on disk.
- Two-tier logging. An always-on diagnostic log, plus an opt-in request/event log that records every MCP request and admin action with secrets redacted.
- Local only. Bound strictly to
127.0.0.1; no network exposure. The optional window UI (below) is a local webview that loads only embedded assets under a strict CSP. Spawned child processes are tied to a Windows Job Object so quitting Patchbay can never leave orphans behind.
Windows-only. Patchbay uses Windows DPAPI, the registry (autostart), Job Objects and the tray, so it targets Windows. The gateway protocol itself is cross-platform MCP, but the host side is not.
- Jack — one upstream MCP server registered in Patchbay (e.g. a GitHub MCP, a database MCP). Think of a patchbay's input socket.
- Patched — the jack is live: its tools are exposed through the gateway to every agent, prefixed with the jack name.
- Unpatched — the jack is off: its tools disappear from every agent immediately, and any call to one is rejected with a clear message.
After this, never edit agent configs again; toggle servers in Patchbay.
| Agent | How to point it at the gateway |
|---|---|
| Claude Code | claude mcp add --transport http patchbay http://127.0.0.1:39100/mcp |
| Codex | in ~/.codex/config.toml →[mcp_servers.patchbay]url = "http://127.0.0.1:39100/mcp" |
| Google Antigravity | in ~/.gemini/config/mcp_config.json → an entry with"serverUrl": "http://127.0.0.1:39100/mcp" |
| Kilo | in its MCP config →{ "type": "streamable-http", "url": "http://127.0.0.1:39100/mcp" } |
Edit the config file at %APPDATA%\Patchbay\patchbay.json. A fully commented
patchbay.example.jsonc is written next to it on first run for reference. Each
jack is either stdio (a local command) or streamable-http (a remote URL):
After editing, click Reload config in the tray.
- Secrets: type them in plaintext; Patchbay DPAPI-encrypts them to a
dpapi:-prefixed value on the next save, so only your Windows user account can ever decrypt them. The config on disk never keeps plaintext secrets. prodships unpatched (patched: false) — opt in explicitly.- Windows note: a
commandlikenpxornpmworks out of the box — Patchbay runs bare commands throughcmd /Cso the.cmdlaunchers npm installs on Windows resolve correctly.
Each jack's tools are exposed to agents as <jack>__<tool>
(e.g. github__create_issue).
Since 1.3.0 Patchbay has two user interfaces over the same state, and a setting chooses which one the tray icon drives.
ui_mode |
left-click the icon | right-click the icon |
|---|---|---|
tray (default) |
native menu | native menu |
window |
popover window | small menu: Show window / Reload config / Quit |
both |
popover window | native menu |
Switch it in Settings → Interface (tray) or on the Settings screen
(window). The default is tray, so upgrading changes nothing until you opt in.
Why a window exists. A Windows menu closes the moment you click anything in it. That is fine for a single blind toggle you already know the position of, and poor for everything else: you cannot see whether a checkbox actually moved, a server that takes a second to start has nowhere to report "starting…" or "failed: connection refused", and flipping four servers means opening the menu four times. The popover stays open, shows live state, and supports selection — so deleting sixty accumulated agent identities is one filter, one select-all and one click instead of sixty menu traversals. It is resizable by dragging any edge — width has a floor so the bottom bar's six links never wrap, height can shrink to about three server rows before the list scrolls, and there is no upper limit on either.
What the window shows.
- Jacks — one row per server with a real switch, its transport, its live tool count, and any failure written on the row with a Retry next to it. Turning on a production-class server asks first, inline in the row.
- Agents — every identity that has connected, with a live dot for the ones connected right now, filters (including Unused: never seen since first contact, or quiet for 30 days), multi-select, and bulk delete or deny with an undo strip. Open one to give it its own per-server permissions.
- Settings — interface, gateway port, autostart, the approval gate, request logging, and the config/log folders.
The window is created the first time you open it, so tray users never pay for
it. It needs the WebView2 runtime (present on Windows 11 and current Windows
10); if it cannot start, Patchbay logs why and falls back to the tray menu for
that session without changing your setting.
- One checkable row per jack — tick = patched (live), untick = unpatched (off, instantly). Toggling is reflected across every connected agent with no restart.
- Retry gateway — re-attempts binding the local port (use this if the tooltip
shows
GATEWAY FAILED, e.g. because port 39100 was in use at startup and has since freed up). - Reload config — re-reads
patchbay.jsonand reconciles jacks. - Open config file / Copy gateway URL — convenience helpers.
- Open logs folder — opens the folder holding Patchbay's log files.
- Enable request logging (in the Settings submenu) — toggles a second-tier log that records each MCP request/response with secrets redacted; off by default.
- Interface (in the Settings submenu) — chooses between the tray menu, the popover window, or both. See above.
- Start with Windows — toggles autostart.
- Quit.
The tray tooltip shows the patched/total counts and the gateway URL, or a
distinct Patchbay — GATEWAY FAILED: <reason> when the port couldn't be bound.
- Codex does not honor
tools/list_changed. After you PATCH a server, Codex won't see the new tools until its session restarts; and if you UNPATCH, a stale Codex call returns a clear "server is UNPATCHED — ask the user to enable it" message instead of the tool. Claude Code, Gemini CLI and OpenCode update live. - Namespacing. Tools are exposed as
<jack>__<tool>(e.g.github__create_issue); any per-agent allow-rules referencing the old bare tool names must be updated once. - Shared stdio child. One child process per stdio jack serves all agents — e.g. a browser-automation MCP shares one browser across Claude, Codex, etc.
- claude.ai connectors (Gmail / Calendar / Drive) are provided by claude.ai directly and cannot be routed through Patchbay.
- Unpatch = no NEW reachability. New calls are blocked instantly and a stdio child is killed; an already-in-flight remote HTTP request is best-effort.
This project builds under the Visual Studio 2022 BuildTools environment
(vcvars64.bat); the included _build.ps1 captures that environment and runs
the release build. A normal cargo build from a VS Developer Command Prompt
also works.
# Debug build + tests (from src-tauri)
cargo build
cargo test
# Optimized release binary (Rust toolchain only)
cargo build --release
# Windows NSIS installer (needs the Tauri prerequisites)
cargo tauri buildTargets: release binary < 12 MB, idle RAM < 40 MB in tray mode
(currently ~3 MB binary / ~16 MB idle RAM). Window mode adds a WebView2 process
once the popover has been opened at least once — the window is created lazily,
so a user who stays in tray mode pays nothing. Bound strictly to 127.0.0.1.
┌─────────────────────────────────────────────┐
Claude Code ──┤ │
Codex ────────┤ Patchbay gateway (axum + tokio) ├──► stdio jack (child proc)
Antigravity ──┤ http://127.0.0.1:39100/mcp │ e.g. npx some-mcp
Kilo ─────────┤ - per-agent session + notification stream │
│ - tools exposed as <jack>__<tool> ├──► streamable-http jack
│ - DPAPI-encrypted secrets │ e.g. https://host/mcp
└──────────────────────┬──────────────────────┘
│ Windows tray (Tauri v2)
▼
toggle jacks / per-agent perms
config: %APPDATA%\Patchbay\patchbay.json
state: %APPDATA%\Patchbay\patchbay.state.json
Patchbay speaks the Model Context Protocol
over Streamable HTTP. The gateway is hand-rolled (JSON-RPC on axum/tokio — no
generic SDK) so it controls session tracking and live tools/list_changed
notifications directly. See docs/architecture.md and
the user-facing ABOUT.txt.
- Architecture — modules, layers, key decisions.
- Security model — trust boundary, DPAPI, localhost binding.
- ABOUT.txt — full user-facing guide (every tray menu item).
- CHANGELOG.md — release history.
Issues and pull requests are welcome. Please read CONTRIBUTING.md first, and report security issues privately (see SECURITY.md) — do not open a public issue for a vulnerability.
Patchbay's tray/DPAPI/autostart/Job-Object integration patterns were adapted from an earlier Tauri v2 system-tray app by the same author.
MIT — see the file for details.
{ "version": 1, "port": 39100, "autostart": false, "jacks": [ { "name": "prod", "patched": false, "transport": "stdio", "command": "npx", "args": ["-y", "some-db-mcp"], "env": { "DB_TOKEN": "secret-token-here" }, "sharing": "shared" }, { "name": "docs", "patched": true, "transport": "streamable-http", "url": "https://example.com/mcp", "headers": { "Authorization": "Bearer xyz" } } ], "bays": {} }