Mantis

io.github.perzianhqPublished by GitHub account perzianhqv0.1.13Updated Nov 6, 2026

The web as short, numbered text for AI agents: a lean browser interface over Playwright.

Overview

AI-generated overview

Mantis is a local Playwright-based browser MCP server that lets an assistant browse the web as short, numbered text instead of screenshots.

What you can do
  • Open URLs and read pages as numbered text, then act on elements by their number
  • Search page text, click, type, select options, fill forms, press keys, scroll, hover and go back
  • Wait for text or element states, manage tabs, and upload local files to file inputs
  • Extract text, table rows and chart values from images, SVGs and canvases, with OCR and a last-resort screenshot view
  • Hand off to a human for CAPTCHA, 2FA, payment or login, then resume on the changed page
When to use it
Useful when an assistant needs to read and operate real websites: navigating pages, filling forms, extracting table or chart data, or completing multi-step web tasks where a compact text view saves tokens over accessibility trees or screenshots.
Requirements
Runs as a local stdio process installed from the npm package mantis-browser (Node.js via npx); no accounts, API keys or environment variables are declared. Login and bot walls rely on a human handoff, which needs a display.
Before you install
Page text is untrusted data and the server tells assistants not to follow commands found in it. Tools click, type, fill, upload local files and submit forms, so actions change remote state; upload sends local file paths to the page. It never solves CAPTCHAs and hands those to a human. It is a small v0.1.x beta with no canvas input.

Installation

In SourceWeft

  1. Open Mantis in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

[mantis]

Lets AI agents browse the web as short, numbered text instead of screenshots.

perzian.dev/mantis · by Perzian

It works with Claude Code, Codex, Cursor or your own agent as an MCP server. Install in two commands.

bash
npx -y -p mantis-browser mantis installclaude mcp add mantis -- npx -y -p mantis-browser mantis-mcpnpx -y -p mantis-browser mantis read https://example.com   # try it without an agent

Windows, Linux servers and other agents: SETUP.

[Side-by-side replay of the same task with Mantis and Playwright MCP: Mantis finishes in 11 calls and about 238k input tokens, Playwright MCP in 25 calls and about 887k]

One real task (Luna, each tool’s median run of 5 by input tokens, replayed): about half the time, over 3.5x fewer input tokens, less than half the calls. Across all 5 runs: 3-5x fewer tokens, about half the time, 11-12 calls vs 21-29. This is a selected example from 16 long tasks; medians across all 16 are in Results. Full video.

Security and threat model: SECURITY.md.

How it works

[Agent sends open/click to Mantis; Mantis reads the page in Chromium, numbers each control and returns only what changed; CAPTCHA, 2FA and payment go to you]

What the agent sees

[A shop page with a cookie popup becomes 8 numbered lines; after click #3 only the changes come back]

Results

Mantis vs the accessibility tree (Playwright MCP) on public sites, gpt-6-luna and claude-haiku-5-5. Every cell is a per-run median; time is end-to-end wall time per run:

0.1.11: headline numbers are 0.1.9's; later builds checked on Dickens (Luna, Haiku) and the capability-v1 local set.

Long tasks (correct: 14 keyed tasks, 42 runs per cell; medians: all 16 tasks, 48 runs per cell; both approaches run in the same session):

Luna MantisLuna treeHaiku MantisHaiku tree
Correct35/4234/4240/4240/42
Input tokens (median)244k345k268k506k
Tool calls (median)17241930
Time (median)42s66s54s85s

Short tasks (30 tasks, 90 runs per cell; tree and screenshot columns are the earlier 20261026 run):

Luna MantisLuna treeLuna screenshotHaiku MantisHaiku treeHaiku screenshot
Correct88/9086/9090/9090/9088/9088/90
Input tokens (median)64k99k104k38k88k33k
Tool calls (median)347356
Time (median)16s31s35s19s30s23s

Versus the accessibility tree:

  • Long tasks: accuracy within one run, 29-47% fewer input tokens, 29-37% fewer calls, about a third less time.
  • Short tasks: accuracy equal or better, 35-57% fewer input tokens.

Versus screenshots:

  • Luna: screenshots score 2 runs higher but use more tokens and time.
  • Haiku: screenshots use fewer tokens.

Caveats:

  • Short-task times compare a newer Mantis build with the earlier tree and screenshot run, so treat that time gap as indicative.
  • Scores come from deterministic answer keys on the final page state. Two long iframe/tab tasks can't be keyed and are left out of the long-task counts.
  • Method and full caveats: bench/RESULTS.md.

Limitations

  • No canvas input: canvas, WebGL, maps and drawing apps are described only as canvas, with no coordinate click or draw tool.
  • Login and bot walls need ask_human, which needs a display.
  • Benchmarked only on read, navigate and form-fill tasks on public sites, with two models. The screenshot baseline is this project's own tool, and a few tasks were swapped after results (disclosed).
  • Page content is untrusted data; see SECURITY.md.
  • Small v0.1.x beta.

Learn more

License

MIT

Source: README.md at commit 74f61b0

Tools

20

open

Open URL as numbered page text; act by #number.

Parametersurlrequired

read

Numbered text; act by #number. ~"x" names are guesses. "Same as before" retains #numbers; region/full/fresh expands it; full is paged with offset. Verify the entity identity before editing. Before finishing, re-read and visibly verify every task constraint (filters, sort, size, quantity, date range). After an action confirms completion, stop and report it rather than re-inspecting. If #number is stale, read() and retry; if on the wrong page, back() and keep searching. open(url) returns to an earlier results page; back() can lose its query string.

Parametersfullfreshoffsetregion

find

Case-insensitive whole-page text search, including trimmed content; returns #numbers, actionable row neighbours, and bounded local context. Give a list of up to 6 texts to search them all in one call. Use context_chars to expand just that local context; a matched heading is not a region label. With no match it scrolls virtualized lists and loads more of an infinite feed to look, and says so.

Parameterstextrequiredcontext_chars

forget

Clear region memory; next read shows everything.

Takes no parameters.

click

Click element #id.

Parametersidrequired

type

Replace input #id text; submit presses Enter.

Parametersidrequiredtextrequiredsubmit

select

Choose option text in select or combobox #id. A <select multiple> takes a list and its selection becomes exactly that list. Matching ignores case, accents and punctuation.

Parametersidrequiredoptionrequired

fill

Prefer one mixed call for related text, dropdown, and checkbox fields; unrelated fields stay unchanged. Verify entity identity before editing. On failure or rerender it stops and reports partial completion; after confirmed completion, report it rather than re-inspecting.

Parametersfieldsrequired

press

Press a key, e.g. Enter. For bottom-loaded feeds, try End (Control+End if no movement) to load more; a scroll key or scroll reports when the page grew; repeat only while new items appear.

Parameterskeyrequired

scroll

Scroll up/down/left/right (default down). id alone brings #id into view; id + direction scrolls its containing list/panel/table. For wide tables use right; without id, a scrollable container is used when the page cannot scroll.

Parametersiddirection

back

Back one page in history.

Takes no parameters.

wait_for

Wait up to 10s: text states are present (or appears) / disappears; #id states are present / enabled. On timeout, inspect the returned current observation.

Parametersidtextstatetimeout_seconds

hover

Hover element #id and show changes.

Parametersidrequired

upload

Select local file path(s) on #id; this selects files but does not submit a form.

Parametersidrequiredpathfilespaths

tabs

List tabs, or switch/close tab #id.

Parametersidaction

media

Only if read is insufficient: media → data (prefer) → ocr → look (last resort) → ask_human. Numbered images/canvases/charts.

Takes no parameters.

data

Prefer; text only. Extract image/SVG/chart alt, caption, text or Chart.js/ECharts/Highcharts values; a table gives its rows. id from read()/media(), or CSS selector (#N refs work too).

Parametersidselector

ocr

Text-only OCR for image/canvas. Use if data found nothing. id or CSS selector.

Parametersidselector

look

LAST RESORT; only image-returning tool (PNG, max 800px). Only after read/data/ocr failed. id or CSS selector.

Parametersidselector

ask_human

Human handoff for CAPTCHA, 2FA, payment or login; never solves CAPTCHAs. Waits for a page change, then returns the page.

Parametersuntilreasonrequiredtimeout_seconds

Version history

8
  1. v0.1.13LatestNov 5, 2026
  2. v0.1.11Nov 4, 2026
  3. v0.1.10Oct 29, 2026
  4. v0.1.8Oct 26, 2026
  5. v0.1.7Oct 26, 2026
  6. v0.1.6Oct 25, 2026
  7. v0.1.4Oct 23, 2026
  8. v0.1.2Oct 16, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts