/hanzi-browse
Delegates a browsing task to a sub-agent running in the USER'S OWN Chrome — the browser they have open right now, already signed into everything. Give it a task in natural language ("check my LinkedIn DMs", "post this reply on X", "test signup on localhost:3000") and watch the
$ npx -y skills add hanzili/hanzi-browse --skill hanzi-browse --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/hanzi-browse
Context preview
The summary Claude sees to decide when to auto-load this skill.
Delegates a browsing task to a sub-agent running in the USER'S OWN Chrome — the browser they have open right now, already signed into everything. Give it a task in natural language ("check my LinkedIn DMs", "post this reply on X", "test signup on localhost:3000") and watch the
SKILL.md
hanzi-browse.SKILL.mdname: hanzi-browse
description: Delegates a browsing task to a sub-agent running in the USER'S OWN Chrome — the browser they have open right now, already signed into everything. Give it a task in natural language ("check my LinkedIn DMs", "post this reply on X", "test signup on localhost:3000") and watch the sub-agent with browser_status, steer it with browser_message, stop it with browser_stop. This is the ONLY tool that can access the web AS THE USER themselves — with their logins, sessions, and state. Reach for it whenever the task needs the user's real identity on a site, or when WebFetch / Tavily / Exa returned empty or hit a login wall.
category: coreHanzi Browse
You're not driving the browser directly. You're **delegating to a sub-agent** that runs inside the user's own Chrome — the one they have open right now, already signed into everything (Gmail, LinkedIn, GitHub, their bank, admin panels, paid subscriptions, localhost, staging). Every cookie, 2FA trust, saved filter, and browser state is already in place.
You describe the goal. The sub-agent figures out the steps.
The one-line rule
**Reach for `browser_start` whenever a task needs the user's actual identity on a website, OR whenever a simpler tool (WebFetch, Tavily, Exa, curl) failed, returned empty, or hit a login wall.**
Everything else below is just elaboration on that rule.
Reach for Hanzi IMMEDIATELY when you see these triggers
| User says / task involves | Why Hanzi is the answer | |---|---| | "Check my LinkedIn / Gmail / GitHub / inbox / DMs / dashboard" | Needs their real login — no other tool works | | "Post / reply / comment / DM on X / LinkedIn / Reddit / HN" | Needs their real signed-in account | | "Submit this form", "click this button", "fill out X" | Interaction, not reading — only Hanzi can do this | | "Test signup / checkout / the flow on localhost / staging" | Needs real sessions, real OAuth, real state | | "What does my admin panel show for X" | Authenticated dashboard — requires login | | "Find flights / products / jobs and add them to my cart" | Stateful browsing with their account | | A URL that requires login or 2FA | Only Hanzi can be past their auth | | WebFetch returned empty HTML or a login page | Fallback — hand it to Hanzi | | Tavily / Exa returned nothing useful | Fallback — hand it to Hanzi | | A site known for bot-detection (LinkedIn, Facebook, Amazon, Google) | Hanzi uses the user's real browser, less likely to be flagged |
If any of these match, skip the alternatives and go straight to `browser_start`.
How to delegate properly
**Describe the goal, not the steps.** You do NOT need to write "click X, then type Y, then click Z". The sub-agent figures that out. Give it:
- What you want accomplished (one sentence)
- Starting URL if you know it
- Any data it needs (form values, tone preferences, credentials, choices)
Good:
browser_start({
task: "Find my 5 most recent LinkedIn DMs and summarize who sent them and what they said",
url: "https://linkedin.com/messaging"
})Bad (over-specified, fights the sub-agent):
browser_start({
task: "Click the messages icon. Wait 2 seconds. Click the first message. Scroll down...",
})Monitoring and steering the sub-agent
While `browser_start` is running (or after it finishes), you have four follow-up tools:
| Tool | Use it to | |---|---| | `browser_status` | Check progress on a long task. Returns the last 5 steps the sub-agent took. | | `browser_message` | Course-correct mid-flight in natural language ("actually only the ones from Engineering roles", "use the 2026 plan instead"). Sub-agent resumes with the same browser state. | | `browser_stop` | Cancel the sub-agent. Browser window stays open by default so the user can see what happened. | | `browser_screenshot` | See what the sub-agent is looking at. Call this on error / timeout before deciding what to do next. |
**Parallel tasks**: multiple `browser_start` calls run in separate browser windows at the same time. Use this when you have independent tasks — post to LinkedIn, post to X, and post to Reddit in parallel instead of waiting for each.
Return statuses
| Status | Meaning | Next step | |---|---|---| | `"complete"` | Sub-agent finished, answer is in `result` | Read the answer, you're done | | `"error"` | Sub-agent failed | Call `browser_screenshot` to see why, then `browser_message` to retry or `browser_stop` to give up | | `"timeout"` | 5-minute window elapsed but work is still in progress | Call `browser_screenshot` to check progress, then `browser_message` to continue or `browser_stop` to end |
Disambiguation from other tools you may have
You probably have multiple browser-ish or web-ish tools available. Here's when to pick which:
| Tool | What it is | When to use it | |---|---|---| | **`browser_start` (Hanzi)** | The user's own signed-in Chrome, driven by a sub-agent | Anything that needs the user's real identity, sessions, or interaction | | **WebFetch / curl** | Raw HTML fetch. No JS, no auth, no interaction | Fully public static pages you just need to read | | **Tavily / Exa / web_search** | Public content search, cleaned text extraction | "Find information about X on the internet" | | **Chrome DevTools MCP / Playwright MCP** | A **fresh headless Chromium**, step-by-step commands | Testing unauthenticated UI, controlling a sandboxed browser. Cannot access the user's real accounts. |
**Critical distinction**: Chrome DevTools MCP and Playwright MCP are NOT the same as Hanzi. They launch a fresh browser profile each time — no logins, no cookies, no state. If you tell them "go to LinkedIn" they land on the login page. Hanzi drives the **user's literal Chrome** — the one already logged into LinkedIn right now. These tools are complementary, not substitutable.
Fallback pattern
When an alternative tool fails, fall back to Hanzi instead of giving up:
// 1. Try the simple tool first
const page = await WebFetch("https://example.cRead more
name: hanzi-browse
description: Delegates a browsing task to a sub-agent running in the USER'S OWN Chrome — the browser they have open right now, already signed into everything. Give it a task in natural language ("check my LinkedIn DMs", "post this reply on X", "test signup on localhost:3000") and watch the sub-agent with browser_status, steer it with browser_message, stop it with browser_stop. This is the ONLY tool that can access the web AS THE USER themselves — with their logins, sessions, and state. Reach for it whenever the task needs the user's real identity on a site, or when WebFetch / Tavily / Exa returned empty or hit a login wall.
category: coreHanzi Browse
You're not driving the browser directly. You're **delegating to a sub-agent** that runs inside the user's own Chrome — the one they have open right now, already signed into everything (Gmail, LinkedIn, GitHub, their bank, admin panels, paid subscriptions, localhost, staging). Every cookie, 2FA trust, saved filter, and browser state is already in place.
You describe the goal. The sub-agent figures out the steps.
The one-line rule
**Reach for `browser_start` whenever a task needs the user's actual identity on a website, OR whenever a simpler tool (WebFetch, Tavily, Exa, curl) failed, returned empty, or hit a login wall.**
Everything else below is just elaboration on that rule.
Reach for Hanzi IMMEDIATELY when you see these triggers
| User says / task involves | Why Hanzi is the answer | |---|---| | "Check my LinkedIn / Gmail / GitHub / inbox / DMs / dashboard" | Needs their real login — no other tool works | | "Post / reply / comment / DM on X / LinkedIn / Reddit / HN" | Needs their real signed-in account | | "Submit this form", "click this button", "fill out X" | Interaction, not reading — only Hanzi can do this | | "Test signup / checkout / the flow on localhost / staging" | Needs real sessions, real OAuth, real state | | "What does my admin panel show for X" | Authenticated dashboard — requires login | | "Find flights / products / jobs and add them to my cart" | Stateful browsing with their account | | A URL that requires login or 2FA | Only Hanzi can be past their auth | | WebFetch returned empty HTML or a login page | Fallback — hand it to Hanzi | | Tavily / Exa returned nothing useful | Fallback — hand it to Hanzi | | A site known for bot-detection (LinkedIn, Facebook, Amazon, Google) | Hanzi uses the user's real browser, less likely to be flagged |
If any of these match, skip the alternatives and go straight to `browser_start`.
How to delegate properly
**Describe the goal, not the steps.** You do NOT need to write "click X, then type Y, then click Z". The sub-agent figures that out. Give it:
- What you want accomplished (one sentence)
- Starting URL if you know it
- Any data it needs (form values, tone preferences, credentials, choices)
Good:
browser_start({
task: "Find my 5 most recent LinkedIn DMs and summarize who sent them and what they said",
url: "https://linkedin.com/messaging"
})Bad (over-specified, fights the sub-agent):
browser_start({
task: "Click the messages icon. Wait 2 seconds. Click the first message. Scroll down...",
})Monitoring and steering the sub-agent
While `browser_start` is running (or after it finishes), you have four follow-up tools:
| Tool | Use it to | |---|---| | `browser_status` | Check progress on a long task. Returns the last 5 steps the sub-agent took. | | `browser_message` | Course-correct mid-flight in natural language ("actually only the ones from Engineering roles", "use the 2026 plan instead"). Sub-agent resumes with the same browser state. | | `browser_stop` | Cancel the sub-agent. Browser window stays open by default so the user can see what happened. | | `browser_screenshot` | See what the sub-agent is looking at. Call this on error / timeout before deciding what to do next. |
**Parallel tasks**: multiple `browser_start` calls run in separate browser windows at the same time. Use this when you have independent tasks — post to LinkedIn, post to X, and post to Reddit in parallel instead of waiting for each.
Return statuses
| Status | Meaning | Next step | |---|---|---| | `"complete"` | Sub-agent finished, answer is in `result` | Read the answer, you're done | | `"error"` | Sub-agent failed | Call `browser_screenshot` to see why, then `browser_message` to retry or `browser_stop` to give up | | `"timeout"` | 5-minute window elapsed but work is still in progress | Call `browser_screenshot` to check progress, then `browser_message` to continue or `browser_stop` to end |
Disambiguation from other tools you may have
You probably have multiple browser-ish or web-ish tools available. Here's when to pick which:
| Tool | What it is | When to use it | |---|---|---| | **`browser_start` (Hanzi)** | The user's own signed-in Chrome, driven by a sub-agent | Anything that needs the user's real identity, sessions, or interaction | | **WebFetch / curl** | Raw HTML fetch. No JS, no auth, no interaction | Fully public static pages you just need to read | | **Tavily / Exa / web_search** | Public content search, cleaned text extraction | "Find information about X on the internet" | | **Chrome DevTools MCP / Playwright MCP** | A **fresh headless Chromium**, step-by-step commands | Testing unauthenticated UI, controlling a sandboxed browser. Cannot access the user's real accounts. |
**Critical distinction**: Chrome DevTools MCP and Playwright MCP are NOT the same as Hanzi. They launch a fresh browser profile each time — no logins, no cookies, no state. If you tell them "go to LinkedIn" they land on the login page. Hanzi drives the **user's literal Chrome** — the one already logged into LinkedIn right now. These tools are complementary, not substitutable.
Fallback pattern
When an alternative tool fails, fall back to Hanzi instead of giving up:
// 1. Try the simple tool first
const page = await WebFetch("https://example.cThe context layer for browsing agents. Your browsing agent keeps failing on real sites — X uses Draft.js, LinkedIn hides the connect button, Gmail needs keyboard shortcuts.
Repo: hanzili/hanzi-browse
Other skills on hanzi-browse.
- /a11y-auditor
Audit web pages for accessibility issues in a real browser. Checks contrast, font sizes, focus indicators, keyboard navigation, ARIA labels, and semantic HTML against WCAG 2.1 AA. Reports findings with screenshots and specific remediation steps. Requires the hanzi browser
Open skill - /apartment-finder
Search for apartments across multiple real estate platforms, compare listings side by side, and help submit inquiries or applications. Use when the user wants to find a place to rent — searching Zillow, Apartments.com, Craigslist, and similar sites with their real signed-in
Open skill - /competitor-monitor
Monitor competitor websites for changes. Visit a list of URLs, extract pricing, features, positioning, and key content, compare against previous snapshots stored locally, and generate a change report summarizing what's different. Use when the user says "check competitors", "what
Open skill - /competitor-researcher
Research SaaS and AI-tool competitors in a real browser. Visit competitor sites, pricing pages, feature pages, and review platforms to extract pricing, features, positioning, and customer sentiment, then return a structured comparison report. Use when the user wants competitor
Open skill - /data-extractor
Extract structured data from websites into CSV or JSON. Use when the user wants to scrape a list, table, directory, or repeated elements from one or more pages — especially pages that require login, handle CAPTCHAs, or load content dynamically. Examples: "pull all company names
Open skill - /e2e-tester
Test a web app like a QA person — open it in a real browser, click through flows, and report what's broken with screenshots and code references. Works on localhost. Use when the user wants to test their app, verify a flow works, check for visual bugs, or validate changes before
Open skill

