Phonebase speaks MCP over two transports. Both publish the same tool surface,
so the config block is the only thing that differs.
- HTTP talks to a control plane over the network, at
POST /mcp.
- stdio spawns the control plane as a local child process and talks to it
over its standard input and output.
Pick HTTP unless your client can only spawn processes. See
Transports for the behavioural differences that follow from
this choice.
HTTP against a local control plane
Start the control plane first. It listens on loopback and reads its device
rows from your machine.
Then give your client the endpoint:
PHONEBASE_DEV_TOKEN is the local development credential. Set it, and the
endpoint requires that exact value as a bearer token. Leave it unset, and the
endpoint accepts unauthenticated requests, which is safe only because local
mode refuses to bind anywhere but loopback.
Local mode grants every scope. It is a single operator on a single machine,
not a permission model. Do not expose that port.
stdio
Your client spawns the process and owns its lifetime. There is no port, no
token, and no header.
Two things follow from the process boundary being the trust boundary:
- stdio serves local mode only. A process configured for hosted tenancy
refuses to start over stdio, because it would be a second control channel
past every check the HTTP endpoint performs.
- Device rows are read once, at startup. Editing them with
phonebase rows needs a client restart, unlike the HTTP server, which reads
rows on every request.
The stdio process also binds an ephemeral loopback port for the agent tier’s
device channel, unconditionally, even in a session that never starts a run.
That port is loopback only and is guarded by a run token, but it is there.
Connecting a hosted control plane
The hosted control plane lives at https://mcp.phonebase.co/mcp. Phonebase is
onboarding design partners, and keys are issued through
phonebase.co. See
Getting a key.
A hosted control plane replaces the development token with one of two real
credential channels:
Most clients cannot expand an environment variable inside a config file, so
paste the key value itself. With Claude Code, one command does it:
The endpoint’s protected resource metadata names Clerk
(https://clerk.phonebase.co) as its authorization server. That server offers
no dynamic client registration, so a client that tries to register itself and
open a browser sign in has nothing to register with, and a browser flow from a
generic MCP client has not been verified end to end. Use an API key. See
Authentication.
Keep the client entry named phonebase. This site’s docs MCP server is a
different server with a different name, and you want to be able to tell them
apart in a client list. See For agents.
Checking the connection
The MCP Inspector talks to the endpoint without a client in the way:
Call list_devices first. It needs no lease, so it answers immediately, and
what it returns tells you whether the control plane can see your hardware.
If the tool list looks shorter than you expect, that is authentication rather
than a fault: a tool your credential is not scoped for is never registered, so
it does not appear at all.
Two things clients get wrong
Host and origin are checked. The HTTP transport refuses requests carrying
a browser Origin header, and accepts only the host it was configured for.
Without those checks any web page could rebind its own hostname to loopback
and drive your device. A client that sets a browser style origin will be
refused.
GET and DELETE on /mcp return 405. The endpoint is stateless: there
is no stream to resume and no session to tear down. Post your requests.