Skip to main content

pointclick

A browser MCP server in under 1,000 tokens. The page comes back as a numbered list of what you can click, type into or select. Your agent points at a number; pointclick clicks it.

PyPI CI License: MIT

url: https://en.wikipedia.org/wiki/Main_Page
title: Wikipedia, the free encyclopedia
[1] link 'Wikipedia The Free Encyclopedia' <CLICK>
[2] searchbox 'Search Wikipedia' <TYPE,CLICK>
[3] button 'Search' <CLICK>
...
(more below: 3156px; SCROLL_DOWN or observe(full=true))

text:
Welcome to
Wikipedia
...
act("TYPE", "2", "Ada Lovelace")   → the new list, once the page has settled
act("PRESS", "2", "Enter")

Why

Same task, same model (Claude Sonnet 5 in headless Claude Code), one browser MCP each — sign in, search, sort, open a record, read a number off it. 18 of 18 runs got it right.

turns tokens read cost per run time
pointclick 7 104k $0.056 15.8 s
Playwright MCP 13 266k $0.118 27.5 s
agent-browser 12 525k $0.223 17.8 s

Medians. Cost is the API price Claude Code reports; time is noisy at this sample size.

  • Eight tools, under 1k tokens of definitions. Playwright MCP's are ~5k, Chrome DevTools MCP's ~7k, agent-browser's ~18k. Clients that load every tool up front pay that on every turn.
  • Only what you can act on. No wrapper divs, no layout tree: controls, their state, and the visible text.
  • Every action returns the settled page. No follow-up snapshot call, and no waiting for the network to go quiet: long-polls and streams don't stall it.

Quick start

Needs Python 3.12+ and uv. Uses your installed Chrome, or Playwright's Chromium if there is none (uvx --from pointclick playwright install chromium).

Claude Code

claude mcp add pointclick -- uvx pointclick

Cursor, Claude Desktop, Windsurf, and other clients — add to the MCP config:

{
  "mcpServers": {
    "pointclick": { "command": "uvx", "args": ["pointclick"] }
  }
}

VS Code

code --add-mcp '{"name":"pointclick","command":"uvx","args":["pointclick"]}'

Codex

codex mcp add pointclick -- uvx pointclick

Your first prompt

Open news.ycombinator.com, go to the second page, and tell me the top story there.

Tools

Tool
navigate(url) Open a page, return the list
observe(full=false) The list again. Viewport only unless full
act(operation, target, text) CLICK TYPE SELECT PRESS HOVER SCROLL_DOWN SCROLL_UP WAIT
upload(target, paths) Set files on a file input
screenshot(full_page=false) JPEG
evaluate(js, max_chars=6000) Run JS in the page, JSON back. A longer result is cut and says so; 0 for all of it
console() Console messages and page errors since the last call
close() End the session; the next call starts fresh

target is a number from the list ("3", or "3:2" for the second option of a select), or any Playwright selector ("input[type=password]", "text=Send", "role=button[name='OK']"). Password and file inputs are never in the list; reach them by selector.

Env
HEADED=1 Show the window
BROWSER_CHANNEL chrome (default), msedge, or chromium for Playwright's bundled build

How it works

  • The list comes from one script that reads every visible control and the visible text in a single pass — adapted from jev-ultrafast (Browser Use × TypeSafe). It runs in every frame, cross-origin ones included, and a control that only repeats its wrapper's label is listed once.
  • Settling. After an action, pointclick returns once the page has been still for 150 ms and no request younger than 0.5 s is pending — at most 2 s. Older requests (long-polls, streams) don't hold it up. If the page is still busy after that, WAIT returns the moment it changes.
  • Numbers point at real elements, not at a position. If a framework re-renders the element, pointclick follows it when its label is unique on the page and says so; a duplicate label (two "Start" buttons) is refused rather than guessed.
  • A timeout on a page that changed anyway is reported that way, so the agent checks before retrying instead of clicking twice.
  • Playwright underneath handles selectors, uploads, popups (they become the current page), screenshots and the console. Every session is a fresh, isolated browser context.

server.py is ~350 lines and snapshot.js ~110. Small enough to read before you trust it.

Benchmarks

bench/ has a small SPA shaped like a real dashboard — demo login, a list with search and sort, a detail page, API calls over the network, and an optional long-poll like a realtime fallback.

With a real agent — headless Claude Code, built-in tools off, the task given in plain words:

uv run python bench/agent_race.py --runs 3 --model sonnet
correct turns tokens read tokens written cost time, no long-poll time, long-poll open
pointclick 6/6 7 104k 620–660 $0.056 13.7 s 16.7 s
Playwright MCP 0.0.81 6/6 13 266–289k 1.1k $0.113–0.118 23.3 s 28.5 s
agent-browser 0.38.1 6/6 12 525k 760–780 $0.223 19.1 s 14.8 s

Medians of 3 runs per column. Turns and tokens barely move between runs; time moves by up to a third with model latency, so read it as a range. Playwright MCP's action replies link to a snapshot file instead of including the page, so the model asks for a snapshot after each step. agent-browser's actions return nothing, so every step is an action plus a snapshot too.

Tools alone — the same flow driven by a script, so no model time is included:

uv run python bench/race.py --runs 8 --poll 0
calls text to the model tool time with a long-poll open
pointclick 6 6.6k chars (~1.9k tokens) 2.25 s 2.31 s
Playwright MCP 0.0.81 6 17.0k chars (~4.9k tokens) 3.32 s 8.27 s
agent-browser 0.38.1 18 12.3k chars (~3.5k tokens) 1.13 s 1.12 s

agent-browser's tool time is lowest because its actions return nothing: it re-snapshots, and the script polls for free. In a real agent every one of those calls is a model turn.

Tool definitions, sent with every request by clients that don't load tools lazily (all four estimated the same way, JSON characters ÷ 3.5):

tools definitions
pointclick 8 ~0.8k tokens
Playwright MCP 26 ~5.2k tokens
Chrome DevTools MCP 29 ~6.9k tokens
agent-browser (core) 29 ~18.4k tokens

Measured on an M-series Mac with Chrome 153. Raw results are in bench/*.json.

When to use something else

  • Playwright MCP — you need network interception, tracing, PDF export, or the full Playwright surface.
  • Chrome DevTools MCP — performance traces, Lighthouse-style audits, deep DevTools debugging.
  • agent-browser — you'd rather drive the browser from a shell (CLI + skills), want saved auth profiles, or need its long tail of commands.
  • Stagehand — you want natural-language act/extract backed by its own model, or hosted browsers on Browserbase.

pointclick does one job: get an agent through a web app with as little text and as few turns as it can — locally, with no account and no second model.

Security

  • Everything on a page — text, labels, titles — is untrusted input to your model. A page can try to instruct your agent. Keep the agent's permissions narrow and confirm consequential steps.
  • Each session is an isolated browser context: no access to your Chrome profile, cookies or passwords. Nothing persists after close().
  • evaluate runs arbitrary JavaScript in the page; upload reads files you name from disk.

Limits

  • The list is viewport-only by default; long pages take SCROLL_DOWN or observe(full=true).
  • Every action returns the whole list, not a diff.
  • Chromium only, one page at a time per server. Calls sent in parallel run one after another.
  • No network inspection, PDF export or dialog control; evaluate covers some of it.

Development

uv sync --group dev
uv run pytest     # 45 tests; fixture pages served from two local origins
uv run ruff check . && uv run ruff format --check .

To release, bump version in pyproject.toml, then push a matching tag (v0.1.0). release.yml publishes to PyPI through trusted publishing; there is no token to keep.

Credits

The page snapshot is adapted from jev-ultrafast, MIT © 2026 Browser Use — see LICENSE-jev.

License

MIT

Release files for pointclick 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pointclick 0.1.0
File Size Uploaded
pointclick-0.1.0.tar.gz 74.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pointclick 0.1.0
File Interpreter ABI Platform
pointclick-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 90.5 kB

Release files / pointclick-0.1.0.tar.gz

Download URL pointclick-0.1.0.tar.gz
Size 74.9 kB
Tags Source
SHA-256 checksum
How to use checksums
3643b6f72fe0e1c2e3cad74b5c85160b15f6de9d38f3f53e25f12bf1733b0cd1
BLAKE2b-256 checksum
How to use checksums
88ddc71909f36c44562d100824c360ce41f721dec74c481a4dc6ca7912cff7d3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / pointclick-0.1.0-py3-none-any.whl

Download URL pointclick-0.1.0-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
16885780d2863354e4dfe5134099a98c90e7c241abb5f32ca03c4098bfc38978
BLAKE2b-256 checksum
How to use checksums
5c70414a67d296024c38a73619decf284f1cd0903b6a3cd708eb850f45d4b4b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page