MCP
Dial speaks the Model Context Protocol two ways, so an agent can reach Dial’s capabilities as MCP tools without writing any HTTP code:
- Local (Recommended) —
npx @getdial/cli mcp, a stdio server you run on your own machine. It reuses the API key already saved bydial onboard, andnpxruns it without a global install. Use it when the agent runs on the same machine as your Dial setup — for example, Claude Code. - Remote — a hosted server at
https://getdial.ai/mcp. Point any MCP client that supports remote servers at that URL and authorize in the browser — no install, no API key to copy. Use it when the agent runs off your machine, like a web or desktop client — for example, Claude Chat or Claude Cowork.
Both expose the same operational tools under the same names (send_message,
place_call, wait_for_event, …), each mirroring a dial CLI command. The Local server is
a strict superset: everything Remote has, plus enhanced inbound capabilities the hosted
server can’t offer (a persistent listen daemon, local event fan-out, and onboarding).
Which one?
Pick Local when the agent runs on the same machine that owns the Dial setup and you want onboarding, the background listen daemon, or local event fan-out. Pick Remote when you want browser auth and the agent runs off-machine.
Connect
Add Dial as an MCP server in your client. The two transports take different config — both expose the same tools:
Local runs the CLI’s stdio server through npx — no global install. It authenticates
with the key already at ~/.local/share/dial/auth.v1.json (no OAuth, no config), so install
the CLI and sign in once first (see
Install & onboarding) — or let the sign_up
and onboard tools bootstrap a fresh machine from inside the agent. The server speaks
JSON-RPC on stdout and logs to stderr.
Remote points at the hosted server over Streamable HTTP at that single endpoint — there is no SSE or stdio variant. On first connect the client opens a browser to authorize:
The client requests access
It registers itself with Dial automatically (OAuth 2.1 dynamic client registration) and opens Dial’s consent page.
Tokens are scoped per account: a tool only ever sees your own numbers, messages, and calls.
Tools
The operational tools are identical on both servers; the enhanced inbound capabilities run only under the local server. See the CLI command reference for the underlying semantics.
When a tool that sends from a number omits fromNumberId, Dial uses your primary number.
A couple of tools behave slightly differently per server: wait_for_event reads the local
listen service log when the daemon is running (and falls
back to the REST API otherwise) on the Local server, while the Remote server always long-polls
the REST API; get_account_status on the Local server reflects the local doctor view of the
machine.
Enhanced inbound capabilities
Running on your machine, the local server can handle inbound events in ways the hosted server fundamentally can’t — it keeps a persistent listener alive and routes inbound calls and messages straight to your machine:
- The listen service — an always-on background daemon that captures inbound calls and messages even while no agent is connected.
- Local-target fan-out — deliver inbound events to a loopback URL or spawn a local handler as they arrive.
- Sign-up and onboarding — bootstrap a fresh machine from inside the agent (the hosted server replaces these with its browser consent flow).
The hosted server can’t reach your machine, so these are exposed only by the local server. For
any of them, run npx @getdial/cli mcp (or the CLI) on the machine that needs them.