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.

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

  1. Open Claude → Settings → Connectors.
  2. Click Add custom connector.
  3. Enter the server URL: https://app.phone.inc/mcp
  4. Save, then click Connect on the new connector. Claude opens a browser window — sign in to Phone.inc and approve access.
  5. 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: POST for 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_... or Authorization: Bearer phk_...
  • OAuth bearer token — send Authorization: Bearer <access_token> with the api scope (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 and request_business_number_porting take business_number_id; get and update take id.

ToolREST equivalent
list_business_numbersGET /api/v1/business_numbers
get_business_numberGET /api/v1/business_numbers/:id
update_business_numberPATCH /api/v1/business_numbers/:id
request_business_number_portingPOST /api/v1/business_numbers/:business_number_id/porting_request
terminate_business_numberPOST /api/v1/business_numbers/:id/termination
cancel_business_number_terminationDELETE /api/v1/business_numbers/:id/termination
send_messagePOST /api/v1/business_numbers/:business_number_id/messages
update_business_number_incoming_call_configPUT /api/v1/business_numbers/:id/incoming_call_config
update_business_number_outside_business_hours_configPUT /api/v1/business_numbers/:id/outside_business_hours_config
update_business_number_no_answer_configPUT /api/v1/business_numbers/:id/no_answer_config

The retired update_outside_opening_hours_config tool is no longer available. Use update_business_number_outside_business_hours_config with business_hours.

send_message sends a real, chargeable SMS from an active SMS-capable inMobile number owned by the authenticated employee's company. Number responses group effective SMS/MMS capabilities under messaging; the company's messaging feature flag must be enabled by Phone.inc (default off). Messaging tools return an endpoint 404 while disabled; inbox tools still return calls and voicemails but exclude SMS. It requires business_number_id, to in E.164 format, text, and idempotency_key. Acceptance is not delivery. Reuse the same idempotency key when replaying the same send after a transport error. See outgoing SMS, especially the retry warning.

The routing update tools accept signed welcome_audio_preview_id, message_audio_preview_id, and greeting_audio_preview_id values matching the number and text. See voice previews.

Read get_business_number before changing routing. Switching the call-flow type creates a new configuration; it does not copy the previous type's greeting or destinations. Collect the caller-facing text and destinations before calling the update tool:

New typeRequired details
VoicemailConfiggreeting: the exact text callers hear before recording
WelcomeTransferConfigwelcome and either non-empty employee_ids or department_id
TransferConfigEither non-empty employee_ids or department_id
RejectConfigmessage: the text played before hanging up
PhoneMenuConfigwelcome and at least one valid menu_options entry, with prompts and either employee targets or a department_id for each transfer action

For outside-hours updates, omit type to preserve routing while changing business hours, or send type: null to clear routing. For no-answer updates, missing or null type clears the fallback; include the current type when changing only the timer. Omitting timeout_secs preserves the timer.

Calls

Use business_number_id to filter list_calls by business number.

ToolREST equivalent
list_callsGET /api/v1/calls
get_unseen_activityGET /api/v1/activity/unseen
set_call_thread_seenPOST /api/v1/calls/seen
get_callGET /api/v1/calls/:id
get_active_callGET /api/v1/calls/active
start_call_transferPOST /api/v1/calls/:id/transfers
complete_call_transferPOST /api/v1/calls/:id/transfers/:transfer_id/completion
cancel_call_transferDELETE /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. Both tools include outside_business_hours: the business-hours decision recorded at call arrival, or null when unknown. There is no separate get_call_transcription tool.

For complete call reports, use start_at (inclusive) and end_at (exclusive) with explicit time-zone offsets, then follow next_cursor with the same filters until null. This retrieves underlying calls rather than a purpose-built report. Cursor pagination is not supported with transcription query; search results are a capped sample.

The dashboard assistant can visualize any retrieved product dataset with its general-purpose render_chart tool. This local, presentation-only tool renders area, bar, line, and pie charts without changing account data. It is not part of the public MCP catalog because external clients own their own visualization UI.

Inbox

ToolREST equivalent
list_inboxGET /api/v1/inbox
list_activityGET /api/v1/inbox/:phone_number/activity
mark_activity_seenPOST /api/v1/inbox/:phone_number/seen

Inbox tools group calls, voicemails, and messages by external phone number. No conversation resource is created. Pagination cursors are bound to the company, filters, and original observation boundary. Seen state is shared by the team; marking a thread seen does not mark its voicemails listened. The catalog has 69 tools including compatibility aliases.

Voicemails

ToolREST equivalent
list_voicemailsGET /api/v1/voicemails
get_voicemailGET /api/v1/voicemails/:id
update_voicemailPATCH /api/v1/voicemails/:id
delete_voicemailDELETE /api/v1/voicemails/:id

Caller context

ToolREST equivalent
get_caller_contextGET /api/v1/caller_context

Integrations

ToolREST equivalent
list_integrationsGET /api/v1/integrations
get_integrationGET /api/v1/integrations/:id
list_integration_providersGET /api/v1/integration_setups
get_integration_setupGET /api/v1/integration_setups/:provider

Read configured connection names, providers, statuses, and timestamps, including disconnected connections. Discover available providers and prepare a browser authorization link with get_integration_setup. The dashboard assistant displays this as a card with an authorization button and automatically updates it after a verified setup callback. External MCP clients can present setup_url as a link. The user must sign into the same company and complete setup in the browser; obtaining a link does not install anything. Verify the result with list_integrations afterward. These tools never expose credentials, endpoint URLs, or raw error messages.

Contacts

ToolREST equivalent
list_contactsGET /api/v1/contacts
get_contactGET /api/v1/contacts/:id
create_contactPOST /api/v1/contacts
update_contactPATCH /api/v1/contacts/:id
delete_contactDELETE /api/v1/contacts/:id

Employees

ToolREST equivalent
list_employeesGET /api/v1/employees
get_employeeGET /api/v1/employees/:id
create_employeePOST /api/v1/employees
update_employeePATCH /api/v1/employees/:id
delete_employeeDELETE /api/v1/employees/:id
get_employee_do_not_disturbGET /api/v1/employees/:id/do_not_disturb
set_employee_do_not_disturbPUT /api/v1/employees/:id/do_not_disturb

Departments

ToolREST equivalent
list_departmentsGET /api/v1/departments
get_departmentGET /api/v1/departments/:id
create_departmentPOST /api/v1/departments
update_departmentPATCH /api/v1/departments/:id
delete_departmentDELETE /api/v1/departments/:id

Use department_id instead of employees for TransferConfig and WelcomeTransferConfig in the incoming, outside-hours, and no-answer routing slots, clearing employee_ids when changing destination. Phone-menu options continue to select employees. Department queues are shared across numbers; each caller retains the number's waiting and fallback rules.

Webhooks

ToolREST equivalent
list_webhooksGET /api/v1/webhooks
create_webhookPOST /api/v1/webhooks
update_webhookPATCH /api/v1/webhooks/:id
delete_webhookDELETE /api/v1/webhooks/:id

Texting

ToolREST equivalent
get_messageGET /api/v1/messages/:id
get_message_attachmentGET /api/v1/messages/:message_id/attachments/:id
retry_messagePOST /api/v1/messages/:id/retries
list_text_snippetsGET /api/v1/text_snippets
create_text_snippetPOST /api/v1/text_snippets
get_text_snippetGET /api/v1/text_snippets/:id
update_text_snippetPATCH /api/v1/text_snippets/:id
delete_text_snippetDELETE /api/v1/text_snippets/:id
get_texting_settingsGET /api/v1/business_numbers/:id/texting_settings
update_texting_settingsPATCH /api/v1/business_numbers/:id/texting_settings

get_message includes attachment metadata only when the company has Message attachments enabled. get_message_attachment requires both Messaging and Message attachments. It returns a download link valid for five minutes when the file is ready, or null download fields while pending. Links are temporary bearer credentials; do not log or share them. Disabling the flag blocks new links but does not revoke links already issued before their expiry.

send_message requires idempotency_key; reuse it only to replay the same send. retry_message requires a key and sends another real, chargeable text only after definitive failure. Enabling auto-replies can also send texts without an app open.

Company

ToolREST equivalent
get_companyGET /api/v1/company, including plan and employee, web outbound-call, and additional-number entitlements; native outbound calling is not gated
update_companyPATCH /api/v1/company

Compatibility

send_message requires idempotency_key and accepts optional format: "sms"; MMS is not yet supported. REST sends accept an optional key. The old proof-of-concept send_sms tool is not exposed.

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 DELETE requests return MCP text content {"success":true} (the REST API returns 204 No Content with 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):

{
  "business_numbers": [
    {
      "id": "mn_abc123",
      "name": "Support",
      "number": "+14155551234",
      "number_formatted": "+1 415-555-1234"
    }
  ]
}