Skip to main content
Glama
README.md
# mcp-helm

Drive your real Chrome session from Claude — copilot mode, with handoff awareness.

Most browser-automation MCP servers spawn a fresh Playwright Chromium. That's
useless when the work is "log into Stripe and click 5 things" — you don't have
your cookies, your 2FA, your bookmarks. **mcp-helm attaches to YOUR Chrome**,
the one you're already signed into, and lets Claude run a small set of
tools against the active tab.

It also knows when to step back: when the page shows a 2FA prompt, captcha,
payment confirmation, or biometric request, the screenshot tool flags it and
Claude can call `handoff()` to wait for you.

## Why this exists

The eyes-and-hands problem: Claude tells you "click Settings → API access"
and you click Settings and there is no API access, so you screenshot back to
Claude, which guesses again. That's 5 minutes of round-trips for a 5-second
task, and it happens on every Stripe / Apple / Play Console / Cloudflare /
Vercel setup.

mcp-helm cuts that loop. Claude sees the actual page, picks elements from
the accessibility tree (no coordinate guessing), and stops when it would do
something it shouldn't.

## Install

```bash
npm install -g mcp-helm
```

Add to `~/.claude.json` (or your MCP client's config):

```json
{
  "mcpServers": {
    "helm": {
      "command": "mcp-helm"
    }
  }
}
```

## Usage

### 1. Launch a driveable Chrome

Add this alias to your shell rc:

```bash
alias chrome-pilot='open -a "Google Chrome" --args --remote-debugging-port=9222 --user-data-dir=$HOME/.chrome-pilot'
```

Run it once: `chrome-pilot`. A separate Chrome profile opens. Sign into
everything you'd want Claude to drive (Play Console, Stripe, etc.).
Cookies persist across launches — you only sign in once per service.

> **Why a separate profile?** Your main Chrome can't be launched in
> remote-debugging mode while it's already running. The dedicated profile
> lives in `~/.chrome-pilot` and stays separate from your daily browsing.

### 2. From Claude

```
You: Upload the AAB at <path> to Play Store internal testing.
Claude: [calls helm.attach] → [helm.navigate to play.google.com/console]
        [helm.screenshot] → sees the dashboard
        [helm.click "Personalized AI Portfolio Bot"]
        ... etc
```

If a 2FA prompt appears, `screenshot` returns
`handoffTriggers: ["2FA prompt"]` and Claude calls `handoff` to wait.

## Tools

| Tool | Purpose |
|---|---|
| `attach` | Connect to Chrome on port 9222. Always call first. |
| `list_tabs` | List all open tabs. |
| `focus_tab` | Switch active tab by index or URL substring. |
| `screenshot` | PNG + URL + title + handoff triggers detected. |
| `inspect` | Numbered list of interactive elements (a11y tree). |
| `click` | Click by id (from inspect), text, or CSS selector. Returns `changed: bool` from screenshot diff. |
| `type` | Type into a field. `submit: true` presses Enter after. |
| `navigate` | Go to a URL. |
| `wait_for` | Wait for text or selector. |
| `handoff` | Pause and ask the human to take over. |

## Design choices

- **Accessibility tree, not coordinates.** Vision-grounded clicking (Anthropic
  computer use) is great but flaky on Retina displays and high-DPR scaling.
  The a11y tree gives stable, semantic IDs — and is what screen readers use.
- **Screenshot diff after every click.** If `changed: false`, the click was a
  no-op. Saves Claude from cheerfully reporting success.
- **Handoff detection is regex-based, not LLM-based.** Cheap, fast, no false
  positives on common login phrases.
- **No tab-management heuristics.** `attach` picks the first non-blank tab;
  use `list_tabs` + `focus_tab` to be precise. Predictable beats clever.

## Status

v0.1 — works for simple flows (Play Console, Stripe dashboard, Vercel,
Cloudflare). Edge cases this doesn't handle yet:

- Shadow DOM components (some web-component-heavy sites)
- iframes (need to surface frame switching)
- File uploads from disk
- Keyboard shortcuts beyond Enter

## License

MIT

TDQS

A3.6/5.0

Scored across 10 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: attaching, navigating, clicking, typing, inspecting, tab management, screenshotting, waiting, and handoff. No overlapping functionality.

Naming Consistency5/5

All tool names follow a consistent verb or verb_noun pattern with lowercase and underscores (e.g., focus_tab, list_tabs, wait_for). No mixing of conventions.

Tool Count5/5

With 10 tools, the set covers core browser automation tasks without being bloated or sparse. Each tool earns its place.

Completeness4/5

The tool surface covers connection, navigation, interaction, inspection, tab management, and human handoff. Minor gap: no explicit scrolling or back/forward navigation, but these are often handled indirectly.

Maintenance

ActivityInactive
ResponsivenessNo issues