Skip to main content
Glama
MobileAiUse

phone-agent-mcp

by MobileAiUse

phone-agent-mcp

Local MCP Server — Exposes the AI Agent capabilities from the WebADB browser page as MCP Tools, allowing external AI clients such as OpenClaw / Qoder to invoke them via the standard MCP protocol.

Architecture Overview

External AI Client (Qoder / OpenClaw / Browser-side MCP Client)
        │
        │  Streamable HTTP (SSE stream, preferred) or stdio (JSON-RPC 2.0)
        ▼
┌───────────────────┐      WebSocket       ┌──────────────────────────────┐
│  phone-agent-mcp  │ ◄──────────────────► │  Mobile AI Agent Browser Page│
│  (Node.js Process)│    ws://localhost    │  (https://mobile-ai-use.xyz) │
│                   │      :7788           │                              │
│  ┌──────────────┐ │                      │  ┌─────────────────┐         │
│  │ McpServer    │ │  callBrowser()       │  │ MCP Relay       │         │
│  │ (HTTP+stdio) │ │ ──── tool/args ────► │  │ (WS Client)     │         │
│  │              │ │ ◄─── result ──────── │  │                 │         │
│  │ 9 Tools      │ │                      │  │ Agent Scheduler │         │
│  │              │ │  progress ◄───────── │  │ Tool Executor   │         │
│  └──────────────┘ │                      │  └─────────────────┘         │
└───────────────────┘                      └──────────────────────────────┘
  • MCP Layer: Built on @modelcontextprotocol/sdk's McpServer, providing two transport channels:

    • Streamable HTTP (default port 7789, /mcp endpoint): SSE streaming output for results and intermediate progress, supports multiple sessions — the preferred channel

    • stdio: Traditional transport compatible with local CLI clients such as Qoder / OpenClaw

  • Relay Layer: Embedded ws WebSocket Server (default port 7788), forwarding tool call requests to the MCP Relay in the browser page

  • Progress Reporting: Supports the MCP notifications/progress protocol, pushing Agent thinking/execution progress to clients in real time

  • Tasks Extension: Supports the MCP Tasks extension (io.modelcontextprotocol/tasks), making long-running tasks asynchronous — clients can poll status, receive progress, and recover after disconnection

Related MCP server: scrcpy-mcp

Prerequisites

  • Node.js ≥ 18

  • pnpm (recommended, the project's unified package manager)

  • Mobile AI Use browser page open and running (https://mobile-ai-use.xyz), with the MCP Relay status indicator in the top bar showing green (connected)

Quick Start

# 1. Enter the mcp-server directory
cd mcp-server

# 2. Install dependencies
pnpm install

# 3. Build (generates dist/server.js)
pnpm run build

# 4. Start the server
pnpm start

Development mode (runs TypeScript directly without building):

pnpm run dev

After successful startup, the console outputs:

[phone-agent-mcp] WebSocket relay on ws://localhost:7788
[phone-agent-mcp] MCP server ready (stdio transport)
[phone-agent-mcp] Streamable HTTP on http://localhost:7789/mcp

Environment Variables

Variable

Default

Description

PHONE_AGENT_WS_PORT

7788

WebSocket relay port

PHONE_AGENT_HTTP_PORT

7789

Streamable HTTP port (also serves the /adb/* control plane)

PHONE_AGENT_ADB_WS_PORT

7790

ADB over WebSocket binary bridge port

PHONE_AGENT_ADB_SERVER_HOST

127.0.0.1

Local adb server host (control plane /adb/* only)

PHONE_AGENT_ADB_SERVER_PORT

5037

Local adb server port (control plane /adb/* only)

PHONE_AGENT_BIND_HOST

127.0.0.1

Bridge/control-plane bind address; a token is required when non-loopback

PHONE_AGENT_ADB_TOKEN

(empty)

Shared token enforced on non-loopback binds (used by both bridge and control plane)

ADB over WebSocket Bridge

Besides direct WebUSB, the web page can also treat a remote/networked phone as a first-class device: the host running phone-agent-mcp connects directly to the phone's adbd (ip:port, i.e. adb tcpip mode) and bridges the raw ADB stream to the browser over a WebSocket. The browser reuses AdbDaemonWebSocketDevice to produce a standard Adb instance, so screen mirroring / AI Agent / workflows all work with zero downstream changes.

Remote phone adbd (adb tcpip 5555)
        ▲  direct TCP to <ip:port>, raw ADB bytes relayed both ways
        │
phone-agent-mcp  ──  binary bridge WS (:7790)  ──►  Browser AdbDaemonWebSocketDevice

Control-plane endpoints (reuse the 7789 httpServer)

Endpoint

Method

Body

Success response

Description

/adb/devices

GET

—

{ "devices": [ { serial, state, model?, device?, product? } ] }

List devices currently known to the local adb server

/adb/connect

POST

{ "host": "192.168.1.5", "port": 5555 }

{ "ok": true, "message": "..." }

Make the host adb connect to the remote phone; failure returns 502 + { ok:false, message }

/adb/disconnect

POST

{ "serial": "192.168.1.5:5555" }

{ "ok": true, "message": "..." }

adb disconnect the given device

Error conventions: unauthorized 401; missing param / malformed JSON 400; wrong method 405 (with Allow header); unknown path 404; no local adb (not on PATH) 503; any other failure 500.

Bridge endpoint (7790)

The browser connects via ws://<host>:7790/?serial=<serial>[&token=<token>]; the bridge parses serial as ip:port, opens a direct TCP connection to the phone's adbd and relays bytes bidirectionally (the browser performs the CNXN/AUTH handshake itself). serial must be ip:port; USB serials are not supported (use WebUSB instead). Only one active bridge per serial is allowed; duplicate connections are rejected. Close codes: 4401 invalid token / 4400 missing serial or serial is not ip:port / 4409 device busy / 4502 failed to connect to adbd (refused / timeout / unreachable) / 4503 adbd connection errored or closed.

Prerequisites

  • adb is on the host PATH (adb version works).

  • The remote phone has been switched with adb tcpip 5555 and is reachable at its ip:port. The random TLS port of Android 11+ "Wireless debugging" is not supported by the bridge yet.

  • The browser uses its own ADB key, so the phone shows an "Allow USB debugging" prompt on the first bridge; confirm it on the phone.

Security

  • localhost needs no token: when PHONE_AGENT_BIND_HOST is loopback (default), the control plane only accepts requests whose peer is a loopback address, and the bridge needs no token.

  • Non-loopback enforces a token: binding to a non-loopback address requires PHONE_AGENT_ADB_TOKEN; otherwise the startup guard assertBridgeAuth throws and aborts startup. Afterwards the control plane requires Authorization: Bearer <token> or ?token=<token>, and the bridge requires ?token=<token>.

  • Mixed content: if the page is served over https, the browser blocks ws://; configure wss:// for the bridge (TLS terminated by a reverse proxy).

Registered Tools

Tool

Permission

Timeout

Description

run_agent_task

Write

Configurable

Run an AI Agent task on the connected phone with a natural language goal (supports async execution via the Tasks extension)

abort_task

Write

10s

Abort the currently running Agent task

get_task_result

Read

10s

Get detailed results (including steps) of a completed task by task ID

get_latest_task

Read

10s

Get the result of the most recent Agent task in the current conversation

take_screenshot

Read

30s

Take a screenshot of the connected phone screen, returns a PNG image

get_device_status

Read

15s

Get device information (model, brand, OS version, etc.)

search_memory

Read

10s

Search the Agent's persistent memory store by keyword

save_memory

Write

10s

Save a semantic memory entry to the memory store

delete_memory

Write

10s

Delete a memory entry by ID

run_agent_task in Detail

Parameter

Type

Required

Description

goal

string

Yes

Natural language task goal, e.g. "Open WeChat and send 'Hello' to Zhang San"

timeoutMs

number

No

Maximum execution time in milliseconds, default 1,200,000 (20 minutes)

The Agent will automatically plan execution steps and achieve the goal through screen visual recognition and touch control. During execution, thinking/tool calls/step results are pushed in real time via MCP notifications/progress.

MCP Tasks Extension (Async Long-Running Tasks)

run_agent_task is registered as a task-based tool (taskSupport: 'optional'), supporting the MCP Tasks extension (io.modelcontextprotocol/tasks) to address blocking and connection interruption issues with long-running operations.

Workflow

Client                                          Server
  │  tools/call run_agent_task                    │
  │  params: { arguments, task: { ttl } }         │
  ├──────────────────────────────────────────────►│  createTask → returns immediately
  │  CreateTaskResult { task: { taskId,           │  continues executing in background
  │    status: 'working', pollInterval } }        │
  │◄──────────────────────────────────────────────┤
  │  tasks/get { taskId }   ◄── poll ───►         │  notifications/tasks/status proactive push
  │  … status: working (statusMessage=progress) … │
  │  tasks/result { taskId }                      │  after task completes
  │◄────────────── CallToolResult ────────────────┤

Task States

State

Meaning

working

Task is executing; statusMessage carries the latest progress (Agent thinking/steps)

completed

Task completed successfully; final result available via tasks/result

failed

Task failed (including browser not connected, timeout, etc.); result contains error details

cancelled

Client cancelled via tasks/cancel

Server Capability Declaration

"capabilities": {
  "tasks": {
    "list": {},
    "cancel": {},
    "requests": { "tools": { "call": {} } }
  }
}

Supported endpoints: tasks/get (check status), tasks/result (get result), tasks/list (list tasks), tasks/cancel (cancel).

Key Parameters

Parameter

Value

Description

TTL

timeoutMs + 10min

How long results are retained after task completion; auto-cleaned after expiry

pollInterval

2000ms

Recommended client polling interval

Backward Compatibility

  • New clients (declare tasks capability): Call with task parameter → immediately receive taskId, poll tasks/get / fetch result via tasks/result

  • Legacy clients (no task parameter): Server automatically falls back to internal polling, synchronously waits and returns CallToolResult directly — behavior identical to the previous version

Note: tasks/cancel only marks the task as cancelled and stops result writing; to actually interrupt execution on the phone, call the abort_task tool separately.

Configuration for AI Clients

Clients supporting remote/HTTP connections (including browser-side MCP clients) can point directly to the URL:

{
  "mcpServers": {
    "phone-agent": {
      "url": "http://localhost:7789/mcp"
    }
  }
}

Verify connectivity:

curl -N -X POST http://localhost:7789/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'

The mcp-session-id response header is the session ID, which must be included in subsequent requests; the response body is an SSE stream (text/event-stream).

stdio (Qoder / Claude Desktop / OpenClaw Local Integration)

Add the following to the client's MCP configuration file:

{
  "mcpServers": {
    "phone-agent": {
      "command": "node",
      "args": ["/path/to/mcp-server/dist/server.js"],
      "env": {
        "PHONE_AGENT_WS_PORT": "7788"
      }
    }
  }
}

OpenClaw

mcp_servers:
  phone-agent:
    command: node
    args:
      - /path/to/mcp-server/dist/server.js
    env:
      PHONE_AGENT_WS_PORT: "7788"

After configuration, all 9 phone Agent tools listed above will be available in the AI client — invoke them directly to control the phone.

Streamable HTTP Transport Details

Streamable HTTP is the standard MCP transport protocol. The server outputs intermediate progress notifications and final results sequentially within the same HTTP response via an SSE stream, eliminating the need for additional client polling:

Endpoint

Method

Purpose

/mcp

POST

Client message entry point (initialize / tools/call / tasks/* etc.), response is an SSE stream

/mcp

GET

Opens a dedicated SSE stream to receive server-initiated pushes (e.g. notifications/tasks/status)

/mcp

DELETE

Close the session

Streaming Output Content

During execution of long-running tools (e.g. run_agent_task), the response stream pushes in real time:

  • notifications/progress: Agent thinking/execution progress (when client declares progressToken)

  • notifications/message: Fallback channel for progress log downgrades

  • notifications/tasks/status: Task state changes (working/completed/failed)

The end of the stream contains the final CallToolResult or CreateTaskResult (task mode).

Session Management

  • Stateful mode: Server generates a sessionId, delivered via the mcp-session-id response header with initialize; subsequent requests must include it

  • One McpServer instance per session; tool handlers share a global browser relay and task store (taskStore is cross-session — tasks can continue to be polled after disconnect/reconnect)

  • CORS is open: Browser-side MCP clients can access directly

Connection Flow

  1. Start mcp-server: pnpm start — launches stdio / Streamable HTTP dual channels and the WS relay

  2. Open the browser page: Navigate to the WebADB page, ensuring the device is connected

  3. Confirm Relay connection: The Relay status indicator in the top bar turns green; console outputs Browser connected

  4. Connect MCP client:

    • HTTP clients point to http://localhost:7789/mcp (include mcp-session-id after initialize)

    • Local CLI clients launch via stdio: node dist/server.js

  5. Invoke tools: Requests are forwarded via WebSocket to the browser for execution; results and intermediate progress are streamed back via SSE / stdio

Project Structure

mcp-server/
├── src/
│   └── server.ts          # Main server: McpServer + WS + 9 tool registrations
├── dist/
│   └── server.js          # Build output
├── package.json
├── tsconfig.json           # TypeScript config (ES2022 / NodeNext)
└── pnpm-lock.yaml

Tech Stack

Component

Version

Purpose

@modelcontextprotocol/sdk

^1.12.0

MCP server framework (McpServer + StdioServerTransport)

ws

^8.18.0

WebSocket server, relays browser connection

zod

^4.4.3

Tool parameter validation and schema declarations

typescript

~5.8.3

Type safety

tsx

^4.19.0

Run TS directly in development mode

Design Highlights

  • Dual transport channels: Streamable HTTP (SSE streaming for results and intermediate progress, multi-session) and stdio (local CLI compatible) coexist; tool registration logic is unified by the createPhoneAgentServer() factory function

  • Cross-session task store sharing: InMemoryTaskStore is a global singleton — clients can continue polling non-expired tasks via tasks/get / tasks/result after reconnecting (new session)

  • Single browser connection: Only one browser WS connection is accepted at a time; new connections replace old ones

  • Request-response matching: WS responses are routed to the corresponding pending Promise via the id field

  • Timeout fallback: Each tool call has an independent timeout; returns an error message on timeout instead of hanging

  • Dual-channel progress: Prefers notifications/progress (requires client to declare progressToken), falls back to notifications/message (logging); in task mode, also writes task.statusMessage and pushes notifications/tasks/status simultaneously

  • Silent fault tolerance: Progress push failures do not interrupt task execution; background writes are safely skipped after task cancellation/TTL cleanup

  • Browser offline hint: Returns a friendly error "Browser not connected" when the WS is not connected

Available Tools

9 tools
abort_taskB

Abort the currently running Agent task.

NameRequiredDescriptionDefault

No parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states it aborts the running task but doesn't disclose consequences (are results lost? Is it reversible? Does it need admin privileges?). An abort operation likely has destructive implications that are not surfaced, and there's no annotation to cover the safety profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with zero wasted words. It's efficient and front-loaded. Slight deduction only because it's arguably under-specified rather than optimally concise for a potentially destructive operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with no output schema, the description is reasonably complete on the surface. However, the absence of any behavioral context about side effects or prerequisites of an abort operation is a notable gap for a destructive-sounding tool. It's adequate but not comprehensive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has 0 parameters and no schema to document, so the schema coverage is trivially 100%. With no parameters, there is nothing for the description to explain, making the baseline 4 for parameter semantics appropriate since no compensation is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Abort') with a clear resource ('the currently running Agent task'). It clearly states what the tool does. It lacks explicit sibling differentiation, though the sibling list shows related task tools (run_agent_task, get_task_result) where this abort action is contextually distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states what it does but gives no guidance on when to use it versus alternatives or what conditions apply. It doesn't specify whether it applies only to tasks started by this system, what happens to partial results, or whether running is a prerequisite. No exclusions or explicit context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_memoryA

Delete one memory entry (semantic or episodic) by its id.

NameRequiredDescriptionDefault
idYesMemory id returned by search_memory / save_memory

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses that the operation targets either semantic or episodic memory types, which is useful scope information. However, it doesn't disclose whether deletion is permanent/irreversible, whether it requires any permissions, or whether related/referenced memories are also affected.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused sentence with zero wasted words. It front-loads the primary verb and resource, then scopes with the semantic/episodic distinction and id requirement. No redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter destructive operation with no output schema, the description is reasonably complete. However, as a delete operation with zero annotations, it would benefit from stating irreversibility or idempotency behavior. The mention of 'semantic or episodic' types is genuinely helpful context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents the 'id' parameter. The description adds minimal value by confirming the id refers to what search_memory/save_memory return (already stated in the schema). With full coverage, the baseline of 3 is appropriate with no significant extra meaning added.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Delete one memory entry (semantic or episodic) by its id' - a specific verb (delete) and resource (memory entry), with clarity that it handles both semantic and episodic types. It differentiates from siblings like save_memory and search_memory by describing the write/delete operation, though it doesn't explicitly contrast with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by specifying 'by its id' and mentioning both semantic and episodic memory types, indicating when this applies. However, it doesn't provide explicit when-to-use vs alternative guidance, nor does it address edge cases like what happens when the operations is attempted on a missing/invalid id.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_device_statusA
Read-only

Get information about the connected phone device (model, brand, OS version, etc.).

NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, and the description aligns with this by framing the operation as 'Get information' — no contradiction. The description adds value by specifying what kind of information is returned (model, brand, OS version, etc.), which helps the agent anticipate output. It doesn't cover edge cases like device-not-connected errors, but for a read-only info tool, the coverage is reasonable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that gets straight to the point. It's front-loaded with the core purpose and enumerates example fields for concreteness without padding. Slightly more structure (e.g., a separate note on return behavior) could help, but it's appropriately lean for a zero-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 0 parameters, a readOnlyHint annotation, no output schema, and low conceptual complexity, the description is largely sufficient. What's missing: no explicit mention of failure modes (e.g., what happens when no device is connected), but for a zero-param info retrieval tool, the description covers the essentials well.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has 0 parameters, and with no params, the baseline is 4 per the rubric. There are no parameters to document, so semantic gaps don't apply. The description appropriately explains what the tool retrieves rather than trying to document nonexistent parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('Get information about the connected phone device') and enumerates example fields (model, brand, OS version), making the purpose clear. However, it doesn't explicitly distinguish itself from sibling tools, though the sibling set (memory, tasks, screenshots) is clearly different enough that no confusion is likely.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context (checking device details) but provides no explicit when-to-use guidance or exclusions. With 8 siblings spanning memory, task, and screen operations, the absence of any 'use this for X, not Y' type guidance leaves some room for ambiguity, though the tool's domain (device info) is fairly self-apparent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_latest_taskA
Read-only

Get the most recent Agent task result from the current conversation.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, so the safety profile is already covered. The description adds scope context ('most recent', 'current conversation') beyond annotations. However, it doesn't disclose what happens if no task exists in the conversation (error, null result, etc.), and being read-only is largely implied by the annotation already.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, tightly-scoped sentence with zero waste. Every word earns its place — verb, resource, and the two scope qualifiers ('most recent', 'current conversation') all carry meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 0-parameter, read-only, no-output-schema tool, the description is reasonably complete. The main gap is behavioral: what happens on an empty conversation or when no agent task has run, and whether 'task result' refers to run_agent_task or get_task_result outputs. Some ambiguity remains around what constitutes a 'task result' and its relationship to sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0 parameters and schema coverage at 100%, the schema fully documents everything. No parameter information is needed in the description since there are no parameters to explain. Baseline 4 for a 0-param tool is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Get the most recent Agent task result from the current conversation' — a specific verb+resource ('get... task result') with clarifying scope ('most recent', 'current conversation'). It's clear about what it does, though it doesn't explicitly distinguish from sibling get_task_result, relying on the 'most recent' qualifier to differentiate scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'from the current conversation' provides some context for when it applies, and having sibling get_task_result implies there's a scoping distinction (latest vs specific). However, there's no explicit guidance on when to choose this over get_task_result, when the conversation context matters, or any prerequisites (e.g., must a task have been run first?).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_task_resultA
Read-only

Get the detailed result of a completed Agent task by its task ID.

NameRequiredDescriptionDefault
taskIdYesTask ID returned by run_agent_task
includeStepsNoInclude per-step details (default: true)

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, which the description aligns with (a 'get' operation is consistent). The description adds context that the task must be 'completed' for a result to exist, implying that incomplete/running tasks won't yield results via this tool. This is a meaningful behavioral constraint beyond the annotation. Siblings like abort_task and run_agent_task suggest a task lifecycle where this tool is the terminal read step.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, compact sentence that states exactly what the tool does with no filler. Every word earns its place. This is appropriately front-loaded and minimal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only result-fetch tool with a fully documented schema (100% coverage, no output schema), the description plus annotations cover the essential contract: what it returns (result of a completed task), key input (taskId), and optional behavior (includeSteps with default). The absence of an output schema reduces the descriptive burden. A minor gap is not noting what happens for a task in progress or an invalid ID, but for a simple fetch tool this is adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with both parameters documented: taskId is described as 'returned by run_agent_task' and includeSteps has a default of true. The description itself adds no parameter-specific detail beyond 'by its task ID,' relying on the schema. Baseline 3 is appropriate since the schema does the heavy lifting and explicitly documents both parameters well.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb+resource: 'Get the detailed result of a completed Agent task by its task ID.' It states the resource (task result), the action (get), and the identifier (task ID). It doesn't differentiate from siblings like get_latest_task, which retrieves tasks but for a different scope (latest vs. by ID). A small mention of 'completed' adds scope but no explicit sibling distinction, so 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving completed task results by task ID, but doesn't explicitly state when to use this vs. get_latest_task or when not to use it. No alternative tools are named. The context (completed task, task ID from run_agent_task) is implied by the parameter description in the schema rather than stated in the tool description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_agent_taskA
Destructive

Run an AI Agent task on the connected phone. The agent will plan and execute multiple steps to achieve the goal using screen vision and touch controls.

NameRequiredDescriptionDefault
goalYesNatural language task goal, e.g. "Open WeChat and send hello to John"
timeoutMsNoMax execution time in milliseconds (default: 120000)

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that the agent autonomously plans and executes multiple steps using screen vision and touch controls, which is important behavioral information (the agent has agency and may perform actions beyond a simple explicit one). The annotations already declare destructiveHint=true and readOnlyHint=false, which the description aligns with. It adds context that the agent is autonomous and may take multiple actions, which is valuable beyond the raw annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused sentence plus an example in the schema. It's front-loaded with the core purpose and adds the key behavioral detail about autonomous planning. Efficient and earns its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 2 well-documented parameters, no output schema, and good annotations, the description covers the essential purpose, the autonomous execution mode, and the execution mechanism. It could mention what the return value looks like (task ID, result, etc.) since there's no output schema, but given the 100% schema coverage and sibling context, it's reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already fully documents both parameters (goal and timeoutMs) with descriptions. The description adds some context by showing a concrete example ('Open WeChat and send hello to John') in the schema, and mentions timeouts indirectly. Baseline of 3 is appropriate since the schema carries the parameter documentation burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool runs an AI agent task on the connected phone, explaining it plans and executes steps using screen vision and touch controls. It uses a specific verb+resource combination ('run agent task'), which distinguishes it from siblings like take_screenshot or get_device_status. However, it doesn't explicitly differentiate itself from related task tools like abort_task or get_latest_task.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description conveys it's for multi-step goals achieved via vision and touch, implying usage for complex tasks. However, there's no explicit guidance on when to use this vs alternatives like take_screenshot or when not to use it. The distinction from simpler direct-action tools is implied but not spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_memoryB

Save a semantic memory (reusable knowledge) into the phone agent's persistent memory.

NameRequiredDescriptionDefault
titleYesOne-line title of the memory
contentYesMemory content, under 200 chars recommended
keywordsNoOptional search keywords

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden for behavioral transparency. It states the write/persist nature ('into persistent memory'), but does not disclose whether the operation is additive-only, how it interacts with existing memories of the same title, whether duplicates are overwritten or stacked, storage limits, or any side effects. Beyond the schema's own field hints, little additional behavior is revealed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, focused sentence that conveys the core action and purpose without waste. Any behavioral or usage detail is absent, but as written it is maximally efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple 3-param write tool with 100% schema coverage and no nested objects, so it doesn't demand much. However, with no annotations and no usage exclusions, it would benefit from clarifying memory-management behavior (e.g., whether same-title writes override or append, and typical use cases vs search_memory). Adequate but with gaps given the sibling tooling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters (title, content, keywords) have inline schema documentation. The description adds the 'under 200 chars recommended' guidance via the schema, not the tool description itself. The description text adds little beyond the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The verb 'Save' plus the resource 'semantic memory' clearly states the tool's action. The parenthetical 'reusable knowledge' usefully clarifies what a semantic memory means. It's distinguishable from siblings like search_memory and delete_memory, though it doesn't explicitly call out any sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description notes this is for 'reusable knowledge' saved into persistent memory, implying it's for knowledge that should persist. However, there is no explicit guidance on when NOT to use it, when to prefer alternatives, or what kind of content is appropriate beyond the persistence framing. It lacks excluded cases (e.g., ephemeral data).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_memoryB
Read-only

Search the persistent memory of the phone agent by keywords. Returns semantic memories (learned experience) and/or episodic records (task history).

NameRequiredDescriptionDefault
typeNoRestrict to one memory type (default: both)
limitNoMax results (default: 5)
queryYesKeyword query, Chinese or English

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint=true annotation already declares this as a safe read operation, so the bar for transparency is lower. The description confirms it's a search (non-mutating) operation, consistent with the annotation. However, it doesn't disclose what happens when no matches are found, whether results are ordered, or anything about the result format, which would be useful given there's no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that packs in the tool's purpose and the semantic/episodic distinction. It's front-loaded with the core action ('search the persistent memory') followed by clarifying detail. No wasted words, though it could arguably say more about result behavior without becoming verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with readOnlyHint, 100% schema coverage, and no output schema, the description provides adequate but not rich context. It defines the two memory types, which is helpful. However, it doesn't describe what the results look like (the return format is undocumented), and it doesn't mention pagination or ordering behavior. A search tool with a limit parameter would benefit from describing what happens with results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters. The description adds the semantic vs. episodic distinction and mentions keyword search, which aligns with the query parameter's 'keyword query' description. However, the description doesn't add meaningful semantic detail beyond what the schema provides—it clarifies what the two memory types mean ('learned experience' vs 'task history') but doesn't enhance parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb (search), resource (persistent memory), and scope (keyword-based search). It also distinguishes between semantic memories and episodic records, which adds specificity. It doesn't explicitly differentiate from sibling tools like delete_memory or save_memory, but the verbs alone make the distinction obvious.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is for searching memory contents but doesn't provide explicit when-to-use guidance or contrast with alternatives. The mention of both semantic and episodic types gives some context, but there's no statement about when to search one type versus the other, nor guidance about when to use run_agent_task or other task-related tools instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

take_screenshotA
Read-only

Take a screenshot of the connected phone screen. Returns a PNG image.

NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already declares this is a safe read operation, so the bar is lower. The description adds that it returns a PNG image, which is a useful behavioral detail. However, it does not disclose potential limitations such as screen lock state, permission requirements, or what happens if no phone is connected.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with zero wasted words. It front-loads the core action ('Take a screenshot') and follows with the output format. Highly efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless, read-only tool with a clear purpose and stated output format (PNG), the description is reasonably complete. There is no output schema, but the description addresses the return type. Minor gaps around failure conditions exist, but they don't substantially impede correct tool usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are 0 parameters, so the schema carries no burden and the description doesn't need to explain any. With no parameters to document, the baseline of 4 applies. The description correctly focuses on behavior and output rather than parameter details that don't exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (take a screenshot), the target resource (connected phone screen), and the output (PNG image). It distinguishes itself from siblings—none of which relate to screen capture—so there is no ambiguity about what this tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it (when a screenshot of the phone is needed) but does not explicitly name alternatives or exclusion conditions. There is no guidance about prerequisites like device connection state, which the sibling get_device_status might help verify. However, the purpose is clear enough that an agent can infer appropriate usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 9 tool updatesv1.0.0
    • First observedabort_task
    • First observeddelete_memory
    • First observedget_device_status
    • First observedget_latest_task
    • First observedget_task_result
    • First observedrun_agent_task
    • First observedsave_memory
    • First observedsearch_memory
    • First observedtake_screenshot

TDQS

A3.7/5.0

Scored across 9 tools

Disambiguation4/5

Most tools are clearly distinct: run_agent_task, get_task_result, get_latest_task, take_screenshot, get_device_status, abort_task, and the three memory tools all have obvious purposes. get_task_result and get_latest_task could be mildly confused (both retrieve task results), and save_memory vs search_memory vs delete_memory are clear. No significant overlap issues.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern throughout: delete_memory, run_agent_task, get_task_result, get_latest_task, take_screenshot, get_device_status, save_memory, search_memory, abort_task. Every name is snake_case with a clear action verb followed by a target noun, showing strong uniformity.

Tool Count5/5

Nine tools is well within the ideal 3-15 range for a phone agent MCP server. Each tool corresponds to a distinct capability: task management (run/get/latest/abort), memory management (save/search/delete), device inspection, and screen capture. None feels redundant or unnecessary.

Completeness3/5

The server covers core workflows: device inspection, task execution/retrieval/abort, screenshots, and memory operations. However, there are no explicit memory update operations (only save/delete/search), and no direct touch-input tool outside of the agent task abstraction, which may be fine given the agent-centric design but leaves some gaps for low-level control.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    C
    maintenance
    A MCP server that enables AI assistants to control Android devices via ADB, supporting device info, screen control, input simulation, app management, shell execution, file transfer, and UI parsing.
    20
    -
  • A
    license
    A
    quality
    A
    maintenance
    MCP server that gives AI agents full vision and control over Android devices via ADB and scrcpy. Supports screenshots, input, apps, UI automation, shell, files, and clipboard.
    38
    365 npm
    125
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that wraps Android ADB functionality into AI assistant tools, enabling device management, shell execution, file operations, app management, media capture, and log analysis via natural language.
    13 npm
    2
    MIT