---
author: 小檬 XMeng · 墨迹 Moji
date: Sep 10, 2026
---

# MengPaw_Browser_skills.md — Browser Command Manual (for am-bridge callers)

> Audience: **same-signature callers** that drive the MengPaw.Browser APK over the am bridge (MengPaw Shell is one of them).
> Version: v0.10.1 · 2026-09-10 · This file covers the browser's entire command surface and operating techniques.
> The 9880 HTTP bridge and open mode are retired (decision #7); third-party integration is no longer supported and only same-signature apps can issue commands.
> For developer-side architecture details, see the companion [`MengPaw.Browser Development Documentation`](article.en?md=articles/mengpaw-browser.en.md)<a class="md-dl" href="articles/mengpaw-browser.en.md" download="mengpaw-browser.en.md" title="Download MengPaw.Browser Development Documentation" aria-label="Download MengPaw.Browser Development Documentation"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 10.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-2.5"/><path d="M8 2v9.5"/><path d="M4.5 8 8 11.5 11.5 8"/></svg></a> in the same directory.
>
> **This document is the only Browser asset that needs to be synced to the Shell side.** The Browser project is
> decoupled from Shell (version line, releases, update path and documentation ownership are all independent),
> keeping only two couplings: this manual and the shared Android engineering notes.

## 1. Quick Start (2 Steps)

```bash
# 1. Wake the browser (run on the Android device)
am start -a com.mengpaw.action.OPEN_URL --es url "https://example.com"

# 2. Execute a command: output lands in the public directory for the caller to read back
am startservice -n com.mengpaw.browser/.service.RunCommandService \
  --es com.mengpaw.browser.RUN_COMMAND_ARGUMENTS "-c,page.content --head 20" \
  --es com.mengpaw.browser.RUN_COMMAND_OUTPUT /storage/emulated/0/MengPaw/out.txt
```

> Browser commands plug into a Linux command flow: once the output is on disk, pipe it straight through `grep` / `head` / `tail`.

## 2. Waking Up the Browser

When the browser is not running (or was killed), the am bridge is unreachable and must be woken first:

| Intent | Purpose |
|--------|---------|
| `am start -a com.mengpaw.action.OPEN_URL --es url <url>` | wake up + open a URL (recommended) |
| `am start -a android.intent.action.VIEW -d <http(s)://...>` | open a web page at the system level |
| Desktop icon / `MAIN + LAUNCHER` | manual wake-up |

Once woken, the am bridge is available immediately (BrowserActivity onCreate initializes
`BuiltinBrowserPlugin.shared`); no manual enabling is needed. While it is not running, calls report
"browser not ready (open the MP browser first and retry)".

## 3. Command-Surface Overview

Commands fall into two groups: `page.*` (22 commands, Playwright semantics, primary) and
`browser.*` (21 commands, retained capabilities).

### 3.1 page.* — The Primary Command Surface

| Command | Description |
|------|------|
| `page.load <url> [--max-height N]` | **semi-automatic all-in-one**: navigation + full-page segmented screenshots + coordinate system (recommended starting point) |
| `page.goto <url> [--wait domcontentloaded\|networkidle]` | navigate + precise waiting |
| `page.screenshot [--full] [--view]` | screenshot; returns only the path + size/coordinates; over-long pages are split into segments |
| `page.screenshot.element <css>` | element screenshot |
| `page.click <seg> <x> <y>` / `page.click <css>` | click by segment-image coordinates / by selector |
| `page.fill <css> <text>` | type input |
| `page.select <css> <value>` / `page.submit <css>` | select a dropdown value / submit a form |
| `page.check` / `page.uncheck` | check / uncheck |
| `page.content [--grep P] [--regex] [-i] [--head N] [--tail N]` | extract content + filter |
| `page.text <css>` / `page.attr <css> <name>` | element text / attribute |
| `page.wait_selector <css> [--timeout N]` | wait for an element to appear |
| `page.scroll <x> <y>` / `page.scroll_by <dy>` | absolute / relative scrolling |
| `page.eval <js>` | execute JS |
| `page.url` / `page.title` | current-page info |
| `page.back` / `page.forward` | history navigation |
| `page.key <key>` | key press (Enter/Tab/ArrowDown/single character) |

### 3.2 browser.* — Retained Commands

- Tabs: `tabs` / `tab` / `tab.open` / `tab.close` / `tab.all`
- Efficiency: `inject` / `diff` / `preload`
- Waiting: `wait` / `wait.nav`
- Storage/Cookies: `storage` / `cookies` / `cookies.set` / `cookies.clear`
- Dialogs: `dialog.accept` / `dialog.dismiss`
- Query/settings: `visible` / `enabled` / `viewport` / `userAgent` / `version`

## 4. Semi-Automatic Loop (Recommended Workflow)

```text
page.load https://example.com        # one call: navigation + segmented screenshots + coordinate system
page.click 1 320 480                  # look at the image → click by segment coordinates (segment 1)
page.scroll_by 800                    # scroll, then verify with page.screenshot --full
page.content --grep "price" --head 20 # filtered extraction; content stays out of context
```

Example return format:

```text
## page.load complete
URL: https://example.com
Segments: 3 (partial: false)
Segment 1: /storage/emulated/0/MengPaw/截图存档/page_..._seg1.png (1080 × 2400, zoom 0.44)
Coordinates: page.click <seg> <x> <y> — the framework restores page coordinates automatically
```

## 5. Invocation Channel — the am Bridge (the Only Channel)

```bash
am startservice -n com.mengpaw.browser/.service.RunCommandService \
  --es com.mengpaw.browser.RUN_COMMAND_ARGUMENTS "-c,page.goto https://example.com" \
  [--es com.mengpaw.browser.RUN_COMMAND_OUTPUT /storage/emulated/0/MengPaw/out.txt]
```

The signature permission `RUN_BROWSER_COMMAND` can be invoked only by a same-signature app; the output is
written to disk and then read by the caller itself. The payload whitelist admits only `page.*` / `browser.*`,
and output paths are confined to the public `MengPaw/` directory.

> The 9880 HTTP bridge and "open MCP control" are retired (decision #7): there is no token, no
> authentication-free channel, and no network entry point — the browser accepts commands only from
> same-signature apps over the am bridge, and third-party processes have no way in.

## 6. Form Automation

```text
page.goto https://example.com/login
page.fill #username <username>
page.fill #password <password>
page.click button[type=submit]
page.title                                  # verify the redirect; never assume success
```

Note: CAPTCHA cannot be passed automatically — guide the user to complete it manually; file uploads have no API — guide the user to do it manually; if typed input appears to be cleared, verify the value with `page.eval` after typing; do not write sensitive credentials into the command history.

## 7. Web Scraping

```text
page.load https://example.com/list          # wake up + screenshot
page.content --head 50                      # extract structure
page.eval JSON.stringify(Array.from(document.querySelectorAll('a')).map(a=>a.href).filter(h=>h.includes('/article/')))
page.eval var n=document.querySelector('.next');if(n){n.click();'next'}   # pagination
```

Scraping strategy: pages that require login / JS rendering / strong anti-scraping go through the browser (with its cookie/JS session); static bulk scraping can use an HTTP client with concurrency on your own; 403/captcha → retry through the browser channel; rate limiting → space requests out one by one.

## 8. Troubleshooting Quick Reference

| Symptom | Handling |
|------|------|
| "browser not ready" / no am-bridge output | the browser is not running → wake it first (§2) |
| `page.load` asks for storage permission | "All files access" not granted → grant it in the first-launch dialog or via system settings |
| `page.click` mispositioned/out of bounds | first refresh the segment images with `page.screenshot --full`, then click using the returned segment number + coordinates |
| `WebView not available` | no open tab → open a page first with `OPEN_URL` |
| `Selector not found` | the element is not loaded / is inside an iframe → probe the DOM with `page.eval`; wait for the load first |
| Page extraction is empty | JS rendering not finished → use `page.goto` to wait for the load, then `page.content` |
| Segmented screenshot `partial:true` | over-long truncation (30-segment cap) is normal → operate on the returned segments, or scroll and re-screenshot |

## 9. Playwright Comparison (Quick Reference)

| Playwright | MengPaw |
|------------|---------|
| `page.goto(url)` | `page.goto <url>` |
| `page.goto + screenshot(fullPage)` | `page.load <url>` |
| `mouse.click(x, y)` | `page.click <seg> <x> <y>` |
| `page.fill(sel, text)` | `page.fill <css> <text>` |
| `page.selectOption()` | `page.select <css> <value>` |
| `page.evaluate(js)` | `page.eval <js>` |
| `page.waitForSelector()` | `page.wait_selector <css>` |
| `page.content()` | `page.content [--grep] [--head]` |
| `page.keyboard.press()` | `page.key <key>` |
| `page.mouse.wheel()` | `page.scroll_by <dy>` |

Differences: selectors are CSS-only (no XPath); `--wait networkidle` is an approximate implementation; screenshots only return paths; over-long pages are returned segment by segment, and clicking uses a segment number plus in-segment coordinates.
