wixzel-phone-mcp. It puts every /v1 operation in front of an AI
agent as a tool — 56 of them — with each tool annotated so the client knows
which are read-only, which delete, and which spend money or ring a real
phone. Those ask before they run.
Two ways to use it:
The console’s AI clients page at phone.wixzel.com/connect
generates the exact commands below with a key already filled in.
Claude Code
1
Add the server
/mcp in Claude Code and choose Authenticate.
Your browser opens the console, you sign in, tick what the client may do, and
Claude Code is connected. No key changes hands.2
Let it set things up
quickstart connects a carrier, registers a number, builds an agent and
places a first call, stopping before anything that dials; diagnose_call
explains why a call failed from its record, usage events, trunk status and
SIP logs; spend_report turns a period’s usage into dollars by component and
by call.Claude.ai and Claude Desktop
- Settings → Connectors → Add custom connector.
- Enter
https://mcp.phone.wixzel.com/mcpand add it. - Press Connect. You are sent to the console to sign in and approve the scopes the client may use.
- Approve. The client receives a key of its own; nothing is pasted anywhere.
Other clients
Any client that launches stdio servers from a JSON config — Claude Desktop’sclaude_desktop_config.json, Cursor, Windsurf, VS Code — uses the local form:
Scopes
An OAuth-connected client asks for a set of scopes, and you can untick any of them on the consent screen. A client that asks for nothing specific is offered the standard set for agents: everything under Agents, Calls, Telephony, Contacts, Knowledge & scheduling, plususage:read and
billing:read.
For a locally run server, the key you put in the environment decides what the
agent can do. The console preselects the same standard set when you create one
from the AI clients page.
Security
- The token is a key. When a client signs in with OAuth, the API mints an ordinary scoped API key for that grant and hands it over as the access token. Nothing downstream needs to know OAuth happened; revoking the grant revokes the key. Because the token is valid against the API directly, it carries only the scopes you approved, and it is hidden from the ordinary key list so that the AI clients page is its one home.
- PKCE only, S256 only. The authorization server refuses the
plainmethod and any request without a code challenge. Redirect URIs match exactly against what the client registered; an unregistered one gets an error in place, never a redirect. A code is exchanged once and expires in a minute; a code presented with the wrong verifier burns the grant. - Money asks first.
place_call,start_campaignandcreate_topupare annotated as open-world and their descriptions tell the model to confirm with you. Every money path carries an idempotency key the server generates, so a retry after a timeout never dials twice. - Nothing leaks through tools. SIP passwords are write-only. A minted key appears once, in the tool result that created it. The key the server itself runs with is never exposed through any tool or resource.
- Errors are actionable. A failure returns the API’s machine-readable
code, therequest_id, and a hint: which scope is missing, that the balance is short, that a cursor was mangled.
Tools
Resources:
wixzel://guide (the operating guide the server also sends as its
instructions) and wixzel://connection (base URL and whether the key is live
or test; never the key itself).
Self-hosting
The package runs the hosted mode too:
A connector discovers sign-in on its own: a request without a bearer is
answered
401 with WWW-Authenticate: Bearer resource_metadata="…", that
document names https://api.phone.wixzel.com as the authorization server, and
/.well-known/oauth-authorization-server there lists the endpoints.
