| name | core |
| description | Core kachilu-browser usage guide. Read this before running any kachilu-browser commands. Covers the snapshot-and-ref workflow, navigating pages, interacting with elements (click, fill, type, select), extracting text and data, taking screenshots, managing tabs, handling forms and auth, waiting for content, running multiple browser sessions in parallel, and troubleshooting common failures. Use when the user asks to interact with a website, fill a form, click something, extract data, take a screenshot, log into a site, test a web app, or automate any browser task. |
| allowed-tools | Bash(kachilu-browser:*), Bash(npx kachilu-browser:*) |
kachilu-browser core
Fast browser automation CLI for AI agents. Chrome/Chromium via CDP, no
Playwright or Puppeteer dependency. Accessibility-tree snapshots with compact
@eN refs let agents interact with pages in ~200-400 tokens instead of
parsing raw HTML.
Most normal web tasks (navigate, read, click, fill, extract, screenshot) are covered here.
The installed skills/kachilu-browser/SKILL.md is only a discovery stub. This
core guide is the runtime source of truth for Kachilu interaction defaults,
control-plane routing, CAPTCHA workflow, troubleshooting, and command usage.
Interaction Priority
Human-like interaction is the default and strongly preferred approach.
- Prefer visible user actions first:
open, snapshot, click, fill, type, scroll, press, wait, tab, screenshot.
- Re-snapshot after each meaningful page change and continue from what is actually visible on screen.
- For feeds and dynamic apps such as X, prefer repeated
scroll + wait + snapshot cycles over DOM scraping.
- For social sites and logged-in web apps, prefer the visible UI flow: open the site or search page, click the search box, type the query, press Enter, switch visible tabs/filters, then inspect what appears.
- Do not construct direct search/result URLs such as
https://x.com/search?... as the default path. Use direct URLs only when the visible UI path is unavailable, ambiguous, or explicitly requested, and state why the fallback is needed.
- Pace actions like a human operator. Wait after page loads, searches, filter changes, and scrolls before observing again; avoid rapid query fan-out, repeated navigations, or one-search-per-second loops.
- For post, comment, message, and other rich composer fields, click the visible editor first and use
keyboard type at the current focus. Use fill only for ordinary form fields such as plain inputs and textareas, or after verifying the composer behaves like one.
- Before clicking a publish, send, save, or submit control from a composer, re-snapshot and confirm the intended body appears once in the focused or visibly active composer.
- Use
eval, raw DOM extraction, or page-internal JavaScript only as a last resort when human-like interaction is clearly insufficient.
If there is any doubt, choose the more human-like path.
Control Plane Routing
Before running any browser command, choose the control plane.
- If host or developer instructions provide a pre-attached browser session, CDP endpoint, session metadata file, or an explicit
kachilu-browser --session ... --cdp ... command, use that exact host-provided session through the CLI.
- In a pre-attached session, do not call MCP
prepare_workspace, do not auto-connect, and do not choose a different browser target. The host has already selected the browser, profile, and visible surface.
- If no pre-attached session is provided and MCP tools are available, use MCP instead of shell commands.
- In Codex, the callable tools may be exposed as
mcp__kachilu_browser__kachilu_browser_prepare_workspace and mcp__kachilu_browser__kachilu_browser_exec, or under the mcp__agent_browser__... server namespace with the same kachilu_browser_* tool names.
- In OpenClaw, bundle MCP may expose provider-safe names such as
kachilu_browser__kachilu_browser_prepare_workspace and kachilu_browser__kachilu_browser_exec; use those when OpenClaw presents them.
- Call
kachilu_browser_prepare_workspace once, then use kachilu_browser_exec for batch, snapshot, click, fill, wait, and other follow-up commands. Reuse the returned session.
- After context compaction, resume, or a long interruption, continue through the same control plane that was chosen earlier. Do not switch from a host-provided session to MCP, or from MCP to raw shell commands, just because prior tool calls are no longer visible.
- MCP may carry host-managed environment such as
KACHILU_BROWSER_CONNECT_MODE=cdp, KACHILU_BROWSER_CDP, KACHILU_BROWSER_AUTO_CONNECT_TARGET=windows, or KACHILU_BROWSER_WINDOWS_LOCALAPPDATA; raw shell commands can miss that setup and control the wrong browser.
- Use raw shell
kachilu-browser only when using a host-provided session, when MCP tools are unavailable, when the user explicitly asks for a CLI command, or when the task intentionally targets a local WSL/Linux browser.
- Keep the same prepared MCP session across related browser work in the same user request, even when moving from LinkedIn to X or between multiple logged-in sites. The
site hint is for routing only; it must not create per-site sessions.
- Do not call
kachilu_browser_close_workspace between related browser subtasks. Close only when the entire workflow is finished or the user explicitly wants cleanup.
Primary MCP tools are kachilu_browser_prepare_workspace, kachilu_browser_exec, and kachilu_browser_close_workspace. When no host-provided session exists, use prepare_workspace first for browser interaction, especially for site-specific requests such as X, LinkedIn, Yahoo, GitHub, Gmail, dashboards, admin panels, or other logged-in web workflows. Pass site when the target site is obvious and initialUrl when you already know the landing page. site is only a hint; it does not mean "start a separate session for this site".
Let MCP default to workspaceMode: "new-window" when you want the same browser profile but a separate workspace window. Use workspaceMode: "fresh-tab" only when you intentionally want to stay in the current browser window. Do not switch to the user's currently focused tab for normal site tasks.
MCP may attach to a configured dedicated CDP endpoint or use auto-connect. Auto-connect is an MCP-managed setup path or an explicit CLI fallback, not a default override for a host-provided session. If MCP reports a missing or unreachable dedicated CDP browser, tell the user to open the host-managed browser or fix the KACHILU_BROWSER_CDP endpoint and then retry. If auto-connect cannot attach, tell the user to open Chrome, keep remote-connect enabled, approve the connection prompt, and then retry. If MCP returns actionRequired: "retry-existing-session", tell the user to retry after a short wait. Do not kill the session or force a reconnect unless the session is clearly stale.
If a daemon is still running but its browser connection is gone, treat that session as stale rather than reusable. The next prepare_workspace should reconnect instead of clinging to the dead session.
Core Loop
kachilu-browser open <url>
kachilu-browser snapshot -i
kachilu-browser click @e3
kachilu-browser snapshot -i
Refs (@e1, @e2, ...) are assigned fresh on every snapshot. They become stale the moment the page changes: after navigations, form submits, dynamic re-renders, dialogs, modals, or iframe changes.
Reading a page
kachilu-browser snapshot
kachilu-browser snapshot -i
kachilu-browser snapshot -i -u
kachilu-browser snapshot -i -c
kachilu-browser snapshot -i -d 3
kachilu-browser snapshot -s "#main"
kachilu-browser snapshot -i --json
Snapshot output looks like:
Page: Example - Log in
URL: https://example.com/login
@e1 [heading] "Log in"
@e2 [form]
@e3 [input type="email"] placeholder="Email"
@e4 [input type="password"] placeholder="Password"
@e5 [button type="submit"] "Continue"
@e6 [link] "Forgot password?"
For unstructured reading (no refs needed):
kachilu-browser get text @e1
kachilu-browser get html @e1
kachilu-browser get attr @e1 href
kachilu-browser get value @e1
kachilu-browser get title
kachilu-browser get url
kachilu-browser get count ".item"
Interacting
kachilu-browser click @e1
kachilu-browser --action-mode ax-ref click @e1
kachilu-browser click @e1 --new-tab
kachilu-browser dblclick @e1
kachilu-browser hover @e1
kachilu-browser focus @e1
kachilu-browser fill @e2 "hello"
kachilu-browser type @e2 " world"
kachilu-browser press Enter
kachilu-browser press Control+a
kachilu-browser check @e3
kachilu-browser uncheck @e3
kachilu-browser select @e4 "option-value"
kachilu-browser select @e4 "a" "b"
kachilu-browser upload @e5 file1.pdf
kachilu-browser scroll down 500
kachilu-browser scrollintoview @e1
kachilu-browser drag @e1 @e2
When using MCP kachilu_browser_exec with batch, pass each browser command
as its own argument. The args array is already argv, so use
["batch", "fill @e1 \"Alice\"", "fill @e2 \"alice@example.com\""]. Do not
join multiple commands into one newline-delimited string such as
["batch", "fill @e1 \"Alice\"\nfill @e2 \"alice@example.com\""]; that is
parsed as one command and can put later commands into the first field.
When refs don't work or you don't want to snapshot
Use semantic locators:
kachilu-browser find role button click --name "Submit"
kachilu-browser find text "Sign In" click
kachilu-browser find text "Sign In" click --exact
kachilu-browser find label "Email" fill "user@test.com"
kachilu-browser find placeholder "Search" type "query"
kachilu-browser find testid "submit-btn" click
kachilu-browser find first ".card" click
kachilu-browser find nth 2 ".card" hover
Or a raw CSS selector:
kachilu-browser click "#submit"
kachilu-browser fill "input[name=email]" "user@test.com"
kachilu-browser click "button.primary"
Rule of thumb: snapshot + @eN refs are fastest and most reliable for
AI agents. find role/text/label is next best and doesn't require a prior
snapshot. Raw CSS is a fallback when the others fail.
Hybrid mode is the default for stale-prone ref actions. It keeps the existing
snapshot/ref workflow but fresh-resolves the target from current AX/DOM
semantics and the last observed geometry before dispatching the coordinate
click. Use kachilu-browser --action-mode ax-ref click @eN only when you want
the legacy fast ref path.
If click @eN, semantic click, or CSS click fails even though the visible
cursor appears to be on the intended button or control, verify the visual state
before changing strategy:
kachilu-browser screenshot /tmp/kachilu-click-state.png
kachilu-browser mouse down left
kachilu-browser mouse up left
kachilu-browser snapshot -i
Use this current-cursor click fallback only after visual confirmation. It is
useful for canvas-like controls, custom pointer handlers, and UI layers where
element-targeted clicks resolve the right element but the page still ignores the
click. Do not keep repeating the same ref click if the cursor is visibly on the
target and the page does not respond.
If refs keep invalidating, elements live inside an iframe, or a rich text
editor ignores DOM-oriented input, switch to the visible GUI path instead of
repeating the same failing ref. Take an annotated screenshot, click the visible
control, use keyboard type at the current focus, then re-snapshot before
submitting.
CAPTCHA Workflow
When a site visibly presents or recognizes a CAPTCHA, always start with
kachilu-browser captcha check. Do not begin with eval, raw DOM clicks, or
the image path unless captcha check has already been attempted.
Direct kachilu-browser captcha ... access is available until 2026-05-31 as a
launch promotion. After that date, CAPTCHA workflows must be run through
kachilu-agent-cli, which supplies a backend-signed, session-bound capability
token used by the browser CLI.
Run captcha check first. Continue on checked; for v3_token_observed, continue the page's normal submit/result flow and verify the outcome; for v3_possible, perform the visible action that should trigger reCAPTCHA and check again. If the response is challenge_required, partial, or the challenge is clearly image-based, run captcha inspect-img --json, analyze the screenshot/crop fields, then click only selected tile centers with captcha check-img --point ... or --points .... Inspect again if the challenge changes or remains partial.
For checkbox CAPTCHAs, captcha check should be the first action every time.
For reCAPTCHA v2 image-grid CAPTCHAs, inspect the challenge crop only after
captcha check has escalated the flow, then select all matching tile centers.
Do not include the verify button in --points; captcha check-img clicks the
provided tiles with human-like movement and presses verify automatically when
all provided tile clicks complete and the challenge is still active.
For reCAPTCHA v3, there is usually no checkbox or image grid. The browser
daemon watches /recaptcha/api2/reload and /recaptcha/enterprise/reload
responses through CDP and reports v3_token_observed when the page obtains a
recent token. Do not describe this as solving a visible challenge; it is only
observing a token that the page acquired normally.
Waiting (read this)
Agents fail more often from bad waits than from bad selectors. Pick the
right wait for the situation:
kachilu-browser wait @e1
kachilu-browser wait 2000
kachilu-browser wait --text "Success"
kachilu-browser wait --url "**/dashboard"
kachilu-browser wait --load networkidle
kachilu-browser wait --load domcontentloaded
kachilu-browser wait --fn "window.myApp.ready === true"
After any page-changing action, pick one:
- Wait for a specific element you expect to appear:
wait @ref or wait --text "...".
- Wait for URL change:
wait --url "**/new-page".
- Wait for network idle (catch-all for SPA navigation):
wait --load networkidle.
Avoid bare wait 2000 except when debugging — it makes scripts slow and
flaky. Timeouts default to 25 seconds.
Common workflows
Log in
kachilu-browser open https://app.example.com/login
kachilu-browser snapshot -i
kachilu-browser fill @e3 "user@example.com"
kachilu-browser fill @e4 "hunter2"
kachilu-browser click @e5
kachilu-browser wait --url "**/dashboard"
kachilu-browser snapshot -i
Credentials in shell history are a leak. For anything sensitive, use the
auth vault (see references/authentication.md):
kachilu-browser auth save my-app --url https://app.example.com/login \
--username user@example.com --password-stdin
kachilu-browser auth login my-app
Persist session across runs
kachilu-browser state save ./auth.json
kachilu-browser --state ./auth.json open https://app.example.com
Or use --session-name for auto-save/restore:
KACHILU_BROWSER_SESSION_NAME=my-app kachilu-browser open https://app.example.com
Extract data
kachilu-browser snapshot -i --json > page.json
kachilu-browser snapshot -i
kachilu-browser get text @e5
kachilu-browser get attr @e10 href
cat <<'EOF' | kachilu-browser eval --stdin
const rows = document.querySelectorAll("table tbody tr");
Array.from(rows).map(r => ({
name: r.cells[0].innerText,
price: r.cells[1].innerText,
}));
EOF
Prefer eval --stdin (heredoc) or eval -b <base64> for any JS with
quotes or special characters. Inline kachilu-browser eval "..." works
only for simple expressions.
Screenshot
kachilu-browser screenshot
kachilu-browser screenshot page.png
kachilu-browser screenshot --full full.png
kachilu-browser screenshot --annotate map.png
--annotate is designed for multimodal models: each label [N] maps to ref
@eN. Use it when the page has unlabeled icon buttons, visual-only elements,
canvas/chart surfaces, or when spatial reasoning is more reliable than text
snapshots.
Handle multiple pages via tabs
kachilu-browser tab
kachilu-browser tab new https://docs...
kachilu-browser tab t2
kachilu-browser tab close t2
Stable tabIds mean tab t2 points at the same tab across commands even
when other tabs open or close. After switching, refs from a prior snapshot
on a different tab no longer apply — re-snapshot.
Run multiple browsers in parallel
Each --session <name> is an isolated browser with its own cookies, tabs,
and refs. Useful for testing multi-user flows or parallel scraping:
kachilu-browser --session a open https://app.example.com
kachilu-browser --session b open https://app.example.com
kachilu-browser --session a fill @e1 "alice@test.com"
kachilu-browser --session b fill @e1 "bob@test.com"
KACHILU_BROWSER_SESSION=myapp sets the default session for the current
shell.
Mock network requests
kachilu-browser network route "**/api/users" --body '{"users":[]}'
kachilu-browser network route "**/analytics" --abort
kachilu-browser network requests
kachilu-browser network har start
kachilu-browser network har stop /tmp/trace.har
Record a video of the workflow
kachilu-browser record start demo.webm
kachilu-browser open https://example.com
kachilu-browser snapshot -i
kachilu-browser click @e3
kachilu-browser record stop
See references/video-recording.md for
codec options, GIF export, and more.
Iframes
Iframes are auto-inlined in the snapshot — their refs work transparently:
kachilu-browser snapshot -i
kachilu-browser fill @e4 "4111111111111111"
kachilu-browser click @e5
To scope a snapshot to an iframe (for focus or deep nesting):
kachilu-browser frame @e3
kachilu-browser snapshot -i
kachilu-browser frame main
Dialogs
alert and beforeunload are auto-accepted so agents never block. For
confirm and prompt:
kachilu-browser dialog status
kachilu-browser dialog accept
kachilu-browser dialog accept "text"
kachilu-browser dialog dismiss
Diagnosing install issues
If a command fails unexpectedly (Unknown command, Failed to connect,
stale daemons, version mismatches after upgrade, missing Chrome, etc.)
run doctor before anything else:
kachilu-browser doctor
kachilu-browser doctor --offline --quick
kachilu-browser doctor --fix
kachilu-browser doctor --json
doctor auto-cleans stale socket/pid/version sidecar files on every run.
Destructive actions require --fix. Exit code is 0 if all checks pass
(warnings OK), 1 if any fail.
Troubleshooting
"Ref not found" / "Element not found: @eN"
Page changed since the snapshot. Run kachilu-browser snapshot -i again,
then use the new refs.
Element exists in the DOM but not in the snapshot
It's probably off-screen or not yet rendered. Try:
kachilu-browser scroll down 1000
kachilu-browser snapshot -i
kachilu-browser wait --text "..."
kachilu-browser snapshot -i
Click does nothing / overlay swallows the click
Some modals and cookie banners block other clicks. Snapshot, find the
dismiss/close button, click it, then re-snapshot.
If no blocker is visible and the cursor is already on the intended button, take
a screenshot/capture to confirm the cursor placement. When it is on target,
click at the current cursor position with mouse down left then mouse up left, and re-snapshot to verify the page changed.
Fill / type doesn't work
Some custom input components intercept key events. Try:
kachilu-browser focus @e1
kachilu-browser keyboard type "text"
Page needs JS you can't get right in one shot
Use eval --stdin with a heredoc instead of inline:
cat <<'EOF' | kachilu-browser eval --stdin
// Complex script with quotes, backticks, whatever
document.querySelectorAll('[data-id]').length
EOF
Cross-origin iframe not accessible
Cross-origin iframes that block accessibility tree access are silently
skipped. Use frame "#iframe" to switch into them explicitly if the
parent opts in, otherwise the iframe's contents aren't available via
snapshot — fall back to eval in the iframe's origin or use the
--headers flag to satisfy CORS.
Authentication expires mid-workflow
Use --session-name <name> or state save/state load so your session
survives browser restarts. See references/session-management.md
and references/authentication.md.
Global flags worth knowing
--session <name>
--json
--headed
--auto-connect
--cdp <port|url>
--profile <name|path>
--headers <json>
--proxy <url>
--state <path>
--session-name <name>
Configuration can also live in kachilu-browser.json. Priority is:
~/.kachilu-browser/config.json < ./kachilu-browser.json < environment
variables < CLI flags. Use --config <path> or KACHILU_BROWSER_CONFIG for a custom config file.
Skill scope
The release package ships a thin discovery skill plus the core runtime
skill. Use the normal snapshot-ref workflow here for browser automation, and
rely on other installed tools or project instructions for workflows outside web
pages.
Full reference
The core skill above is enough for most tasks. When you need the complete
command/flag/env listing, supporting references, or starter scripts, load the
full bundle:
kachilu-browser skills get core --full