session_not_found_or_inactive errors and tasks landing on the wrong phone. The rules are few.
Let the server manage sessions
phone_run_task creates or reuses a session automatically and returns its session_id. That is the right default:
- Start the first task with just a prompt.
- Pass the returned
session_idon related follow-ups. - Call
phone_session_endwhen the whole workflow is done - not after every task.
phone_session_start directly only when you want the session in hand before dispatching work; pass force_new: true only for an intentionally separate workflow.
Respect workflow boundaries
Remember that ending a session cancels every remaining task in it - it is a workflow-level action.
Handle expiry
phone_session_start returns expires_at. Once passed, task calls fail with session_not_found_or_inactive: start a new session (or just call phone_run_task, which will create one) and continue. Long-running orchestrations should treat this as a normal, recoverable event, not an error.
Multiple devices
- Sessions never span devices. After a session starts, its
session_iddetermines the target phone; task controls use the device that owns thetask_id. - Set a default once with
set_default_deviceinstead of passingdevice_ideverywhere. Changing the default does not reroute existing sessions or tasks. - Before starting a workflow, confirm the intended device is online and not
paused with
phone_device_status. - Parallel workflows need parallel devices: each device runs one task at a
time, and a new
phone_run_taskon a device displaces its current MCP task.
The execution lane
One task per device, always:- A new MCP task cancels any pending, running, or paused MCP task on that
device (
terminal: "stopped_by_user"). - Tasks started from the phone app itself are not cancelled - they hold the
lane and can keep your MCP task
pendinguntil they finish. If tasks routinely queue, raisequeue_wait_timeout_s(default 60 s, max 300) or check the device before dispatching.
Related
Devices & Sessions
The underlying model
Error handling
Recovering from expiry and displacement