Cereon Browser Operator
An open, self-hosted browser-control layer: a Manifest V3 extension that drives a real, logged-in browser over the Chrome DevTools Protocol — from any model, or none.
drives a real, logged-in browser — not a headless sim
browser tools (+4 reserved), one open protocol
actions in the unified computer tool
self-hosted, bring your own model
The problem
An agent with a browser is a liability unless its blast radius is bounded. The real risk isn't one bad URL — it's the agent reaching into your live, logged-in tabs. That boundary has to be structural, enforced by construction, not a list of sites you hope covers every case.
A Manifest V3 browser extension plus a small MCP bridge that let an AI agent operate a real, logged-in Chrome tab over the Chrome DevTools Protocol: navigate, click, type, read the page, run JavaScript, inspect the console and the network. It is model-agnostic — drive it from any MCP client or a thirty-line backend loop, with Claude, GPT, a local model, or no model at all — and embeddable, so you can white-label it inside your own product. MIT-licensed, and proof that the discipline generalizes beyond one codebase.
// Every tab-targeting tool runs this guard first. The boundary is
// structural: the agent can only ever act inside the dedicated
// automation tab group — never your real, logged-in tabs.
async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult> {
const tabId = Number(args.tabId)
if (!Number.isInteger(tabId)) return text("tabId is required and must be a number.")
if (!(await ctx.tabGroup.isInGroup(tabId))) {
return text(`Tab ${tabId} is not in the MCP group.`) // refuses, doesn't trust
}
return this.run(tabId, args, ctx)
}What it does
Real browser control
Navigate, click, type, scroll and screenshot a real Chrome tab over the Chrome DevTools Protocol — not a headless simulation.
Reads pages like an agent
An accessibility-tree read and a plain-text read give a model a clean, structured view of the page instead of raw HTML.
Natural-language find
Ask for the search box or the submit button in plain English and get back the element to act on — no brittle CSS selectors.
Fills forms and uploads files
Set inputs, selects and checkboxes, and attach files, so an agent can complete real workflows end to end.
Inspects what happened
Capture console messages and network requests to see why a page behaved the way it did — debugging an agent can read.
Model-agnostic by protocol
Plug in any LLM through an MCP client, or drive it from a short backend loop. No vendor, no cloud dependency, no subscription.
What we built
- Fourteen typed tools (plus four reserved) over one protocol — navigate, a thirteen-action computer tool, accessibility-tree and plain-text reads, natural-language find, form input, JavaScript eval, and console/network capture.
- Model-agnostic by design — driven from any MCP client (Claude Desktop, Cursor, Claude Code) or a ~30-line backend loop against any LLM, hosted or local.
- Security by construction — every tab-targeting tool refuses to run unless the target tab sits inside a dedicated automation group, so your normal tabs are off-limits.
- The same discipline as the CRM — zod-validated tool arguments, unit-tested pure logic (parsers, transports, config), and one structured { id, tool, args } → { commandId, result } contract over WebSocket or SSE.
Stack
- TypeScript
- Manifest V3 extension
- Chrome DevTools Protocol
- Model Context Protocol
- Zod
- esbuild
How it works
- 01
Connect
The extension links to your backend — or the bundled MCP server — over WebSocket or SSE, and authenticates with a token you control.
- 02
Scope
tabs_context opens or adopts the dedicated automation tab group and hands back the tab id every tool must target.
- 03
Act
Your model sends a { tool, args } command; the extension drives the page over CDP and returns a structured result.
- 04
Stay bounded
Any tool aimed at a tab outside the automation group is refused — the blast radius is fixed by construction.
That the secure-MCP discipline isn't tied to one codebase. A hard tool boundary, enforced by construction rather than trust, holds up in a completely different runtime — the browser.