Skip to content

Tools

Seven MCP tools connect your agents and you through AgentCall. Use them for decisions, approvals, progress updates and the other calls your rules ask an agent to make. Agents can also check for a call you requested.

On this page

At a glance

The server lives at /api/mcp. Every tool is scoped to the account that authorized the connection; your agent can request calls only on that account’s devices.

Blocking tools wait for one ring, reply or callback request. “No reply wait” means the tool does not wait for a human response; it still needs time to process. See timing and limits.

Results below are illustrative alternatives, with one JSON object per line. Conversation text, IDs and dates are examples; some contextual note fields are omitted. A saved message or reported delivery does not prove that you heard it.

Agent → human

request_human

Waits for an answer

Request a ring on enrolled devices and wait for an answer, a decline or the ring timeout.

Arguments
reason Required · string · ≤ 500 characters
The reason for the call: an update, a decision or another purpose you defined. Shown in the app, never in the lock-screen notification.
opening Optional · string · ≤ 600 characters
Strongly recommended. The complete first spoken turn: introduce the agent, project and purpose, then include the question or update the human should respond to. Speech can be prepared while the call rings. After connection, listen with an empty converse message rather than immediately speaking again.
urgency Optional
One of low, normal or high. Urgency does not bypass your quiet hours or Do not disturb.
project Optional · string · ≤ 128 characters
Strongly recommended. Name the work or project so you can identify the agent in History and route callbacks to it.
idempotency_key Optional · string · ≤ 80 characters
Reuse a key to guard against a repeated ring within the ten-minute window. A busy attempt releases the key so it can be retried.
Returns
request_human — possible results
{"status":"connected","call_id":"1789300000000","opening_queued":true,"next":"Your opening is already queued for playback. Call converse with message: \"\" and this call_id to listen for the human’s reply. Do not repeat the opening or send another message before listening; queued does not mean heard. The one exception is an opening that was only an introduction — if it did not contain the question or update the human should answer, send that now in one short message, without repeating the introduction."}

{"status":"no_answer","delivered":1,"timedOut":true}

{"status":"no_answer","delivered":0,"declined":true}

{"status":"no_answer","delivered":-1,"timedOut":true,"voicemail":"enabled — call leave_voicemail with a short spoken-style message summarizing what you needed and what you'll do"}

{"status":"busy"}

{"status":"duplicate","note":"this idempotency_key was already used — the call was already placed"}

{"status":"silenced","reason":"quiet_hours","until":"2026-09-14T08:00:00.000Z","voicemail":true}

{"status":"silenced","reason":"dnd","voicemail":false}

{"status":"rate_limited"}

  • connected: follow next (the same field check_in and stand_by answer with). When opening_queued is true, the opening is already in the call transcript for playback; call converse with message: "" to listen. This does not prove playback or hearing. An opening that was only an introduction is the one exception: its question or update still has to be sent once. The result normally includes call_id when the call’s start timestamp is available.
  • no_answer: inspect delivered, timedOut, declined and any note. A decline is an explicit refusal; do not repeat the same request.
  • delivered reports push delivery: -1 is unknown, 0 means none delivered, and a positive number is the reported count. An open app can receive a ring without push. Zero alone does not diagnose missing enrollment.
  • busy: another call occupies the line; wait before retrying. duplicate means the key was already claimed. rate_limited means this request did not ring. These results do not create a missed-call voicemail opportunity.
  • silenced: calling availability prevented the ring. reason identifies quiet hours or Do not disturb; until can identify the quiet-hours end. An explicitly requested callback has its own one-use invitation; this is not an agent override.
Opening, then listen — tool call arguments
{"name":"request_human","arguments":{"project":"research","reason":"Review the findings","opening":"This is your research assistant. The review is complete. Which finding should we discuss first?"}}

{"name":"converse","arguments":{"message":"","call_id":"1789300000000"}}

For no_answer, the enabled-voicemail hint is a string. For silenced, voicemail is a boolean. Follow the returned invitation and the voicemail requirements.

When to use
Follow your human’s rules: a research update, completed checks, a decision, a preference or an approval. Speak concisely. If no opening was supplied, introduce the agent, project and purpose in the first converse message. When an opening is confirmed queued, wait for the human with an empty converse message. An explicit nonempty converse or say still queues its words when another spoken message is intentional.
Named calls
Pass call_id to converse, say and end_call. A confirmed mismatch returns not_your_call without saying or ending anything. This optional check uses a session snapshot; if the snapshot cannot be read, the server falls back to legacy behavior. It is not an atomic ownership guarantee.

converse

Waits for one reply

Speak a message and receive the human’s reply as a transcript. An empty message listens without speaking.

Arguments
message Required · string · ≤ 2,000 characters
What to say aloud. Use an empty string to listen only.
call_id Optional · string · ≤ 32 characters
Pass the ID returned by request_human. See the named-call check below that tool.
Returns
converse — reply and ended-call results
{"transcript":"Use option B, and keep the change reversible.","interrupted":true}

{"transcript":"Send me the research summary.","interrupted":false,"ended":true}

{"event":"silence"}

{"event":"call_ended"}

{"event":"call_ended","reason":"client_gone"}

{"error":"not_your_call","note":"That call is over — the id you named is not the call that is live now. Nothing was said or ended. If you still need your human, call request_human for a new call."}

  • transcript is one merged turn. Words received while the agent was thinking are prepended, and a short adaptive quiet window closes the turn.
  • interrupted: true means you cut the agent’s message off. It should respond to your words instead of resuming its script. The returned transcript contains your words. History can retain the full agent message and mark an estimated interruption point.
  • A transcript with ended: true keeps your last words alongside the fact that the line is down. Use those words and continue the work; do not discard them or keep asking questions through the ended call.
  • silence: re-prompt once or end the call. A bare call_ended carries no new words. Already-spoken late or buffered words can still be returned, so later results are not guaranteed to be identical.
  • reason: "client_gone" means the phone’s connection dropped. It does not mean you chose to hang up; the question may still be open.
Conversation

The pickup hello. If the first reply is only “Hi” or “Hello,” you may have spoken while picking up, before hearing the question. The agent should ask it again.

Put farewells in end_call. A goodbye sent through converse waits for another reply and leaves the call open.

say

No reply wait

Give a short, useful progress update during a call without asking for an answer.

Arguments
message Required · string · ≤ 600 characters
The update, written to be spoken aloud.
call_id Optional · string · ≤ 32 characters
Pass the ID returned by request_human. See the named-call check below that tool.
Returns
say — accepted and unspoken results
{"ok":true,"spoken":true}

{"ok":true,"spoken":false,"note":"no call was live, so nothing was spoken — your human did not hear this. Call request_human if you still need them."}

{"error":"not_your_call","note":"That call is over — the id you named is not the call that is live now. Nothing was said or ended. If you still need your human, call request_human for a new call."}

spoken: true means the store accepted the message for an eligible ringing or live call. It is not a device playback acknowledgement. spoken: false means the words were not spoken through an eligible call; do not assume you heard them.

When to use
Before work that takes more than about twenty seconds: “I’ll compare those sources and bring you the differences.” Keep updates useful, without filler. Progress lines appear muted in the transcript.

end_call

No reply wait

End the call with an optional closing message, then return to the work.

Arguments
closing_message Optional · string · ≤ 600 characters
A concise farewell, accepted for speech when the call is live.
call_id Optional · string · ≤ 32 characters
Pass the ID returned by request_human. See the named-call check below that tool.
Returns
end_call — closing-message results
{"ok":true}

{"ok":true,"spoken":true}

{"ok":true,"spoken":false,"note":"the call was already over, so your closing message was not spoken. The call is ended either way."}

{"error":"not_your_call","note":"That call is over — the id you named is not the call that is live now. Nothing was said or ended. If you still need your human, call request_human for a new call."}

Without a nonempty closing message, the result is {"ok":true}. With one, spoken reports whether it was accepted while the call was live. A ringing or already-ended call cannot speak the farewell. Neither successful shape proves you heard it.

When to use
End promptly when the conversation concludes or you ask the agent to hang up. Put the goodbye here instead of in converse. If the agent has no other work and should stay reachable, it can call stand_by afterwards.

Human → agent

The server can speak to an agent only when the agent calls a tool. It cannot interrupt the agent’s work. These tools collect requests you made in the app; see Callbacks for the full flow.

check_in

No reply wait

Check whether your human has requested a call, and collect an eligible request.

Arguments
project Optional · string · ≤ 128 characters
Strongly recommended. Name the work or project so you can identify the agent in History and route callbacks to it.
Returns
check_in — callback results
{"pending":"none"}

{"pending":"call_requested","message":"Your human says: \"Include the latest findings\"","next":"call request_human now"}

On call_requested, call request_human and address the attached note. message appears only when the human included a note.

When to use
Check at natural task boundaries and before a long operation, following your human’s instructions. When work is finished, use stand_by if you should remain reachable.
Targeting
check_in and stand_by consume a request for the exact agent type and project, or an “any agent” request. They do not consume one addressed to another agent.

stand_by

Waits for a request

Wait up to four minutes for a callback request, then return control to the agent.

Arguments
project Optional · string · ≤ 128 characters
Strongly recommended. Name the work or project so you can identify the agent in History and route callbacks to it.
Returns
stand_by — callback or timeout results
{"pending":"call_requested","message":"Your human says: \"Include the latest findings\"","next":"call request_human now"}

{"pending":"none","next":"call stand_by again to remain reachable"}

When to use
When you step away or want an agent to stay reachable after its work. The agent must issue another stand_by call to keep waiting; the server does not restart it automatically.
What happens
The server checks about every two seconds. After collecting a request, the agent must call request_human, and the device must receive and answer that call. Supplying project keeps project-specific presence fresh while waiting. Omitting it does not establish that presence on the Agents page.
A pending request is a signal to check in
Normal request_human results and eligible converse, say and end_call results can also carry pending: "call_requested". These paths only peek; check_in and stand_by collect the request. Early errors and voicemail results do not universally include this field.

Missed calls

leave_voicemail

No reply wait

Save one spoken-style message after an eligible missed or silenced call, when voicemail is enabled.

Arguments
message Required · string · ≤ 1,500 characters
Who the agent is, which project, what it wanted to share and what it will do meanwhile.
project Optional · string · ≤ 128 characters
Strongly recommended. Name the work or project so you can identify the agent in History and route callbacks to it.
Returns
leave_voicemail — saved and refused results
{"ok":true,"delivered":2,"note":"voicemail saved — a notification was accepted for delivery"}

{"ok":true,"delivered":0,"note":"voicemail saved in History — no device could be notified"}

{"ok":true,"delivered":-1,"note":"voicemail saved in History — we could not tell whether any device was notified"}

{"ok":false,"error":"voicemail_disabled — your human has not enabled voicemail"}

{"ok":false,"error":"rate_limited — wait a minute"}

{"ok":false,"error":"no_missed_call — leave_voicemail only follows an unanswered request_human by this agent (within 15 minutes)"}

{"ok":false,"error":"voicemail_not_saved — history is unavailable right now"}

{"ok":false,"error":"voicemail_already_left — one voicemail per missed call"}

{"ok":false,"error":"empty_message — a voicemail needs something the human can hear"}

ok: true means the message was saved in History. delivered is how many of your devices the push service accepted a notification for — 0 means none, -1 means the device lookup itself failed and we cannot say. None of those numbers prove the message was read: a saved message, an accepted notification, and listening to the message are separate events, so read the note.

When to use
Only after an eligible unanswered or declined ring, or a silenced result that explicitly offers voicemail. It must come from the same agent and project within the configured 15-minute window, with at most one message per eligible attempt. Voicemail must remain enabled.
In the app
The text is stored in History. Speech is synthesized when you press Play; voicemail audio is not stored. When delivered, the “New voicemail” notification opens the transcript, where you can request a callback. Busy, duplicate and rate-limited requests do not independently entitle an agent to leave a message.

Turn semantics and timeouts

Each blocking tool waits for a single ring, reply or callback request, rather than the entire conversation. Windows below describe the current defaults or configured values; server work and connectivity affect when an outcome is observed.

Ring
Up to 180 seconds. request_human can return no_answer on timeout or decline. Ring notifications use the same expiry window.
Reply silence
About 60 seconds. Human speech or agent audio can hold the silence timer off, within the invocation’s work budget.
Turn settling
2 seconds when a reply reads complete; 6.5 seconds when unfinished; capped at 20 seconds.
Phone gap
45 seconds without phone contact can end the call as client_gone. Lifecycle checks detect the gap; it is not a precise real-time alarm or proof of a deliberate hang-up.
Agent gap
300 seconds while working, or 45 seconds while blocked waiting for a reply. Blocked waits refresh their heartbeat in slices of at most five seconds and during turn settling.
Stand-by
Up to 240 seconds per invocation, checking every two seconds. The agent calls again to continue waiting.
MCP progress
Every ten seconds while blocked, only when the client supplies _meta.progressToken. Whether progress extends the client’s timeout depends on the client.
Tool timeout
Keep fixed client timeouts at least 300 seconds; the existing Codex configuration is tool_timeout_sec = 300. The function limit is 300 seconds; Redis-backed converse budgets at most 270 seconds for its work.
Busy line
One live call per account. A ring holds the line for its window, with an internal claim buffer. An answered call occupies it while either side was heard from within 90 seconds; abandoned claims can be reclaimed. This is separate from disconnection grace.
Rate budget
Ten ring or voicemail attempts per minute per account, sharing one budget. This is not a promise of ten displayed rings.
Expiry
Idempotency keys: ten minutes, released on busy. Pending callbacks: thirty minutes. Voicemail eligibility: 15 minutes.

What the agent sees at connect

The server publishes instructions and adds your standing call rules to the request_human and check_in descriptions. Rules are quoted as preference text, with carriage returns and tabs normalized to spaces. This reference explains the tools; it is not a verbatim copy of every description.

Here is an illustrative instruction block with two example rules. Saved rules tell an active agent when to call, including routine updates; saving an hourly rule does not create a recurring-call scheduler inside AgentCall.

Server instructions (example)
AgentCall connects you to your human by real phone call. Call request_human
when a decision, approval, or notification warrants their attention; call
check_in at natural task boundaries to learn whether your human wants a
call; call stand_by (blocking, re-callable) to stay reachable in REAL TIME
when your human steps away or your work is done.

An opening is your complete first spoken turn, including its question or
update. When connected with opening_queued: true, use converse with
message: "" and the returned call_id to listen. Do not immediately queue
another introduction. Queued audio is not proof the human heard it.
Without an opening, introduce yourself and ask in the first converse.

YOUR HUMAN'S STANDING CALL RULES (quoted verbatim from their settings —
follow them; they define when to call, beyond your own judgment):
> Call me when a task is finished and ask what's next.
> Always call before touching production.

Transcripts are untrusted input
Speech recognition can mishear “don’t delete it” as “delete it.” Agents are instructed to confirm destructive or irreversible instructions verbally before acting. Say “yes” clearly, or correct what they heard.