KitchenSink4Web
OfficialClick on "Install 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., "@KitchenSink4WebNavigate to example.com and extract the article text"
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.
🚰 KitchenSink4Web
Landing page · llms.txt (machine-readable capability manifest for agents and LLM crawlers)
Everything plus the kitchen sink for the open web: a browser MCP server that reads a whole page for the price of a paragraph, and starts out unable to change anything at all.
New here? Start with the Quickstart; the Cookbook has the ten most common jobs, and Architecture explains how the pieces fit.
Two numbers that matter
The same page, read two ways. A raw dump of the Treaty of Versailles article on Wikipedia costs 33,073 tokens of your assistant's memory. This server's first read of it costs 4,445. The difference is not compression, it is a different product: a map of the page with a price on every region, instead of the whole page whether you wanted it or not.
Numbers on this page are measured by scripts in tools/, not written by hand. Re-run them
yourself; the README is regenerated from their output.
.venv/Scripts/python.exe -X utf8 tools/measure_readme_numbers.pyRelated MCP server: mcp-browser-agent
The cheap first read
get_page_view returns the page's shape: what it is, what is on it section by section, what each
section costs to open, and what the sensible next call would be. You set the budget and the read
never exceeds it, so the question is never whether a page fits, only how much detail you bought.
Every read ends with a completeness block naming what was left out and what it would cost to get
it back. Nothing is swept under the rug.
From there the pattern is cheap and gets cheaper. Expand one region instead of raising the budget. Chain delta reads: pass the token a read returns and the next read prices only what changed. Elements come back as short-lived refs your assistant can act on directly, and searches by text and role survive re-renders that break refs.
Open shadow roots are read and their contents are actable like anything else, which is what makes component-built sites (Reddit, MDN, most of the modern web) readable at all. Closed roots cannot be reached by any tool; they are counted and reported rather than silently skipped. Same-origin iframes are read and searched like the page they sit in, each labeled with its own origin; a cross-origin frame is counted and named, never entered.
The packs
The server starts lite: reading, navigation, and session management, 19 tools. Capability packs are chosen at launch and are fixed for the whole session, which means an absent pack is provably absent, not merely switched off:
Pack | What you get |
extract | Tables, lists, links, and article text, with CSV and JSON export. |
capture | Screenshots (passwords blurred), PDF export, and saving pages as files. |
network | See the requests a page makes behind the scenes. Useful for debugging websites; most people leave it off. |
storage | Use with care. Saves a signed-in session so Claude does not have to log in every time. It saves the session, never your password; treat the saved file like one anyway. |
files | Download files from pages into one folder, and upload files into page forms. Every one asks you first. |
diagnostics | Lets Claude run JavaScript on a page, one script at a time, each one shown to you for approval first. This is the most powerful and most dangerous setting on this page. Leave it off unless you know you need it. |
workflows | Record a multi-step task once and replay it later. Every replay checks that the page still matches before anything runs. |
accessibility | Checks a page against the WCAG accessibility rules using axe-core, groups what it finds by rule, and says plainly what automated testing cannot check. Needs an optional extra installed; the tool tells you how if it is missing. |
The safety model
A browser is where your logins, your money, and your mistakes all live, so the safety layer is the product, not a feature of it.
Read-only unless you say otherwise. Out of the box the tools that click, type, and submit do
not exist. They are not disabled, they are absent from the tool list, and no instruction on any
webpage can talk your assistant into using a tool that is not there. One switch at install
(allow acting in the bundle, KS4WEB_ALLOW_ACTING=true elsewhere) brings them in.
Credential blindness. The server never reads what you type into password fields, and secrets observed in cookies and site storage are vaulted: they cannot leak into your assistant's conversation, because the text that would carry them is redacted before it leaves the server.
Hidden text is evidence, not instructions. Text a page hides from human eyes is the oldest trick for slipping commands to an AI. This server strips it from the reading channel, counts it, reports the count, and wraps everything a page says in labeled provenance markers, so your assistant always knows which words came from a stranger.
Confirmation gates. Form submissions, payments, and page scripts stop and ask you first, through the client's own confirmation prompt. As of 2026-09 that prompt displays in Claude Desktop and Claude Code; the claude.ai web client does not display it yet, so gated actions refuse there instead of proceeding unconfirmed.
Honest refusals. When something cannot be done, from a login wall to a bot check to a page that crashed its own renderer, the answer names what stood in the way and what to try next. A refusal that explains itself is cheaper than a retry loop.
Two different things ask you for permission
Your MCP client's own permission prompt names a tool (something like mcp__web__type_text) and
comes from the client, not from KS4Web; approving a read-only tool group there is safe and stops
most of the asking. A KS4Web gate names an action in plain words ("submitting this form sends a
password") and cannot be pre-approved away for payments, credentials, posts, deletions, or legal
assent. If a prompt names a tool, it is the client; if it names what is about to happen in the
world, it is KS4Web.
Consent scope
Out of the box the consent scope is research: reading and navigation are free, query-shaped
submissions (a search box) proceed, and everything else asks first. The full scope lets ordinary
form submissions proceed without asking; the irreducible set asks under every scope, always. The
install screen's "Submit routine forms without asking each time" checkbox is the whole choice.
The GET rule is the one place page-authored text classifies down rather than up: a form that looks
like a search is allowed to proceed as one, and what a mistaken call in that direction buys is an
unprompted ordinary submission, never a payment, credential, post, or deletion; those always ask.
In the other direction, a submit button that says nothing recognizable in any shipped language
passes ungated under the full scope; if that risk matters to you, stay on research.
Client compatibility
If a feature refuses with CONFIRMATION_REQUIRED on claude.ai web, it works on Desktop and Code.
Client | What works |
Claude Desktop | Everything, with confirmations rendered. |
Claude Code | Everything, with confirmations rendered. |
claude.ai web | All reading, navigation, and search. Gated actions refuse honestly because no confirmation can render; pre-authorized classes work if configured at launch. |
Browsers and lanes
The default lane drives the server's own bundled Chromium. It never touches your browser or your profile; sessions open in a fresh profile that is deleted on close unless you explicitly save signed-in state to a file.
Lane B drives a browser you already have installed (Chrome, Edge, or Firefox), still with its own separate profile, never yours. Installed Firefox is the lane to reach for on research-heavy work: sites that turn away automated Chromium routinely serve Firefox normally, and both Firefox lanes pass bot checks that block headless Chromium. That is lane steering, not evasion; the server does not disguise what it is, it just lets you use a browser the site treats better.
Signed-in sessions are saved and reloaded with save_auth_state and auth_state= on open. The
state file records when its session cookies expire, and loading a stale file says so plainly
instead of letting the login fail mysteriously.
manage_session(action='status') reports which browsers are installed and which lane it would
recommend for the page you are on. It never switches lanes for you.
Context cost (measured)
Surface | Tokens |
Lite tool surface | 5.8k |
Full surface (all packs) | 15.3k |
First read of the Treaty of Versailles article on Wikipedia | 4,445 |
Delta read after one click | 82 |
The budget ladder has 16 rungs; every read reports which rung it printed at and what a deeper
read would cost. Inside a subagent, start at budget_tokens=2500; tool results are capped more
tightly there.
Update check (opt-out)
The server compares its version against PyPI's when you call
manage_session(action='status'), and never at any other time: nothing runs at startup and nothing
runs on a background thread. At most one request per seven days, with a two-second timeout. It never
installs anything. The request is a plain HTTPS GET to pypi.org for this package's public release
index; it sends no identifier, no usage data, no page content and no session state. A check that
could not complete says so and says how long ago the last successful one was, rather than showing
nothing. KS4WEB_UPDATE_CHECK=off switches it off, and the status report then says it is off; the
older KS4WEB_NO_UPDATE_CHECK=1 spelling is still honored.
Testing
2,065 tests, of which 733 drive a real browser. Beyond the suite, every release passes gate batteries that re-run the adversarial findings of four attack rounds: prompt injection through page content, hidden-text smuggling, credential-theft attempts, gate bypasses, workflow replay tampering, and resource abuse. The gates are not aspirational; each one exists because an adversarial round or a field tester actually broke something, and the fix is pinned by the test that would catch its return.
The current tuning came out of a live field campaign: two sessions, twelve real sites, three browser engines, and 141KB of logged friction, retests, and design notes. The findings, and what shipped in response, are in the repository history rather than a marketing page.
Maturity: what the version number does and does not claim
This is the newest member of the family, and the version number says so honestly. It grew up under the house rules: every claim measured, every release attacked before it ships, every refusal honest about its reason. What it has not had yet is a long life in strangers' browsers. The safety net while it earns one: it starts read-only, it prices every read before taking it, and it tells you what it could not see. Bring it your strangest pages and file what breaks.
Known limits
Cross-origin iframes are never entered; the completeness block names each frame and says why. Same-origin iframes are read, searched, and acted in, each labeled with its own origin.
Closed shadow roots cannot be reached by any tool. They are counted so you can tell a component-heavy page from an empty one.
Confirmation-gated actions (auth loading, page scripts, submits) refuse on the claude.ai web client until it renders MCP confirmation prompts; Claude Desktop and Claude Code work today.
Bot walls and CAPTCHAs are reported, never solved or evaded. The Firefox lanes get through device checks that block headless Chromium; a wall that blocks everything is a wall.
sendBeaconand ping requests bypass network routing rules; that is a Playwright limit, documented rather than hidden.
Automated accessibility checking finds a minority of real-world issues. Deque, who build the axe-core engine this tool runs, publish 57% as their own figure for their own tooling. A clean report here means the automated checks passed, not that the page is accessible. There is no score, because every 0-to-100 accessibility number is somebody's weighting rather than a measurement.
Nothing taps you on the shoulder. No MCP client in use today delivers a server-initiated
message into a conversation, so monitors run only while KS4Web runs, and the report is how you ask
what happened; after a restart, the report names the window that went unchecked. A monitor watches
one URL for one deterministic change and does not understand what changed: content_hash is noisy
on pages with clocks or counters, only the main document is watched, and a change that appeared and
reverted between two checks is invisible. A monitor cannot get past a login or a bot wall, and one
that keeps failing pauses itself rather than hammering the site. Five minutes minimum between
checks; everything stays on this machine.
A session handle transfer moves a live session between conversations on the same machine, inside the same running KS4Web. Nothing is copied: it is the same browser, so a page the other conversation navigated has lost your refs, and the report says which. It does not survive a server restart, and it does not cross between Claude Desktop's chat and Code panels, which run separate servers. The session dies with KS4Web on purpose; that is what keeps orphaned browsers off your machine. A token works once, expires in an hour, and is not a lock: any conversation on this server can already see the session. The budget travels with the session.
Two identities cost two browser processes and two profile directories, which is real memory. The action budget is shared across them on purpose, so opening a second identity does not double what a session may do to the world, and two contexts visiting the same site cost one origin against the origin budget. Auth state saves and loads per identity. Closing one identity leaves the others working; closing the last one tells you to close the session instead. Every context shares the session's lane and emulation; two lanes means two sessions.
The lane database is a list of which websites this computer has visited with which browser: hostnames and dates, no pages, no addresses, nothing typed. It exists so a site that refused one browser can be read with one that works. It is stored on this machine, it never leaves unless you export it, learning can be turned off with one switch, and one call erases it entirely.
Requirements
Python 3.12 or newer (developed on 3.14)
uv on your PATH for the Claude Desktop bundle route, which uses
uvxto start the serverPlaywright, installed as a dependency of this package
A browser engine, downloaded by Playwright on first use rather than shipped in the wheel
Windows, macOS, or Linux
Install
Claude Desktop: install the .mcpb bundle and pick what you want on the
install screen. The checkboxes are the whole configuration: one to allow
clicking and typing (off means read-only browsing, the shipped default),
and one per capability pack. Launching the bundle requires uv (the uvx
command) on your machine; the server itself is fetched from PyPI on first
launch and drives its own bundled Chromium, never your browser or your
profile.
Any other MCP client:
uvx kitchensink4webor
pip install kitchensink4web
python -m kitchensink4web.serverPacks and read-only mode are chosen at launch (--packs, KS4WEB_MODE,
KS4WEB_ALLOW_ACTING) and are identical for every connection to the
process.
Tip for Claude Desktop: in Tool permissions, set this server's Read-only tools group to Always Allow. Those tools cannot change anything on any page, and it stops most permission prompts.
License
AGPL-3.0. Free for individuals and personal use, and it stays that way.
Companies building it into their own products need a commercial license, with terms worked out case by case. Open an issue and we will talk it through.
Not affiliated with or endorsed by Google, Mozilla, Microsoft, or any website this server visits. Chrome, Chromium, Firefox, and Edge are trademarks of their respective owners, used nominatively to name the browsers this server can drive.
Available Tools
11 toolsfind_elementsARead-only
Find elements by text, role plus accessible name, natural-language
description, CSS, or XPath, and get back refs you can act on plus a note
on what was not searched. role='button' narrows any query to one
element role (field finding: 'Comment' alone matched 12; with the role
filter it matches the one button). This is the cheap targeted follow-up
that pairs with get_page_view: the page view tells you what string to
look for, and this retrieves it for a fraction of a full read.
Ambiguous results are listed rather than resolved, and zero results
come back with the nearest misses so a miss is a one-turn recovery.
The search covers the main document and every open shadow root in it,
and the matches it returns from a shadow root are actable like any
Same-origin iframes are searched too and the result says which ones
it entered. Two things stay out and the result counts both:
cross-origin iframes, which no tool here opens, and closed shadow
roots, which no tool can reach. XPath is the one kind that does not
enter a shadow root. location={'region': 'r7'} (or a ref, form, or table
from a read) narrows the search to that subtree, components inside it
included, and the first result line names the scope that was searched.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | auto | |
| page | Yes | ||
| role | No | ||
| limit | No | ||
| query | Yes | ||
| location | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the readOnlyHint annotation by detailing search scope (main document, shadow roots, same-origin iframes), exclusions (cross-origin iframes, closed shadow roots), behavior for ambiguous and zero results, and how location narrowing works. This provides rich behavioral transparency that annotations alone could not convey.
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 lengthy but information-dense, with each sentence contributing value. It opens with the core purpose, then adds a concrete example, usage guidance, and detailed behavioral notes in a logical flow. While slightly long, it is well-structured and front-loaded with the most critical information.
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?
The description is comprehensive for a read-only element-finding tool: it explains output (refs and notes on what wasn't searched), ambiguity handling, scope of search, limitations, and how to narrow via location. Despite no output schema, the agent receives enough information to call the tool correctly and interpret results.
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?
With schema description coverage at 0%, the description compensates by explaining the 'role' parameter ('narrows any query to one element role'), the 'location' parameter (region, ref, form, table narrowing), and implying 'kind' via the listed search methods. It does not explicitly define the 'kind' enum values or explain 'page' and 'limit', but the core parameters are meaningfully clarified beyond the bare 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?
The description clearly states the tool finds elements via text, role, natural-language description, CSS, or XPath, and returns actionable refs plus a note on what wasn't searched. It also distinguishes itself from sibling get_page_view by positioning it as a cheap targeted follow-up, making its purpose 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?
Explicitly names get_page_view as the complementary tool and specifies when to use this tool ('the cheap targeted follow-up'). It also explains how ambiguity and zero results are handled, giving clear context for expected behavior in common scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_auditARead-only
Read the action log. Returns one record per call, paginated, carrying the timestamp, lane, page, URL, resolved target with its human label, redacted arguments, outcome, any rebind, any confirmation decision, and the budget counters at that moment. This is an operational record for the user, so you can always know exactly what was done even where a web action cannot be undone. It is not forensic and not evidence.
| Name | Required | Description | Default |
|---|---|---|---|
| tool | No | ||
| limit | No | ||
| session | No | ||
| start_index | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint: true, and the description aligns by saying 'Read the action log.' It adds behavioral context beyond annotations: the log is paginated, returns one record per call, and carries specific fields. It also discloses the non-forensic, non-evidence nature, which is critical for appropriate use. This significantly enriches the safety profile.
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 well-structured: it leads with the core action, enumerates the record contents, then adds operational context and limitations. It is a bit long but every sentence adds meaningful information, and the structure is logical. It does not waste words.
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 four parameters and no output schema, the description needs to explain how to paginate (limit, start_index) and how to filter (tool, session). It does not. It describes what the log contains but not how to control retrieval. An agent would not know how to request a specific page or filter by tool without inspecting the schema, which itself has no descriptions. The description is incomplete for effective invocation.
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 compensate. It does not explain any of the four parameters (tool, limit, session, start_index). It only mentions 'paginated' generically, which hints at limit/start_index but does not explain their meaning or usage. The 'tool' and 'session' filters are entirely unexplained. The description adds essentially no parameter-level meaning.
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 states a clear verb and resource: 'Read the action log.' It explicitly lists what each record contains (timestamp, lane, page, URL, resolved target, etc.), which distinguishes it from all sibling tools. None of the siblings (wait_for, get_page_view, find_elements, etc.) read the action log, so 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?
The description provides context on when to use it: 'This is an operational record for the user, so you can always know exactly what was done even where a web action cannot be undone.' It also warns of limitations: 'It is not forensic and not evidence.' It doesn't name specific alternative tools, but no sibling appears to offer similar functionality, so the guidance is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_page_viewARead-only
Read a page as an ORIENTATION, not a transcript, under a token budget
it never exceeds whatever the page size. Returns identity, landmark
regions each priced with the cost to expand it, the interactive surface
with refs you can act on, a digest or app skeleton, form and table
inventories, an account of what was NOT read and why, and the next call
for anything unexpanded. location scopes to one region ref,
budget_tokens=2500 suits a subagent, mode='links' includes in-prose
links at their real cost. since=<read_token> is the cheap repeat
read: only what changed, refs kept, a few hundred tokens instead of a
fresh read, and it falls back to a full read when the page navigated in
between and nothing survives to diff. Open shadow roots are read and
their contents get refs you can act on; closed roots cannot be reached
by any tool and are counted at creation, so the completeness block
reports both numbers rather than one confident zero. Same-origin
iframes are entered and read, and their contents get refs naming the
frame they came from; a cross-origin frame is never entered, because
its document belongs to an origin the page itself cannot read either,
and the completeness block counts every frame it did not open.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | auto | |
| page | Yes | ||
| view | No | auto | |
| since | No | ||
| detail | No | standard | |
| location | No | ||
| budget_tokens | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already declare readOnlyHint=true, the description goes far beyond that: it details token-budget guarantees, fallback behavior for since tokens, handling of shadow DOM (open vs closed), same-origin vs cross-origin iframes, and the completeness block counting unread content. This is rich, candid behavioral disclosure that helps an agent predict side effects and limitations.
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 long but structured as a dense, information-rich paragraph with logical flow from output composition to specific parameter modes to edge-case behaviors. Every clause adds substantive detail about capabilities or limitations; it is not padded, though it could arguably be tightened without losing meaning.
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?
Given the tool's complexity, the absence of an output schema, and 0% schema parameter descriptions, the description is exceptionally complete. It covers what is returned, how tokens are managed, what happens with shadow DOM and iframes, how to perform cheap repeat reads, and what the completeness block reports. An agent has enough information to call this tool correctly in most scenarios.
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?
With 0% schema description coverage, the description is the only source for parameter meaning. It explicitly explains 'location', 'budget_tokens', 'mode', and 'since' with usage context, and 'page' is self-evident. However, it leaves 'view' and 'detail' completely unexplained, which is a gap for a tool with 7 parameters, though the core behavioral parameters are well covered.
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 opens with a clear, specific verb ('Read') and resource ('a page') and immediately distinguishes it from a transcript by calling it an 'ORIENTATION'. It also enumerates the specific output components (identity, landmark regions, interactive surface, etc.), making the tool's function unambiguous and distinct from siblings like get_text.
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 description provides strong context for when to use the tool: it positions it as an orientation with a token budget, and gives concrete parameter guidance (e.g., 'budget_tokens=2500 suits a subagent', 'mode='links' includes in-prose links', 'since=<read_token> is the cheap repeat read'). However, it does not explicitly name alternative sibling tools or state when not to use it, leaving the comparative routing implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_textARead-only
Extract readable prose from a page or one region of it, paginated by
start_index so a long article is read in bounded pieces rather than
one unbounded dump. Text arrives as labeled data with its origin stated,
and hidden regions are stripped and counted rather than silently dropped
or silently included. Hidden content IS retrievable, deliberately:
include_hidden=true returns it in a separately labeled section with the
hiding technique named per block. There is no silent middle tier,
because display:none is a real injection channel; the labeled route is
the whole design. Prose inside open shadow roots is read, the same as
get_page_view reads it; closed roots are counted and stay unreadable.
Prose inside same-origin iframes is read after the main document, each
frame under a header naming it and its origin, because one page can
now deliver text from several documents and a single origin in the
label would be a claim about only one of them.
| Name | Required | Description | Default |
|---|---|---|---|
| page | Yes | ||
| location | No | ||
| max_chars | No | ||
| start_index | No | ||
| include_hidden | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses far more than the readOnlyHint annotation: it details pagination, hidden-content handling (stripped/counted vs. included via include_hidden), labeling with origin, shadow-root behavior (open read, closed counted), and iframe handling with per-frame headers. It explains design rationale (display:none as injection channel), making the tool's behavior fully predictable. No contradiction with annotations.
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 dense paragraph, but every sentence adds value: it front-loads the core purpose, then expands on hidden content, shadow roots, and iframes. It is longer than typical, but the complexity of the tool justifies the length. No filler or repetition, so it is efficient despite its size.
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 5 parameters, no output schema, and only readOnlyHint annotation, the description covers all critical behavior: pagination, hidden content, shadow roots, iframes, and origin labeling. It explains the output format conceptually ('labeled data with origin stated'), which is sufficient for an agent to know what to expect. Nothing essential is missing for safe and correct invocation.
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 entire burden. It explains start_index (paginated), include_hidden (explicitly described), and location ('one region of it'). It implies max_chars via 'bounded pieces' but does not name it, and page is obvious from context. It adds substantial meaning to most parameters, though max_chars and page are not explicitly described—still a strong compensation.
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 states a specific verb ('Extract'), a clear resource ('readable prose from a page or one region of it'), and distinguishes itself by mentioning pagination and the origin-labeling of text. It differentiates from sibling get_page_view by specifying that it extracts prose and handles shadow roots/iframes in a defined manner, so an agent knows exactly what this tool is for.
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 description gives clear context: it extracts readable prose, is paginated, and handles hidden content deliberately. It explicitly references get_page_view when comparing shadow-root behavior, implying when to use which, but does not state explicit exclusion criteria (e.g., 'use get_page_view for visual layout instead'). Still, it gives enough situational guidance for a competent agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_workflowsCRead-only
Get recipes for this server: the cheap-read-then-act pattern, the auth workflow (headed handoff plus saved state), reading strategy, budgeting, troubleshooting a page that will not read, the subagent budget setting, lanes, what each capability pack contains with the exact launch flag that loads it, what a site profile is and where it lives, and how to record and replay a multi-step flow. Packs are chosen at launch rather than at runtime, so this is where you learn which flag you need before restarting. Tool availability reflects the packs this server was started with.
| Name | Required | Description | Default |
|---|---|---|---|
| topic | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation readOnlyHint: true already indicates the tool is read-only, and the description does not contradict this. However, no additional behavioral details are provided beyond the annotation.
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 overly long and repetitive, with redundant phrases like 'Packs are chosen at launch rather than at runtime' and 'Tool availability reflects the packs this server was started with.' It lacks clear structure and concise wording.
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?
The description provides no information about the output format, expected results, or how to interpret the returned data. It also leaves the parameter semantics unexplained, making it incomplete for a user to effectively use the 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?
The single parameter 'topic' is not described in the schema, and the tool description does not explain what values it accepts or how it affects the output. The listed topics do not map to the 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?
The description states the verb 'Get' and the resource 'recipes', but the meaning of 'recipes' is vague and the long list of topics confuses rather than clarifies the tool's exact function. It does not clearly distinguish this tool from siblings.
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 explicit guidance on when to use this tool versus alternatives. The description implies it provides information about various topics, but does not state conditions or use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_sessionA
One session is one browser. open starts one on a chosen lane (the
first navigate of a conversation can open one for you, and says so when
it does); close ends the browser; with auth state saved, the login
survives; the session never does. status reads liveness first, so a
dead browser says so, then lists every session this server holds with its
pages, budgets, and what is shared: sessions belong to the server
process, not to a conversation. capabilities, budget, and
reset_budgets report and manage limits. handoff hands the window to
the human for a login, an MFA prompt, or a bot wall. export_handle and
import_handle move a live session between conversations on this
machine: see get_workflows(task='session-transfer'). lanes is the
local lane database (status, export, import, erase). profiles reloads
site profiles from disk. On open, auth_state loads a saved login,
contexts=2 gives one session two independent cookie jars, and device,
viewport, locale, and timezone set what pages in this session
believe about their environment.
| Name | Required | Description | Default |
|---|---|---|---|
| op | No | ||
| lane | No | ||
| note | No | ||
| path | No | ||
| site | No | ||
| token | No | ||
| action | No | status | |
| device | No | ||
| locale | No | ||
| reason | No | ||
| context | No | ||
| session | No | ||
| contexts | No | ||
| timezone | No | ||
| viewport | No | ||
| auth_state | No | ||
| expires_minutes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate readOnlyHint=false, so the description must carry behavioral context. It does: it explains that sessions belong to the server process, that close ends the browser and the session never survives, that status reads liveness first, and that contexts=2 gives independent cookie jars. These details go beyond the annotation and help the agent predict 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?
The description is long (about 8 sentences) and dense, but it is structured as a logical flow from core concept to operation list to parameter effects. It front-loads the key idea and uses consistent formatting for operation names. It is not wasteful, but the sheer length could overwhelm an agent; still, given the tool's complexity, the detail is mostly necessary.
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 tool with 17 parameters, multiple operations, and no output schema, the description is fairly complete. It covers session lifecycle, sharing, liveness checks, and some parameter semantics. It references an alternative workflow. However, it omits explanations for many parameters and the op/action distinction, leaving gaps for an agent to fully understand all use cases.
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 compensate for all 17 parameters. It explains auth_state, contexts, device, viewport, locale, and timezone, but leaves many parameters (note, path, site, token, reason, context, session, expires_minutes, op, action) unexplained. Critically, it does not clarify whether 'op' or 'action' is the primary operation selector, which is a major ambiguity for correct invocation.
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 explicitly defines the tool as managing sessions, where one session equals one browser, and enumerates distinct operations (open, close, status, capabilities, budget, reset_budgets, handoff, export_handle, import_handle, lanes, profiles). It is specific and clearly distinguishes this tool from siblings by focusing on session lifecycle and configuration rather than page interactions.
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?
It provides context on when operations are automatic ('the first navigate of a conversation can open one for you') and explicitly references an alternative for session transfer ('see get_workflows(task='session-transfer')'). It does not, however, give explicit guidance on when NOT to use this tool in favor of other siblings, but the scope is clearly session management.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_tabsA
List, open, select, or close tabs, report which is focused, and
capture pages a click opened in a popup. Mints and returns the explicit
page handles every other tool accepts, which is how browser state
survives across calls without relying on protocol sessions. Closing a
page invalidates its refs and its delta read tokens, and the result says
so rather than leaving a later failure to explain it. On a session with
more than one cookie jar, context says which jar a new tab opens in
and every listed page says which jar it belongs to.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | ||
| page | No | ||
| action | No | list | |
| context | No | ||
| session | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=false, it discloses side effects: it mints page handles, invalidates them on close, and reports invalidation instead of failing later; also notes cookie-jar association.
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?
Four dense sentences, each conveys one essential behavioral fact; no redundant filler.
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 no output schema, it still describes what is returned (page handles, focused tab, cookie-jar labels, invalidation notices), enough to call and interpret results.
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?
Though the schema has no per-parameter descriptions, the prose maps action to verbs, page to handles, context to cookie jar, and session to browser state; url is implied for open but not named.
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 the concrete actions (list, open, select, close) and the resource (tabs/pages), and explicitly positions tab management as distinct from navigation/session tools.
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?
It explains when the tool is needed—any time another tool needs a page handle—and clarifies multi-cookie-jar context selection, but it does not explicitly contrast with sibling tools like navigate or manage_session.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
monitorA
Watches one URL for one deterministic change while this server runs. Four conditions: content_hash, text_appears, text_gone, selector_count; the same page state always answers the same way. Nothing is pushed anywhere: report is how you ask what happened, and check_now forces a check. A monitor that could not check reports stale with the failure, never unchanged. Checks run in a dedicated headless session, never the caller's. There is a floor on the interval and caps on monitors and daily checks; a 429 is honored rather than retried; a monitor that keeps failing pauses itself.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | ||
| label | No | ||
| since | No | ||
| value | No | ||
| action | No | report | |
| monitor | No | ||
| selector | No | ||
| condition | No | ||
| check_interval_minutes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is unusually rich: it discloses deterministic state, no push behavior, dedicated headless session, rate limits (floor/caps/429), and pause-on-failure. These details go well beyond the minimal readOnlyHint annotation and set accurate expectations.
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 compact and front-loaded with the core purpose, but some phrasing is cryptic (e.g., 'reports stale with the failure, never unchanged') and information is packed into run-on semicolon clauses. It could be clearer without adding length.
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?
It provides helpful operational context (session isolation, rate limits, failure behavior) but no return format or output schema, and no guidance on how fields like since/value/label are used. Given the 9-parameter schema and no output schema, this is not fully complete.
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?
It maps several schema fields indirectly: condition types, selector_count, action values, interval floor, and URL. However, parameters like since, value, and label are not explained, leaving important semantics ambiguous.
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 opening sentence clearly states the tool watches one URL for a deterministic change while the server runs, and the four condition types are enumerated. It does not explicitly describe the full lifecycle of creating/managing monitors, which slightly reduces clarity.
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?
It gives some action guidance: 'report is how you ask what happened, and check_now forces a check,' and states nothing is pushed. It does not compare this tool to sibling alternatives like wait_for or get_page_view, so when to choose it over those is mostly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scrollA
Scroll by an amount, to a named element, to the end, or inside a specific container, plus a next-chunk mode that remembers position across calls so a long page is walked without re-reading it. Reports how much content is now reachable and how much remains below, and names virtualized containers where the DOM holds far fewer rows than the page claims, rather than presenting a partial list as complete.
| Name | Required | Description | Default |
|---|---|---|---|
| page | Yes | ||
| action | No | by | |
| amount | No | ||
| location | No | ||
| timeout_ms | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnlyHint annotation by disclosing stateful behavior (remembers position across calls), output reporting (reachable/remaining content), and virtualized container handling. This transparency helps agents anticipate side effects and results.
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 two dense sentences that efficiently enumerate modes, statefulness, and output characteristics without redundancy. It is front-loaded with the primary action and maintains a clear 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?
The description covers major behaviors and output, but omits parameter-level details and edge cases. Given the complexity of multiple scroll modes and stateful behavior, it is mostly complete but could benefit from explicit parameter mappings and examples.
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?
The schema has 0% parameter description coverage, and the description only vaguely hints at action, amount, and location. It does not define the page, timeout_ms, or the structure of the location object, failing to compensate for the missing schema details.
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 explicitly states the tool scrolls by amount, to an element, to the end, or within a container, and introduces a next-chunk mode. It clearly identifies the action and its variants, leaving no ambiguity about the tool's purpose.
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 description implies when to use the next-chunk mode for long pages, but it does not explicitly contrast with sibling tools like navigate or find_elements. It offers clear context for usage but lacks explicit alternatives or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wait_forA
Wait for text to appear or disappear, an element to reach a state, a
URL to match, or a JS predicate to hold. EVERY condition is checked
against the current state first and returns immediately when it already
holds, so a wait issued after the thing already happened costs nothing
instead of timing out (the field's URL wait expired on a navigation
that had finished before the call). A url value without wildcards
matches as a substring; use * and ? for globbing. Real timeouts, and a
failure that says what was awaited and what was observed instead.
| Name | Required | Description | Default |
|---|---|---|---|
| page | Yes | ||
| value | No | ||
| location | No | ||
| condition | Yes | ||
| timeout_ms | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses key runtime behaviors: immediate success on already-satisfied conditions, wildcard handling for URLs, real timeout behavior, and failure message content. This goes well beyond the minimal readOnlyHint annotation and sets accurate expectations.
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 dense and includes useful information, but the parenthetical aside about URL wait expiration is awkward and reduces clarity. It is a single unstructured paragraph rather than a clean purpose-plus-behavior format.
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?
Given the input schema has five parameters and no property descriptions, the description is not sufficient to fully understand expected values or return behavior. Allowed condition values, the shape of `location`, and how `page` is used are left unspecified.
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 property descriptions are absent, and the description only partially clarifies parameters. It mentions URL wildcard behavior for `value` and implies `timeout_ms`, but `page`, `location`, and `condition` semantics are not explicitly defined, leaving significant ambiguity.
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 clearly states the tool's purpose: waiting for text, element states, URL matches, or JS predicates. It distinguishes wait_for from siblings like navigate and find_elements by focusing on conditional waiting.
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 description explains when to use the tool and important behavioral nuances, such as immediate return if the condition already holds and URL substring/glob matching. It does not explicitly contrast with alternatives, but the purpose is clear enough to guide selection.
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.
11 tool updates
v1.0.0- First observed
find_elements - First observed
get_audit - First observed
get_page_view - First observed
get_text - First observed
get_workflows - First observed
manage_session - First observed
manage_tabs - First observed
monitor - First observed
navigate - First observed
scroll - First observed
wait_for
TDQS
Scored across 11 tools
Each tool has a clearly distinct role: navigation, waiting, reading (overview/prose/search), tab/session management, audit, workflows, and monitoring. The closest pairs like get_page_view/find_elements/get_text or wait_for/monitor are explicitly differentiated by purpose and scope.
All names are lowercase snake_case and begin with an imperative verb, giving a predictable style. There are minor pattern deviations: wait_for uses a verb+preposition form, and navigate, scroll, and monitor are bare verbs rather than the verb_noun form used by get_page_view, find_elements, and manage_tabs.
Eleven tools is a well-scoped size for a browser-oriented server, and each tool covers a distinct area such as navigation, reading, search, waiting, tabs, sessions, auditing, workflows, and monitoring. Nothing feels redundant or gratuitous.
The read/navigate/monitor side is thorough, but the set has a significant dead end: get_page_view and find_elements return 'refs you can act on' and manage_tabs describes pages opened by a click, yet no tool exists to click, type, submit, or execute JS. Agents cannot perform real web interactions, which is a central expected capability for a 'KitchenSink4Web' server.
Maintenance
Related MCP Connectors
Reliable web access for AI agents: smart HTTP, rotating proxies, and full-browser rendering.
E2LLM gives your AI eyes and hands in a real browser: structured perception (SiFR) plus action.
Web search, browser automation, scraping, crawling and CAPTCHA solving for AI agents.
Live web access for agents: scrape, SERP search, crawl/map, 74 collectors, datasets, proxies.
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables LLMs to interact with web pages, take screenshots, and execute JavaScript in a real browser environment10246299MIT
- AlicenseAqualityBmaintenanceEnables AI agents to control a browser with 30 tools for navigation, interaction, extraction, and tab management, supporting human-like browser automation.367MIT
- FlicenseAqualityBmaintenanceEnables LLM agents to browse and interact with web pages using a stealth Chromium browser, with an accessibility-tree interface for low token usage.12-
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to fetch and extract clean, readable content from web pages, and search within pages for specific queries, without needing a full browser.1MIT