Docs

Everything an agent needs

The endpoint, the eight tools, every status and error code, and the limits that apply.

Connect

Endpoint: https://staging.patchmcp.com/mcp (Streamable HTTP, OAuth 2.1 with PKCE, dynamic client registration and client-ID metadata documents supported). Discovery lives at /.well-known/oauth-protected-resource/mcp and /.well-known/oauth-authorization-server. The consent flow verifies the user's number with a text code, and that verified number is the account; there is no separate sign-up.

  1. Open grok.com/connectors, choose New Connector, then Custom.
  2. Give it this server URL: https://staging.patchmcp.com/mcp
  3. A Patch MCP page opens asking for your number. Type in the code we text you and press Allow. That is the whole sign-up.
  4. Back in Grok, ask for a call: “Call Bay Vet Clinic and move Pepper's checkup from Thursday morning to any afternoon next week.”
  1. In Claude, open Settings → Connectors → Add custom connector.
  2. Give it this server URL: https://staging.patchmcp.com/mcp
  3. Click Connect. A Patch MCP page opens asking for your number. Type in the code we text you and press Allow. That is the whole sign-up.
  4. Ask Claude to call someone.
  1. Turn on Developer mode under Settings → Connectors → Advanced.
  2. Create a connector with the MCP server URL https://staging.patchmcp.com/mcp and OAuth authentication.
  3. A Patch MCP page opens asking for your number. Type in the code we text you and press Allow. That is the whole sign-up.

Tell Claude Code “Connect to https://staging.patchmcp.com/mcp to make phone calls.” and it adds the server itself, or run:

claude mcp add --transport http patch-mcp https://staging.patchmcp.com/mcp

Run /mcp to connect your number whenever you like; skip it and the first call your agent attempts opens the connect page for you.

Add to .cursor/mcp.json (or the global one):

{ "mcpServers": { "patch-mcp": { "url": "https://staging.patchmcp.com/mcp" } } }
codex mcp add patch-mcp --url https://staging.patchmcp.com/mcp

Or in ~/.codex/config.toml: [mcp_servers.patch-mcp] with url = "https://staging.patchmcp.com/mcp".

Tools

place_call

Dials a number from the user's verified caller ID and returns straight away with a call_id and a listen_url; the conversation carries on in the background.

to
Destination in E.164 (+14155551234). US/CA only.
objective
What the call must achieve, with specifics and acceptable fallbacks (10–2000 chars).
callee_name
Who is being called. Optional, improves the conversation.
context
Extra facts the agent may reveal if asked. Optional.
max_duration_minutes
Optional cap on the call's length. The plan sets the ceiling: 3 minutes on the free plan, whatever the month's remaining usage pays for on a paid plan (no per-call cap). The cap actually applied is returned as max_duration_minutes.
user_name
The name the opening gives (“I’m …’s AI assistant calling …”), e.g. Sam or Sam at Acme. Only needed after a user_name_required error; it is saved to the account for every later call.

get_call

Status and, once terminal, the resolution, transcript and recording_url. Pass wait_seconds (≤ 50) to long-poll.

end_call

Stops a call that is still running: the assistant says a short goodbye, lets the other person answer it, and hangs up — within about twenty seconds.

list_calls

The account's latest calls, newest first, each with its status and result.

send_text

Texts the account's own verified number (never anyone else's) from the service's number: a call's outcome, a confirmation number, an address, a question to answer from the phone, or a picture. Returns a text_id and the status. Messages are part of the plan: 10 free ones, then each text's SMS segments, or each picture message, come out of the month's usage; there is no hourly or daily cap beyond fair use.

message
The text to send (up to 1000 chars). It arrives prefixed with “Patch MCP:”. Optional when pictures are attached.
media_urls
Up to 5 public https image URLs: the message goes as a picture message (MMS), which counts as one message however long its caption.

receive_texts

What the user texted back from their verified phone, oldest first. The sender's number is the account, so nothing else is checked. Without after, the pending texts: returned on every call until the agent passes ack with the last text_id it handled (usually on its next poll), so a dropped response never loses a text. With after (a text_id), everything newer than that text, which is how an agent reads the reply to a particular send_text. Pass wait_seconds (≤ 50) to wait for a text to arrive. A picture the user sends arrives with type: "mms" and its attachments in media (URLs that work for 30 days). A text of STOP opts the user out of texts until they text START.

get_text / list_texts

One text by id, with its delivery status (queuedsentdelivered or failed) or, for a text from the user, what they wrote; and the whole conversation, newest first, both directions. Each carries type (sms or mms) and, for a picture message, its attachments in media.

Call lifecycle

Statuses: queuedringingin_progress → one of completed, no_answer, busy, voicemail, failed, canceled, declined_recording, opted_out.

Every terminal call carries a resolution: { outcome: achieved | partially_achieved | not_achieved | no_conversation, summary, commitments[], follow_ups[], key_facts[], callee_requested_no_further_calls }. The resolution can lag the terminal status by a few seconds while it is extracted.

Transcript rows are { role: agent | callee, text, at_ms }. recording_status moves from processing to available typically 15–90 s after the call ends; recording_url links expire after about an hour, listen_url after a few hours.

Plans

Accounts start on the free plan: 5 calls of up to 3 minutes, counted only when someone picks up and says something, and 10 texts. Paid plans are Starter ($10/month) or Pro ($25/month, 3× the usage): one allowance of usage per billing period that calls and texts share, metered on what each costs to carry (an answered call: a small fixed amount plus an amount per whole minute, one-minute minimum; a text: an amount per SMS segment; a picture message: about twice a text, each way) and reported only as the percentage left. The message field of a successful place_call or send_text states what the plan has left; agents should relay it when the user asks.

Errors

Rejections come back as tool errors with a machine-readable error code and a human message. Relay the message to the user; do not retry blindly.

invalid_number / unsupported_region / blocked_number
The destination is invalid, outside US/CA, or in a blocked range.
subscription_required
The free calls (or, from send_text, the free texts) are used up. Includes upgrade_url, a private link that opens checkout for this account: show it to the user.
plan_limit_reached
The month's usage will not cover another call (or this text). Includes usage_left_percent, reset_at, retry_after_seconds and manage_url.
caller_id_not_verified
The account's number lost its verification; finish it again at /verify.
user_name_required
The account has no name for the disclosure yet. Ask the user for one and call again with it in user_name.
do_not_call
The destination is on the do-not-call list.
concurrent_call_in_progress
Includes active_call_id; wait or end it first.
objective_rejected
Safety screening declined the objective.
carrier_error / service_unavailable
Temporary provider problems.
texts_coming_soon / opted_out
Text tools only: texting is not available yet (tell the user it is coming soon), or the user texted STOP (they can text START to resume).
invalid_params
An argument failed validation: for send_text, a message with nothing to send, or a picture URL that is not a public https link.

Limits