Start here
Add the browser extension
A side panel in Chrome or Firefox. Speak to it, type at it, or press record and show it once. This is Browsentic.
MIT licensed, and it runs on the agent CLI you already pay for: Claude Code, Codex or Antigravity
No new browser. No new subscription. Hand any tab to the AI agent you already run: it senses what is on the page, works out what you asked for, and carries the job through in the session you are already signed in to. Anything you would otherwise do by hand, it can automate for you.
Chrome or Firefox · or open the side panel and speak it aloud
Start here
A side panel in Chrome or Firefox. Speak to it, type at it, or press record and show it once. This is Browsentic.
Or wire it in
The same paired browser, driven from Claude Code, Codex, Cursor or Zed. One command, and your agent has a tab that is already logged in.
claude mcp add browsentic -- browsentic-mcp
41
page tools
read, act, navigate, wait
3
read-only resources
page context, zero tool calls
0
API keys to configure
it runs on the login you already own
10 min
pairing code lifetime
single use, then a session key
Architecture
No relay, no hosted runner, no browser in someone else’s data centre. The extension dials out to a daemon on loopback, because a Manifest V3 service worker cannot listen for connections. One daemon owns the browser link, so several MCP clients can share one browser.
Speak, type, or show it once
Dictate hands-free in the side panel, hold to talk in the popup, or just type. Work through a tedious job yourself once and it keeps every step.
Manifest V3, Chrome & Firefox
Weighs your instruction against a local grammar before anyone spends a token. Confident one-step commands fire right here, in milliseconds. Everything else travels on untouched.
Local WebSocket, loopback only
The extension dials out, because an MV3 service worker cannot listen. One daemon owns the browser link, so several MCP clients can share one browser.
claude, codex or agy
Reasons locally, spawned against the login you already have. Claude Code, Codex or Antigravity, switched with one click. No API client in the repository, no key to configure, no third-party relay.
Capabilities
Perceiving the page as structure rather than pixels, acting with a human hand, and remembering enough to run the whole thing again unprompted.
Takes in the page as structure rather than pixels: a snapshot carrying a layout diagram and stable selectors, rendered text, patient waiting for an element to appear or vanish, the search control wherever a site hid it, a capture of the whole tab or one element, the palette and luminance a page actually paints, a WCAG contrast score, and the captcha hiding inside a closed shadow root. When it cannot name the thing you mean, it hands you the lens and you point at it.
page_getPageInfopage_extractTextpage_waitForElementpage_findProgress+6
Reaches into the page with a human hand. Pointing, hovering, dragging, focusing, filling inputs and contenteditables, streaming text in keystroke by keystroke at a human pace, choosing an option, selecting a passage, pressing keys with modifiers, committing a form, clicking with a genuine browser-level gesture where a synthetic one is refused, ticking a captcha checkbox, and retheming a page on its own terms.
page_clickElementpage_trustedClickpage_hoverElementpage_dragElement+10
Finds its own way around. Opening a URL, retracing back and forward, reloading, searching a site on its own terms rather than guessing at query strings, scrolling to whatever matters, spawning a tab, surveying the ones you already have open, closing the ones it is finished with.
page_navigatepage_searchSitepage_scrollTopage_openTab+2
Senses the progress signals a page gives off, then keeps watch in the background while an upload, a build or a deploy runs its course: the tab stays pinned, percent and ETA are tracked, and an MCP client can long-poll until it lands. When a page offers nothing to watch, it works to a clock instead, waking itself in ten minutes or every two to redo the check and tell you only what changed.
page_startMonitorpage_monitorStatuspage_awaitMonitorpage_stopMonitor+3
Reaches for the files you keep in Browsentic and hands one to a file input on the page, so an upload flow stops waiting on a human at the file picker.
page_listFilespage_attachFile
Recalls the sessions you recorded and replays them as ordered, deliberate steps, re-checking every target against the live page before it commits to acting.
page_listRecordingspage_readRecording
page_getPageInfo
page_extractText
page_waitForElement
page_findProgress
page_findSearch
page_pickElement
page_screenshot
page_readTheme
page_auditContrast
page_findCaptcha
page_clickElement
page_trustedClick
page_hoverElement
page_dragElement
page_focusInput
page_fillInput
page_typeText
page_selectOption
page_selectText
page_pressKey
page_submitForm
page_solveCaptcha
page_applyTheme
page_highlightElement
page_navigate
page_searchSite
page_scrollTo
page_openTab
page_switchTab
page_closeTab
page_startMonitor
page_monitorStatus
page_awaitMonitor
page_stopMonitor
page_startTimer
page_timerStatus
page_stopTimer
page_listFiles
page_attachFile
page_listRecordings
page_readRecording
page_getPageInfo
page_extractText
page_waitForElement
page_findProgress
page_findSearch
page_pickElement
page_screenshot
page_readTheme
page_auditContrast
page_findCaptcha
page_clickElement
page_trustedClick
page_hoverElement
page_dragElement
page_focusInput
page_fillInput
page_typeText
page_selectOption
page_selectText
page_pressKey
page_submitForm
page_solveCaptcha
page_applyTheme
page_highlightElement
page_navigate
page_searchSite
page_scrollTo
page_openTab
page_switchTab
page_closeTab
page_startMonitor
page_monitorStatus
page_awaitMonitor
page_stopMonitor
page_startTimer
page_timerStatus
page_stopTimer
page_listFiles
page_attachFile
page_listRecordings
page_readRecording
Agent orchestration
A conversation belongs to the tab it started in, not to whatever you happen to be looking at. Start one where an upload is running, another where support is waiting on an answer, a third watching a release, then go and read something else. The extension holds each session in its own tab and dials out to a single local daemon, which wakes one agent per session and streams the work back to the panel as it happens.
claude
codex
claude
agy
In practice
Ordinary browsing work, in sites you are already signed in to: the negotiation, the application, the cancellation, the thing you redo every Friday. The agent senses what is in front of it, works out what the job needs and sees it through. Anything that commits something, or sends it to someone other than you, pauses first and names itself before it happens.
Your account, your ticket history, last year’s invoice open in the next tab. It takes in what support actually said, weighs it against what you paid before, drafts the counteroffer in your own words, and holds right at the moment it would reach them.
Pauses at Send, under the form-submission rule
Point it at a billing page and it works out where the cancellation actually lives, sees the retention offer for what it is, answers the exit survey and comes to a halt in front of the one step that cannot be undone. The consequence is the last step, so that is the step you keep for yourself.
Name page_clickElement in requireApproval and the final step asks first
Start the upload, the build or the export, then hand the tab over. It senses the progress a page gives off, keeps percent and ETA in view from the background, and tells you the moment it lands. Nobody has to sit watching a bar that moves once a minute.
Nothing to approve. It is only watching
Show it once, with the recorder on. Browsentic keeps ordered steps named after what you accomplished, and whatever you typed comes back as a placeholder it asks you for. Next Friday the whole instruction is “do it like last time”.
Replay is a plan, not a script. A step that no longer lands halts the run
Five tools you are logged into, one summary. It takes each one in as rendered text, the way it appears to you, rather than scraping markup full of hidden nodes and off-screen strings that never met your eyes.
Raw HTML reads are denied by default, hidden text with them
The same twelve fields across forty rows: the job nobody schedules and everybody postpones. It works each record through, checks what came back against what it expected, and moves on, stopping the moment a page stops resembling the one before it.
Asks each time it commits one, until you grant Always on this host
Skills
Turn it loose on a site and it maps itself. It reads robots.txt and the sitemap, explores, screenshots, writes down what it worked out, then hands you a skill to read before you arm it. Walk it through a job once and that becomes a skill of your own. And the obvious commands never bother a model at all.
Automated site discovery
An agent that has never seen your site burns its first minutes rediscovering it: where search lives, what a button is really called, why the list looks empty until you scroll. So let it learn the place once. Browsentic reads the site’s own robots.txt and sitemap.xml, looks up public background on the domain, then explores for a few minutes, screenshotting as it goes. From then on every instruction on that domain arrives already knowing its way around. Elsewhere those notes stay inert.
@site-mapper map this site
A map in flight is written to a staging directory the skill loader cannot read. An unreviewed map is not merely unused, it is never opened.
The panel shows it as plain text, never rendered, alongside the domain it will match. Activate arms it, Discard deletes it.
It cannot click, fill or submit, cannot leave the site, and stays pinned to the tab it started in. Switching tabs stops it rather than following you.
15 pages, 10 screenshots and 10 minutes by default; 40, 24 and 30 minutes are the hard limits enforced by the daemon.
Record once, replay later
Press record in the composer, then work through the job yourself. Click across the pages, fill the fields, submit the form, press stop. Browsentic breaks what you did into ordered steps, names each one after what you accomplished, and keeps them in a list you can rename. That is a browsing skill of your own making. From then on, “do it like last time” is the whole instruction.
record my browsing session
Every field you fill becomes a placeholder ({{email}}, {{invoice_number}}) and the assistant asks you for the value when it replays.
Passwords, hidden fields, one-time codes and anything shaped like a card number are dropped whether or not you opt in to literal values.
The steps are a plan, not a script. The agent re-checks each target against the live page and prefers the visible text it recorded over the CSS selector, because selectors are what a redesign breaks first.
If a step no longer lands, the run halts and tells you which one, instead of finding a different route to the same effect.
Local intent classification
So every instruction is scored against a local grammar first. Confident single-step commands run in the browser and stop there, marked with a bolt on the timeline. Everything else goes to the agent with the text untouched. The bias is deliberately toward escalating, because the two mistakes are not symmetric: escalating something it could have handled costs a round trip, while acting on something it misread spends a wrong click on your real page.
yarn check:intent "take me to the checkout page"
back, forward, reload · open github.com · scroll to the top · press enter · click Sign in · google something · stop recording
“is there a login button?” · “open the settings menu” · “click Buy now” · “scroll down and tell me what it says” · “click it”
So do multi-step asks, conditionals, vague targets and consequential clicks, as does any local command that runs and fails.
Route one utterance through the grammar from the command line and see exactly why it went where it went.
MCP server
Claude Code, Codex, Antigravity, Cursor, Zed: anything fluent in MCP takes the wheel of the same real tab. Headless automation wakes up with amnesia, no session, no cookies, no two-factor state, and a login wall between it and anything worth doing. Browsentic inherits the tab you are already signed into.
The daemon speaks MCP over stdio, so Claude Code, Codex, Antigravity or anything else that speaks the protocol drives the same real, logged-in browser. Several at once, because one daemon owns the link.
Tool definitions are generated from the same registry the extension ships. A tool that describes something the browser cannot do is not a bug you can write. It is a build that does not exist.
A module under lib/actions/page/ plus one line in the registry, and it publishes as an MCP tool at the same time. No second place to remember.
browsentic://page/diagramLayout diagram with stable selectorsbrowsentic://page/currentStructured snapshot of the active tabbrowsentic://page/textRendered text, as a reader would see itSecurity model
Everything below is a property of how it is built, not a promise in a policy document. It is a local daemon, an extension that dials out to it, and no third party in between.
A fresh install connects to nothing. An unpaired extension never contacts the daemon at all, and pairing takes a single-use code you redeem yourself.
Any web page can open a WebSocket to loopback, so the daemon first classifies the peer by handshake Origin, which browsers set themselves and pages cannot forge, then requires a pairing token or a session key bound to that same origin. A web page can never reach the control path.
Approval prompts appear in the side panel with the action named. Form submission is gated by default, because it is the one effect that reaches someone other than you. Cancelling a run stops it mid-flight.
A recording stores the identity of each field and a placeholder for its value. Keeping literal values is per-recording and off by default. Recording only ever starts from your own click or your own words.
No model is bundled and nothing is downloaded. Chrome’s Web Speech API streams audio to Google to transcribe it, and replacing the speech engine is a one-file change.
Pairing keys, logs, config, skills and screenshots live under ~/.browsentic and ~/browsentic. Never in your checkout, never in a commit.
Pairing controls which browser, not which process
Anything running as your user can read the daemon lockfile and drive an already-paired browser.
A hostile page is still a hostile page
An agent reading one is susceptible to prompt injection. Treat page content as data, never as instructions.
Quickstart
You need Chrome or another Chromium browser, Node.js 20 or newer, and one agent CLI on your PATH: claude, codex or agy. Yarn is pinned inside the repository, so whichever yarn you have re-executes into the right one. There is no global install or Corepack setup.
The extension and the daemon are separate packages. One command installs and builds both. It needs nothing on your PATH but Node 20+, because the pinned Yarn release ships in the repository.
git clone https://github.com/imshaikot/browsentic.git
cd browsentic
node scripts/setup.mjs
Open chrome://extensions, enable Developer mode, choose Load unpacked and select the build output. Firefox builds work too.
dist/chrome-mv3
The pairing code is single-use and lives for ten minutes. Paste it into the popup and press Connect. The daemon then issues a long-lived session key that survives browser and daemon restarts, and dies only when you revoke it.
yarn mcp:link # global npm prefix, so it stays a separate step
browsentic-mcp pair # prints a single-use code, valid for 10 minutes
Your agent now commands 41 page tools plus browsentic_status, and three read-only resources that hand back page context without spending a tool call.
claude mcp add browsentic -- browsentic-mcp
FAQ
No. Browsentic runs on the agent CLI login you already have: Claude Code, Codex or Antigravity. There is no API client anywhere in the repository and nothing to paste into a settings field. The daemon spawns your chosen CLI locally, as you.
The opposite. It drives the real, logged-in tab in front of you: your sessions, your cookies, your extensions, your two-factor state. Nothing has to be re-authenticated in a throwaway profile.
Two gates. The daemon classifies every WebSocket peer by its handshake Origin, which the browser sets and a page cannot forge, and then still requires a pairing token or an origin-bound session key. A page fails the first gate and never reaches the second.
Yes. The daemon speaks MCP over stdio, so any MCP client drives the same browser: Codex, Antigravity, Cursor, Zed, Claude Desktop. Run claude mcp add browsentic -- browsentic-mcp, or the equivalent in your client. Tool definitions are generated from the same registry the extension ships, so they cannot drift from what the browser can actually do. The side panel is switchable too: it runs on Claude Code, Codex or Antigravity, picked from the popup with one click.
Yes. Every tab gets its own conversation, bound to the tab it started in, so a session carries on there while you look at something else instead of following whichever tab is in front. Eight sessions can be open and three work at once by default, raised as far as eight with maxConcurrentRuns. A fourth holds for a slot, ending one leaves the rest alone, and a tab another conversation has claimed answers TAB_IN_USE.
Free and MIT licensed. Nothing to sign up for, no key to paste, and a fresh install connects to nothing until you redeem a pairing code yourself.
claude mcp add browsentic -- browsentic-mcp