A small native macOS menu-bar controller for local MTPLX daemons.
Switchboard starts and stops models independently, keeps stable OpenAI-compatible endpoints available while the app runs, reports actual scheduler and cache activity, and stays out of the way. It is a controller, not a chat application, model runtime, or model bundle.
| Model ready | Generation in progress |
|---|---|
![]() |
![]() |
Images use synthetic telemetry and contain no user data.
This repository is source-only. There is no prebuilt or notarized application to download.
Give the repository URL to a coding agent running on your Mac and use this prompt:
Inspect this repository and its scripts. Confirm that my Mac and MTPLX installation meet the prerequisites. Run the complete preinstall verification, explain any failure, and only then run
scripts/install-local.sh. Do not download models, change system settings, or remove existing files without asking me.
The agent should install the verified local build at:
~/Applications/MTPLX Switchboard.app
The build is ad-hoc signed for that Mac. Gatekeeper will not treat it as a notarized public release.
- Apple Silicon Mac running macOS 14 or newer
- Swift 5.9 or newer through Xcode or the Command Line Tools
- MTPLX installed separately; this revision requires exactly MTPLX 2.10.2
- MTPLX CLI at
~/Library/Application Support/MTPLX/runtime-venv/bin/mtplx,~/.local/bin/mtplx,~/.mtplx/venv/bin/mtplx,/opt/homebrew/bin/mtplx,/usr/local/bin/mtplx, or an explicitMTPLX_SWITCHBOARD_CLIpath - Enough unified memory and disk space for the models you choose
- Network access when downloading an official model from the catalog
- Optional: ThermalForge at
~/.mtplx/bin/thermalforge,/opt/homebrew/bin/thermalforge, or/usr/local/bin/thermalforgefor CPU/GPU temperatures
Switchboard does not install MTPLX or silently download model weights.
The initial configuration contains two local slots:
- Shiftedx Qwen 3.8 27B on
http://127.0.0.1:8000/v1 - Gemma 4 31B Heretic ARA on
http://127.0.0.1:8001/v1
Their expected model directories are:
~/.mtplx/models/Shiftedx--qwen3.8-27b-aeon-ultimate-uncensored-attention8-bf16recurrence-vision-mtplx
~/.mtplx/models/zecanard--gemma-4-31b-it-heretic-ara-mixed4_6-mtplx
Missing weights do not prevent the application from opening. That model simply cannot be loaded.
- Runs each model in a separately supervised MTPLX process
- Verifies PID, model path, launch identity, and ownership before destructive lifecycle actions
- Uses MTPLX's parent-death watchdog to avoid orphaned model processes
- Keeps each public
/v1endpoint stable through a lightweight in-process loopback gateway - Optionally loads a configured model on its first generation request, with one shared startup for concurrent callers
- Optionally unloads an idle model after a configurable interval; enabling load-on-request initially proposes five minutes
- Finishes accepted requests before normal Unload, Reload, reload-requiring settings changes, and Quit; waiting can be cancelled
- Copies each model's local
/v1endpoint with one click - Shows prefill, decode, queue, real batch width, memory, swap, SessionBank, SSD-cache, fan, and thermal telemetry when MTPLX publishes it
- Keeps the panel lazy and stops RAM/thermal subprocess sampling while it is closed; daemon health polling backs off when everything is offline
- Keeps RAM SessionBank policy automatic;
Keep contextscontrols SSD persistence only - Supports independent model settings and independent expandable cards
- Offers 22 Youssofal-published MTP artifacts from the MTPLX 2.10.2 catalog
- Downloads only after an explicit click, then requires
mtplx inspect --require-mtpbefore registration - Permits one additional catalog model and can move its verified managed-cache directory to Trash
- Provides native
mtp_batchonly for the exact qualified Qwen 3.6 35B-A3B Optimized Speed artifact
Left-click the menu-bar item for the main panel. Right-click it for Load all, Unload all, restore, login-item, and Quit actions.
- Load-on-request works only while Switchboard is running and the model's Automation setting is enabled. Existing configurations default to manual loading with idle unloading off.
- Generation requests to a stopped model return 503 when load-on-request is disabled.
/v1/modelsdiscovery never loads a model; unloaded discovery uses its configured Switchboard ID as a chat alias. Live MTPLX responses may use the runtime's native model ID. - Public gateway ports and private MTPLX upstream ports bind only to
127.0.0.1, without an API key. Other local processes can reach them and, when enabled, trigger model loading. They are not exposed to the LAN by default. - Configure clients with the public endpoint shown in the card, never a private upstream port. Private ports are launch-scoped implementation details. Drain guarantees cover gateway-routed requests; direct private callers have only best-effort activity protection.
- Normal shutdown waits rather than silently force-killing active work. Missing or stale activity evidence is not proof of idleness. OS force-quit, crashes, and external process manipulation cannot promise request completion.
- The gateway is a bounded HTTP/1.1 relay, not a general web proxy: one request per connection, no CONNECT/upgrades/pipelining, and a client FIN after upload is treated as cancellation. Generation routes are
/v1/chat/completions,/v1/completions, and/v1/responses; public MTPLX mutation routes and/v1/messagesare not exposed. - Request bodies are limited to 16 MiB, with a shared 64 MiB buffered-request budget and 32 connections. Each model has at most eight queued admissions and a 150-second admission deadline. Transport inactivity is bounded independently of model output length; requests are never automatically replayed.
- The catalog is a pinned copy of MTPLX 2.10.2 metadata, not a live marketplace.
- The bundled Gemma slot uses MTPLX's
--unsafe-force-unverifiedpath because that derivative remains family-compatible but not broadly qualified. - Native batching is not generic. Only the exact supported A3B package receives the fixed Turbo/D1/128K batch contract.
- Flash-Next uses its own D1–D5 control range and requires KV precision Off.
- Switchboard does not verify model-file cryptographic digests independently; repository identity, canonical cache location, and MTPLX inspection are the current gates.
- Ad-hoc signing is suitable for a local source build, not public binary distribution.
Expand a model card and open Automation. Enable Load on request and choose an idle-unload interval, or Off. Apply saves these policies without reloading a running model. Discovery and telemetry polling do not keep a model warm.
Idle unloading waits for accepted requests to finish and for fresh, owned daemon activity to prove idle. It discards RAM-only contexts; enabling Keep contexts separately allows MTPLX's supported SSD persistence. Unload and Quit show a waiting state while work finishes, with cancellation available. Automatic unloading is not batching: dense Qwen and Gemma still use serial MTP.
Configuration ~/Library/Application Support/MTPLXSwitchboard/config.json
Recovery ~/Library/Application Support/MTPLXSwitchboard/config.invalid-*.json
Logs ~/Library/Logs/MTPLXSwitchboard/
Models ~/.mtplx/models/
Daemon logs rotate at 10 MiB. An unreadable configuration is moved aside before defaults are written; Switchboard does not silently destroy it.
Switchboard has no analytics and sends no project telemetry elsewhere. It stores model settings and paths in the configuration file, launch identities in macOS preferences, and MTPLX process output in local logs. MTPLX logs may contain model paths, session identifiers, diagnostics, and short output previews; do not publish them without inspection. RAM and SSD context snapshots are maintained by MTPLX rather than copied into this repository.
Switchboard uses the network only when you explicitly start a catalog download through MTPLX. Normal model serving, health checks, settings, and telemetry stay on loopback. The downloaded repository and its upstream hosting service retain their own data and licensing policies.
Ask your coding agent to disable Launch at Login, unload the models, quit Switchboard, and run:
./scripts/uninstall-local.shThe script unregisters the login item through the exact installed application, then removes that application. If the bundle or helper is already missing or damaged, it stops with an actionable partial-removal error rather than claiming that Launch at Login was removed. Configuration, logs, model weights, and previous application backups remain unless you explicitly remove them.
The project is a dependency-free Swift package using AppKit NSStatusItem/NSPopover with a SwiftUI interface.
swift test
python3 scripts/test-command-safety.py
./scripts/verify-preinstall.shverify-preinstall.sh builds into .build, runs unit and synthetic UI/lifecycle-control smokes, assembles an app, and verifies its ad-hoc signature. Its subprocesses have bounded deadlines. The optional live ThermalForge/ioreg integration check runs only when explicitly requested with ./scripts/verify-preinstall.sh --live-hardware; it is not an installation gate. Live lifecycle smokes can launch large models and are intentionally not part of ordinary CI.
README images are deterministic fixtures. Regenerate them after a verified build with:
".build/app/MTPLX Switchboard.app/Contents/MacOS/MTPLXSwitchboard" \
--render-readme-assets docs/assetsMTPLX Switchboard's source is available under the Apache License 2.0, matching MTPLX. Copyright and attribution notices are in NOTICE. MTPLX remains a separately installed project. ThermalForge, model repositories, and downloaded weights retain their own licenses and terms. See THIRD_PARTY_NOTICES.md.
This is an independent companion project and is not an official MTPLX distribution.
- Work from the repository root and inspect the scripts before executing them.
- Confirm Apple Silicon, macOS, Swift, MTPLX 2.10.2, CLI location, free disk, and configured model paths.
- Run
scripts/verify-preinstall.sh; stop on any failure. - Run
scripts/install-local.shonly after verification succeeds. - Never download models, alter system power/memory controls, or delete retained settings and weights without explicit permission.
- Report the installed path, signature result, and anything still missing.


