For AI agents
Switchboard speaks MCP, so Claude Code, Codex, Cursor and anything else that talks the protocol can operate it directly — check what is wrong, send a message, ask whether it arrived, and link a new number.
Hosted — nothing to install#
The server runs at https://switchboard.atrix.dev/mcp. Point a client at it and pass your key.
claude mcp add --transport http switchboard \ https://switchboard.atrix.dev/mcp \ --header "Authorization: Bearer <project-key>" \ --header "X-Switchboard-Root-Key: <root-key>"
Or, for any client that reads an MCP config file:
{ "mcpServers": { "switchboard": { "type": "http", "url": "https://switchboard.atrix.dev/mcp", "headers": { "Authorization": "Bearer <project-key>", "X-Switchboard-Root-Key": "<root-key>" } } } }
The hosted server holds no credentials
Local — stdio#
If you would rather not route through the hosted endpoint, the same server runs as a local process.
claude mcp add switchboard \ --env SWITCHBOARD_KEY=<project-key> \ --env SWITCHBOARD_ROOT_KEY=<root-key> \ -- npx -y @atrix.dev/switchboard-mcp
SWITCHBOARD_URL is optional and defaults to the live deployment. The key is read from the environment and never from an argument — a key on the command line lands in shell history and in every process listing on the machine.
Which key#
| Key | What an agent can do with it |
|---|---|
| Project key | Its own numbers: send, check whether a message arrived, link a new number. |
| Root key | All of that across every project, plus onboarding, undelivered events and discarding. |
Switchboard refuses the root key on the tenant surface and a project key on the operator surface, so one key covers only half the tools. Give the server both and it picks the right one per call. With only one, everything it can reach still works and the rest says which key it needed — rather than repeating the API’s deliberately ambiguous not authorized.
The two things agents get wrong#
Sent is not delivered
Linking a number always needs a person. Someone holding that handset has to scan a QR code; there is no remote path and no amount of retrying creates one. The pairing tool returns the code three ways — a PNG for clients that render images, a block-character version that prints in a terminal, and the raw payload — so it works over SSH as well as in a chat window. Codes expire after about a minute; ask for a fresh one rather than reusing an old image.
Never poll a linked number for a QR code
Destructive tools#
Discarding undelivered events removes them permanently. Called without confirm it only counts them and changes nothing, so the size is known before anything is committed. It is annotated destructiveHint so a client can require approval, and every confirmed discard is written to an audit trail kept for a year.