Colibri
Colibri is a local MCP browser server that lets an AI agent navigate, read, fill, and interact with real web pages using compact text rows instead of screenshots.
Open pages (
browse_open): launch Chrome/Edge, auto-dismiss non-essential cookies, return actionable page rows (optionally header/counts only or filtered).Search the web (
browse_search): DuckDuckGo results (Bing fallback) asn. title | url | snippet, no ads.Inspect current page (
browse_view): filtered rows, full scope including header/nav/footer, or refs for unlabeled clickable/drag areas; supports paging.Batch actions (
browse_do): run up to 40 chained steps in one call — click, fill, type, select, check, press, pick, hover, scroll, wait, waitFor, goto, back, tabs, upload, dialogs, find/read — returning only the diff.Read without acting (
browse_read): main text without menus, tables, repeated result cards (trains/flights/products), find lines, describe elements, or PDF text.Guided form tasks (
browse_task): local engine maps human labels to fields (synonyms, typos, languages), fills selects/dates/autocompletes/checkboxes, verifies, submits, extracts typed values, and asks questions when uncertain.Screenshots (
browse_screenshot): small JPEG of window, element, or region with optional ref labels — only when text is insufficient (charts, canvas, maps).Session stats (
browse_stats): tokens used by the browser this session vs screenshots.Safety guardrails: side-effect actions (
!c) require explicit user confirmation; secrets (!xlike passwords, cards, OTP) are never typed by the AI; allowed-domain lists, and nofile://orjavascript:URLs.
Provides web search through DuckDuckGo, returning result rows with title, URL, and snippet, without ads.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Colibrigo to news.ycombinator.com and summarize the top 5 stories"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
One line, any agent — no account, no API key, no build:
claude mcp add colibri -- npx -y github:t4zxxx1/colibri-mcp # or: codex / copilot mcp add …Why · Install · VS Code · vs Jev · Benchmarks · How it works · Tools · Safety · Config · FAQ
English · Italiano
Why Colibri
A hummingbird weighs about 3 grams, beats its wings around 50 times a second and hovers with millimetric precision. That is the idea: the lightest possible browser for an AI agent, fast and exact.
AI agents browse the web in the most expensive way possible: a screenshot costs ~1,366 tokens, an accessibility-tree dump 4,400–7,700 tokens per page, and every extra tool call makes the model re-read the whole conversation.
Colibri turns each page into a few hundred tokens of plain rows — fields, values, state, risk flags — runs many steps in one call, answers with only what changed, and fills forms with a local Jev-style engine that needs no API key and costs zero tokens.
⚡ 27,760 tokens for a 22-field, two-page application — vs 318,910 with Playwright MCP and 2.48 M with screenshots
🧠 Jev-style typed decisions, locally — and ahead of Jev 1.14 on form filling:
Jev 1.14 (public System One Bench, 2,450 choice questions)
Colibri v0.4 (419 form-matching cases)
Accuracy
75.7%
98.6% · 87.9% on a form never seen before
Confidence AUROC
0.81
0.95
Latency p50
136 ms
1.7 ms
Cost
$0.028 / 1,000 calls + API key
$0, no key
The two datasets are different, so take this as an order of magnitude: Jev handles any domain, Colibri does one job (data → form field). Method and caveats are in Better than Jev.
🔌 One line in any agent: Claude Code, OpenAI Codex, GitHub Copilot (CLI & VS Code), Gemini CLI, Cursor, Claude Desktop, Windsurf… — see how
🛡️ Safe by default: submit/pay/delete need your OK (
!c), passwords/cards/OTP are never typed by the AI (!x)🏠 100% local: your Chrome profile, your logins, nothing goes through third-party servers
Related MCP server: Charlotte
Install in one line
You only need Node.js ≥ 18 and Chrome or Edge. No account, no API key, no build step: npx fetches Colibri from GitHub and runs it on your machine.
Your agent | Install |
Claude Code |
|
OpenAI Codex (CLI + IDE extension) |
|
GitHub Copilot CLI |
|
GitHub Copilot in VS Code | one click · or |
Gemini CLI |
|
Claude Desktop | download colibri.mcpb → double-click |
Cursor | |
Cline (VS Code) | paste the JSON in MCP Servers → Configure — step by step |
Windsurf · Roo · any other client | paste the 3-line JSON |
Then just ask — "Open the supplier portal and fill in the application with these details: …" or "Use Colibri to read the editions of project PF-2026-115". Chrome opens on the first call; you log in once, it remembers.
VS Code — step by step
Colibri works in VS Code with GitHub Copilot (Agent mode) and with Cline. They keep separate MCP lists, so set it up for the one you use.
GitHub Copilot
Pick one of these:
One click — Install in VS Code → VS Code opens → Install.
Terminal — adds Colibri to your user profile, for every project:
# macOS / Linux code --add-mcp '{"name":"colibri","command":"npx","args":["-y","github:t4zxxx1/colibri-mcp"]}'# Windows PowerShell code --add-mcp '{\"name\":\"colibri\",\"command\":\"npx\",\"args\":[\"-y\",\"github:t4zxxx1/colibri-mcp\"]}':: Windows cmd code --add-mcp "{\"name\":\"colibri\",\"command\":\"npx\",\"args\":[\"-y\",\"github:t4zxxx1/colibri-mcp\"]}"Using VS Code Insiders? Replace
codewithcode-insiders.Command Palette —
Ctrl+Shift+P(⌘⇧Pon Mac) → MCP: Add Server → Command (stdio) → pastenpx -y github:t4zxxx1/colibri-mcp→ name itcolibri→ Global.Only for one project — create
.vscode/mcp.jsonin the project folder:{ "servers": { "colibri": { "type": "stdio", "command": "npx", "args": ["-y", "github:t4zxxx1/colibri-mcp"] } } }
Then open Copilot Chat, switch to Agent mode, click the 🔧 tools icon and make sure colibri (8 tools) is ticked. The first time, VS Code asks you to trust the server: say yes.
Cline
Open the Cline panel → click the MCP Servers icon → Installed tab → Configure MCP Servers.
cline_mcp_settings.jsonopens: paste this (or add just the"colibri"block next to your other servers) and save:{ "mcpServers": { "colibri": { "command": "npx", "args": ["-y", "github:t4zxxx1/colibri-mcp"] } } }Colibri appears in the list with a green dot and its 8 tools. Ask Cline: "Use Colibri to open example.com".
Windows: if VS Code or Cline says
npxis not found, use"command": "cmd"and"args": ["/c", "npx", "-y", "github:t4zxxx1/colibri-mcp"].
Manual configuration
~/.cursor/mcp.json, ~/.codeium/windsurf/mcp_config.json, ~/.gemini/settings.json, claude_desktop_config.json…
{
"mcpServers": {
"colibri": {
"command": "npx",
"args": ["-y", "github:t4zxxx1/colibri-mcp"],
"env": { "CB_ALLOWED_DOMAINS": "" }
}
}
}[mcp_servers.colibri]
command = "npx"
args = ["-y", "github:t4zxxx1/colibri-mcp"]git clone https://github.com/t4zxxx1/colibri-mcp
cd colibri-mcp && npm ci --omit=dev
# then point your client to: node /path/to/colibri-mcp/extension/server/index.jsWindows tip: if your client can't find
npx, use"command": "cmd", "args": ["/c", "npx", "-y", "github:t4zxxx1/colibri-mcp"].
Better than Jev — with real numbers
Jev popularised the "System One" idea: answer typed questions with a calibrated confidence and act only above a threshold. It is excellent — and it is a paid cloud model with its own tokens and API key.
Colibri ships the same idea as a local engine inside the MCP server, specialised for the one decision a browsing agent makes all the time: which form field does this piece of data go into? Your existing Claude/Copilot subscription is all you pay.
Jev 1.14 (System One Bench) | Colibri local engine v0.4 | |
Choice accuracy | 75.7% | 98.6% (419 cases) · 87.9% on the independent Test 5 |
Calibration error (ECE) | 8.4% (choice) · 6.0% overall | 5.9% · 4.6% on Test 5 |
Confidence AUROC | 0.81 | 0.95 |
Latency | 136 ms p50 · 175 ms p95 | 1.7 ms p50 · 8.3 ms p95 (≈80× faster) |
Cost | $0.028 per 1,000 calls + API key | $0, no key, no network |
Wrong autonomous actions | — | 0 (100% precision when it acts alone) |
Scope | any domain (trained model) | web forms only (heuristics + vocabulary) |
Honest note. The datasets differ: Jev 1.14 was measured on 2,450 general choice questions, the local engine on 419 form-matching cases from test pages written by the author (the independent Test 5 was written after the engine changes and measured once). Jev is a generalist; this engine does one job and is tuned for it. Read it as an order of magnitude, not a leaderboard. Full method: docs/calibrazione.md.
Benchmarks
Same pages, same tasks, eight methods. Every method completed every task. "Total context" is the sum of tokens the model re-reads across all turns — what actually drives cost and latency.
Task | Screenshots | Playwright MCP | agent-browser MCP | Fast Playwright MCP | Colibri |
T1 22-field form, 2 pages | 2,480,688 · 154 s | 318,910 · 52 s | 1,373,730 · 108 s | 115,624 · 57 s | 27,760 · 19 s |
T2 list → detail table | 34,630 · 13 s | 73,333 · 15 s | 167,751 · 18 s | 37,480 · 12 s | 20,700 · 10 s |
T3 navigate a heavy home | 23,809 · 10 s | 69,739 · 15 s | 148,169 · 17 s | 36,480 · 12 s | 12,849 · 8 s |
Reading one form page | 1,366 (image) | 5,354 | 4,464 | 5,283 | 628 |
Tool definitions, every turn | — | 4,536 | — | — | 1,347 |
Full tables, assumptions and caveats (the test pages were built alongside this tool, so it plays at home): docs/benchmark.md.
How it works
Page → rows. A script inside the page keeps only what you can act on: fields, menus, buttons, links, checkboxes — with name, value, state (
req,inv,off) and a risk flag. Header, nav and footer are folded; repeated table rows are compressed.Many steps, one call.
browse_doruns up to 40 steps (fill, select, check, click, wait, read) and keeps going across page changes, because targets can be named.Diff only. After acting, the model gets verified writes, changed/new elements, form errors and new text (
»Application sent, protocol n. …) — not the whole page again.Guided tasks. With
browse_taskthe model doesn't even look at the form: it passes the user's own labels ("VAT": "01234567890","start date": "03/11/2026") and the local engine decides which field is which, with a calibrated probability. Above the threshold it acts; below, it asks.
What the model sees
http://127.0.0.1:8811/domanda1.html | Nuova domanda - passo 1 di 2
h1: Richiesta di contributo per piano formativo · scroll 0/1747
[fs "Dati dell'azienda"]
e28 text "Ragione sociale" req
e31 sel "Codice ATECO" ="Seleziona" opz:97 req
e33 sel "Provincia" ="Seleziona prima la regione" off req
e34 combo "Comune" req col
[fs "Dichiarazioni"]
e54 chk "Dichiaro di aver letto l'informativa privacy e accetto il t…" [ ] req !c
e56 btn "Salva bozza" !c
e57 btn "Avanti"
[nascosti 73 in hdr,search,nav,ftr: scope:"all" o filter]After 22 steps in one call, the entire answer is:
ok 22/22
---
16 campi impostati come richiesto · 5 altre variazioni
~ e31 "Codice ATECO" ="62 - Industrie alimentari (62)" req
~ e33 "Provincia" ="Napoli" req
~ e34 "Comune" ="Pozzuoli" req colTool descriptions are in terse English for the model; page output keeps the page's language. It works on any site, in any language — keywords for submit, consent, passwords, cards and cookie banners are recognised in English, Italian, French, Spanish, German and Portuguese.
Tools
Tool | What it does |
| Open a URL (auto-starts Chrome), reject non-essential cookies, return the rows. |
| Web search without Google CAPTCHAs: one row per result |
| Rows of the current page, with |
| Up to 40 steps in order; returns only the diff |
| Read without acting: |
| Jev-style guided task: params by human labels, |
| Small JPEG (~900 tokens) of the window, an element or a region — only when text is not enough |
| Tokens used this session vs screenshots |
Safety
!cside effects — submit, confirm, save, delete, pay, accept terms, upload: blocked until the user says OK, then repeated with"confirm": true. Buttons that only open a menu (aria-haspopup/aria-expanded) and quantity steppers ("remove passenger") are not blocked.!xsecrets — passwords, card numbers, CVV, OTP, IBAN: the AI can never type them, not even with confirmation. You type them in the window.Guided tasks act alone only above the confidence threshold; submit never fires with open questions, errors or empty required fields.
Allowed domains, no
file:///javascript:, page text treated as untrusted data (prompt-injection resistant), refs unique per session.
Configuration
Env var | Default | |
| all | comma-separated allow-list |
|
| keep it on |
|
| invisible browser |
|
| logins and cookies live here |
|
| |
| auto | only if Chrome/Edge is not found |
|
| |
|
| seconds Colibri waits for you to solve a CAPTCHA / human check ( |
|
| tool profile: |
|
| when headless and a check doesn't clear on its own, reopen Chrome visibly on the same page |
|
|
|
|
| in |
|
| profile used by the real Chrome that Colibri starts |
| DuckDuckGo, then Bing | search page(s) for |
Limits
Charts, canvas and maps have no text: the agent falls back to the small screenshot (with refs drawn on it) and relative-coordinate clicks.
The
browse_taskengine is a calibrated vocabulary, not a trained model: with unknown jargon it asks more often (never acts wrongly). Answers are remembered per site.CAPTCHAs and logins are done by you, in the window: Colibri never bypasses them, it pauses and resumes on its own (see FAQ).
Tested on pages modelled on public-administration portals: please report sites that don't work in Issues.
FAQ
No. The Jev-style engine runs locally inside Colibri. You only use the agent you already have (Claude, Copilot, Codex, Gemini…).
Chrome or Edge, with a dedicated profile in ~/.colibri/profile: log in once and it remembers. To use your own running Chrome instead, start it with --remote-debugging-port=9222 and set CB_MODE=cdp.
github:t4zxxx1/colibri-mcp follows the latest main. To pin a release use github:t4zxxx1/colibri-mcp#v0.4.0. Claude Desktop users download the new .mcpb from Releases.
Yes: CB_HEADLESS=true. Logins and CAPTCHAs still need a visible window the first time.
Colibri recognises the check (Cloudflare "Just a moment" / Turnstile, reCAPTCHA, hCaptcha, DataDome, PerimeterX "press & hold", AWS WAF, Arkose, GeeTest, Friendly Captcha, image captchas) and does not try to cheat it. Instead it:
waits a few seconds: many checks (e.g. Cloudflare) clear by themselves;
otherwise shows a bar on top of the page — "🐦 Colibri is paused: complete the check below" — and brings the window to the front (if it was running headless it reopens Chrome visibly on the same page);
resumes automatically as soon as you solve it, and continues the remaining steps;
for a CAPTCHA inside a form it fills everything else, then waits for you before pressing Submit.
If you don't solve it within CB_HUMAN_WAIT seconds (default 50) the agent is told to ask you, and browse_view resumes waiting. Sites with very strict bot protection work best in real Chrome mode (next question).
By default Colibri starts Chrome through Playwright, which marks the browser as automated, so some sites loop on "verify you are human". Real Chrome mode makes Colibri drive a normal Chrome instead. No stealth tricks: it is simply a regular browser.
Add
"env": { "CB_MODE": "cdp" }to the Colibri entry in your agent's MCP config.That's it: on the first call Colibri starts a normal Chrome on port 9222 (profile in
~/.colibri/real-chrome). To start it yourself:npx -y github:t4zxxx1/colibri-mcp --chrome.
In this mode Colibri never closes your Chrome: on reconnect (/mcp) it only closes the tabs it opened. When a check blocks in the default mode, Colibri itself suggests switching.
No. Side effects (!c) need your explicit OK, secrets (!x) can never be typed by the AI. See Safety.
Development
npm ci # dev + runtime deps
npm test # 180+ end-to-end tests over the real MCP protocol (needs Chrome or Edge)
npm run test:live # optional checks on real sites: search, PDF, httpbin form, Wikipedia, upload area (network)
npm run bench # vs screenshots, Playwright MCP, agent-browser, Fast Playwright MCP
npm run bench:task # repeated train search: calls, tokens, seconds (add paths to older index.js to compare)
npm run bench:pages # Vinted / Amazon / calendar / discount-code scenarios: calls and tokens (same)
npm run calibrate # engine calibration (VERIFY5=1 adds the independent Test 5)
npm run build # dist/colibri.mcpbDocs (Italian): how it works · benchmark · calibration & Jev comparison.
Release: bump version in package.json, extension/manifest.json, extension/server/package.json, then git tag vX.Y.Z && git push --tags — CI tests, builds the .mcpb and publishes it.
Support the project
If it saves you tokens, ⭐ star the repo — it's the best way to help others find it. Ideas, bugs and sites to support: open an issue. Made with care in Italy by @t4zxxx1 · Roca Software.
License
MIT — see LICENSE. © 2026 Roca Software.
Available Tools
8 toolsbrowse_doEsegui passiB
Run up to 40 steps in order and return only the diff; stops at the first error or block. view: diff (default) | full | none.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | ||
| steps | Yes | One verb per step. T = ref "e12" | name text | {name,role,row,n} | {x,y} 0-1 for canvas/maps. click:T (force:true = JS click if covered) · fill:T+text (native date: YYYY-MM-DD) · type:T+text (keystrokes, autocomplete) · select:T+option (native <select>; label, value or part) · check:T (on:false unchecks) · press:key (+target:T) · pick:"text" (visible suggestion/option) · hover:T · scroll:down|up|top|bottom|T · wait:ms (max 10000)|"idle" (network+spinners done) · waitFor:"visible text" (+timeout ms) · goto:url · back:true · tab:n|"list"|"close" · upload:T+file (path or list; T may be a "drag here" area) · dialog:accept|dismiss (next alert/confirm) · find:"text" (matching lines) · read:text|table|cards (+target, max, links) · confirm:true only after the user OKs a !c step. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full burden and does disclose real traits: a 40-step cap, strict ordering, first-error/first-block halt, and diff-only response. It omits mutation/permission implications, whether state persists across calls, and the fact that some steps require prior user confirmation (that only surfaces inside the schema).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the core behavior and limits, then the view enum with its default. No filler; only minor density loss from cramming the view options into a sentence fragment.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers limits, ordering, failure semantics and return shape for a complex browser-automation tool with no annotations and no output schema. Still missing what a "block" is, whether browse_open must precede it, and how errors/diffs are surfaced — meaningful gaps for a 40-step mutating executor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%, but the covered parameter (steps) is exhaustively documented in the schema itself, so the description rightly does not repeat it. The description does add one thing the schema lacks: the default value for view ("diff (default)"), which is genuine value-add. It does not explain what full vs none mean in output terms, leaving a gap for that parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Run up to 40 steps in order") plus the return contract ("return only the diff; stops at the first error or block"). This distinguishes it from the read-oriented siblings (browse_view, browse_read, browse_screenshot) without naming them directly, so an agent can infer it is the executor, but full sibling differentiation is implicit rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use/when-not-to-use guidance or named alternatives, though the execution model (ordered steps, stop at first error, diff-only return) implies it is for performing actions after inspection. The default "view: diff" hints at the intended normal path, but an agent gets no rule for choosing browse_do over browse_task or browse_open.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browse_openApri paginaB
Open URL (starts the browser), reject non-essential cookies, return rows. rows:false: header+counts only; filter: matching rows.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| rows | No | ||
| filter | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose real behavior: launching a browser, automatically rejecting non-essential cookies, and two response modes. It omits error/timeout behavior, auth requirements, and what happens if a session already exists, which matters for a tool with side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is short and front-loaded with no filler, but the telegraphic fragment style ('rows:false: header+counts only; filter: matching rows') makes the two most load-bearing clauses hard to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema and no annotations, so the description is the only guidance, yet it leaves the return shape ('rows') undefined and gives no sibling-selection or failure-mode guidance for a browser-launching tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must define all three parameters. It gestures at 'rows' (false = header+counts only) and 'filter' ('matching rows'), but never explains what a 'row' actually is or what syntax 'filter' accepts, and 'url' is undocumented beyond 'Open URL'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource (open URL, starts the browser) plus concrete side behaviors (cookie rejection, returning rows). It does not, however, distinguish itself from any of the eight siblings such as browse_view or browse_search, so an agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the 'rows:false' note hints at a lightweight header-only mode and 'filter' hints at narrowing results, but there is no statement of when to pick browse_open over browse_view or browse_search, nor any exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browse_readLeggi contenutoARead-only
Read without acting. mode: text (main content, no menus; ref/selector "body"=all; paged) | table (tab-separated rows) | cards (repeated results: trains, flights, products → 1 row each, buttons as [ref], +links:true URLs; auto or selector) | find (lines containing query) | describe (ref: options, value, href, box) | pdf (open/downloaded PDF; query=URL or file in downloads).
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | chars (text) or rows | |
| ref | No | ||
| mode | No | ||
| links | No | ||
| query | No | ||
| offset | No | ||
| selector | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered; the description adds real behavior beyond that — text mode strips menus, cards collapses repeated results to one row each, links:true appends URLs, pdf handles open or downloaded files. It does not describe return shape or how paging interacts with max/offset.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The key constraint 'Read without acting' is front-loaded and the pipe-delimited mode breakdown is dense but scannable. The telegraphic style occasionally sacrifices clarity (e.g., '+links:true URLs'), but there is little wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 7 parameters, zero required, no output schema, and 14% schema coverage, the description carries most of the burden. It covers modes and ref/query well but leaves offset/paging and the meaning of max partially unexplained, and gives no indication of what the returned content looks like.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 14%, so the description must compensate, and it largely does: every mode value is explained, ref/selector semantics are given ('body'=all), and query changes meaning per mode (find = matching lines, pdf = URL or downloaded file). The gaps are max (only half-documented in schema) and offset, whose paging semantics are never explained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and constraint ('Read without acting') and enumerates the six read modes, which makes the tool's function concrete. It implicitly distinguishes itself from the mutating sibling browse_do, but never names the resource (current page) or explicitly contrasts with browse_view/browse_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The mode list implies when each mode applies (cards for 'trains, flights, products', find for searching lines), which is useful implied guidance. However, there is no explicit statement of when to prefer this over browse_view, browse_search, or browse_screenshot, so the agent must infer routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browse_screenshotScreenshotARead-only
JPEG (~900 tokens) of window, ref or region [l,t,r,b] 0-1; labels:true draws refs. Only when rows are not enough (charts, canvas, layout).
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | ||
| labels | No | ||
| region | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, so safety is covered; the description goes further and discloses the token cost (~900 tokens) and the output medium (JPEG), both of which an agent needs for budgeting context. It omits what the image actually shows at default scale (full window vs viewport) and any size limits, keeping it off a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, cost and addressing modes front-loaded, no filler. The semicolon-and-colon compression is efficient but borders on cryptic, costing a point on readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-param, zero-annotation-coverage, no-output-schema tool this covers the essentials: cost, format, coordinate system, and the labels flag. It does not say what ref accepts or whether ref/region can be combined, which is the main residual gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the full burden and largely does: region is given as [l,t,r,b] in 0-1 normalized space, and labels:true is explained as drawing refs. Only 'ref' is left unglossed, which assumes familiarity from sibling tools and prevents a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names the artifact (JPEG screenshot), the three addressing modes (window, ref, region) and the coordinate convention, so the agent knows exactly what it gets. The telegraphic noun-phrase style lacks an explicit verb and doesn't contrast itself against browse_view or browse_do by name, but the resource and scope are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Only when rows are not enough (charts, canvas, layout)' gives an explicit trigger and implicitly the condition for not using it — i.e. prefer row/text output otherwise. It stops short of naming a sibling to use instead, but the alternative mode is concrete enough to route on.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browse_searchCerca sul webA
Web search (DuckDuckGo): rows "n. title | url | snippet", no ads.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | results, default 8, max 20 | |
| query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the burden. It usefully discloses the return shape ('n. title | url | snippet') and the no-ads behavior, but says nothing about rate limits, failure modes, or result freshness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight line with the distinctive traits front-loaded; nothing is padded. The telegraphic 'no ads' is terse but still readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with no output schema, describing the return row format is exactly the compensation needed. Only the omission of 'query' semantics and sibling routing keeps it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only 'max' is documented, and that documentation lives in the schema, not the description. The description adds no meaning for 'query' or for how 'max' interacts with the row output, so it neither compensates for the 50% coverage nor adds value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Web search') plus the engine (DuckDuckGo) and the exact result format, so it is clearly distinguished from open/view/read siblings. It stops short of explicitly naming which sibling follows it, but the purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the name and by the row format (search then presumably open a URL). Against eight siblings there is no explicit when-to-use or when-not-to-use guidance, e.g. no note that browse_open fetches a result's page.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browse_statsConsumo sessioneBRead-only
Tokens used by the browser this session vs screenshots.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes that this is a safe read-only operation, so the description does not need to cover safety. It adds some session scoping and names token usage and screenshots as the measured data, but it does not clarify the return structure or whether the values are counts, comparisons, or both.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short sentence fragment with no wasted text and the metric context is front-loaded. Its brevity is appropriate, though the cryptic 'vs screenshots' wording slightly weakens the structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only stats tool, the description gives a minimal indication of what is reported: session token usage and screenshots. However, without an output schema, the description should more clearly explain what the returned statistics look like and what 'vs screenshots' means.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
This tool has zero parameters, so parameter semantics are trivially complete. The empty schema and 100% schema description coverage mean no additional parameter explanation is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description hints at session token usage and screenshots, but the phrase 'vs screenshots' is ambiguous and does not clearly state the resource or metric returned. It is distinguishable from the action-oriented browse_* siblings only because of the tool name and title, not because the description explicitly differentiates it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool instead of browse_screenshot or the other browse_* tools. The description does not mention prerequisites, expected context, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browse_taskCompito guidatoB
Form task: local engine maps params to fields (synonyms, typos, languages), fills selects, autocompletes, dates (split day/month/year[/h/min] fields too: one "DD/MM/YYYY [HH:MM]") and checkboxes, verifies, then submit/expect/extract/read. Uncertain params come back as questions with probabilities.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | ||
| read | No | ||
| view | No | ||
| before | No | browse_do steps run first | |
| expect | No | text expected after submit | |
| params | No | field label (or ref) -> value | {value, about, secret} | |
| submit | No | button name(s) to press last; true = form submit | |
| answers | No | param -> ref (remembered per site) or suggestion text | |
| confirm | No | only after the user OK: allows !c actions | |
| extract | No | name -> text|number|money|date|url|table | |
| confidence | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses genuinely useful behavior: fuzzy field matching (synonyms, typos, languages), date normalization into a single DD/MM/YYYY [HH:MM] value, verification before submit, and a probabilistic question-return mode for uncertain params. It does not disclose failure semantics, what happens to partially-filled forms, whether submission is reversible, or auth requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is dense with no filler, but it is a single run-on sentence that mixes mechanism, field types, and workflow, with the critical ask/answer behavior buried at the end. Front-loading is weak and the parenthetical date clause interrupts the flow.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with nested objects, no annotations, and no output schema, the description covers the core mechanics but not the workflow shape (when to call it, what a question-response cycle looks like before re-invoking) or failure behavior. Adequate to attempt a call, insufficient to call it confidently on a complex form.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 64%, so the baseline is 3, but the description adds real meaning beyond the schema: the format expected for date-shaped params ('one DD/MM/YYYY [HH:MM]'), how 'answers' pairs with returned questions, and the gating condition for 'confirm'. It still leaves url, view, before, and confidence unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete capability: driving a form task end-to-end (map params to fields, fill selects/autocompletes/dates/checkboxes, verify, then submit/expect/extract/read). That is far more than a restated title such as 'guided task'. It stops short of stating how this differs from the close sibling browse_do, which it only mentions indirectly as a step-runner in the 'before' param.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the sentence about uncertain params returning as questions reveals a two-turn ask/answer workflow (with 'answers' resolving it), and 'confirm: only after the user OK' hints at the safety gate. There is no explicit when-to-use vs browse_do/browse_open/browse_read, nor any exclusion or prerequisite.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browse_viewVista paginaCRead-only
Current page rows. filter: matching only; scope all: +header/nav/footer, areas: refs for unlabeled clickable/drop areas (icons, canvas, "drag here"); offset: next rows.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | ||
| filter | No | ||
| offset | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint already declares this is a safe read, so the bar is lower. The description does add real value beyond annotations by explaining what scope=all pulls in (header/nav/footer) and what scope=areas returns (refs for unlabeled clickable/drop zones like icons and canvas). It says nothing about row volume, truncation, or how returned refs are consumed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is short and front-loads the resource, but the telegraphic semicolon style drops articles and verbs, making it read like notes rather than instructions. Nothing is padded, yet clarity was traded away for brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 0% schema coverage, no output schema, and only a readOnlyHint annotation, the description should explain what a returned row/ref looks like and how refs feed into browse_do. Those gaps matter for a 3-parameter inspection tool and are not covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the burden; it partially does so by explaining filter, two of the three scope values, and offset. But scope=main is undefined, filter syntax (substring vs regex) is unstated, and "offset: next rows" leaves the page size unknown.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The phrase "Current page rows" identifies the resource (rows of the current browser page) but omits an explicit verb and never states that it reads/snapshots the page. An agent can guess it inspects the active view, but nothing distinguishes it from browse_read or browse_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance is given: nothing says to call this before browse_do, or when to prefer browse_read/browse_search/browse_screenshot. The scope values imply some usage but the agent must infer it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.5.8- Changed
browse_do1 field changed- changed
Input schema / properties / steps / descriptionPrevious value: -"One verb per step. T = ref \"e12\" | name text | {name,role,row,n} | {x,y} 0-1 for canvas/maps. click:T (force:true = JS click if covered) · fill:T+text (native date: YYYY-MM-DD) · type:T+text (keystrokes, autocomplete) · select:T+option (native <select>; label, value or part) · check:T (on:false unchecks) · press:key (+target:T) · pick:\"text\" (visible suggestion/option) · hover:T · scroll:down|up|top|bottom|T · wait:ms (max 10000) · waitFor:\"visible text\" (+timeout ms) · goto:url · back:true · tab:n|\"list\"|\"close\" · upload:T+file (path or list) · dialog:accept|dismiss (next alert/confirm) · find:\"text\" (matching lines) · read:text|table (+target, max) · confirm:true only after the user OKs a !c step."New value: +"One verb per step. T = ref \"e12\" | name text | {name,role,row,n} | {x,y} 0-1 for canvas/maps. click:T (force:true = JS click if covered) · fill:T+text (native date: YYYY-MM-DD) · type:T+text (keystrokes, autocomplete) · select:T+option (native <select>; label, value or part) · check:T (on:false unchecks) · press:key (+target:T) · pick:\"text\" (visible suggestion/option) · hover:T · scroll:down|up|top|bottom|T · wait:ms (max 10000)|\"idle\" (network+spinners done) · waitFor:\"visible text\" (+timeout ms) · goto:url · back:true · tab:n|\"list\"|\"close\" · upload:T+file (path or list; T may be a \"drag here\" area) · dialog:accept|dismiss (next alert/confirm) · find:\"text\" (matching lines) · read:text|table|cards (+target, max, links) · confirm:true only after the user OKs a !c step."
- Changed
browse_open2 fields changed- added
Input schema / properties / filterAdded value: +{ + "type": "string" +} - added
Input schema / properties / rowsAdded value: +{ + "type": "boolean" +}
- Changed
browse_read2 fields changed- added
Input schema / properties / linksAdded value: +{ + "type": "boolean" +} - changed
Input schema / properties / mode / enumPrevious value: -[ - "text", - "table", - "find", - "describe" -]New value: +[ + "text", + "table", + "cards", + "find", + "describe", + "pdf" +]
- Added
browse_search - Changed
browse_task3 fields changed- changed
Input schema / properties / params / descriptionPrevious value: -"field label as the user would say it (or ref) -> value | {value, about, secret}"New value: +"field label (or ref) -> value | {value, about, secret}" - changed
Input schema / properties / read / enumPrevious value: -[ - "text", - "table" -]New value: +[ + "text", + "table", + "cards" +] - changed
Input schema / properties / submit / descriptionPrevious value: -"button name(s) to press at the end; true = form submit"New value: +"button name(s) to press last; true = form submit"
- Changed
browse_view1 field changed- changed
Input schema / properties / scope / enumPrevious value: -[ - "main", - "all" -]New value: +[ + "main", + "all", + "areas" +]
7 tool updates
v0.4.0- First observed
browse_do - First observed
browse_open - First observed
browse_read - First observed
browse_screenshot - First observed
browse_stats - First observed
browse_task - First observed
browse_view
TDQS
Scored across 8 tools
Most tools have clearly distinct roles: open/search/view/read/do/task/screenshot/stats. There is some overlap between browse_view and browse_read, and between browse_do and browse_task, but the descriptions provide enough differentiation for an agent to choose.
All tools follow the same predictable browse_verb pattern in snake_case. The convention is consistent across the entire set with no naming outliers.
Eight tools is well-scoped for a browser automation server. Each tool covers a distinct capability without excessive fragmentation or missing obvious primitives.
The surface covers core browser workflows: opening, searching, reading, acting, form filling, screenshots, and session stats. Minor gaps exist around explicit navigation/history/tab management, but browse_do likely handles many of these as steps.
Maintenance
Related MCP Connectors
AI-powered web automation. Navigate websites using AI agents for one page or a thousand
AI-powered web automation. Navigate websites using AI agents for one page or a thousand
AI-powered browser automation — navigate, click, fill forms, and extract data from any website.
Hosted browser for AI agents: screenshots, post-JS DOM, console, WCAG. No install, no API key.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI agents to browse and interact with web pages through compact, typed structural representations — landmarks, headings, interactive elements, and forms — served in three controllable detail levels instead of full accessibility-tree dumps. Agents can navigate, query for specific elements, fill forms, manage tabs and cookies, capture screenshots, and run audits while paying a fraction of the token cost.4 npm-
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to browse and interact with web pages through compact, structured representations — page summaries, targeted element queries, and full detail on demand — instead of paying for a full accessibility-tree dump on every call. This cuts the token cost of reading content-heavy pages by up to ~140x while still supporting navigation, forms, clicks, screenshots, and session management.4 npm-
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to browse and interact with web pages through structured, token-efficient representations instead of raw accessibility trees, with navigation, element finding, form filling, screenshots, and session management. It returns a compact page orientation by default and full detail only on request, cutting context cost on content-heavy pages.4 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to browse and interact with web pages through a compact, structured representation, returning a small orientation on arrival plus targeted queries for specific elements instead of a full accessibility-tree dump. Supports navigation, element interaction, form filling, screenshots, network monitoring, and session management while cutting token cost dramatically on content-heavy pages.4 npmMIT