Browsa for Mac / Developers
Build for Browsa.
Everything runs inside WebKit, and everything is free. If you've made a browser extension, you already know most of it.
Chrome extensions Works today
From the Chrome Web Store, on Apple's WebKit with a compatibility layer in front. Seven are verified in the Library.
How they run →Browsa plugins Start building
A web extension with a browsa block that adds a sidebar section, a panel, commands, badges and agent tools.
Agents Works today
A local MCP server, so Claude Code, Codex or Cursor can use the browser you're watching, with page notes they can read and resolve.
Connect one →A plugin is an extension, plus a little more.
Add a browsa block to a normal Manifest V3 extension. Other browsers ignore it, so the same plugin still works anywhere else. Pick a part to see where it lands.
{ "manifest_version": 3, "name": "Deploy Watch", "background": { "service_worker": "bg.js" }, "browsa": { "sidebar": { "page": "sidebar.html" }, "panel": { "page": "panel.html" }, "commands": [{ "title": "Open the latest preview" }], "agentTools": [{ "name": "deploys_list" }], "badges": true } }
Start buildingBrowsa reads the browsa block today, and its own plugins (Notes, Agents, Radar, Downloads) already plug into the window this way. The runtime that lets your plugin do the same is still being built, so details may change. When it opens up, plugins will be listed in the Library next to ours, and they'll be free.
Talking to Browsa.
Plugins send native messages to a built-in host, app.browsa. Each part of the browsa block is a permission people see before they add it, and plugins never run native code.
runtime.sendNativeMessageapp.browsaChecks the plugin's permissionsbadge.setA count or dot on a tabcommands.registerRows in ⌘Kui.toastA short messagetabs.openOpen a page in a spaceagentTool.resultAnswer an agent's callnotes.listRead page notesLet agents use the real browser.
Switch on the Agent Pack in the Library, or press Turn On Agents in the Agents panel, and Browsa listens on 127.0.0.1 for MCP. Add to Claude Code sets it up in one click, token and all. For Codex, Cursor or anything else that speaks MCP over HTTP, Connect an Agent gives you the lines to paste.
tabs_listtab_openpage_navigatepage_readpage_screenshotpage_clickpage_typepage_evalnotes_listnotes_addnotes_replynotes_resolve
- Visible. Agents open pages in their own Agent space, with a yellow pointer and a caption on the page. Each call shows in the Agents panel as a sentence.
- Your tabs ask first. Anything in the Agent space runs without a prompt. Using one of your own tabs, or listing them, asks you until Browsa quits.
page_evalonly runs on localhost. - Stoppable. Stop, in the sidebar or the panel, refuses everything that changes a page until it's resumed.
- Local only. A bearer token is required, and requests carrying a web page's Origin are refused.
# What Add to Claude Code runs for you $ claude mcp add --scope user --transport http browsa \ http://127.0.0.1:47913/mcp \ --header "Authorization: Bearer <your token>" ✓ Added browsa > open localhost:3000 and check the sign-in form ● tab_open localhost:3000 ● page_read Sign in · 2 fields ● page_type email ● page_click Continue
How Chrome extensions run.
Browsa installs extensions from the Chrome Web Store on Apple's WKWebExtension, checks for updates once a day, and asks again when an update wants more permissions. A small compatibility layer goes in front of each one, without changing the extension's own files.
Filled in for you
WebSocketReal sockets in service workers, which WebKit would freezenavigator.locksLocks inside the workerchrome.offscreenHidden documents for copying and translatingKeep-aliveBackgrounds aren't paused or unloadedChrome APIsStand-ins for the ones WebKit lacks, so startup doesn't throwUser agentSays Chrome inside the extension onlyLimits to design around
- Desktop-app connections
- Unlocking with a password manager's desktop app needs that app to trust Browsa, and those helpers only trust a signed list of browsers. Extensions work on their own instead: 1Password signs in inside the extension.
- Stand-ins, not features
notifications,downloads, side panels andidentity.launchWebAuthFlowanswer but do nothing yet. Each can become a real Browsa feature when an extension needs it.- No API wrapping
- Wrapping
chrome.*in a JS Proxy stops runtime messages reaching the background, so missing APIs are added as plain objects. - Not supported
chrome.debugger, blockingwebRequestand DevTools panels.declarativeNetRequestworks.
Where it lives in the code.
Browsa is MIT licensed. The full write-up is docs/extensibility.md.
| Piece | Where |
|---|---|
| The Library and the verified list | Mac/Sources/Library/, docs/library.md |
| Store links, updates, CRX unpacking | Extensibility/ExtensionSources.swift |
| The Chrome compatibility layer | WebKitEngine/ExtensionCompat.swift |
Manifest and the browsa block | Extensibility/ExtensionManifest.swift |
| Tools: panel, sidebar, commands | Mac/Sources/Workbench/ |
| MCP toolbox | Extensibility/AgentToolbox.swift |
| Local endpoint and Agent space | Mac/Sources/Agents/ |
| Page notes | Extensibility/Margin.swift |