Browse — Visual Feedback Browser Automation
SkillWeb & browsingVisual feedback browser automation with multi-session, multi-tab, iframe support, and enterprise primitives. Navigate sites, interact with elements, manage tabs/sessions, handle file uploads, dropdowns, iframes, and verify results using the screenshot-analyze-act-verify loop. Use when asked to "open a site", "test a page", "fill a form", "check a deployment", "browse to", "click on", "verify the UI", "compare pages side by side", or any task involving web interaction. Also use proactively when a task would benefit from checking a live URL.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Browse — Visual Feedback Browser Automation skill
What this skill tells your AI
The instructions your AI receives, as published by seifbenayed/cloclo in .claude/skills/browse/SKILL.md and read by ahel’s review.
You have a Browser tool with an action-based interface. This skill teaches you how to use it
effectively with a screenshot → analyze → act → verify loop that prevents blind clicking.
Core Principle
Never act without seeing. Never assume an action worked. Always verify.
OBSERVE → DECIDE → ACT → VERIFY
(get_state (analyze (click/ (get_state
+ screenshot elements) type) + screenshot
+ compare)
Starting a Session
Every browser session starts the same way:
- Navigate to the target URL
- Observe the page with
get_state— this returns the DOM with indexed interactive elements AND the page text - Screenshot to see the visual layout
Browser { action: "navigate", url: "https://example.com" }
Browser { action: "get_state" }
Browser { action: "screenshot" }
Read the screenshot to understand the visual layout. The get_state output gives you:
- URL and title
- Scroll position (how far down the page you are)
- Interactive element count (links, inputs, buttons)
- Indexed elements:
[0] <button> "Submit",[1] <input:text> name="email" - Page text (first 3000 chars)
JSON Format
For structured processing, use format: "json":
Browser { action: "get_state", format: "json" }
Returns: { url, title, scroll, stats, elements: [{index, tag, text, ...}], text, session_id, active_tab_id }
Interacting with Elements
Always prefer element indices over CSS selectors. The indices come from get_state and are
reliable. CSS selectors can break if the page structure changes.
Browser { action: "click_element", index: 5 }
Browser { action: "type_element", index: 3, value: "hello@example.com" }
Fall back to CSS selectors only when:
- The element doesn't appear in the indexed list
- You need to target something very specific (like
input[name="csrf_token"])
Browser { action: "click", selector: "#submit-btn" }
Browser { action: "fill", selector: "input[name='email']", value: "test@example.com" }
Keyboard Input (send_keys)
For named keys and key combinations:
Browser { action: "send_keys", keys: "Enter" }
Browser { action: "send_keys", keys: "Tab Tab Enter" }
Browser { action: "send_keys", keys: "Ctrl+a" }
Browser { action: "send_keys", keys: "Shift+Tab" }
Supported named keys: Enter, Tab, Escape, Backspace, Delete, Space, ArrowUp/Down/Left/Right, Home, End, PageUp, PageDown, F1-F12. Modifiers: Ctrl, Alt, Shift, Meta/Cmd. Sequences: space-separated.
File Upload
Browser { action: "upload_file", selector: "input[type='file']", file_path: "/path/to/file.pdf" }
Dropdowns
Browser { action: "dropdown_options", selector: "#my-select" }
Browser { action: "select_dropdown", selector: "#my-select", value: "option_value" }
Structured Data Extraction
Extract structured data from the page using CSS selectors:
Browser { action: "extract", schema: {"title": "h1", "price": ".price", "description": ".desc"} }
Returns JSON: {"title": "Product Name", "price": "$29.99", "description": "..."}
Multi-Tab Workflows
Open, switch between, and close tabs for side-by-side comparison:
Browser { action: "navigate", url: "https://site-a.com" }
Browser { action: "new_tab", url: "https://site-b.com" }
Browser { action: "list_tabs" }
Browser { action: "switch_tab", tab_id: "PREVIOUS_TAB_ID" }
Browser { action: "close_tab", tab_id: "TAB_TO_CLOSE" }
Tab IDs are strings (CDP target IDs). Get them from list_tabs.
Multi-Session Workflows
Use separate sessions for isolated browser instances (different profiles, auth states):
Browser { action: "new_session", session_id: "admin", profile_name: "admin-profile" }
Browser { action: "navigate", url: "https://app.com/admin", session_id: "admin" }
Browser { action: "new_session", session_id: "user", profile_name: "user-profile" }
Browser { action: "navigate", url: "https://app.com/dashboard", session_id: "user" }
Browser { action: "list_sessions" }
Browser { action: "close_session", session_id: "admin" }
Named Profiles
Profiles persist cookies and state across sessions:
profile_name: "my-profile"→ stored in~/.claude/browser-profiles/my-profile/user_data_dir: "/custom/path"→ raw Chrome user data directoryprofile_dir: "Profile 1"→ Chrome's--profile-directoryflag
Attach Mode (Remote Chrome)
Connect to an already-running Chrome instance:
Browser { action: "new_session", session_id: "remote", cdp_url: "http://localhost:9222" }
Or set BROWSER_CDP_URL=http://localhost:9222 env var for the default session.
In attach mode, close disconnects without killing Chrome.
Iframe Support
Browser { action: "list_frames" }
Browser { action: "click_element", index: 0, frame_id: "FRAME_ID" }
Browser { action: "fill", selector: "input", value: "text", frame_id: "FRAME_ID" }
Frame IDs come from list_frames. Use frame_id on any DOM action to target elements inside iframes.
Events & Dialogs
The browser captures events (dialogs, navigations, crashes, downloads):
Browser { action: "get_events" }
Browser { action: "set_dialog_auto_dismiss", enabled: true }
Dialogs (alert/confirm/prompt) are auto-dismissed by default. Disable with enabled: false to handle manually.
The Verify Loop
After every action that changes the page, you must verify:
1. Take action (click, type, navigate, submit)
2. Wait briefly if needed: Browser { action: "wait_for", selector: ".result", timeout: 3000 }
3. Observe again: Browser { action: "get_state" }
4. Screenshot again: Browser { action: "screenshot" }
5. Compare: did the page change as expected?
- YES → continue to next step
- NO → try a different approach (different element, different selector, scroll first)
Iteration Budget
You have a maximum of 10 iterations (observe-act-verify cycles) per task. This prevents infinite loops. If you haven't achieved the goal in 10 iterations:
- Stop
- Report what you accomplished and what failed
- Include the last screenshot as evidence
Count your iterations. Mention the count when reporting.
Error Recovery
When something doesn't work:
- Element not found — the page may have changed. Run
get_stateagain to refresh the element indices. - Click didn't work — the element might be obscured. Try
scroll_tofirst, then click again. - Page didn't load — try
wait_forwith a key selector, orreload. - Form submission failed — screenshot to see error messages, read them, adjust input.
- Same action 3 times — the Browser tool has loop detection. If you get a loop warning, you MUST try a completely different approach.
Fallback chain for clicking:
click_element by index → click by CSS selector → evaluate with JS click → scroll + retry
Scrolling
Pages are often longer than the viewport. The get_state output shows scroll position.
If you need elements below the fold:
Browser { action: "scroll_to", value: "500" } // scroll down 500px
Browser { action: "scroll_to", selector: "#footer" } // scroll to element
Browser { action: "get_state" } // refresh elements after scroll
Always get_state after scrolling — the element indices change.
Evidence and Reporting
When completing a task, provide evidence:
- Before state — screenshot of the page before your actions
- Actions taken — list of what you did (clicked X, typed Y, navigated to Z)
- After state — screenshot showing the result
- Verification — what you checked to confirm the task is done
Format your report:
## Browser Task: [description]
**URL:** https://example.com/page
**Session:** default
**Iterations:** 4/10
### Actions
1. Navigated to https://example.com
2. Clicked [3] <button> "Login"
3. Typed email into [5] <input:email>
4. Typed password into [7] <input:password>
5. Sent keys: Enter
### Verification
- Page title changed to "Dashboard"
- User avatar visible in header
- No error messages present
### Screenshots
- Before: [screenshot 1]
- After: [screenshot 2]
JavaScript Evaluation
For complex checks or actions not covered by built-in actions:
Browser { action: "evaluate", value: "document.querySelectorAll('.error').length" }
Browser { action: "evaluate", value: "window.localStorage.getItem('token')" }
This is powerful but use it sparingly — prefer the built-in actions.
Cookies
For authenticated sessions:
Browser { action: "cookies_get" }
Browser { action: "cookies_set", cookie: { name: "session", value: "abc123", domain: ".example.com" } }
Browser { action: "cookies_clear" }
Closing
Always close the browser when done:
Browser { action: "close" }
This frees system resources. The browser will auto-launch again if needed.
Quick Reference
| Goal | Action | Notes |
|---|---|---|
| See the page | get_state + screenshot | Always first |
| See page (structured) | get_state with format: "json" | For parsing |
| Click a button | click_element with index | From get_state |
| Type text | type_element with index and value | |
| Press keys | send_keys with keys | "Enter", "Tab", "Ctrl+a" |
| Navigate | navigate with url | |
| Upload a file | upload_file with selector, file_path | |
| Read dropdown | dropdown_options with selector | Returns [{value,text,selected}] |
| Select dropdown | select_dropdown with selector, value | |
| Extract data | extract with schema | Returns structured JSON |
| Wait for content | wait_for with selector | |
| Scroll down | scroll_to with value or selector | |
| Open new tab | new_tab with optional url | |
| Switch tab | switch_tab with tab_id | |
| List tabs | list_tabs | |
| Close tab | close_tab with tab_id | |
| New session | new_session with session_id | Optional: profile_name, cdp_url |
| List sessions | list_sessions | |
| List frames | list_frames | For iframe inspection |
| Get events | get_events | Dialog, crash, download, navigation |
| Run JS | evaluate with value | |
| Go back | back | |
| Save page as PDF | pdf | |
| Check cookies | cookies_get | |
| Done | close |
Signals
- GitHub stars
- 114
- Forks
- 30
- Last commit
- Apr 2026
Advanced
- Catalog kind
- skill
- Gateway key
browse-seifbenayed- Source
- github.com/seifbenayed/cloclo