agentleFS
FZ2000FZ2000/android-jev/.cursor/rules/android-phone-control.mdc

android-jev / rules

Cursor rule1 starsChanged 37 days agoMITView on GitHub

Read by Cursor. Attached on request rather than always, like the skill it mirrors. The instructions below are written for any agent. The phone is driven through an MCP server, so any client that speaks MCP can use it: the tools appear here under the android server namespace as mcpandroidread_screen and so on, and your client may present that name differently. Say what you want done. The phone works out how. The phone is attached over USB. You do not…

We split this android-phone-control.mdc into the rules it gives an agent

5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Call run_task with the outcome you want, in plain language:

    line 26
  2. Distinctive:

    If the two disagree the run carries on, because a wrong "done" ends everything and reports success that never happened.

    line 81
  3. Distinctive:

    A locked phone cannot be worked around: If the run reports the phone is locked, ask the user to unlock it.

    line 106
  4. Distinctive:

    Non-ASCII text cannot always be typed as keystrokes: If a goal involves accented text, emoji or a non-Latin script and it fails, that is …

    line 110
  5. Very specific:

    A goal the phone cannot do will be reported as such: If the user asks for something no phone can do, achieved will be false.

    line 114

≈ “Common” is an estimate: at least 1 in 5 of the 6,350 Cursor rule files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
android-phone-control.mdc
<!-- Generated from skills/android-phone-control/SKILL.md by scripts/render_skill_for_agents.py. Edit that file, not this one. -->
---
description: Operating, driving or automating an Android phone over USB
alwaysApply: false
---

> Read by Cursor. Attached on request rather than always, like the skill it mirrors.
>
> The instructions below are written for any agent. The phone is driven
> through an MCP server, so any client that speaks MCP can use it: the
> tools appear here under the `android` server namespace as
> `mcp__android__read_screen` and so on, and your client may present that
> name differently.

# Doing things on an Android phone

Say what you want done. The phone works out how.

The phone is attached over USB. **You do not need to know anything about how it
is driven** — no screen-reading, no tapping, no accessibility trees. That is the
server's job, and a decision model inside it works out each step and tells you
when the instruction is complete.

## State the goal

Call `run_task` with the outcome you want, in plain language:

```
run_task("open the email app")
run_task("turn on aeroplane mode")
run_task("set an alarm for 7am")
run_task("send a text to Alice saying I'll be late")
```

That one call replaces a whole back-and-forth. The phone reads its own screen,
decides what to do, does it, checks the result, and repeats until the goal is
reached or it cannot get there — then reports back.

**Phrase the goal as the outcome, not the steps.** "open the email app", not
"tap the Gmail icon". You are describing what should be true when it finishes.

**Keep it short, and ask for one thing at a time.** A goal that names the app and the
thing you want, and no more, is the one that works:

```
run_task("open the Play Store")
run_task("search for YouTube")
run_task("open YouTube")
```

Three calls, each waiting for the one before it, beat a single request that spans
them: "find YouTube in the app store and install it" asks the phone to hold a plan
across several screens, and leaves you with one report to guess at instead of three
you can read.

Multi-step work is fine — send the steps one at a time, and send the next once the
one before has come back. When something fails you will know which step it was, and
so will the person you are working for.

`max_steps` bounds how much it will try. Leave it alone unless the task is
genuinely long.

## Read the report

`run_task` returns what happened, and the two fields that matter most are at the
top:

| Field | Meaning |
| --- | --- |
| `achieved` | Whether the goal was reached. **Trust this, not the phrasing.** |
| `outcome` | How it ended, as a name: `done`, `nothing_helps`, `stalled`, `step_limit`, `not_carried_out`. Branch on this rather than reading `reason`. |
| `summary` | One sentence you can relay to the user as-is. |
| `reason` | Why it stopped — especially useful when `achieved` is false. |
| `steps` | Every action taken, in order, with what decided each one. |
| `final_foreground_app` | What ended up in front, for your own sanity check. |
| `goal_achieved_probability` | How likely it judged the goal already met, asked separately from the action it chose. A low number on a failed run says it knew it had not got there. |
| `decided_by` | Which decision model ran, so you know what to expect. |

**`achieved` is not one model's opinion.** The work is only declared done when
the chosen action says so *and* a separate question about the same screen agrees.
If the two disagree the run carries on, because a wrong "done" ends everything and
reports success that never happened.

**A run that fails says so.** It does not claim success for something it could
not do. If `achieved` is false, `reason` says why — most often that it could not
get there from the screen it reached, or that it was about to repeat itself.

## If it comes back unfinished

Say so. `achieved` false with `reason` is the honest answer, and the report names
the screen it stopped on and every action it took — which is what the person
holding the phone needs in order to take it from there, and what you need in order
to explain what happened.

Report it rather than trying the job again by hand. There is no set of smaller
tools to reach for: the phone is driven by describing the outcome, and working out
which control to touch from a screen is the server's job. An agent that starts
choosing controls instead is doing that job with less of the information.

## Things worth knowing

**The phone is real and someone is holding it.** Sending a message, deleting
something or spending money has consequences. Say what you are about to do
before you do it, and do not take an instruction further than it was given.

**A locked phone cannot be worked around.** If the run reports the phone is
locked, ask the user to unlock it. A PIN cannot and should not be entered for
them.

**Non-ASCII text cannot always be typed as keystrokes.** If a goal involves
accented text, emoji or a non-Latin script and it fails, that is usually why —
say so rather than retrying.

**A goal the phone cannot do will be reported as such.** If the user asks for
something no phone can do, `achieved` will be false. Relay that; do not invent a
success.

## When something fails

Failures come back with a plain explanation and, where there is one, a concrete
next step. Relay it rather than retrying blindly.

Two need the user's hands on the phone, so say so plainly instead of retrying:

- **no Android device is attached** — the cable is unplugged, or USB debugging
  has been switched off
- **the phone has not authorised this computer** — it is showing an *Allow USB
  debugging?* prompt that needs a physical tap

## If `run_task` is not among your tools

The phone is driven through an MCP server, and this skill only describes how to ask
it for things. If you have no `run_task`, the server is not mounted in this session:
say so rather than improvising with other tools. `README.md` in the repository this
skill came from has the setup — connecting the phone, the key, and mounting the
server — and mounting usually needs a new session before the tools appear.

## Full reference

[`skills/android-phone-control/references/tools-reference.md`](skills/android-phone-control/references/tools-reference.md) has every tool
with its arguments, and the keys `press_key` accepts.

Download now (ZIP)

  • Where files are headingNew Cursor rule files have more rules about planning and tracking tasks, and fewer about code style.

    Of the Cursor rule files we read, the 3,978 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repository4 other files it gives its agents.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.