plugins/browser-use/skills/navigation-patterns/SKILL.md
URL navigation, multi-tab orchestration, session creation and management, back/forward navigation, browser profile persistence, session export/import for authentication reuse.
npx skillsauth add madappgang/magus navigation-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Patterns for URL navigation, multi-tab workflows, session lifecycle management, and browser profile persistence.
The fundamental browser pattern: navigate, inspect, interact, close.
Step 1: Navigate to URL (session created automatically)
mcp__browser-use__browser_navigate(url="https://example.com")
→ Save session_id from response
Step 2: Inspect the page
mcp__browser-use__browser_get_state(session_id="abc123")
→ Returns selector_map with numbered elements
Step 3: Interact (optional)
mcp__browser-use__browser_click(index=3, session_id="abc123")
Step 4: Always close
mcp__browser-use__browser_close_session(session_id="abc123")
Verify page loaded: After browser_navigate, check the response title and url. If title is blank or URL redirected unexpectedly, call browser_get_state to inspect the actual page content before proceeding.
Wait for dynamic content: For SPAs (React, Vue, Angular), the DOM may not be ready immediately after navigate. If selector_map in browser_get_state is sparse or empty, call browser_get_state again after a short delay:
1. browser_navigate(url="https://spa-app.example.com")
2. browser_get_state(session_id) → sparse selector_map?
3. browser_get_state(session_id) → call again; SPA renders after first paint
Use browser_go_back to return to the previous page without creating a new navigation entry.
Pattern: Visit detail page, then return to list
1. browser_navigate(url="https://shop.example.com/products") → session_id
2. browser_get_state(session_id) → find product links in selector_map
3. browser_click(index=5, session_id) → navigate to product detail
4. browser_extract_content(query="price and specs", session_id)
5. browser_go_back(session_id) → back to product list
6. browser_get_state(session_id) → DOM refreshed
7. browser_click(index=6, session_id) → next product
... repeat ...
N. browser_close_session(session_id)
Note: browser_go_back uses the browser's history stack. It will fail if there is no previous page (e.g., you navigated directly to a deep URL). In that case, use browser_navigate with the list URL instead.
Open multiple tabs within a single session to compare pages or extract data in parallel.
1. browser_navigate(url="https://example.com", session_id=None) → session_id: "s1"
2. browser_navigate(url="https://example.com/page-2", session_id="s1", new_tab=True)
→ opens tab_1
3. browser_list_tabs(session_id="s1")
→ [{"tab_id": "tab_0", "url": ".../page-1", "active": false},
{"tab_id": "tab_1", "url": ".../page-2", "active": true}]
4. browser_switch_tab(tab_id="tab_0", session_id="s1") → activate tab_0
5. browser_get_state(session_id="s1") → DOM of tab_0
6. browser_extract_content(query="pricing", session_id="s1")
7. browser_switch_tab(tab_id="tab_1", session_id="s1") → activate tab_1
8. browser_extract_content(query="pricing", session_id="s1")
9. browser_close_tab(tab_id="tab_1", session_id="s1") → close second tab
10. browser_close_session(session_id="s1") → close session (closes remaining tabs)
| Use Case | Pattern | |----------|---------| | Compare prices on two sites | Open site A → new_tab for site B → extract from each | | Scrape paginated list into detail pages | Open list → each item in new tab → extract → close tab → next item | | Compare before/after a UI change | Navigate to staging → new tab to production → screenshot both | | Log in on one tab, use auth on another | Log in on tab_0, navigate to protected resource on tab_1 (same session shares cookies) |
Sessions are created implicitly when browser_navigate is called without a session_id. Always save the returned session_id:
response = mcp__browser-use__browser_navigate(url="https://example.com")
session_id = response["session_id"] # e.g., "abc123"
List active sessions to detect leaks from previous runs or to resume a workflow:
mcp__browser-use__browser_list_sessions()
→ {"sessions": [{"session_id": "abc123", "url": "...", "created_at": "..."}]}
Always check for existing sessions before starting a new workflow — a previous error may have left sessions open.
# Clean up a specific session
mcp__browser-use__browser_close_session(session_id="abc123")
# Clean up all leaked sessions at start of new workflow
sessions = mcp__browser-use__browser_list_sessions()
for s in sessions["sessions"]:
mcp__browser-use__browser_close_session(session_id=s["session_id"])
| Situation | Action |
|-----------|--------|
| Workflow completed successfully | browser_close_session |
| Workflow failed with an error | browser_close_session (still required) |
| Need to use the same session in the next step | Keep open, pass session_id to next tool |
| Starting a new unrelated task | browser_list_sessions + close all |
| Debugging a stuck page | browser_screenshot first, then close |
Browser profiles save cookies, localStorage, and login state across Claude Code sessions. Use them to skip login flows.
Profiles are stored in ~/.browser-use/profiles/ (one directory per profile, named by you):
~/.browser-use/
├── profiles/
│ ├── github/ # Saved login state for GitHub
│ ├── jira/ # Saved login state for Jira
│ └── work-google/ # Work Google account cookies
└── sessions/ # Exported session snapshots (JSON files)
After completing a login workflow, export the session state to a JSON file:
# 1. Navigate and log in normally
mcp__browser-use__browser_navigate(url="https://github.com/login")
# ... complete login workflow (fill username, password, click submit) ...
# 2. Export the authenticated session
mcp__browser-use__browser_export_session(
session_id="abc123",
output_path="~/.browser-use/sessions/github-session.json"
)
# 3. Close the session
mcp__browser-use__browser_close_session(session_id="abc123")
In the next Claude Code session, restore the saved login state:
# Import saved cookies into a new session
mcp__browser-use__browser_import_session(
import_path="~/.browser-use/sessions/github-session.json",
navigate_to="https://github.com/dashboard"
)
→ {"session_id": "new_xyz", "cookies_imported": 12, "url": "https://github.com/dashboard"}
# Verify login worked
mcp__browser-use__browser_get_state(session_id="new_xyz")
# Check: selector_map should show dashboard elements, not login form
Saved sessions expire when site cookies expire. After importing, verify login succeeded:
1. browser_import_session(import_path="...", navigate_to="https://site.com/dashboard")
2. browser_get_state(session_id)
3. Check: if selector_map contains login form elements → session expired, login again
if selector_map contains dashboard elements → session active, proceed
# WRONG: Forgot to close session
mcp__browser-use__browser_navigate(url="https://example.com")
mcp__browser-use__browser_extract_content(query="pricing", session_id="abc123")
# Task complete — session never closed. Browser process running, memory leaked.
# CORRECT: Always close
mcp__browser-use__browser_navigate(url="https://example.com")
mcp__browser-use__browser_extract_content(query="pricing", session_id="abc123")
mcp__browser-use__browser_close_session(session_id="abc123")
# WRONG: Reusing a session_id from a previous Claude Code session
mcp__browser-use__browser_click(index=3, session_id="abc123")
# → {"error": "session_not_found"}
# CORRECT: Always navigate first to create a fresh session
mcp__browser-use__browser_navigate(url="https://example.com")
→ session_id: "new_session_id"
# WRONG: Opening new tab in a loop without closing old ones
for each product_url:
browser_navigate(url=product_url, session_id=s, new_tab=True)
# 50 tabs open at once → browser crashes
# CORRECT: Close tab before opening next
for each product_url:
browser_navigate(url=product_url, session_id=s, new_tab=True)
tab_id = browser_list_tabs(session_id=s)["tabs"][-1]["tab_id"]
# ... extract data ...
browser_close_tab(tab_id=tab_id, session_id=s)
# WRONG: URL without scheme
mcp__browser-use__browser_navigate(url="example.com")
# → navigation error
# CORRECT: Always include https://
mcp__browser-use__browser_navigate(url="https://example.com")
testing
A test skill for validation testing. Use when testing skill parsing and validation logic.
tools
--- name: bad-skill description: This skill has invalid YAML in frontmatter allowed-tools: [invalid, array, syntax prerequisites: not-an-array --- # Bad Skill This skill has malformed frontmatter that should fail parsing. The YAML has: - Unclosed array bracket - Wrong type for prerequisites (should be array, not string)
development
Sync model aliases from the curated Firebase database. Fetches default model assignments, short aliases, team compositions, and known model metadata from the claudish API. Run this to get fresh model recommendations.
tools
Release one or more Magus plugins to the distribution repos (magus, magus-alpha, magus-marketing). Handles version inference from git history, marketplace.json updates, tagging, and force-push to lean dist repos. Use whenever the user says "release kanban", "release the dev plugin", "cut a new version of gtd", "bump kanban to 1.7", or hands you a batch like "release kanban and gtd". Also use for multi-plugin releases and for checking what a release would contain before committing.