Browse a web page
Job: you need the content of a public page (or a short chain of pages) without dumping raw HTML into the prompt. Use browse. It fetches the page, defaults to markdown, and turns further bash_exec calls into a small REPL until you quit or park.
Same network policy as curl (allow-list / full-internet flag). Private and reserved IPs (including localhost) are always blocked. Form submit and click do not run page JavaScript.
Skill source of truth: /skills/browse.md.
Done looks like
browse https://example.com -- 'links; go 0; show; quit'
Stdout opens the URL (status 200), lists numbered links (0-based), follows link 0, prints the next page as markdown, then returns you to normal bash. There is no active browse session afterward.
Worked example: open, list links, follow one
browse https://example.com -- 'status; links; go 0; show; quit'
Expected shape (titles and link counts can change):
- Open line:
browse: https://example.com/ (200)withformat: markdownandlinks: 1. statusrepeats URL, title, format, and counts.linksprints0. Learn more — https://iana.org/help/example-domains(indexes start at 0).go 0loads that URL.go 1errors withlink 1 out of range (0-0)when there is only one link.showprints the markdown body (truncated by output limits).quitends the session.browse statusthen reportsno active session.
Interactive REPL (several bash_exec calls)
browse https://example.com
# next bash_exec calls are browse verbs until quit/park:
links
go 0
show
quit
Batch verbs in one call with newlines or ; (quote fill values that contain ;):
status; links; show
One-shot script on open
Quote the script so bash does not split on ;:
browse https://example.com -- 'links; go 0; show; quit'
Forms (no JavaScript)
browse https://example.com/login -- 'forms; form 0; fill email=ada@example.com password=secret; submit; show; quit'
forms lists forms. form N selects one (0-based) and shows fields. fill k=v … sets values. submit / submit N posts or gets per the form method. A click N that only works via JS returns a clear error.
Park and resume (in memory)
Park keeps HTML, markdown, forms, history, and format on the MCP tenant. Not written to disk. No cookie jar. Lost if the tenant session is evicted.
browse https://example.com
park docs
browse jobs # or: browse ls
browse resume docs # or: browse fg docs
show
quit
browse drop docs # discard a parked session without resuming
Starting browse <url> while another session is active auto-parks the current one.
CLI (verified)
browse <url>
browse <url> -- <script>
browse status
browse jobs | browse ls
browse resume [id|name] | browse fg [id|name]
browse drop <id|name>
While a session is active, bash_exec is the browse REPL:
| Command | Meaning |
|---|---|
show | Current page body in the active format |
format md / format html | Sticky view mode (markdown also accepted) |
links | Numbered outbound links (0-based) |
go <url|N> | Navigate to a URL, or follow link N (open N still works) |
back | Previous page in history |
forms / form N | List forms / select form N and show fields |
fill k=v … | Set field values on the selected form |
submit / submit N | Submit form |
buttons / click N | List controls / activate button N (clickables alias) |
park [name] / bg [name] | Background this session; return to bash |
status | URL, title, format, counts (+ parked list from outer browse status) |
quit | End the active session (parked ones stay) |
Successful replies often end with a next: line suggesting follow-ups.
Notes that bite agents
- Default view is markdown (HTML→markdown; script/style stripped). Use
format htmlwhen attributes or structure matter. - Pages served as
text/markdownortext/plainopen as text.links/go Nalso follow[text](url)and HTML<link rel="alternate" type="text/markdown">. - Batch scripts stop on the first failing statement. Failed
go/submitleave you on the previous page; the error says the REPL is still active. Typequitorparkto return to bash. - An unknown verb such as
curlis a browse error, not a missing shell command. - REPL priority:
debugwins overbrowse;browsewins overlogs. browseis a workspace command. There is no separatesailsshell binary required in the agent environment.
Failure modes
| What you see | What it means | What to do |
|---|---|---|
| Network / allow-list error | Host not allowed, or private IP | Use a public host on the allow-list, or the full-internet flag your workspace already uses for curl |
link N out of range (0-M) | Indexes are 0-based | Run links, then go 0 … go M |
session still active after a failed script | REPL did not close | Send quit or park as the next bash_exec |
| Click / submit needs JS | Control is client-side only | Use a real form submit, or fetch an API the page calls |
| Parked session missing | Tenant session was evicted | Open the URL again; park is in-memory only |
browse: no active session but parked sessions listed | You quit and left parks | browse resume N or browse drop N |
Related
- Outbound shell to a real host: SSH to a host
- Fetching bytes into the workspace: Send a file (
transfer) - Skill:
/skills/browse.md