web-browsing
Use before any web browsing task — navigating sites, filling forms, clicking buttons, or extracting data. Routes to site-specific skills; universal protocol as fallback.
Web Browsing — Master Router
Invoke this skill before any browser task. It routes you to a site-specific skill when one is installed, and provides universal fallback navigation for everything else.
Step 1: Check for a Site-Specific Skill
Before opening a browser, check whether a skill exists for the target domain:
| Domain | Skill | Covers |
|---|---|---|
caniuse.com | caniuse | Browser compat data — programmatic path via GitHub raw, shadow DOM gotchas |
pub.dev | pub-dev | Dart/Flutter packages — REST API, search, score, advisories |
developer.mozilla.org | mdn-web-docs | MDN search API, article navigation, reference lookup |
crates.io | crates-io | Rust crates — REST API, search, versions, dependencies |
pypi.org | pypi | Python packages — JSON API, search, release data |
news.ycombinator.com | hacker-news | HN feed, comments, search via Algolia API |
If the target domain is in this table: Invoke the matching skill immediately. Do not open a browser until you have read it.
If the target domain is not in this table: Continue to Step 2.
Step 2: Universal Navigation Protocol
For sites without a specific skill, follow this protocol to navigate efficiently with minimum screenshots.
Reconnaissance (1 screenshot max)
1. Navigate to the URL
2. Take ONE screenshot
3. Use read_page with filter="interactive" to get all clickable/input elements
4. From this single pass, identify:
- Navigation structure (top bar, sidebar, hamburger)
- Search capability
- Auth state (login buttons vs user avatar)
- Blocking overlays (cookie banners, modals, paywalls)
Clear Obstacles First
Handle these BEFORE your actual task — they block everything:
| Obstacle | Action |
|---|---|
| Cookie banner | Click "Reject All" or most privacy-preserving option |
| Login wall | Stop — tell the user; never guess credentials |
| Newsletter popup | Find X/close button; if none, press Escape |
| CAPTCHA | Stop — tell the user; do not attempt to solve |
| "Accept terms" modal | Stop — ask user permission before accepting |
| Paywall | Stop — tell the user the content is paywalled |
Navigate to Target
Use this priority order (fastest to slowest):
- Direct URL — Construct and navigate directly if possible. Zero wasted clicks.
- Search — Type query into site's search field, submit, scan results.
- Navigation menu — Use
read_pageorfindtool to locate nav links. - Scroll and scan — Last resort. Scroll methodically, screenshot to orient.
Element Finding (fastest to slowest)
| Tier | Method | Use When |
|---|---|---|
| 1 | find tool with natural language | Buttons, links, labeled elements |
| 2 | read_page filter="interactive" | Full page inventory, forms with many fields |
| 3 | javascript_tool with CSS selector | Known selectors, dynamic/hidden elements |
| 4 | Screenshot + analyze coordinates | Last resort — element unreachable programmatically |
Anti-patterns:
- Taking a screenshot to find a button you could
findby label - Clicking by coordinate when you have a ref_id
- Taking multiple screenshots to "make sure" (
read_pageconfirming an element is enough)
Timing and Waiting
| Situation | Wait | Duration |
|---|---|---|
| After link click (navigation) | wait | 1–2s |
| After form submit | wait | 2–3s |
| After AJAX / dynamic content | wait | 1–2s |
| SPA / dashboard initial load | wait | 3–5s |
| Between form field fills | none | — |
| After tab/accordion on same page | none | — |
Detect page load without guessing: Use read_page — if it returns content, the page is ready. Check document.readyState === 'complete' via javascript_tool for heavy SPAs.
Data Extraction
| Data type | Method |
|---|---|
| Article / documentation text | get_page_text — order of magnitude faster than screenshots |
| Tables and lists | javascript_tool → query table/list elements |
| Visual layout or positioning | Screenshot → analyze |
| Paginated data | Extract page → find "Next" → loop |
Error Recovery
- Retry once — Click didn't register? Try again. Page didn't load? Wait 2s, check again.
- Alternative path — Button not clickable? Try keyboard shortcut. Navigation broken? Try direct URL.
- Tell the user — Auth required, CAPTCHA blocking, site down, element truly missing.
Never silently fail or loop. Three attempts max, then escalate to the user.
Common Site Patterns
SPA (React/Vue/Angular): URL changes may not trigger real page loads. Wait for dynamic content, not just document.readyState. Use read_network_requests to detect when API calls finish.
Dashboard/Admin: Left sidebar navigation, breadcrumbs for orientation, settings under gear icon or bottom of sidebar.
E-Commerce: Products at /product/, /p/, or /dp/. Cart at /cart. Search via ?q= or ?search= parameter. Account at /account.
API-backed sites: Try site.com/api/ or check for OpenAPI spec at /openapi.json, /swagger.json, /api/docs. Programmatic API calls are always faster than browser navigation when available.
Performance Rules
- One screenshot to orient, then use programmatic tools.
- Construct URLs directly when possible — avoids clicking through menus.
- Batch form inputs — read all fields once, fill all in sequence, no screenshots between.
- Use
get_page_textbefore screenshots for text extraction. - Use
findbeforeread_pagebefore screenshots — escalate from fast to slow. - Never wait "just in case" — check if the page is ready, don't assume it isn't.
- Tell the user what's happening if something is slow or broken.