Skip to main content
Glama
GiantRavens

mdb-mcp

by GiantRavens

mdbrowse

Compile and browse the web in markdown.

mdb is a web → markdown compiler with a terminal browser on top to make it possible to browse the full web from a terminal window.

Humans get a non-noisy way to browse the web in simple markdown, llms get a token-efficient way to browse the web.

How it Works

When you launch mdb in a terminal, mdb launches an actual Chromium/Chrome browser behind your terminal window. The page loads with all the niceties of a full browser, from JavaScript loading, cookies and more - something W3M could never give you. From that browser window mdb extracts the structure and essence of that page (geometry, landmarks, computed styles — never re-parsed HTML strings). The full DOM and page interaction stay inside the browser; but humans get a zen-like no-fluff browsing experience, and agents get a highly token-efficient view of the web. The compiler classifies each page's shape and emits clean, hierarchically correct markdown that can be snapshotted to archive webpages as clean markdown.

mdb includes an archive store, change-watching sensors, an MCP server for agents, speech output ideal for sight-challenged users.

  • Full browser feature-set mdb reads your Safari cookies by default so your logged-in and paywalled-to-you pages render as you'd see them. Or use the --private flag to go without.

  • No fluff Light DOM re-ordering ensures articles come out as clean prose that drops most ads and pushes all that menubar and sidebard junk down - and works well with feeds (HN, news sites) presenting one linked line per story

  • Site-smart. Write site-handling rules as you like - by default thin-mobile sites (Wikipedia, Stack Overflow, Reddit) are captured with a desktop UA; Reddit uses its .json endpoint for a browser-free structured read (old.reddit HTML when unauthenticated); Cloudflare "Just a moment…" challenges are waited out before capture. Per-host rules live in policy.py (+ ~/.mdb/policy.json).

  • Deterministic and diffable. Front-matter carries provenance (source, retrieved, mode, shape+confidence, extractor version) and a body content-hash. Same page state → identical body. Pages become versionable.

  • Reader's-choice ad policy. Tracker hosts are blocked at the network; first-party ad furniture (reddit promoted posts, AdSense slots) is dropped by per-host policy rules (policy.py) — each rule carries its why, removal is counted in front-matter (policy_killed), user rules merge from ~/.mdb/policy.json, and MDBROWSE_NO_POLICY=1 turns the layer off.

Simple, Zen browsing from a terminal console

Terminal browsers have always been the calm way to read the web, but have been quietly broken for twenty years: lynx and w3m parse HTML, meanwhile most sites are unreadable without a full JavaScript engine.

mdbrowse is a spiritual successor to those tools in a full browser processor, then delivers the text as md format in the terminal. mdbrowse by default uses keyboard-first vim motions, tabs to hop to focusable links, even forms work such as Wikipedia or DuckDuckGo.

Related MCP server: agentfetch

Built for agents; with a toolbox for analysts

Since LLMs charge per token, reading full HTML is highly inefficient - raw HTML costs about 9× mdb's tokens per fact, and most "clean" extractors pay for their cleanliness by dropping the links or flattening the structure.

In the benchmark suite of tools mdb is the only extractor with 100% fact recall AND navigable links AND surviving structure — the suite table below has the details. The MCP server (mdb-mcp) hands that surface to any agent: fetch with provenance, web search, link filtering, pagination slices served from the capture cache.

The same properties make it an exellent open-source intel tool:

  • Capture the web as citable 'point in time' snapshots: Same page state → identical bytes, with front-matter provenance (source URL, retrieval time, auth mode, shape + confidence, extractor version) and a body content-hash. Captures are diffable, versionable, quotable evidence.

  • Watch pages for change over time: mdb watch keeps versioned snapshots and fires only on real change — classified readings (ok / changed+diff / error+why), never a bare "page fetched".

  • Build your searchable web content memory Everything captured lands in a full-text-searchable archive (mdb search, archive_search) that works offline.

  • Read failure feedback: Sites that throw up bot-walls and paywalls come back classified as walls with the reason - you can simply key 'O' no a page to open the URL in your rich browser - likely the cookies you save will let mdb through the next time.

Install

brew install giantravens/tap/mdbrowse     # installs mdb and mdb-mcp

mdb drives your installed Google Chrome when present. Without Chrome, give Playwright its own engine once: playwright install chromium.

From source instead:

git clone https://github.com/GiantRavens/mdbrowse
cd mdbrowse
./mdb --version         # first run builds .venv (via uv) and installs Chromium

The project .venv is host-local. Not mandatory either: any Python 3.11+ environment works if you install mdb into it and give that same environment a Chromium.

Optional authenticated backends

mdb always tries its native browser/compiler first. On a covered X or Reddit URL that classifies as a login wall or application shell, the terminal reader offers an E action to confirm a read-only retry through an installed authenticated backend. Nothing is installed or invoked silently.

mdb setup backends                         # detect tools + show installation/security notes
mdb <x-status-url> --backend opencli       # explicitly use logged-in Chrome
mdb <x-status-url> --backend twitter-cli   # explicitly use X's structured API adapter
mdb <url> --allow-external-fallback        # native first; retry only after wall/app classification

OpenCLI and twitter-cli are separate, optional upstream projects. OpenCLI requires its Chrome Browser Bridge extension and local daemon; twitter-cli extracts X cookies and calls unofficial private APIs. See Authenticated and gated sites before enabling either.

Getting Started

This section assumes you are comfortable copying commands into Terminal, but not necessarily comfortable debugging Python, virtual environments, or browser automation.

What you are installing

mdb is a command-line app. You run it from Terminal, and it opens web pages through a real browser engine in the background. It then shows the page as clean, keyboard-friendly markdown in your terminal.

Three pieces are involved:

  • The mdbrowse project folder: the source code you are in now.

  • A local Python environment: .venv/ inside this folder. It keeps mdb's Python packages separate from the rest of your computer.

  • A Playwright Chromium browser: the browser engine mdb uses for page capture. This is separate from Safari, Chrome, and Firefox.

One-time setup

Open Terminal and go to the project folder. If you keep this repository somewhere else, use that folder instead:

cd ~/Documents/mdbrowse

Run mdb once. The first run creates the local Python environment, installs mdb into it, and installs the browser engine mdb needs:

./mdb --version

You will see first-run setup messages like:

mdb: first-run setup
  project: /Users/you/.../mdbrowse
  venv:    /Users/you/.../mdbrowse/.venv
  phases:  create venv -> install mdb -> install Chromium

If that finishes by printing a version number, setup worked. Later runs reuse the same .venv and start normally.

If you prefer to do the same setup by hand:

uv venv
uv pip install -e .
.venv/bin/playwright install chromium

Set MDBROWSE_NO_BOOTSTRAP=1 if you want ./mdb to fail instead of building the .venv automatically.

Using your own Python environment

You do not have to use the project .venv. If you already manage Python environments with another tool, use Python 3.11 or newer, activate your environment, then install mdb and its browser there:

cd ~/Desktop/notebook/code/mdbrowse
uv pip install -e .
python -m playwright install chromium
mdb --version

The important rule is that mdb, the Python packages, and Playwright's Chromium install must belong to the same active environment. If you use your own environment, run mdb ... instead of ./mdb ...; the repo-root ./mdb launcher is designed around this checkout's .venv.

Your first page

Start with a small, reliable page:

./mdb https://example.com --plain --no-pager

You should see a short markdown page. This proves the Python environment, browser engine, network, and compiler are all working.

Now try the interactive reader:

./mdb https://news.ycombinator.com

Useful first keys:

  • j and k move down and up.

  • Tab moves to the next link or image.

  • Enter opens the focused link.

  • H goes back.

  • Space previews the focused image, or scrolls when no image is focused. Press Space again to close that preview.

  • ? opens help.

  • q quits.

Mouse wheel scrolling and clicking links also work in most terminals.

Running mdb from anywhere

The safest command is always ./mdb from inside the project folder.

If your shell has ~/bin on PATH, this repository can also be exposed as mdb from any folder:

mkdir -p ~/bin
ln -sf ~/Desktop/notebook/code/mdbrowse/mdb ~/bin/mdb

Open a new Terminal window and test:

mdb --version

If mdb says "command not found", use ./mdb from the project folder until your shell PATH includes ~/bin.

Common things to do

Read a page interactively:

./mdb https://www.wikipedia.org

Print a page without opening the reader:

./mdb https://example.com --plain

Search the web:

./mdb search "most useful open source intel tools"

Save a page as Markdown in Safari's download folder:

./mdb https://example.com --save
./mdb https://example.com --save-to research/example.md

Add a page to mdb's searchable machine archive:

./mdb https://example.com --archive

Watch a page for future changes:

./mdb watch add https://example.com --name example
./mdb watch scan

Download a linked file:

./mdb get https://example.com/file.pdf

Where files go

The project folder contains code. Generated user data goes somewhere more appropriate for your operating system.

Explicitly saved pages and downloaded links go to Safari's configured download folder on macOS (normally ~/Downloads). In the reader, s prompts for the page filename and d prompts for the download directory; press Return to accept the displayed default.

The searchable agent archive and watch history remain application data:

  • macOS: ~/Library/Application Support/mdbrowse/archive and ~/Library/Application Support/mdbrowse/watch

  • Linux/BSD: ${XDG_DATA_HOME:-~/.local/share}/mdbrowse/archive and ${XDG_DATA_HOME:-~/.local/share}/mdbrowse/watch

  • Windows: %LOCALAPPDATA%\mdbrowse\archive and %LOCALAPPDATA%\mdbrowse\watch

MDBROWSE_DOWNLOADS overrides the default folder for both saved pages and downloaded links. --save-to FILE and mdb get --out DIR provide per-command destinations.

Old folders named ~/mdbrowse-archive or ~/mdbrowse-watch are from older defaults. They are safe to move into the new app-data folders, or you can keep using them by setting MDBROWSE_ARCHIVE and MDBROWSE_WATCH_DIR.

Privacy basics

By default, mdb reads Safari cookies on macOS so pages look like they do when you are signed in. That is useful for sites you already have access to, but it also means mdb is browsing as you.

Homebrew installs bash and zsh completions automatically. For a manual installation, generate the completion script from the executable:

mdb completion bash
mdb completion zsh

Use private mode when you do not want Safari cookies sent:

./mdb https://example.com --private

Saved pages and archives are plain Markdown files on your computer. Do not save private pages unless you are comfortable storing their text locally.

If something goes wrong

If uv is missing, install it first. On macOS with Homebrew:

brew install uv

If first-run setup fails, run the setup steps manually from the project folder so you can see exactly which phase failed:

uv venv
uv pip install -e .

If mdb says the browser is missing:

.venv/bin/playwright install chromium

If you are using your own Python environment instead of .venv, run:

python -m playwright install chromium

If a site blocks the background browser, try a visible browser window:

./mdb https://example.com --headed

If a page is acting strangely because of login state, compare normal and private mode:

./mdb https://example.com
./mdb https://example.com --private

If you only want to check whether the installed copy still works:

./mdb --selftest

Use

mdb                                  # Safari start page (bookmarks, reading list)
mdb news.ycombinator.com             # interactive reader (default in a terminal)
mdb <url> --plain                    # non-interactive render (centered; --no-center)
mdb <url> --raw                      # markdown document with front-matter
mdb <url> --save                     # Markdown in Safari's download folder
mdb <url> --save-to research/a.md    # Markdown at an explicit path
mdb <url> --archive                  # searchable mdb application-data archive
mdb <url> --headed                   # visible real-Chrome window; verification walls (wall shape) trust it
mdb <url> --fallback-headed          # retry headed only after an explicit access-denied wall
mdb <url> --backend opencli          # explicit authenticated Chrome backend (optional install)
mdb <url> --backend twitter-cli      # explicit structured X backend (optional install)
mdb <url> --allow-external-fallback  # native first; authenticated retry only after wall/app
mdb setup backends                   # backend status, installation, and security notes
mdb <url> --speak                    # the page talks (macOS say; --voice, MDBROWSE_VOICE)
mdb <url> --speak-out article.aiff   # page as an audio file
mdb search rust atomics              # web search (DuckDuckGo; MDBROWSE_SEARCH_ENGINE/URL overrides)
mdb feed https://xkcd.com/atom.xml   # RSS/Atom as a feed page
mdb get <file-url>                   # authenticated download (~/Downloads)
mdb oracle <url>                     # judge markdown fidelity against a screenshot
mdb <url> --dump bundle|manifest|body  # inspect any compiler stage
mdb --selftest                       # re-emit the fixture corpus, diff vs goldens

Search defaults to DuckDuckGo now that mdb runs a full Playwright browser. Choose another built-in engine with MDBROWSE_SEARCH_ENGINE=mojeek or MDBROWSE_SEARCH_ENGINE=ddg-html, or provide a custom template with MDBROWSE_SEARCH_URL='https://example.com/search?q={q}'.

Data locations

Human-directed page saves and downloads use Safari's configured Downloads folder (or MDBROWSE_DOWNLOADS). The searchable MCP archive and watch stores default to per-user application data:

  • macOS: ~/Library/Application Support/mdbrowse/{archive,watch}

  • Linux/BSD: ${XDG_DATA_HOME:-~/.local/share}/mdbrowse/{archive,watch}

  • Windows: %LOCALAPPDATA%\mdbrowse\{archive,watch}

MDBROWSE_HOME relocates both stores. MDBROWSE_ARCHIVE and MDBROWSE_WATCH_DIR override the archive or watch store individually. Older ~/mdbrowse-archive and ~/mdbrowse-watch folders are not moved automatically; move them into the new paths or set the env vars above if you want to keep using them in place.

Watch sensors — versioned pages that fire on real change

mdb watch add https://example.com/pricing --name pricing
mdb watch scan          # check all; commits changes to a git store
mdb watch diff pricing  # last change as a patch
mdb watch digest        # Claude narrates the week's changes (briefing material)

Store: the app-data watch directory (git; git log -p <name>.md is the page's history). The trigger hashes visible text only — rotating URL tokens never false-fire.

The reader

Vim-style, with a single focus ring over links, images, and forms (browser-like Tab). Two verbs: Enter = go, Space = peek (preview or close the focused image; page-down otherwise). Every keystroke's effect is predictable from what is visibly highlighted.

Search forms are visible affordances, but they do not auto-focus on page load. Press f for the prompt-driven search flow, or Tab into the field when you want typed characters to go there.

keys

Tab / S-Tab

next / previous focusable — full-extent highlight, even wrapped

Enter / o · Space

go · peek

y · u / Y · d

yank focused URL · copy current URL · download focused target

( ) · { }

heading / block motions

j k C-d C-u C-f C-b gg G zt zz zb

scrolling and placement

/ n N

search

H / L · r

history back / forward · reload

f

fill the page's search form (GET), submit as navigation

F

open the page's advertised RSS feed

. / ,

next / previous detected page

S / a

summarize / ask this page (Claude); answers are pages, H returns

v

speak from the focused element (v again stops; --announce speaks on focus)

s · B · O

Save As Markdown · add to Safari Reading List · open in browser (MDBROWSE_BROWSER)

:

URL, s terms, ddg terms, mojeek terms, safari:start, feed:URL

? · q

help overlay · quit

Mouse: wheel scrolls, click follows, click 🖼 previews. (tmux: set -g mouse on.)

Agents and speed

  • MCP server (mdb-mcp, registered as mdbrowse): fetch_page (markdown + provenance; long pages paginate via start_char, the continuation served from the capture cache), search_web (results as linked lines), page_links (with a pattern regex filter), archive_page (returns the body hash — compare to detect change), archive_search (full text over the archive: a personal web memory), and the watch fleet — watch_add / watch_list / watch_scan (structured readings: ok / changed+diff / error+why) / watch_diff / watch_remove.

  • Agent probe suite (tests/agent_probes.py): live regression guards for the actions agents actually perform — docs code fidelity, pipe tables, search, feed digests, link filtering, pagination stitching, hash determinism, fast classified failure.

  • Engine daemon: warm Chromium behind ~/.mdb/engine.sock, auto-spawned on first CLI capture, idle-exit after 30 min. Warm fetches run ~0.7–1.0s. mdb daemon start|stop|status|run; MDBROWSE_DAEMON=off disables.

  • Browser execution, token-shaped output: agents are not scraping a TUI transcript. They ride the same real browser capture as the reader, but only the classified markdown page, links, forms, provenance, and requested slices cross the MCP boundary.

How it works

  1. Capture — Chromium/Chrome via Playwright, Safari cookies unless --private, stealth shim, tracker/image/media blocking, autoplay suppression, content-stability settle, 3s DNS preflight (black-holed names fail fast with the why). walker.js runs inside the page and emits leaf blocks with landmark, kind, inline-markdown, links, and geometry, plus document-level feed and pagination affordances. page.content() is never taken.

  2. Classify — a cheap shape manifest (article | feed | page | app with confidence) from bundle signals, before any emission.

  3. Emit — per-shape assembly: repeated-unit detection collapses card fragments to one line per item (shared link target + signature periodicity); headings remap to a strict hierarchy; nav/aside/footer demote to link lists; forms stay out of documents (they're affordances — the reader's f uses them from the bundle).

Every stage is inspectable (--dump), every change is measured, across five suite tiers:

tier

guards

run

fixture corpus (10)

emit truths, offline, deterministic

mdb --selftest

live probes

network truths (hostile CDNs, DNS)

tests/live_probes.py

agent probes

task truths (the MCP verbs agents ride)

tests/agent_probes.py

checkin gate

fixtures + 11-site live sweep, every commit

tests/checkin.py (pre-commit hook: --install-hook)

fidelity oracle

pixel truths — screenshots as judge, never extractor

mdb oracle URL

benchmark

mdb vs other agent web tools: tokens, recall, links, structure, speed, determinism

tests/benchmark.py

The benchmark compares seven approaches (mdb, raw HTML, tag-strip, Chromium innerText, trafilatura, pandoc, Jina reader) against ground-truth fact signals that no contender defines. Headline numbers (2026-07-05): mdb is the only contender with 100% recall AND navigable links AND surviving structure; raw HTML costs ~9× mdb's tokens per fact; the pandoc pipeline emits 2 tokens for all of HN.

History

v1 (a single-file mdbrowse.py: fetch → strip → convert → repair) was retired on 2026-07-04 after the v2 compiler exceeded it on every axis — see CHANGELOG.md and git history. Its best parts (settle heuristic, binarycookies parser, Safari integration, tracker lists) live on inside v2.

Available Tools

16 tools
archive_pageA

Fetch a page and save a timestamped markdown archive with provenance front-matter (to the mdbrowse app-data archive, or $MDBROWSE_ARCHIVE).

Returns {path, title, shape, hash}. The hash covers the body only, so re-archiving an unchanged page yields the same hash — compare hashes to detect real content changes without diffing.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
privateNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It discloses the return shape ({path, title, shape, hash}), explains hash covers body only, and describes the provenance front-matter. This meaningfully discloses behavioral traits beyond what a schema would show. It could mention whether it overwrites or creates new files, and the 'timestamped' wording implies immutable append-style behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight paragraphs, no filler. First paragraph states the action and target; second explains return value and hash semantics. Every sentence earns its place with concrete operational detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a write-style tool with 2 params and no annotations, this is reasonably complete: storage target, return shape, and hash semantics are all covered. The 'private' parameter remains a gap, and interaction with watch_diff/watch_scan siblings isn't addressed, but the core behavior is well-documented.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. The description explains url (page to fetch) indirectly, and 'private' is never mentioned. However, with only 2 params and one being self-evident (url), the coverage gap is modest. The description adds value about storage location and return semantics but leaves 'private' semantically unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Very specific: 'Fetch a page and save a timestamped markdown archive with provenance front-matter.' Verb+resource+output format are all clear. It distinguishes from siblings (archive_search, fetch_archived) by describing the archiving action and the storage target.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains that it saves to app-data archive or $MDBROWSE_ARCHIVE, giving context on where results land. It explains how to detect content changes via hash comparison, which functions as a when/WOW-to-use pattern for repeated archiving. However, it doesn't explicitly state when to prefer this over fetch_archived or fetch_page, nor exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

curate_to_corpusA

Capture a page and FILE it into document-forge — the 'read it, keep it' bridge. The clean markdown (with provenance front-matter: source URL, retrieval time, content hash) lands as a searchable document in the corpus, so a page you read today is recallable later from your own substrate.

corpus_root defaults to $MDBROWSE_CORPUS_ROOT or /mnt/herfjotur/work; the df CLI path is $MDBROWSE_DF or the notebook default. Use after fetch_page when a page is worth KEEPING, not just reading. For a linked file (PDF/dataset) use download_document instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
privateNo
corpus_rootNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It describes the output (markdown with provenance front-matter: source URL, retrieval time, content hash) and mentions default config paths ($MDBROWSE_CORPUS_ROOT, /mnt/herfjotur/work, $MDBROWSE_DF). However, it doesn't disclose whether this is a safe/read-only operation or what side effects occur beyond creating the document. It adds decent behavioral context but doesn't fully cover mutation semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with front-loaded purpose and inline config details, but it's slightly verbose for a single tool. The branding ('the read it, keep it bridge') and substrate metaphor add flavor but not functional value. The configuration block is useful but could be more compact. Roughly 100 words for a 3-param tool is acceptable but not lean.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has a clear output schema, which lightens the return-value burden. The description covers purpose, when-to-use, alternatives, defaults, and output format. For a 3-param tool with rich prose, this is reasonably complete. The main gap is the unexplained 'private' parameter and the absence of caveats about failure modes or prerequisites beyond fetch_page.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 explains corpus_root's default resolution behavior ($MDBROWSE_CORPUS_ROOT or /mnt/herfjotur/work) and the df CLI path ($MDBROWSE_DF), which adds real meaning. However, it doesn't explain the 'private' boolean parameter or how 'url' is used beyond 'capture a page.' The corpus_root and url are covered; private is not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action ('Capture a page and FILE it into document-forge') with a specific verb and resource. It distinguishes from siblings by noting 'For a linked file (PDF/dataset) use download_document instead' and explicitly references fetch_page as the prerequisite. It's clear but slightly verbose with the marketing-style framing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use: 'Use after fetch_page when a page is worth KEEPING, not just reading.' It also names the alternative (download_document) for linked files. This is exemplary guidance that directly aids tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

download_documentA

Download a linked file directly to disk — a PDF, spec sheet, dataset, image, archive, anything. Fetches through the user's session (Safari cookies + a browser UA + optional Referer ride along), so session-gated and hotlink-protected files come through, and names the file from Content-Disposition or the URL.

Use this when a page LINKS a document worth keeping rather than reading inline — e.g. a solution-brief PDF found via fetch_page/page_links. Pass referer as the page the link was on for hotlink-protected hosts. Saves to ~/Downloads by default (override with dest_dir, or the MDBROWSE_DOWNLOADS env var). Returns the saved path, size, and type. If a hostile WAF tarpits the direct fetch, open the page in the reader and press d (that path fetches through the live browser engine).

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
privateNo
refererNo
dest_dirNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full burden of behavioral disclosure. It thoroughly explains session cookie reuse, browser UA spoofing, optional referer riding, Content-Disposition naming, default save location, env var override, return values, and a fallback through the reader. This is exceptionally transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense yet every sentence earns its place by conveying concrete operational details—no filler or repetition. It front-loads the core action, then layers conditional/advanced guidance in a logical order.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (session auth, hotlink protection, file naming, save paths), the description covers nearly all operational needs: how/why to use, environment overrides, return values, and failure fallback. The only notable omission is the undocumented `private` parameter, which prevents a perfect score.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% for parameter descriptions, so the description must compensate. It effectively explains referer, dest_dir, and the MDBROWSE_DOWNLOADS env var override, but it does not clarify the `private` boolean and only indirectly implies `url` as the link target. This leaves a meaningful gap in a 4-parameter schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Download a linked file directly to disk,' listing PDFs, spec sheets, datasets, images, and archives. It clearly distinguishes itself from siblings like fetch_page (inline reading) and download_video (media-specific), making the tool's scope unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit use-case guidance is provided: 'Use this when a page LINKS a document worth keeping rather than reading inline,' with a concrete example and alternative (fetch_page/page_links). It also explains when to pass referer and what to do if a WAF tarpits the direct fetch, giving clear situational context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

download_videoA

Download a video (or just its audio) from a page or media URL via yt-dlp — which handles what a plain file download can't: direct mp4/webm, HLS/DASH manifests (.m3u8/.mpd), and YouTube/Vimeo/embedded players resolved from the page URL.

Muxes best video+audio to mp4, or extracts m4a with audio_only=true. Saves to ~/Downloads by default (override with dest_dir or MDBROWSE_DOWNLOADS). Returns the saved path. For gated video, set MDBROWSE_YTDLP_BROWSER (e.g. 'chrome'/'safari') to ride your browser cookies; it retries anonymously if the cookie backend fails. Use this for a /embed a user wants to keep; use download_document for a plain file (PDF, image, dataset).

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
dest_dirNo
audio_onlyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It discloses key behaviors: muxing video+audio to mp4, extracting m4a with audio_only, default save location (~/Downloads), browser-cookie riding for gated videos, and anonymous retry fallback. Missing some detail (e.g., what happens if muxing fails), but strong coverage for a tool with zero annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense paragraphs, zero wasted words. Front-loaded with the core purpose, then muxing behavior, then save/override options, then gated-content handling, and a closing sibling differentiation. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has real complexity (multiple input URL types, gated content, cookie handling, output format selection) and an output schema exists. The description covers all dimensions: what it downloads, output formats, save location, authentication/cookie handling, fallback behavior, and sibling differentiation. Complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so description must compensate. It explains the audio_only=true flag (extracts m4a) and dest_dir (override save location), and reveals the MDBROWSE_DOWNLOADS env var as an alternative override. The url parameter is well-implied as a page or media URL. Doesn't cover every parameter exhaustively but the key semantics are present.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource: downloads video (or audio) via yt-dlp. Clearly distinguishes from download_document (plain files) and explains what yt-dlp handles that a plain download can't (HLS/DASH, YouTube/Vimeo, embedded players). Strongly differentiates from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use this tool vs download_document — 'Use this for a <video>/embed a user wants to keep; use download_document for a plain file (PDF, image, dataset).' Also specifies environment variables (MDBROWSE_DOWNLOADS, MDBROWSE_YTDLP_BROWSER) and retry behavior for gated content.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_archivedA

Fetch a page from the Wayback Machine (archive.org) instead of live. Recovers pages the live fetch can't get — bot walls, IP-blocked sites, dead links, or content that changed. Returns the archived snapshot as clean markdown, tagged with its capture date. Reach for this when fetch_page returns a wall, or when you want the historical version of a page.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
max_charsNo
start_charNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so the description carries the full burden of behavioral disclosure. It discloses the key behavior: fetches from archive instead of live, returns clean markdown tagged with capture date. This gives the agent expectations about output format and provenance. Could go further on error behavior (e.g., when no snapshot exists), but the core behavioral profile is well covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences, front-loaded with purpose, then use cases, then output format. Zero fluff, every sentence earns its place. The second sentence explains both the 'why' and 'what you get,' and the third gives actionable routing guidance. Exemplary conciseness for a tool description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has a clear purpose, a strong routing recommendation against a named sibling, and clean output ('clean markdown, tagged with its capture date'). With an output schema present, return-value details don't need elaboration. Given the moderate complexity and strong supporting signals, the description is complete for an agent to select and use it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description mentions no parameters explicitly. However, only one parameter is required (url), and the prompt suggests max_chars/start_char relate to pagination within the markdown (defaults given). Since the description doesn't explicitly explain these params, it relies on the schema's defaults and naming. Behavior of max_chars/start_char is intuitive from names — with 0% coverage but 3 simple params, the description could add a bit more, but the schema defaults carry reasonable meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource: 'Fetch a page from the Wayback Machine (archive.org) instead of live.' Clearly states what it does and differentiates from the sibling 'fetch_page'. Explicitly mentions the output ('clean markdown, tagged with capture date') and problem cases, which distinguishes it well from related archive tools like 'archive_search' and 'archive_page'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance: 'Reach for this when fetch_page returns a wall, or when you want the historical version' with concrete scenarios (bot walls, IP-blocked sites, dead links, changed content). Names the specific sibling alternative (fetch_page) and the condition under which to prefer this tool. Strong guidance for agent selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_pageA

Fetch a web page as clean, deterministic markdown with provenance.

Renders the page in a headless browser (JS/SPA content included), classifies its shape (article / feed / page / app), and emits hierarchically clean markdown. The YAML front-matter carries title, source URL, retrieval timestamp, auth mode, shape verdict with confidence, and a content hash of the body — the same page state always produces the same body, so hashes and diffs are meaningful. Data tables come back as markdown pipe tables.

Browses with the user's Safari cookies by default (logged-in pages render as the user sees them); set private=true for an anonymous fetch. Use wait_selector (a CSS selector) only for SPAs that paint late. Feed/listing pages (HN, news fronts) come back as one linked line per story; article pages as clean prose with inline links.

Long pages paginate: on truncation the tail says which start_char fetches the next slice (served from the capture cache, no re-render).

Optional authenticated backends are never used silently. If native capture is gated on a covered URL, the result explains the available choices. Repeat with backend="opencli" or backend="twitter-cli", or set allow_external_fallback=true to permit the preferred installed backend.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
backendNonative
privateNo
max_charsNo
start_charNo
wait_selectorNo
allow_external_fallbackNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full disclosure burden and does it well: it details auth mode (Safari cookies default, private for anonymous), pagination behavior with start_char, deterministic hashing, and that backend selection is never silent. It even discloses truncation tail markers. Minor gap: no explicit statement of destructive/side-effect behavior (e.g., whether fetching stores data permanently), but overall disclosure is strong.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is five dense paragraphs covering substantial complexity (headless rendering, shape classification, determinism, auth, pagination, backend fallback). It front-loads the core purpose in the first sentence, then layers detail. A little tabular or bulleted structure for params and backend options would improve scannability, but given the complexity, the prose is appropriately economical.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a complex, 7-parameter tool with no annotations and 0% schema coverage, yet the description covers rendering semantics, determinism, auth modes, pagination, shape behavior, and backend selection. An output schema exists (documenting return values), so the description needn't explain them. The main residual gaps are the exact list of valid backend values and a systematic param-by-param mapping, but for the complexity level it's remarkably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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, and it does for several params: private (anonymous fetch vs Safari cookies), wait_selector (SPA late-paint handling), start_char (pagination slicing), backend and allow_external_fallback (backend selection). However, url, max_chars, and the specific syntax/format of backend values (native/opencli/twitter-cli) aren't documented in a systematic way. Coverage is good but not exhaustive given 7 params.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific, vivid purpose: 'Fetch a web page as clean, deterministic markdown with provenance.' It distinguishes itself from siblings by detailing headless-browser rendering, shape classification, YAML front-matter, and hash-based determinism. This clearly differentiates it from archive_search, fetch_archived, download_video, and page_links.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: private=true for anonymous fetches, wait_selector only for late-painting SPAs, and clear notes on feed vs article page shapes. It also explains backend fallback behavior when native capture is gated on a covered URL, directing users to backend='opencli'/'twitter-cli' or allow_external_fallback=true. This is strong alternative-and-condition guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

page_formsA

List the fillable forms on a page — each form's method, action, submit-button label, and fields (name, type, placeholder, label, select options), plus loose search boxes not wrapped in a . The OBSERVE step before submit_form: call this to learn the field names to fill.

Note: site search often needs no form at all — a GET form just puts the query in the URL, so fetch_page("site.com/search?q=...") (with the field's real name) is simpler when the method is GET.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
privateNo

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. The description does disclose the two main behaviors: what gets returned (form details + loose search boxes) and the GET-form simplification. However, it doesn't disclose edge cases like pages with no forms, JavaScript-rendered forms, or handling of malformed HTML, leaving some behavioral ambiguity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two paragraphs and is front-loaded with the core purpose. Every sentence earns its place — the first paragraph defines the tool and its role, the second gives a practical alternative. Slightly verbose in the field enumeration but no wasted sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only inspection tool with no output schema and no annotations, the description is fairly complete: it lists what fields are returned, its relationship to submit_form, and a pragmatic GET-form simplification. It could be more complete about the 'private' parameter, but overall it covers the key usage scenarios well.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 the two params (url, private). The description describes 'on a page' referencing the url parameter contextually, but it doesn't explicitly document what each parameter means or how 'private' alters behavior. For a 2-param tool, this is a modest gap rather than a severe one.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description has a specific verb+resource ('List the fillable forms on a page') and clearly enumerates exactly what's returned: method, action, submit-button label, fields (name, type, placeholder, label, select options), plus loose search boxes. It clearly distinguishes from sibling fetch_page and submit_form by stating this is the 'OBSERVE step before submit_form'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Excellent when-to-use guidance. It explicitly states this is the OBSERVE step to call before submit_form to learn field names. It also provides a clear when-NOT-to-use alternative: for GET forms, fetch_page with a query in the URL is simpler. This directly differentiates from sibling fetch_page and submit_form.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_webA

Search the web; results come back as markdown, one linked line per result. Uses the user's configured engine (DuckDuckGo by default; MDBROWSE_SEARCH_ENGINE or MDBROWSE_SEARCH_URL overrides — e.g. Kagi with the user's session, since searches ride Safari cookies like any page). Follow up with fetch_page on the results worth reading.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
privateNo
max_charsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals key operational details: that searches ride Safari cookies (so results may reflect authenticated sessions), that the engine is configurable via environment variables, and the output format. However, it doesn't disclose rate limiting, pagination behavior, or what happens on empty results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is tightly written and front-loaded with the core purpose. The engine/cookie detail is valuable behavioral context but adds length beyond the essentials. Every sentence earns its place, though the format and follow-up guidance could arguably be split for clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given low schema coverage (0%), an output schema exists, and no annotations, the description does substantial work but omits parameter semantics entirely. It covers purpose, output format, engine configuration, and workflow, which is solid for a read-only search tool. The missing parameter explanations for private and max_chars leave a notable gap, but the output schema presumably documents the return structure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate for all three parameters, but it only mentions the query indirectly. The description doesn't explain what 'private' or 'max_chars' do. The engine configuration context is useful but doesn't address parameter semantics. Since the description does not document any parameter meaning, this scores at baseline for a low-coverage case but not higher.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb-resource pair ('Search the web') with clear output format ('results come back as markdown, one linked line per result'). It distinguishes from siblings by explicitly naming fetch_page as the follow-up tool, which differentiates searching from fetching pages.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool ('search the web') and explicitly directs the agent to 'follow up with fetch_page on the results worth reading,' naming the alternative/next-step tool. It doesn't describe exclusions or when NOT to use it versus archive_search, but it identifies the natural workflow distinction between search and page retrieval.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

submit_formA

Fill a form on url and return the RESULT page as clean markdown (same pipeline as fetch_page). fields maps each field's name / label / placeholder to a value, e.g. {"q": "wireless headphones"} or {"From": "SFO", "To": "JFK"}. submit is a button's visible text; if omitted, Enter is pressed in the last filled field (the search-box convention). Rides the user's session, so site search, filters, and logged-in forms work.

Discover field names first with page_forms(url). This unlocks site search, faceted browsing, and any GET/POST/JS form. For a simple GET search, fetch_page with the query in the URL is lighter.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
fieldsYes
submitNo
privateNo
max_charsNo
wait_selectorNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full disclosure burden. It does well: states it returns the result page, rides the user's session (privacy-relevant behavior), and explains the submit fallback behavior. It doesn't address rate limits or destructive potential, but the tool is primarily a form-submission action with benign scope; the session and Enter-fallback disclosures add meaningful value beyond schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and richly informative, with concrete examples and front-loaded purpose. It's somewhat long but every sentence earns its place—covering pipeline, fields mapping, submit behavior, session, and usage guidance. The only mild inefficiency is the slightly repetitive closing paragraph about use cases.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 6 params with 0% schema coverage and no annotations, the description covers the core ones well and references the parent pipeline. An existing output schema lightens the return-format burden. It could add a bit more on private/max_chars and error conditions, but for a mid-complexity form tool it's largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain the parameters, which it does well. It explains 'fields' with concrete mapping examples (label→value), clarifies 'submit' semantics and its default fallback (Enter in last field), and for max_chars/wait_selector/private/url it implies meaning through the fetch_page pipeline reference. A tiny gap: private and max_chars are not individually described, but the framework reference partially compensates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fills forms on a URL and returns the result page as markdown. It explicitly names the resource (form on url), the verb (fill/submit), and distinguishes it from siblings like fetch_page (simple GET) and page_forms (discovery). The examples and the search-box convention make the purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use this tool over alternatives: 'Discover field names first with page_forms(url)', recommends fetch_page for simple GET searches ('lighter'), and enumerates the use cases it unlocks (site search, faceted browsing, GET/POST/JS forms). It also documents the session-riding behavior for logged-in forms.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

watch_addA

Start watching a URL for real content change. Takes the first snapshot now (git-committed to the watch store); later watch_scan calls fire only when visible text changes — link-token churn never false-fires. Name defaults to a slug of the URL.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
nameNo
privateNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose key behavioral traits: first snapshot is git-committed to the watch store, fires only when visible text changes, link-token churn never false-fires, and name defaults to a URL slug. However, it doesn't explain what the return value is, how to stop/remove a watch, or any limits on concurrent watches. Reasonable transparency but gaps remain for a tool with zero annotations and no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is economically written in a single concise paragraph, front-loads the core purpose, and every clause adds meaningful information. Minor inefficiency in slightly awkward phrasing ('let later watch_scan calls fire when...'), but no wasted words or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 3 parameters with 0% schema coverage and no annotations or output schema, so the description must compensate heavily. It explains the watch mechanism well and distinguishes from watch_scan, but leaves 'private' semantics unexplained, doesn't describe what the tool returns, and doesn't address how the watch integrates with watch_list/watch_diff/watch_remove. Adequate for basic use but incomplete for a tool that creates persistent state.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, meaning all 3 parameters (url, name, private) are undocumented in the schema itself and there are no parameter descriptions. The description mentions 'Name defaults to a slug of the URL' (clarifying the 'name' parameter's default behavior), which adds some value, but 'url' and especially 'private' are completely unexplained — the semantics of the private flag are entirely opaque.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('Start watching a URL for real content change'), explains the core action (takes snapshot now, fires later on visible text change only), and distinguishes from the sibling watch_scan tool by noting when scan fires. Clear and precise.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the mechanism (initial snapshot, subsequent fires on visible text change) which implies when this should be used (to monitor content change). However, it doesn't explicitly state when NOT to use it or name alternative tools, though watch_scan is implicitly contrasted. Decent implied guidance but no explicit exclusions or named alternatives for differing use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

watch_diffA

A watch's most recent change as a git patch (old lines -, new lines +). Use after watch_scan reports 'changed' to see exactly what moved.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds useful context: it's read-only (returning a patch, no mutation implied), and it's scoped to the 'most recent' change, which is a meaningful behavioral constraint. However, it doesn't disclose things like whether the patch is partial/full, whether there's a limit on patch size, or whether all diff formats are git-specific. Since there are no annotations, the description carries the transparency burden but delivers moderate detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero wasted words. It front-loads the core function (git patch of most recent change) and then gives a sequencing tip. Every clause adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given it has an output schema, return values don't need explanation. The description covers purpose, timing (after watch_scan), and content (patch format). For a single-parameter tool with output schema, this is near-complete. Minor gaps: doesn't explain the 'name' parameter explicitly, but the low parameter count and coherent description compensate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only one parameter (name) and 0% schema description coverage, the schema provides no semantics. The description implies the tool operates on a named watch but doesn't explicitly state that 'name' refers to the watch name/identifier. The context of 'a watch' plus the single 'name' parameter makes this reasonably inferable, but explicit confirmation would strengthen the parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns 'a watch's most recent change as a git patch' with line annotations. It uses specific verbs and resource ('watch' + diff/patch), and the reference to 'what moved' clarifies the diff nature. It distinguishes from siblings like watch_scan and watch_list by specifying it shows the patch content rather than status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage context: 'Use after watch_scan reports changed to see exactly what moved.' This clearly tells the agent when to invoke this tool in sequence. However, it doesn't state when NOT to use it or name explicit alternatives, though the sequencing guidance covers the primary use case well.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

watch_listA

List configured watches: name, url, mode, when last checked and last actually changed.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It's a read-only list operation implied by the phrasing 'List configured watches', which is clear. It discloses what fields are returned (name, url, mode, last checked, last changed), providing useful behavioral context about the output even without an output schema. Being a no-arg read is self-evidently safe.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, well-structured sentence that front-loads the action (List) and immediately enumerates the output fields. Zero waste, every word contributes meaning. Perfectly sized for a zero-argument tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only list tool with no output schema, this description is complete. It names the operation and enumerates all output fields. There's no complexity requiring more. The only minor gap is that it doesn't hint at sorting/ordering or whether results differ from watch_scan output, but this is adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and schema coverage is 100% (there is nothing to document). The description doesn't need to explain parameters since there are none. The baseline 4 for zero-parameter tools applies here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb+resource: 'List configured watches' with specific fields enumerated (name, url, mode, last checked, last changed). Distinguishes from siblings since watch_add, watch_remove, watch_scan, and watch_diff are all actions while this is a list operation, though it doesn't explicitly name any sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies it's for viewing configured watches, and the sibling set makes the listing-vs-mutation contrast implicit. However, it doesn't explicitly state when to use this vs alternatives, nor does it note that it's the read-only complement to watch_add/watch_remove. No exclusions or prerequisites given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

watch_removeB

Stop watching a page. Its snapshot history stays in the store's git log.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. It does disclose one meaningful behavior: that snapshot history remains in the git log after removal, which helps an agent understand this is not destructive to historical data. However, it doesn't disclose whether the operation is reversible (whether re-adding is needed), side effects on ongoing scans or diffs, or what happens to watch-list state. The partial disclosure earns a mid-range score but leaves gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very concise — two short sentences with zero filler. It's front-loaded with the primary purpose and adds one valuable behavioral detail. Appropriately sized for a simple 1-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter tool with no output schema and no annotations, this is on the lower end of adequate. The description covers the core action and one consequential behavior, but given the absence of all structured metadata, it should say more about the 'name' parameter format and the relationship to watch_add/watch_list to be fully complete for an agent deciding to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is only one parameter (name) with 0% schema description coverage, so the description must compensate. The description implies 'name' refers to the identifier of the page to stop watching, but it doesn't specify the naming convention (URL, title, slug, internal ID) used by sibling watch tools. Since schema coverage is 0%, a brief note on what 'name' refers to would be valuable; its absence keeps this at baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Stop watching a page') and the resource (a page being watched), making the core purpose evident. However, it doesn't differentiate from siblings like watch_add or watch_list, and the purpose of 'watching' itself is implied rather than explained. The description is clear enough to understand the action but lacks explicit scoping or distinction from closely related watch operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context (action on a page currently being watched, likely paired with watch_add), but provides no explicit when-to-use or when-not-to-use guidance, and doesn't name any alternative tools. Siblings like watch_list, watch_scan, and watch_diff exist, but the description offers no guidance on choosing among them. The stated behavior that snapshot history persists could be seen as a reassurance cue, weakly implying this tool is safe when history retention matters.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

watch_scanA

Re-fetch watches and report one reading each: status ok (no real change) / changed (snapshot committed; diff_sample shows what moved) / error (with the why). Empty names scans everything. Changes are detected on visible text only, so a 'changed' reading means a reader would agree the page changed.

ParametersJSON Schema
NameRequiredDescriptionDefault
namesNo

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does well. It discloses a critical behavioral trait: changes are detected on visible text only, meaning a 'changed' reading signifies a reader would agree the page changed. It also clarifies that 'snapshot committed' on changed and reports 'why' on error. This is meaningful behavioral context beyond what structured fields would provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact (two sentences) and front-loaded with the core action and the three status outcomes. Every sentence earns its place — the visible-text detection detail and empty-names behavior are both useful. Slightly dense with the parenthetical explanations but no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with no output schema, the description covers the action, the result statuses, the return-field example (diff_sample), the default behavior, and the critical scoping constraint (visible text only). This is fairly complete for the tool's simplicity. It could have noted the need for prior watch_add setup, but the sibling structures make that inferable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and there is only 1 parameter (names, an array with no item type specified). The description compensates somewhat by noting 'Empty names scans everything,' which clarifies the default/empty behavior of the names parameter. However, it doesn't explain what the array items should be (watch identifiers? names?), leaving ambiguity about how to populate the parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool re-fetches watches and reports one reading each (ok/changed/error), distinguishing its monitoring/scanning purpose from sibling tools like watch_list (lists watches) and watch_diff (shows diffs). It's specific about the verb and resource ('re-fetch watches') and the three possible outcomes. However, it doesn't explicitly distinguish it from watch_diff, which is a close sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states 'Empty names scans everything,' giving useful default behavior, and explains the semantics of each result status. However, it doesn't explicitly say when to use this vs watch_diff or watch_list, nor does it mention any prerequisites (e.g., must have watches added first via watch_add). Usage context is implied but not explicitly contrasted with alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A3.8/5.0
Disambiguation4/5

Most tools are clearly distinct (fetch/save/watch/search each own a clearly bounded behavior), but there is some deliberate overlap: fetch_page, fetch_archived, and archive_page/archive_search all touch page retrieval, and download_video vs download_document boundaries are implied rather than spelled out. The page_forms/submit_form pair and curate_to_corpus/archive_page both file captures, which could cause some misselection.

Naming Consistency4/5

Names follow a consistent verb_noun pattern (fetch_page, search_web, download_video, archive_page, watch_add, watch_scan). Minor deviations exist: curate_to_corpus uses a verb_object phrase instead of a clean verb_noun, and fetch_archived breaks the pattern that fetch_page/fetch_work might suggest. Overwhelmingly regular and predictable overall.

Tool Count4/5

15 tools for a browsing/capture/watch server is slightly on the heavier side but each earns its place across the distinct concerns of live fetching, archiving, watching, searching, form handling, and media download. It sits just past the ideal range, slightly above the comfortable mid-teens ceiling.

Completeness4/5

The surface covers a rich browsing-to-archiving-to-watching workflow well: fetch, search, forms, links, archive write/search, download, and a full watch lifecycle (add/list/scan/diff/remove). Minor gaps: watch_edit/rename is absent, and there's no bulk archive deletion or a direct 'list archived pages' beyond archive_search — but agents can route around these.

Maintenance

ActivitySlowing
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for AI agents -- fetch any URL with full JavaScript rendering (Playwright/Chromium) and convert to clean, token-efficient markdown. Works on React, Vue, Angular, and any JS-heavy page. Includes web search, batch fetching, binary file download, LRU cache, SSRF protection, and structured output.
    25
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    An open-source web retrieval MCP server that fetches, crawls, and searches the web, returning clean markdown for AI agents. It integrates with Claude MCP, LangChain, and other frameworks for agentic web access.
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that fetches web pages, extracts clean markdown (reducing token count), caches results, and provides searchable reading history.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    MCP server that provides read_page, screenshot, and pdf tools using a real browser, enabling agents to fetch clean markdown, screenshots, and PDFs from any URL.
    5
    38
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/GiantRavens/mdbrowse'

If you have feedback or need assistance with the MCP directory API, please join our Discord server