For developers

Give your agent a phone-call tool.

Connect an MCP client, define the call task, and read back the outcome and transcript. This guide walks through the integration on your existing phone line.

01

Connect your agent to a phone line

Remote MCP over Streamable HTTP. One device-bound key gives your client access to one phone line.

Before you connect

A classic ESP32 board paired with your phone, connected over USB to an awake computer running the ParrotBridge tab in desktop Chrome. Keep the bridge open during calls.

Set up your phone line ↗
  1. Create a key. In Console, open Devices → your device → MCP. Create a key for this line and copy the client snippet. The secret is shown once.
  2. Add the server. For Claude Code, replace <device-key> below with that key. Other MCP clients use the same URL and Bearer header.
  3. Check the connection. Run claude mcp list, then ask your agent to call get_device_status(). Check that the line is online, Bluetooth is connected and the call state is idle. This check does not place a call.
Add to Claude Code $ claude mcp add --transport http parrot https://parrotvoice.app/mcp --header "Authorization: Bearer <device-key>"

Revoke a device-bound key from Console to remove access. A second phone line needs its own key and MCP entry.

02

Define what the call should accomplish

For a one-off task, pass an objective to place_call. For repeatable calls, save an assistant with its provider, voice, goal and extraction fields, then pass its assistant_id.

scn_instock

Example assistant · Check store stock

01 · GoalWhat to ask

Find out whether {{item}} is in stock, its price and the limit per customer.

02 · GuardrailsWhat to avoid

Don’t place an order or share personal details. End the call once you have the answer.

03 · OutputGet structured answers

in_stockboolean
true
pricenumber
499.99
limit_per_customeroptional integer
2

Illustrative values. Your configured fields arrive as optional extracted JSON after processing.

Create saved assistants in Console. Agent-driven creation and editing use the separate /mcp/authoring endpoint; the calling endpoint runs existing assistants and one-off tasks.

03

Run a call and handle the result

A dial returns a call_id. Follow that call through events before reading its final result.

Start with a one-off task

place_call requires a destination and a time cap. The objective fills the built-in task assistant; no saved assistant is required.

{
  "to_number": "+14155550151",
  "max_duration_s": 120,
  "objective": "Ask whether the PS5 Pro is in stock and its price. Do not place an order."
}

Example number and task. Replace the destination before calling.

The call lifecycle
ToolWhen to use it
get_device_statusCheck that the line is connected and free before dialing.
place_callStart the call and keep the returned call_id. Set max_duration_s to bound its length.
get_call_eventsFollow transcript and state events. Continue long-polling until call_ended; pass the returned cursor to the next poll.
steer_callGive the assistant a new instruction while the call is running.
get_call_resultRead the outcome, reports and transcript after the call ends.

Read the result

{ "call_id": "example-call-id" }

After the call ends, outcome, retryable and ended_by describe its disposition. An answered call does not by itself mean the task succeeded: read the reports and transcript.

{
  "outcome": "answered",
  "retryable": false,
  "ended_by": "agent",
  "summary": null,
  "extracted": null
}

Illustrative response excerpt. summary and extracted are best-effort, asynchronous outputs and may be null. Do not block your integration on them.

Handle unavailable lines explicitly. For device_offline or bt_not_connected, restore the connection before retrying. For device_busy, supervise the existing call rather than dialing again.