Switchboard
Integrates with Apple Home through a HomeKit relay and with Apple Calendar and Reminders via EventKit, enabling home control and calendar/reminder access.
Optional native macOS helper that holds macOS privacy grants for Calendar, Reminders, Things automation, and Local Network, answering fixed requests over a Unix socket.
Provides media search and read access to Plex libraries, with related media request workflows routed through Seerr.
Provides an SSH forced-command remote host agent for a Raspberry Pi or second machine, exposing status, logs, diagnostics, allowlisted restarts, and package-list refreshes without shell access.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Switchboard
Agent harnesses come and go. Your home's tools, rules and context shouldn't have to.
The problem
If you run a home server and use AI agents, you probably use more than one:
Claude Code or Codex in a terminal;
a chat assistant on your phone;
a voice gadget on the counter;
whichever new harness launched this month.
Each one wants its own way to reach your stuff, and each one has to be taught again:
which Plex library is which, and which API key goes where;
that requests go through Seerr and never straight to Sonarr;
that the garage door needs a confirmation;
that one service is slow because its data sits on a USB disk, and isn't actually down.
That knowledge ends up scattered across prompt files, MCP configs, shell history and one-off scripts. It drifts apart, it leaks credentials into places they shouldn't be, and it's gone the day you switch tools. Meanwhile every agent improvises with curl, docker logs and ssh, does the same chores by hand over and over, and has as much access as your shell does.
The harness is the part that changes fastest. What should stay put is everything else:
the capabilities: what can actually be done;
the rules: who may do what, and what needs a human's yes;
the context: names, preferences and conventions;
the operational memory: what's running, what broke, and what was tried.
Related MCP server: Qevyra
The idea
Switchboard is that stable layer. It's one local service on your server, and every agent plugs into the same typed capabilities through whichever door it supports: MCP, a JSON CLI, or HTTP on loopback.
Write a capability once and every agent gets it. Today's agent, tomorrow's and your phone assistant all call the same
media_search,home_setorops_service_logs, with the same inputs, outputs and error shapes.Keep policy in one place, not in prompts. Each agent gets its own token and scopes. Sensitive actions need an exact, single-use approval, which only the owner (or a client explicitly trusted to collect the owner's confirmation) can grant. Every call is audited, and secrets stay in owner-only files the agents never see.
Keep context in one place too. Shared owner context resolves your names for things: "living room lights", "the bedroom TV", your Things projects. Skills explain the workflows in plain text, and one rules file is synced into every agent's global instructions on deploy, so a new harness learns the house in seconds.
Let it maintain itself. It monitors your services and alerts you by phone and email. Slow-but-alive services can get longer timeouts and higher failure thresholds so they don't page you. A dead-man heartbeat to a second machine catches the case where the whole server dies. Agents report broken or missing tools to a shared issue queue, and they're expected to improve Switchboard itself: it's built to keep evolving, not to be set up once.
Swap harnesses freely. When a new agent tool appears, register one MCP server or point it at the CLI, give it its own token and scopes, and it inherits everything.
It started as one person's home setup, a Mac mini and a Raspberry Pi shared by Claude Code, Codex, Antigravity, ChatGPT and a small ESP32 voice device. If you're juggling several agents on one box, you probably have the same problem.
What's in the box
Core: a Python service on
127.0.0.1:18800with a typed registry. Per-client scopes, resource allowlists, approvals, jobs, durable state and an audit log apply the same way to MCP (stateless 2026-07-28, plus legacy initialization), HTTP and the CLI. A stdio bridge serves harnesses that only speak stdio.Integrations (each optional):
service health probes, monitoring and alerts with self-ending silences;
service status, logs and restarts, plus host snapshots;
Plex, Tautulli and Seerr reads and requests;
LazyLibrarian books;
Apple Home, through a HomeKit relay app;
Calendar and Reminders (EventKit) and Things 3;
NWS weather;
shared owner context, an issue queue and federation to an MCP device hub.
Native macOS helper (optional): a small signed app that holds the macOS privacy grants that a launchd Python service can't get: Calendar, Reminders, Things automation and Local Network. It answers a fixed set of requests over a Unix socket.
Remote host agent (optional): one fixed command set reached over an SSH forced command for a second machine, such as a Raspberry Pi. It covers status, logs, diagnostics, allowlisted restarts and package-list refreshes, with no shell.
Skills and agent rules: plain-text workflow guides, linked into each agent's skills folder on deploy.
Each integration needs its own backend; this is not a bundle of those services.
See the capability catalog, example config, example policy, contributor guide, roadmap and workflow skills.
Quick start
Requires Python 3.13+; the native helper additionally needs macOS and the Swift build tools. Runtime Python dependencies are aiohttp and PyYAML.
python3 -m venv .venv
.venv/bin/pip install -e '.[dev]'
mkdir -p ~/.config/switchboard
chmod 700 ~/.config/switchboard
cp config/config.example.yaml ~/.config/switchboard/config.yaml
cp config/policy.example.yaml ~/.config/switchboard/policy.yaml
chmod 600 ~/.config/switchboard/config.yaml ~/.config/switchboard/policy.yamlEdit those private files first: remove sample probes you do not run, disable
unused backends and reduce client scopes and allowlists to what you need.
Weather is disabled without a location; enabling it requires name, a five-digit
zip, numeric lat and lon. Tools use the configured location. Maintenance
snapshots and compression are disabled without explicit deployment paths.
Secret config values are file paths, never inline credentials.
Provision only the client identities you intend to use:
.venv/bin/sb token create owner
.venv/bin/sb token create codex
.venv/bin/sb serveToken creation prints a path, never the credential. Tokens are owned regular
0600 files in a 0700 directory. Removing a token revokes it on the next request;
sb token list lists identities and sb token revoke codex revokes one.
In another terminal:
.venv/bin/sb --client codex list
.venv/bin/sb --client codex call ops_health --json '{}'
.venv/bin/sb doctor
.venv/bin/sb manifestCLI calls default to the owner credential. Agents must select their own identity
with --client; the flag selects a token, not a claimed server-side identity.
The stdio adapter requires an explicit client:
~/.local/share/switchboard/current/.venv/bin/sb mcp-stdio --client codexRegister that deployed absolute executable path and arguments in your agent's MCP configuration. See Dot integration for the tunnel workflow. No public listener is needed. Skills are guidance and grant no permissions.
Configuration defaults to ~/.config/switchboard/; override with
SWITCHBOARD_CONFIG_DIR. State defaults to ~/Library/Application Support/switchboard
and logs to ~/Library/Logs/switchboard, overridable with SWITCHBOARD_STATE_DIR
and SWITCHBOARD_LOG_DIR. Runtime directories must be 0700. No policy file means
no authorized calls, including for owner.
Deployment on macOS
Use a reviewed committed revision for deployment. scripts/deploy.sh requires a
clean checkout, runs checks, builds an immutable release, switches current
atomically, restarts the configured launchd job and checks health. It restores
the previous release on a failed health check. The newest five releases are kept.
It also links skills into supported agent directories and runs
scripts/sync-agent-rules.py, which updates marked blocks in agent instruction
files under Path.home(). Review those targets before first deployment.
Both deployment and native-build scripts source the optional private
~/.config/switchboard/deploy.env. It must be an owned regular non-symlink file
with mode 0600, otherwise the scripts refuse it. It is shell code; only the
owner should edit it. For example:
SWITCHBOARD_LABEL=com.example.switchboard
SWITCHBOARD_EVENTKIT_LABEL=com.example.switchboard.eventkit
SWITCHBOARD_BUNDLE_ID=com.example.switchboard.eventkit
SWITCHBOARD_SIGN_IDENTITY='Developer ID Application: <identity>'
SWITCHBOARD_PYTHON=/absolute/path/to/python3The service label defaults to com.example.switchboard. The deployment Python
default is pinned in scripts/deploy.sh; override it for your installed runtime.
SWITCHBOARD_DEPLOY_ROOT optionally replaces ~/.local/share/switchboard.
The helper label is for owner installation of the helper template; deploy does
not install or restart the helper. Existing deployments should keep their private
labels, bundle ID and signing identity to preserve launchd and macOS privacy grants.
Copy the service template to a private file
under ~/Library/LaunchAgents/<label>.plist. Replace __HOME__, __RELEASE__
(the stable current path) and __LABEL__ with absolute values. The template
passes the configured label into the service environment for self-restart
protection. launchd does not expand ~. Create the private config and log
directories with the required modes, then install the reviewed job with
launchctl bootstrap gui/$(id -u) <absolute-plist-path> and kickstart its label.
scripts/deploy.sh
scripts/deploy.sh --status
scripts/deploy.sh --rollbackOnly the deployment script should change the running Python release. MCP
registrations, launchd and skill symlinks must point at current, not a checkout.
Optional native helper and remote host agent
Build the helper with scripts/build-eventkit.sh. Set a stable signing identity
and bundle ID in private deployment settings before installing it. The script
sets the built app's bundle ID before signing; the source plist stays generic.
Ad-hoc signing is available for development but re-signing can invalidate grants.
The app is built under native/build/Switchboard EventKit.app.
Use the helper template with its own
__LABEL__ and an absolute __RELEASE__ path containing the built app. Enable
backends.eventkit only after installing the helper. Calendar/Reminders access,
Things Automation and Local Network permission are independent macOS grants.
Only the local owner, present to answer prompts, may run:
sb eventkit status
sb eventkit request-access
sb things status
sb things request-access
sb net request-accessThe helper uses an owned 0600 Unix socket in a 0700 directory and checks same-UID peers. Things can be enabled independently and uses the same socket. Its fixed compiled AppleScript receives descriptor arguments; user text is not source code. Task writes require policy destinations; checklist and Evening creation are currently unsupported. See the task workflow.
RFC1918 probes route through the helper when enabled; loopback probes stay in
Python. Privacy denial produces unknown rather than a false device-down alert.
For remote hosts, follow the Pi agent setup: fixed requests,
restricted SSH keys, pinned host keys and no shell, forwarding, pairing or reboot.
Monitoring and results
ops_health probes the configured non-finance service list concurrently and
caches results for 15 seconds. HTTP below 500 is up, 500+ is degraded, and
connection/TLS/timeouts are down. Continuous monitoring is opt-in and persists
incident state, reminders, recovery notifications and delivery retries. Configure
ntfy and/or STARTTLS email with private secret files and explicit delivery-host
allowlists. An optional private heartbeat URL file sends a native RFC1918 ping.
Doctor checks setup without sending notifications.
Before planned maintenance, use ops_alerts_silence with the configured probe;
service-restart tools automatically silence linked probes and enforce a durable
cooldown. ops_alerts_status reports incidents, silences and delivery backlog.
Results include status, outcome, source and as_of; lists report truncation.
Acceptance means a request/job was accepted, not that downstream work finished.
Poll returned job IDs. Weather reports observation time and stale cache age;
external prose is untrusted data. See each skill for workflow-specific limits.
Security model
Authentication derives identity from the bearer token. Every call, even to a tool hidden from discovery, validates a closed schema and current policy. Unknown or missing policy fails closed. Scopes and resource rules both apply.
Approval grants bind the exact client, capability and canonical arguments, expire, and are atomically consumed before execution, including failures. Notification answers alone grant nothing. Only owner CLI resolution or an explicitly trusted client's confirmation path resolves a grant.
Every capability call is audited in SQLite and redacted JSONL. Credentials, request headers, backend bodies and arbitrary exception text must not be logged.
The server rejects non-loopback peers/Host and Origin headers. Local backend URLs use HTTP literal loopback addresses. Probes accept loopback and RFC1918; remote hosts additionally accept RFC 6598 shared space. No broader private-IP classification is used. Backend redirects and environment proxies are disabled; NWS has a separate fixed HTTPS origin and bounded same-origin redirects.
No generic shell/exec, raw HTTP passthrough, finance/trading, credential exposure, Docker socket, device pairing, OTA or reboot capabilities are permitted.
The owner controls policy, tokens and deployed binaries. A process with that user's filesystem access can bypass this boundary. Routine clients should get only their own credential and the public adapters.
Development and publication
PYTHONPATH=src .venv/bin/sb manifest --markdown > docs/CAPABILITIES.md
PYTHONPATH=src .venv/bin/python -m pytest -q
.venv/bin/ruff check src tests
.venv/bin/ruff format src tests
(cd native/SwitchboardEventKit && swift test --cache-path ../build/cache --disable-sandbox)Tests use fake backends and temporary files, never live mutations or services. See AGENTS.md for registry, policy and schema requirements.
Nothing personal belongs in the public repository: no home addresses, owner
names, credentials, personal filesystem paths or deployment identifiers. Use
private configuration and AGENTS.local.md for deployment notes. Snapshot
publication honors .oss-export-exclude; private history is not the public tree.
Run the publication privacy checker on the export before publishing.
Licensed under MIT.
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Zero-secret MCP gateway for AI agents: risk-scored, audited calls with human-in-the-loop approval.
Credential broker for AI agents: scoped, revocable API access with policy enforcement and audit.
Governed AI agent skills — one library, distributed to devs and exposed to remote agents over MCP.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceA local-first MCP server that lets AI agents use gated APIs without holding keys, enforcing declarative policies, injecting secrets server-side, and auditing access without content.2Apache 2.0
- FlicenseNot gradedqualityBmaintenanceGives AI agents a single MCP interface to discover, inspect, scope, and execute external capabilities—downstream MCP servers, HTTP APIs, and local tools—resolved on demand from a local index instead of preloaded catalogs. Enforces agent scopes, allow/ask/deny policies, health gates, and schema snapshots at execution time, with local execution traces.-
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients and AI agents to discover and invoke only explicitly authorized, resource-bounded operational capabilities through a policy-enforced gateway with confirmation, audit, and isolated executor routing. It separates trusted transport identity from execution and supports declared tools over stdio MCP without exposing generic shell or privileged API surfaces.Apache 2.0

tremelay-mcpofficial
FlicenseBqualityAmaintenanceEnables AI agents to list, describe, and invoke scoped capabilities so they can perform brokered HTTP or SSH operations without ever receiving the underlying credential. All uses are deny-by-default, revocable, expiring, and recorded in a hash-chained audit log.31-