Research in your Chrome
web_fetch and web_browse see the public web as a logged-out stranger. The Chrome bridge lets the agent read pages in your browser instead, with your cookies and logins. It uses a small tsforge Chrome extension, and the agent’s tabs live in a “tsforge” tab group so you can always see which ones it is using.
Pair it with a local model and long research is free. Open a forum thread you’re logged into and say:
I've opened a forum thread in my active tab. Read the whole thread (every page) and save notes.The agent adopts the tab and reads it chunk by chunk, following “next page” and “show more replies”. It appends findings to notes/<topic>.md as it goes, then summarises.
Read and navigate only
Section titled “Read and navigate only”The extension enforces this itself. It does not rely on the agent behaving, because page text is written by strangers and may try to instruct the agent.
- Clickable: real links, pagination,
<summary>, and expanders (“Show 12 more replies”,aria-expandedtoggles). Nothing else gets a click number. - Never clickable: anything in a form, inputs, editable areas, submit buttons, download links, and non-http links. Short labels that name an action (Reply, Like, Post, Delete, Log out, Subscribe, Add to cart…) and GET links that look like actions (
/logout,?action=delete, CSRF tokens) are also refused. - The click policy runs again on the live element at click time. A page that swaps a link for a form button after the read gets refused.
- Links are followed by the extension (
tabs.update), not by page scripts, sotarget=_blankcan’t escape the group. - The agent may only act on tabs in the tsforge group. It can adopt one of your tabs only when that tab is active, or when you clicked the tsforge toolbar button on it.
- Only
http(s)pages. Private and loopback hosts (routers, intranet, the bridge itself) are blocked unless you setTSFORGE_BROWSER_ALLOW_PRIVATE=1. - There are no typing, posting or form-filling tools.
Remaining risk: injected text could still ask the agent to open a URL that carries something it read. Other tabs are unreadable unless you share them, which limits this, but review what a research session did if the pages were hostile.
-
Build the extension (from a tsforge checkout):
Terminal window bun run --cwd packages/chrome-extension build -
Open
chrome://extensions, turn on Developer mode, click Load unpacked, and pickpackages/chrome-extension/dist. The extension ID is fixed, so tsforge recognises it on any machine. -
Start tsforge with the bridge on, or flip Chrome browser in
/config:Terminal window TSFORGE_BROWSER=1 tsforge # once; or set "browser": true in ~/.tsforge/config.json (or toggle it in /config) and it sticksThe boot chip reads
browser · waiting for the Chrome extension. -
Run
/browser. It prints the pairing token, which is stored in~/.tsforge/browser-token. Paste it into the extension’s options page (it opens on install) and save. The chip and/browserswitch to connected within a few seconds.
The extension reconnects by itself whenever tsforge starts, and keeps retrying (with backoff) while tsforge isn’t running.
The tools
Section titled “The tools”| Tool | What it does |
|---|---|
browser_tabs | list your tabs: which are in the tsforge group, which is active |
browser_adopt | move your tab (active or shared) into the group |
browser_open / browser_navigate | open a URL in a new group tab / load one (or go back) |
browser_read | the page as markdown in ~6000-char chunks (chunk 2/7), with inline refs like [12 link: text](url) and [13 expand: Show more] |
browser_click | click a ref from the last read: follow a link, next page, expand replies |
browser_scroll | scroll (down, page, bottom) for infinite-scroll pages |
browser_screenshot | save a PNG for read_image (only with a vision backend) |
browser_close | close a tab tsforge opened; your adopted tabs are only released |
note | append timestamped notes to notes/<topic>.md (append-only) |
browser_read picks between an article view and the whole page on its own. It falls back to the whole page when the article extractor would drop most of the text, which is what happens with forum replies.
Long runs
Section titled “Long runs”Research sessions are meant to run for hours, so a single model hiccup doesn’t end them:
- Repetition loops. The retry is forced to make a tool call, at a higher temperature, and the repeated lines are removed from the history first. The loop budget counts only consecutive loops and starts over whenever a tool call succeeds. If three loops in a row get through, the context is compacted and tried once more before the session stops.
- “Let me record it.” with no tool call. When there’s no gate, a reply that announces its next step without taking it gets a nudge to make the call. It is not treated as the final answer.
- Compaction. The summary request is bounded. If it still fails, your requests are kept verbatim and the older tool output is dropped, so the context always shrinks.
- No turn cap. Without a live gate a single message can run for days. Gated builds keep the 1000-turn backstop.
TSFORGE_MAX_TURNSsets a cap anyway, or0for unlimited everywhere. - Saved as it goes. The session is saved every 40 turns, not only when a message finishes, so
--continuepicks up close to where a crash or reboot stopped it. - Data files.
appendadds records to a data file (.jsonl, CSV, logs) without an edit anchor. JSONL lines are checked, so a malformed record never gets written. Code and config files are refused. - No TypeScript rules on prose. The streaming TypeScript rules (like “no
ascast”) stay off until the workspace has code.
Site plugins
Section titled “Site plugins”For some sites tsforge knows a better way than reading rendered pages: it reads the site’s own structured data through your logged-in tab. Plugins are built in and reviewed like any other tsforge code. Reddit is the first.
They rely on one extra extension capability, page.fetch: a same-origin GET made from a tsforge tab, allowed only for hosts compiled into the extension. When you update tsforge, rebuild the extension and reload it in chrome://extensions. /browser shows outdated until the two versions match.
One browser, one session
Section titled “One browser, one session”The bridge listens on 127.0.0.1:47823. Only the first tsforge process gets the port. A second session shows port 47823 in use and offers no browser tools. Set TSFORGE_BROWSER_PORT (and the same port in the extension options) to run one elsewhere.
| Env var | Default | Effect |
|---|---|---|
TSFORGE_BROWSER | off | start the bridge and offer the browser tools (=1) |
TSFORGE_BROWSER_PORT | 47823 | bridge port (1024–65535) |
TSFORGE_BROWSER_ALLOW_PRIVATE | off | let the browser tools open private/loopback hosts (=1) |
The browser tools are classified as network by the policy. They are allowed while planning (they can’t change your workspace) and denied in modes that deny network. note counts as a file edit, so it is withheld in plan mode.