Switchboard
Switchboard is a directory and an encrypted task mailbox for sharing selected local agent sessions with permitted people in your workspace. Readable prompts, answers and transcripts never leave the harness on the Mac that ran them — the hosted service routes opaque ciphertext between permitted devices and stores nothing it can read.
Switchboard is in alpha. Calls between separate signed-in Macs have completed end to end. Treat every other path as pilot material.
How it works
flowchart LR
UI[Switchboard Web App<br/>or Desktop App]
U[Caller asks a question] --> H[Caller harness<br/>any supported harness]
H <-->|MCP over local stdio| L[Local MCP server]
L <-->|local loopback| C[Caller Local Connector]
UI -.->|local service health and sharing controls| L
UI -.->|identity, pairing and sharing controls| M[Switchboard Network Backend<br/>directory, grants, opaque mailbox]
C -->|signed encrypted envelope over HTTPS| M
M -->|opaque ciphertext only| W[Owner Local Connector<br/>and mailbox worker]
W -->|decrypt + recheck grant and policy| A[Local A2A task and harness adapter]
A --> S[Owner source session<br/>or caller-isolated continuation]
S --> A
A -->|encrypted result follows the reverse path| H
| Component | What it does | Where |
|---|---|---|
| Switchboard Web App | Authenticated browser UI: directory, sharing, inbox, settings | switchboard-control behind Cloudflare Access |
| Switchboard Desktop App | Companion app: onboarding, agents, contacts, wallet and service controls | apps/desktop (Tauri: Rust + React) |
| Switchboard Network Backend | Hosted control plane: identity, grants, opaque mailbox routing, credit ledger | switchboard-control, Docker + PostgreSQL |
| Local Connector | Discovers local harnesses, enforces the answer-only policy, runs the mailbox worker and local MCP server | src/switchboard/local, supervised per platform (LaunchAgent, systemd user service, Scheduled Task) |
Getting started
Open the dashboard
Your workspace administrator runs the Switchboard Network Backend and has the dashboard URL. Sign in with a permitted account and continue to the workspace. Workspace membership admits you to the directory; each agent's owner still chooses who may call it.
Set up a machine
The desktop app is the easy path: it checks for uv, installs the connector,
registers your harnesses, runs the Verified A2A sign-in, pairs the machine and
starts the resident service. No source checkout is involved.
cd apps/desktop && pnpm install && pnpm tauri build # then open the built app
Prefer the terminal? The same steps, on macOS and Linux alike:
uv tool install "switchboard-connector[qedb]" # installs the `switchboard` CLI
switchboard install --switchboard-url <url> # harnesses, Verified A2A, resident service
switchboard pair --device-name "my machine"
The PyPI distribution is switchboard-connector (the name switchboard belongs
to an unrelated project); the command it installs is switchboard. Update it
later with uv tool upgrade switchboard-connector.
install sets up a LaunchAgent on macOS, a systemd user service on Linux and a
Scheduled Task on Windows; switchboard start, stop, status and uninstall
manage it afterwards. Only the pair sign-in and the Share approval are manual, by
design.
The control-plane address is set once per machine with
switchboard install --switchboard-url <url> and stored locally; the connector
worker and the harness-launched MCP both resolve that single setting, so they
cannot point at different servers.
Linux notes
switchboard install writes ~/.config/systemd/user/switchboard.service; run
loginctl enable-linger "$USER" to keep it running while you are logged out,
and journalctl --user -u switchboard to read its log. The device credential
and mailbox keys live in the macOS Keychain; on Linux they are 0600 files
under ~/.local/state/ProvablySwitchboard/, protected by your disk encryption.
Windows
Windows runs Switchboard natively: switchboard install registers a per-user
Scheduled Task that starts the connector at logon and restarts it if it fails,
needing no elevation. Credentials are files under your profile directory, where
Windows' own ACL keeps other standard users out. switchboard start, stop,
status and uninstall drive the task exactly as they drive the service
elsewhere.
Two caveats. Harness CLIs installed by npm or bun are .cmd shims, which
Switchboard runs through cmd.exe — this path gets less real-world use than the
Unix one, so report anything that misbehaves. And Hermes Desktop's automatic
gateway discovery needs ps and lsof, so on Windows set HERMES_API_URL
instead.
Windows (WSL2)
WSL2 is the alternative, and the better-travelled one: it is the Linux path above, with two requirements.
-
Enable systemd, so
switchboard installcan manage the service. Add this to/etc/wsl.conf, then runwsl --shutdownfrom Windows:[boot] systemd=true
Without it,
switchboard installsays so and you runswitchboard runin the foreground instead. -
Install your harness CLIs inside the same distribution. Switchboard discovers sessions from the Linux home directory, so CLIs installed on Windows are invisible to it.
WSL forwards localhost, so the dashboard in a Windows browser still reaches the
approval bridge on 127.0.0.1:8766.
Platform support
| Platform | State |
|---|---|
| macOS | Supported: desktop app or CLI, LaunchAgent service, Keychain credentials |
| Linux | Supported: desktop app or CLI, systemd user service, file-backed credentials |
| Windows | Supported: desktop app or CLI, Scheduled Task service, file-backed credentials under the user profile. Less exercised than the others; WSL2 is the safe alternative |
Self-host the control plane
The hosted control plane (identity, directory, mailbox routing, credit
ledger) lives in the separate
switchboard-control
repo — see that repo's README for docker compose up self-hosting.
Security model
- The Network Backend routes and revokes deliveries; it never sees a prompt, an answer or a transcript. Envelopes are opaque ciphertext at rest.
- Sharing is one atomic action: the owner's fixed answer-only policy installs locally before a share can be created, and the mailbox worker rechecks the grant and policy before every invocation.
- Revocation blocks future delivery immediately. It does not rewrite either person's local transcript.
- Verified A2A (optional, QEDB-backed) adds route-and-record-integrity proofs, shown as green, orange or red marks on an answer.
- Private caller (opt-in per share) shows the owner a caller-chosen alias instead of an account identity. The alpha credit ledger settles each answer in one double-entry transaction.
Development
Requires Python 3.12+ and uv. Verified A2A needs
the qedb extra, which pulls sourcerykit from PyPI.
uv sync
make check # pre-commit, full test suite, build — the CI gate
Common targets: make lint, make format, make typecheck (strict mypy on
src), make test.
src/switchboard/
├── harness/ adapters for Codex, Hermes, Claude Code, OpenCode and OpenClaw
├── local/ the resident service: CLI, connector, approval bridge, policy
│ ├── owner_app/ the owner-local A2A app (task API, agent cards, state, web UI)
│ ├── mcp/ the harness-facing MCP server and its remote calls
│ ├── policy/ owner policy authoring and enforcement
│ └── skills/ the switchboard-ask skill installed into every harness
├── mailbox/ envelope crypto, client and worker, commitments, QEDB ledger
├── qedb/ A2A task store, task proofs and the A2A profile
└── verified_sources/ narrow read-only SourceryKit-backed sources
apps/desktop/ Tauri desktop companion app
scripts/ MCP launcher and the verified-A2A smoke test
docs/ harness registration and session publishing
tests/ mirrors src/switchboard
The hosted control plane (control/) lives in the separate
switchboard-control repo
— users installing this repo never pull down that server-side code.
Releases
The connector and the desktop app ship separately, each from its own tag, so a fix to one never forces a version bump of the other. Both refuse to run if the tag disagrees with the version in the manifest, and both leave a draft release for you to read before anyone sees it.
| What | Tag | Produces |
|---|---|---|
| Connector wheel | connector-v0.1.0 (matches pyproject.toml) |
dist/* on the release, then PyPI |
| Desktop app | desktop-v0.1.0 (matches tauri.conf.json) |
.dmg, .deb, .AppImage, .msi, .exe |
git tag connector-v0.1.0 && git push origin connector-v0.1.0
git tag desktop-v0.1.0 && git push origin desktop-v0.1.0
PyPI publishing waits on the pypi GitHub environment and uses trusted
publishing, so there is no token in the repo: configure the publisher once on
PyPI (project → Publishing → GitHub, workflow release-connector.yml,
environment pypi), and add a required reviewer there if you want publishing to
be a deliberate click.
Both workflows also run from the Actions tab, where they build and attach the artifacts to the run without creating a release or publishing anything — that is how to test a build, or to get a single platform's installer. The desktop one asks which platforms to build; Tauri cannot cross-compile, so each runs on its own runner.
Neither build is signed yet: macOS Gatekeeper blocks the .dmg and Windows
SmartScreen warns on the installer until signing and notarization are set up.
License
Business Source License 1.1 — see LICENSE.md. You may not offer the Software as a commercial hosted service without a commercial license from Provably Technologies Ltd. On the change date the license converts to GPL-3.0-or-later.
Release files for switchboard-connector 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| switchboard_connector-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / switchboard_connector-0.1.0-py3-none-any.whl
| Download URL | switchboard_connector-0.1.0-py3-none-any.whl |
|---|---|
| Size | 181.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0cd7df5dc90342b1105d5ee0f2c8b2803743b38815b8b3c54d69df3a90a88374
|
|
BLAKE2b-256 checksum How to use checksums |
47928876aca479256f2176bac7e11069314963465c1b89036c145aaf14b6ef9d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency log