MCP
Phone.inc exposes a Model Context Protocol (MCP) server so AI assistants can read your account data and take actions on your behalf. The MCP endpoint sits on the same host as the REST API and uses the same credentials.
MCP is built for AI clients — Claude Desktop, Cursor, and similar tools. If you're writing your own integration, the REST API is usually simpler.
Setup
The MCP server URL is https://app.phone.inc/mcp. Nothing to install — it's a remote HTTP endpoint. Pick your client below and connect once.
You'll authenticate with Phone.inc the same way as the REST API: an API key you paste into a config file, or OAuth where the client opens a browser sign-in for you. Claude uses OAuth automatically; Cursor uses an API key in mcp.json.
Claude Desktop
- Open Claude → Settings → Connectors.
- Click Add custom connector.
- Enter the server URL:
https://app.phone.inc/mcp - Save, then click Connect on the new connector. Claude opens a browser window — sign in to Phone.inc and approve access.
- Start a new chat, make sure the Phone.inc connector is enabled, and try: "List my main phone numbers."
Claude registers itself via dynamic client registration and stores a refresh token. You don't need to create an API key or OAuth app by hand.
Cursor
Add the server to your MCP config — either ~/.cursor/mcp.json (all projects) or .cursor/mcp.json in a project root:
mcp.json
{
"mcpServers": {
"phone-inc": {
"url": "https://app.phone.inc/mcp",
"headers": {
"Authorization": "Bearer phk_YOUR_API_KEY"
}
}
}
}
Create an API key at app.phone.inc/api_keys and replace phk_YOUR_API_KEY. Restart Cursor after saving — Phone.inc tools should appear in the agent tool list.
Endpoint
The MCP server uses Streamable HTTP in stateless mode:
- URL:
https://app.phone.inc/mcp - Methods:
POSTfor JSON-RPC requests (tools/list,tools/call,initialize, and so on) - Accept header:
application/json, text/event-stream - Content-Type:
application/json
Responses are returned as application/json (not SSE) because the server runs in stateless mode — each request is self-contained and no session is required.
GET and DELETE on /mcp are not used in stateless mode (GET returns 405 Method Not Allowed).
Authentication
Every MCP request must be authenticated. Use the same credentials as the public REST API:
- API key — send
X-Api-Key: phk_...orAuthorization: Bearer phk_... - OAuth bearer token — send
Authorization: Bearer <access_token>with theapiscope (see OAuth 2.0 for partners)
Unauthenticated requests receive 401 Unauthorized with a WWW-Authenticate header pointing at our protected-resource metadata:
WWW-Authenticate: Bearer realm="Phone.inc MCP",
resource_metadata="https://app.phone.inc/.well-known/oauth-protected-resource/mcp",
scope="api"
MCP clients use that URL to discover the authorization server and start the OAuth flow. The metadata document at /.well-known/oauth-protected-resource/mcp advertises resource: https://app.phone.inc/mcp.
Tools
Call tools/list to see what's available. Each tool is a thin wrapper around the public REST API — request and response shapes match the corresponding endpoint documented on the resource pages linked below.
Business numbers
Manage business numbers and their call routing. The three routing tools take business_number_id; get and update take id.
| Tool | REST equivalent |
|---|---|
list_business_numbers | GET /api/v1/business_numbers |
get_business_number | GET /api/v1/business_numbers/:id |
update_business_number | PATCH /api/v1/business_numbers/:id |
update_business_number_incoming_call_config | PUT /api/v1/business_numbers/:id/incoming_call_config |
update_business_number_outside_business_hours_config | PUT /api/v1/business_numbers/:id/outside_business_hours_config |
update_business_number_no_answer_config | PUT /api/v1/business_numbers/:id/no_answer_config |
Calls
| Tool | REST equivalent |
|---|---|
list_calls | GET /api/v1/calls |
get_call | GET /api/v1/calls/:id |
get_active_call | GET /api/v1/calls/active |
start_call_transfer | POST /api/v1/calls/:id/transfers |
complete_call_transfer | POST /api/v1/calls/:id/transfers/:transfer_id/completion |
cancel_call_transfer | DELETE /api/v1/calls/:id/transfers/:transfer_id |
list_calls accepts a query to search call transcriptions and saved caller context by keywords or related topics, plus business-number, caller/callee phone-number, direction, and state filters. limit is optional, defaults to 10, and is capped at 50. get_call includes the call transcription when one exists. There is no separate get_call_transcription tool.
Voicemails
| Tool | REST equivalent |
|---|---|
list_voicemails | GET /api/v1/voicemails |
get_voicemail | GET /api/v1/voicemails/:id |
update_voicemail | PATCH /api/v1/voicemails/:id |
delete_voicemail | DELETE /api/v1/voicemails/:id |
Caller context
| Tool | REST equivalent |
|---|---|
get_caller_context | GET /api/v1/caller_context |
Contacts
| Tool | REST equivalent |
|---|---|
list_contacts | GET /api/v1/contacts |
get_contact | GET /api/v1/contacts/:id |
create_contact | POST /api/v1/contacts |
update_contact | PATCH /api/v1/contacts/:id |
delete_contact | DELETE /api/v1/contacts/:id |
Employees
| Tool | REST equivalent |
|---|---|
list_employees | GET /api/v1/employees |
get_employee | GET /api/v1/employees/:id |
create_employee | POST /api/v1/employees |
update_employee | PATCH /api/v1/employees/:id |
delete_employee | DELETE /api/v1/employees/:id |
get_employee_do_not_disturb | GET /api/v1/employees/:id/do_not_disturb |
set_employee_do_not_disturb | PUT /api/v1/employees/:id/do_not_disturb |
Webhooks
| Tool | REST equivalent |
|---|---|
list_webhooks | GET /api/v1/webhooks |
create_webhook | POST /api/v1/webhooks |
update_webhook | PATCH /api/v1/webhooks/:id |
delete_webhook | DELETE /api/v1/webhooks/:id |
Company
| Tool | REST equivalent |
|---|---|
get_company | GET /api/v1/company |
update_company | PATCH /api/v1/company |
Notes
- The tools cover the public API. Voice preview generation and standalone call transcription retrieval are excluded; transcriptions are included in
get_call. - Tool arguments mirror REST query parameters, path ids, and JSON bodies. See the linked REST docs for field names, validation rules, and response shapes.
- Successful
DELETErequests return MCP text content{"success":true}(the REST API returns204 No Contentwith an empty body). - Results are scoped to the company tied to your API key or OAuth token.
Example tools/call request (list_business_numbers):
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_business_numbers",
"arguments": {}
}
}
Example response content (returned as MCP text content):
{
"main_numbers": [
{
"id": "mn_abc123",
"name": "Support",
"number": "+14155551234",
"number_formatted": "+1 415-555-1234"
}
]
}