a hands-on workshop

Your phone, driven by any AI

AGI Agentic Phone MCP, end to end: set up the phone, connect a client, run tasks, and handle what comes back.

api.agi.tech/v1/mcp 90 minutes Bring an Android phone

the next 90 minutes

Where we're going

Part 1 · 10 min

The idea

What MCP is, and the three pieces that make a phone controllable.

Part 2 · 20 min

Set up & connect

Prepare the phone, attach Claude Code or another client, sign in.

Part 3 · 25 min

Run tasks

The start, monitor, act loop. Outcomes, handoffs, sessions, prompts.

Part 4 · 35 min

Go deeper & build

Security, inside the phone, troubleshooting, then four hands-on labs.

You leave with a working connection, a mental model of every hop, and prompts that hold up on a real device.

before we start

Check you have these

Phone

An Android phone

With the AGI Android app installed. Unlocked, charged, on Wi-Fi.

Account

One AGI account

The same sign-in on the phone, in the browser and on platform.agi.tech.

Laptop

An MCP client

Claude Code is fastest. Claude Desktop, Cursor and ChatGPT work too.

Desktop

Node.js 18+

Only for Claude Desktop, which needs the mcp-remote bridge.

part 1

The idea

Real apps, real screen, any assistant.

what it does

Your assistant asks. Your phone does it.

Connect the AGI MCP server to any MCP client. The assistant runs plain-language tasks on your phone: opens apps, navigates, types and reports back while you watch.

No per-app integration. Anything installable is automatable.

Visible. Every action happens on the phone's own screen.

Native trust. Logins and payments stay with you, on the device.

Claude Code Claude Desktop Cursor ChatGPT
Working…

mcp in sixty seconds

A plug standard for AI tools

The Model Context Protocol lets any compliant client discover and call tools on a server. Nothing is hardcoded per client.

tools/list

Ask the server which tools exist for this account.

tools/call

Run one tool with JSON arguments, get JSON back.

AGI speaks MCP 2024-11-05 over JSON-RPC 2.0. Transport is Streamable HTTP with JSON responses, or SSE.

POST https://api.agi.tech/v1/mcp
// the client asks { "jsonrpc": "2.0", "id": 7, "method": "tools/call", "params": { "name": "phone_run_task", "arguments": { "prompt": "Open Settings and report the battery percentage." } } } // the server answers at once { "task_id": "…", "session_id": "…" }

architecture

Three pieces, one relay

phone_run_task dispatch progress result
Your AI client

Decides what to do

Claude Code, Cursor, ChatGPT or your own agent. Calls tools and reads results. Never touches the phone.

AGI cloud MCP server

Queues and relays

Authenticates you, queues tasks, dispatches them to your device, relays progress back.

api.agi.tech/v1/mcp
AGI Android app

The agent itself

Executes on-device through Android accessibility: real apps, real UI. Streams progress back.

Execution is asynchronous. A task takes seconds to minutes, so starting one returns a task_id at once and the client waits separately.

part 2

Set up & connect

Phone first, then your client, then one call to prove it.

on the phone

Four steps to Connected

1

Install and sign in

AGI Android app, same account as platform.agi.tech.

2

Grant Accessibility and overlay

How the agent reads the screen and shows while it works.

3

Settings › Developer connection

Tap Connect device. Wait for Connected.

4

Verify from your client

list_devices shows the phone as online.

‹ Developer ↻
</>
Connected
You can control this phone using your MCP client
Device ID 5b6dc94d-615c-461c-b8... c5839b69
Disconnect device

fastest path

Connect Claude Code in one command

~ zsh
$ claude mcp add --transport http agi-devices https://api.agi.tech/v1/mcp Added HTTP MCP server agi-devices to local config $ claude > /mcp agi-devices needs authentication → Authenticate Opening browser for AGI sign-in… agi-devices ✓ connected · 14 tools $ claude mcp list agi-devices: https://api.agi.tech/v1/mcp (HTTP) - ✓ Connected
1 · Add

Registers the remote server under the name agi-devices.

2 · Sign in

Run /mcp, pick agi-devices, finish the browser sign-in.

3 · Check

claude mcp list shows it connected. Claude Code stores and refreshes the token.

Terminal output is illustrative.

every other client

Same URL, different config

Claude Desktop

OAuth via bridge
{ "mcpServers": { "agi-devices": {
    "command": "npx",
    "args": ["mcp-remote", "https://api.agi.tech/v1/mcp"] } } }

In claude_desktop_config.json. Restart after saving. Needs Node 18+.

Cursor

API key
{ "mcpServers": { "agi-devices": {
    "url": "https://api.agi.tech/v1/mcp",
    "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } }

In .cursor/mcp.json. Key from platform.agi.tech/me/api-keys.

ChatGPT

OAuth

Turn on developer mode in Settings › Apps › Advanced settings. Then Settings › Apps › Create, enter the URL, choose OAuth, select Scan tools and sign in.

Plan and workspace availability is set by OpenAI.

VS Code, Windsurf, Zed

API key

Add a remote HTTP server named agi-devices with header Authorization: Bearer YOUR_API_KEY, then reload.

Any other client: OAuth 2.1 discovery or the same header.

what the sign-in does

OAuth 2.1, discovered automatically

Your client
AGI MCP server
AGI sign-in
request, no token
401 + where to sign in
fetch metadata, register client
browser sign-in · PKCE · email scope
retry with Bearer token
tools/list → phone tools
Recommended · OAuth

Add the URL with no token. The client discovers, registers itself and opens the browser. Tokens refresh on their own and are revocable per client.

Fallback · API key

For clients without OAuth. Create it at platform.agi.tech/me/api-keys and send it on every request.

Either credential is full control of your registered phones. Treat it like your unlocked phone.

prove it

Ask: “Which of my phones are online?”

list_devices → result
{ "account_email": "you@example.com", "devices": [ { "device_id": "5b6dc94d-615c-461c-b829-c5839b6986e8", "device_name": "samsung SM-S731U1", "status": "online", "paused": false, "is_default": true, "last_seen": "2026-08-04T00:49:41Z" } ] }

Phone listed, online

You're done with setup. Move on.

Call works, no phone

A phone-side problem. Check the account matches and Developer connection says Connected.

Only 2 tools

No device registered yet: only list_devices and set_default_device appear.

part 3

Run tasks

Start, monitor, act. Everything else is detail.

your first task

You

Check which of my Android devices are online, then open Settings on my phone and tell me the battery percentage.

list_devices1 device · samsung SM-S731U1 · online · default
phone_run_task · "Open Settings and report the battery percentage."returns at once · task_id · session_id
phone_task_monitormonitor_timed_out: true · still running, call again
phone_task_monitorstatus: completed · terminal: ok · result: "Battery is at 82%."
Assistant

Your Samsung is online. Battery is at 82%.

Settings
Connections
Sounds and vibration
Display
Battery
Apps
Accessibility
Battery
82%
About 14 h remaining
Power saving
Background usage limits

Example run. Device and battery values are illustrative.

the pattern

Start. Monitor. Act.

1 · Start
2 · Monitor
3 · Act
monitor_timed_out: true just call it again
phone_run_task

Send a prompt. Get task_id and session_id back right away.

phone_task_monitor

Blocks up to 120 s. Returns the moment the task is paused or completed. Timed out means still working.

read terminal

ok → use result. needs_user_control → answer it. Anything else has a recovery move.

Don't poll with phone_task_status. It is a snapshot, not a wait.

task lifecycle

Four states, one terminal

picked up terminal pause resume
pending
running
completed
paused

pending means the server has it and the phone hasn't started.

paused keeps the same task_id. Paused time doesn't count against the timeout.

completed always carries exactly one terminal that says why.

terminal outcomes

Every ending has a next move

terminalmeaningwhat to do
okFinished successfully.Read result.
needs_user_controlThe phone needs you: login, confirmation, CAPTCHA.Answer with phone_task_message.
timeoutRan past its deadline.Raise per_call_timeout_s or narrow the prompt.
queue_wait_exceededThe phone never started it.Check online and free, start a new task.
stopped_by_userCancelled, ended, or displaced by a new task.Start a new task if still needed.
agent_errorThe phone agent failed.Retry. Read error.
device_offlineCouldn't reach the device.Reconnect the phone, retry.
session_expiredSession ended first.New session, new task.
iteration_limitHit the agent's action limit.Split into smaller tasks.

human in the loop

When the phone hands control back

Assistant
AGI cloud
Phone + you
login screen → need_login
monitor: needs_user_control
you sign in on the phone
phone_task_message
→ continuation_task_id
monitor the continuation until ok
Triggers

Logins, confirmations, CAPTCHAs, or the agent asking a question. Read error.control_type and error.prompt.

Success signal

A continuation_task_id in the reply. delivered_to_device: false is fine here.

Never send passwords through messages. Let the user finish the step on the device.

the toolbox

Fourteen tools, four jobs

Devices list_devicesset_default_devicephone_device_statusphone_device_pausephone_device_resume

Find phones, pick a default, check health, stop new work.

State phone_get_state

Read-only snapshot: battery, network, locale, current app, launchable apps. No IMEI, contacts or location.

Sessions phone_session_startphone_session_end

Group a workflow on one phone. Usually automatic.

Tasks phone_run_taskphone_task_monitorphone_task_statusphone_task_messagephone_task_pausephone_task_resumephone_task_cancel

Start, wait, steer, pause, resume, cancel.

In practice you configure one tool, phone_run_task. The rest are handled by your assistant.

devices and sessions

One phone, one task at a time

Execution lane · samsung SM-S731U1
task Arunning
task Bnew phone_run_task

A new phone_run_task on the same phone cancels the old MCP task with stopped_by_user. A task you started in the app itself is not cancelled; it holds the lane and the MCP task waits as pending.

situationdo this
Follow-up, same workflowReuse the session_id
Unrelated errandLet phone_run_task decide
One task went wrongphone_task_cancel, keep session
Workflow finishedphone_session_end
Parallel workOne phone per workflow

Changing the default device never reroutes a session that already started.

task design

Prompts that hold up on a real screen

One errand per task

Chain follow-ups in the same session. Big prompts burn the timeout.

Name apps and people exactly

“WhatsApp, not WhatsApp Business. Chat with Sam Rivera.”

Gate anything that acts

“Show me the draft and wait for my OK before sending.”

Say what the result looks like

“Airline / time / price, one per line. Say so if none.”

Draw read-only lines

“Don't reply, don't archive, don't open links.”

Fragile

Check my battery, then go through all my unread email, reply to the important ones, find me a flight to Denver, and update my calendar.

Reliable

On my phone, open my calendar and tell me my first three events today. Don't change anything. If unsure, stop and ask me.

Always include an escape hatch: “if you're unsure, stop and ask me.” It turns a wrong guess into a handoff.

part 4

Go deeper & build

Trust, what runs on the phone, fixing problems, then your turn.

trust model

Treat it like your unlocked phone

Trust decision 1

Your client

It sees screen content and drives the phone. Connect only clients you trust.

Trust decision 2

Your credentials

An OAuth grant or API key is full control. Prefer OAuth. Revoke keys on any doubt.

Trust decision 3

What's on screen

Data, never instructions. A message saying “tap Allow” is not you.

Built in

Sensitive steps always come back as needs_user_control. State snapshots leave out IMEI, serial, contacts, location and notifications. Everything happens visibly on the screen.

Your part

Gate sends, buys and deletes in the prompt. Use a test phone for QA. phone_device_pause is the kill switch for new work. Results and screenshots can hold personal data.

inside the android app

What happens after the cloud dispatches

FCM

Wake-up push

Agents API stores the task and sends an FCM remote_task push that only references it.

Fetch

Load the task

The app fetches the prompt and deadline from Agents API, retrying through replica lag.

Claim

Own the lane

Persisted so it survives process death, then queued on the one device lane chat and voice also use.

Act

Step loop

Each step asks the action model what to do next. Accessibility taps and types it.

Report

Steps and result

Steps with screenshot thumbnails, then one terminal result. Retried up to 30 times; the first result wins.

Source: feature/remote-control in agi-inc/mobile. One agent loop serves chat, voice and remote tasks, which is why the phone runs one task at a time.

for engineers

The phone's side of the contract

Register

POST /v1/devices/register

FCM token, device model, OS and app version, and the tools the app can answer itself. The response id is the Device ID on the Developer screen.

Stay alive

POST /v1/devices/{id}/heartbeat

Every 15 minutes and after each push. A 404 triggers a fresh registration.

Answer directly

mcp_request → POST /v1/devices/{id}/mcp-result

phone_get_state never starts the agent. The phone collects the snapshot and replies within 10 s.

Push types the phone accepts

FCM typewhat the phone does
remote_taskFetch the task, queue it, run it
remote_followupDeliver a steering message to the running task
remote_pausePause the task in place
remote_resumeResume with an optional new instruction
remote_cancelStop it, stamped with a stop_reason
mcp_requestAnswer a direct tool call

Every push carries an id, never the content. The phone fetches each body by reference, so a large prompt never hits FCM's payload size limit.

when it doesn't work

The 60-second triage

1

Can you call list_devices?

No → authentication or client config. Check the URL, re-run sign-in, check the key.

2

Is the phone online and unpaused?

No → phone side. Same account? Developer connection says Connected? Tap Refresh.

3

What does the task say?

phone_task_status: its status, terminal and error almost always name the problem.

Know your error layer

HTTP 401

Credentials never reached MCP.

JSON-RPC error

device_paused, task_not_found. Fix the call.

Task terminal

The task ran and ended. Use the outcomes table.

your turn · 25 minutes

Four labs on your own phone

Lab 1 · 5 minthe loop

Open Settings on my phone and tell me the battery percentage.

Watch for: phone_run_task, then phone_task_monitor until ok.

Lab 2 · 5 minread-only

Open my calendar and list my first three events today as time / title. Don't change anything.

Watch for: a structured result, no edits on the phone.

Lab 3 · 8 minhandoff

In WhatsApp, draft “workshop test” to my own chat. Ask me before sending.

Watch for: needs_user_control, your reply, a continuation_task_id.

Lab 4 · 7 mincontrol

Start a long browse task, then steer it mid-run, pause it, resume it, and finally pause the whole device.

Watch for: phone_task_message, phone_task_pause, phone_device_pause.

keep going

Questions?

Serverhttps://api.agi.tech/v1/mcp
Supportsupport@theagi.company