tablaze
<p align="center">
<a href="https://tablaze-browser-mcp.isdiandian0825.chatgpt.site">
<img src="docs/assets/tablaze-banner.svg" alt="Tablaze — a compact browser MCP. Observe. Act. Verify." width="100%">
</a>
</p>
<p align="center">
<strong><a href="https://tablaze-browser-mcp.isdiandian0825.chatgpt.site">Website ↗</a></strong> ·
<a href="https://tablaze-browser-mcp.isdiandian0825.chatgpt.site#demo">Watch the demo</a> ·
<a href="docs/CODEX.md">Codex guide</a> ·
<a href="README.zh-CN.md">简体中文</a>
</p>
<p align="center">
<a href="https://github.com/SweetDianDian/tablaze/actions/workflows/ci.yml"><img src="https://github.com/SweetDianDian/tablaze/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-b7db9a?style=flat-square" alt="MIT license"></a>
<a href="package.json"><img src="https://img.shields.io/badge/node-%E2%89%A520-80b7ff?style=flat-square" alt="Node.js 20 or later"></a>
</p>
**Give your agent a browser it can work with.** Tablaze connects Codex and other MCP clients to Chromium through seventeen focused tools. Inspect a page, fill a form, extract a result, and check that the task actually succeeded.
Built with Playwright. Browser sessions stay running between calls; your MCP client supplies the reasoning. The MCP browser tools require no additional model API key. The optional standalone Agent loop uses an explicitly configured planner.
## See it work
**[Watch the complete demo — about 2 minutes →](https://tablaze-browser-mcp.isdiandian0825.chatgpt.site#demo)**
A real MCP SDK client completes one travel workflow: six form actions in one batch, five result checks, then a changed approval button. The stale reference is rejected with no approval or order; a fresh snapshot lets the workflow continue through an explicitly followed popup, four approval actions and three receipt checks. Finally, the recorder verifies the downloaded CSV's bytes and SHA-256, closes both owned tabs and confirms zero remaining sessions.
[](https://tablaze-browser-mcp.isdiandian0825.chatgpt.site#demo)
`Batch the form` → `Verify` → `Stop and re-observe` → `Approve in the popup` → `Check the file`
The 154-second recording presents actual tool responses and screenshots with conversational English male narration and optional captions. It contains no simulated cursor. A deterministic SDK script drives the local fixture; no model inference is involved. It is a presentation recording, not a continuous video feed from the controlled tab.
[Reproduce the recording](demo/README.md) · [Inspect the full trace](docs/evidence/demo-run.json)
## Measured development results
The [third matched Codex run](docs/CODEX_COMPARISON_RESULTS_V3.md) used five visible development tasks, one attempt per engine and task. Both engines passed independent business checks **5/5**; Tablaze returned complete success **4/5**, Browser Use **5/5**. Tablaze's order task was interrupted by the old inference bridge after the order was recorded. Its failed call had no usage data, so total tokens remain unknown.
A [separate order follow-up after the bridge fix](docs/CODEX_TERMINAL_FOLLOWUP.md) completed successfully for both engines, each creating one order with no duplicate write:
| Follow-up measurement | Tablaze | Browser Use |
| --- | ---: | ---: |
| Agent reported completion | 59.247 s | 75.354 s |
| End-to-end time | 59.415 s | 93.706 s |
| Model calls, including judging | 4 | 4 (1 judge) |
| Input / output tokens | 59,123 / 664 | 70,868 / 1,002 |
Browser Use's default judge is included in its totals. Agent and end-to-end clocks have different starting boundaries. This single follow-up does not replace the original 4/5 result, and these small, visible samples do not establish overall superiority. Both reports retain raw results, source hashes, settings, and limitations.
A [new four-task matched development smoke](docs/CODEX_CURRENT_FOUR_SMOKE.md) tested iframe input, interrupted-response order recovery, a virtual list and a visual canvas. Both engines completed all four with independent business acceptance; Tablaze's iframe sample was slower (83.799 s versus 52.515 s), while its other three whole-run samples were shorter. Each task ran once per engine, so this does not prove stable efficiency or overall superiority.
The initial iframe observation gives newly attached child frames a bounded readiness wait. When the main page has no controls and exactly one visible child frame contains a form field, the first `tab_open` returns actionable child refs without another snapshot call; a real-Chrome regression fills and submits a delayed child form from those refs. In a [six-pair matched Codex follow-up](docs/CODEX_IFRAME_DIRECT_OPEN_SMOKE.md), both sides passed 6/6 with zero duplicate writes and all Tablaze runs skipped the extra frame snapshot. Tablaze's visible median whole-run time was 34.128 versus Browser Use's 57.526 s, while Agent-done time was 33.973 versus 39.778 s; Browser Use's judge is included only in whole-run time. One fixture does not establish stable speed or overall superiority.
In the [three-pair post-fix iframe follow-up](docs/CODEX_IFRAME_READINESS_SMOKE.md), both engines passed every independent business check, but Tablaze's visible median whole time was 79.699 s versus Browser Use's 56.040 s. Two Tablaze runs spent extra model rounds recovering from an unnecessary text check of an input value; efficiency parity remains unproven.
Action feedback now retains the operated child frame after such a failed post-check, allowing the next decision to inspect the right page without another frame-switch snapshot. In a [fresh three-pair matched follow-up](docs/CODEX_IFRAME_FEEDBACK_SMOKE.md), both sides passed 3/3 with no duplicate writes. Tablaze's median whole-run time was 46.037 s versus 56.132 s, but its observed Agent-done time was 45.880 s versus 39.114 s. No run triggered the failed-check path, so the comparison does not measure this fix's speed effect.
The [current Browser Use capability and public-issue audit](docs/BROWSER_USE_2026_AUDIT.md) tracks what is implemented, what remains missing across Agent/MCP/Harness/Pi/cloud, and which reported defects have a local reproduction or regression. Password fields now reveal only whether a value is present, while keeping its bytes redacted.
A [four-task, two-seed matched Codex comparison](docs/CODEX_MIXED_FOUR_20260924.md) covers forms, a virtual list, visual canvas and interrupted-response order recovery. Both engines passed 8/8 independent business checks with one correct write and no duplicates per attempt. Tablaze's visible median whole-run time was 56.331 versus Browser Use's 61.211 s, but Agent-done time was 56.177 versus 44.063 s; Browser Use's default judge runs after Agent completion. This development sample does not prove stable efficiency or overall parity.
The new first-open canvas image was tested in a [separate four-pair Codex follow-up](docs/CODEX_CANVAS_INITIAL_VISION_SMOKE.md). Tablaze passed 4/4 business checks with no duplicate writes; Browser Use passed 3/4 after one attempt clicked twice despite reporting success. All four Tablaze traces skipped a separate `tab_capture`. On the three jointly successful seeds, median whole-run time was 41.552 versus 61.113 s and Agent-done time was 41.401 versus 42.578 s. This one visible task does not establish overall superiority.
## Get started
Requires **Node.js 20+**, npm and Git. This is a developer preview; npm publication is pending, so install from source:
```sh
git clone https://github.com/SweetDianDian/tablaze.git
cd tablaze
npm ci
npm run build
node dist/cli.js setup
```
<details>
<summary>Already have Chrome, or running on Linux?</summary>
For installed Chrome, skip `setup`, run `node dist/cli.js doctor --channel chrome`, and append `--channel chrome` to the Codex command below. This launches a separate browser session.
On Linux, use `npx playwright install --with-deps chromium` in place of `setup` to install the browser and system dependencies.
[Browser modes and diagnostics](docs/CODEX.md#1-build-and-choose-a-browser)
</details>
### Connect Codex
From the cloned directory, register the built server:
```sh
codex mcp add tablaze -- "$(node -p 'process.execPath')" "$PWD/dist/cli.js"
codex mcp get tablaze
```
Then ask Codex:
> Use Tablaze to open https://example.com, read the heading and links, verify that the title contains “Example Domain”, then close the session. Report the result of the checks.
[Complete Codex setup](docs/CODEX.md) covers desktop configuration, browser selection and troubleshooting. Other MCP clients can launch the same `node /absolute/path/to/tablaze/dist/cli.js` command over stdio.
For workflows that need page-origin JavaScript, `--page-script` adds an opt-in `tab_script` tool. It has the page's full authority, including account data and network requests; it is unavailable with configured secrets, external CDP or a navigation policy. Scripts require a current main-frame snapshot and return a fresh one. See [the page-script contract and recovery limits](docs/PAGE_SCRIPT.md). The default catalog remains seventeen tools.
A [separate native-Codex page-script smoke](docs/CODEX_PAGE_SCRIPT_SMOKE.md) passed the independent authenticated-response judge once for both Tablaze and Browser Use CLI-MCP, with one correct write and no duplicates per arm. Codex-process samples were 198.359 s and 239.400 s respectively; browser setup differed, so this is not a controlled speed ranking or overall win.
### Run a standalone task
The optional `run` command supports `codex`, `anthropic`, `ollama`, and `openai-compatible` planners. Always specify a model. Codex reuses the installed CLI and its existing login:
```sh
node dist/cli.js run --provider codex --model "<your-codex-model>" \
--task "<authorized task>" --channel chrome
```
For a task with exactly one intended starting URL, add `--direct-open-task-url` to open it before the first model call. This is opt-in; `--start-url <url>` remains available when the caller already knows the exact page. See [initialization and resume behavior](docs/AGENT.md).
For trusted setup before the first model call, `--initial-actions ./initial-actions.json` accepts an HTTP(S) starting `url`, then more URLs or `{"click":{"name":"Open details","role":"button"}}`. A click requires one uniquely named current-page control; ambiguity or truncated observation stops input. The SDK exposes the same sequence as `initialActions`. Each attempted action is checkpointed and never replayed automatically after an uncertain outcome. See [the format and recovery rules](docs/AGENT.md).
In a [three-pair same-Codex initial-click task](docs/CODEX_INITIAL_CLICK_20260924.md), both Tablaze and pinned Browser Use passed independent business checks 3/3. Tablaze clicked before planning; Browser Use's queued click after navigation was skipped and its model completed the click later. Tablaze's median whole-run time was 68.562 versus 62.911 seconds and used one more model call per run. This visible task does not show a speed lead or overall feature parity.
In the [same-source Codex task-URL follow-up](docs/CODEX_DIRECT_TASK_URL_20260924.md), all 18 form/iframe attempts across Tablaze on/off and Browser Use passed the independent business judge once. On the form task, Tablaze's median Agent-done time was 30.378 s with direct-open versus 55.583 s without it; Browser Use took 37.647 s before its default judge. On the iframe task, Tablaze still took 56.317 s versus Browser Use's 40.495 s because all three Tablaze runs added an invalid input-as-page-text check. These visible tasks do not prove a general speed lead.
After making `text` and `value` check scopes explicit in the model-facing tool schemas, a [six-pair iframe follow-up](docs/CODEX_CHECK_DOMAINS_IFRAME_20260924.md) passed 6/6 per side with one correct write each. None of the six Tablaze runs repeated that invalid check; four finished in two planning calls and two used a separate verification call. Median Agent-done time was 42.162 s Tablaze versus 45.713 s Browser Use, with a 22-second Tablaze disadvantage on one seed. This remains a visible synthetic sample, not stable speed or overall superiority.
Use `--output-schema ./result.schema.json` to require a schema-valid JSON deliverable before the Agent can finish; the application should still check business correctness. The same schema is required on resume. See [the Agent contract](docs/AGENT.md).
SDK callers can use `createAgentControl()` to pause at a safe boundary, add trusted steering, and resume with a fresh plan; queued writes are skipped and prior verification must be repeated. See [live operator intervention](docs/AGENT.md#live-operator-intervention-sdk).
The default compatible provider still requires `--endpoint`. Native Anthropic and Ollama use their own protocols and default endpoints; authentication, output settings, and model capabilities differ. An explicit `--fallback-model` can take over after transient planning failures, then remain active for that run without replaying browser actions. See [provider setup and boundaries](docs/PROVIDERS.md), [CLI examples](docs/CODEX.md#choose-a-planner-for-run), and [Agent verification and recovery](docs/AGENT.md). Anthropic/Ollama have local protocol coverage, without live inference results; the earlier comparison results above retain their original runtime hashes.
The new production Codex path also has a [separate live smoke](docs/CODEX_PROVIDER_SMOKE.md): two visible tasks passed independent business checks and completed successfully (2/2), with zero duplicate writes. This is not a new matched Browser Use comparison.
A [new matched virtual-list task](docs/CODEX_VIRTUAL_LIST_SMOKE.md) completed once on each engine with independent acceptance and zero duplicate writes. Under a shared 120,000-token budget, whole-run time was 86.830 s for Tablaze and 141.597 s for Browser Use, including its default judge. This one visible development task does not establish a general performance or success-rate advantage.
The [delayed-control development comparison](docs/CODEX_DELAYED_TARGET_SMOKE.md) records a real Codex run that opened a menu and clicked its newly appearing option in one guarded Tablaze action batch. In the final visible matched attempt, both agents completed with one correct write and zero duplicates; Tablaze took 80.715 s and Browser Use 77.720 s. The report retains an earlier wrong-role failure and recovery. These changing-source samples do not establish a stable speed or overall advantage.
The separate [cross-origin authorization-return task](docs/CODEX_AUTH_RETURN_SMOKE.md) also passed once on each engine with one provider authorization and one app submission. Browser Use's 119.515 s whole run was slightly shorter than Tablaze's 123.719 s. This synthetic popup flow does not establish production login parity or an overall ranking.
For debugging an actual run, `--record-video` optionally records each owned isolated tab as a private WebM. `tab_close` returns finalized paths and SHA-256 digests; the standalone `run` report includes them after cleanup. It is off by default and adds no simulated cursor or audio. See [real browser recording and privacy limits](docs/RECORDING.md).
`--record-har` and `--record-trace` optionally save an owned session's network HAR and Playwright trace ZIP. HAR response bodies are omitted by default; trusted operators can explicitly select `--har-content embed|attach` and `--har-mode full|minimal`. Finalized private paths, sizes and SHA-256 digests appear after cleanup. Every mode can contain private request data, and body modes can include sensitive responses. See [diagnostic artifacts](docs/DIAGNOSTICS.md).
Trusted operators can set viewport, screen, pixel ratio, user agent, locale, time zone, mobile behavior, touch and page permissions on owned browser contexts. `--no-viewport` lets desktop content follow the browser window; headed sessions also accept `--window-size` and `--window-position`. `--device-preset pixel-7` and `pixel-7-pro` apply a coherent set of mobile emulation properties from pinned Playwright descriptors. `doctor` reports effective settings without echoing the user-agent string; external CDP browsers cannot be reconfigured. See [browser configuration and limits](docs/BROWSER_CONFIGURATION.md).
Owned contexts also accept `--proxy-server` with optional bypass rules and credentials read from an environment variable; the [configuration guide](docs/BROWSER_CONFIGURATION.md) records the tested HTTP routing path and remaining proxy validation.
## A small loop, with useful controls
| Capability | What it gives your agent |
| --- | --- |
| **Warm sessions** | Keep page state between calls. Temporary, isolated browser contexts by default; explicit CDP attachment for an existing profile. |
| **Owned persistent profile** | Opt into a [dedicated private Chrome directory](docs/PROFILES.md) with a required profile ID on reuse and exclusive ownership. Browser-managed login state can survive a cold restart. |
| **Compact observations** | Full or incremental snapshots with element refs, text budgets and visible truncation. |
| **Guarded actions** | Check snapshot revisions and DOM targets before input. Re-observe when a target changes. |
| **Ordered batches** | Send up to 20 actions in one call, with completed, failed and skipped steps. Stops on error; earlier effects remain. |
| **Delayed controls** | After clicking an observed opener, wait for one exact-name visible button or menu item and click it in the same guarded batch. Ambiguous matches stop before input. |
| **Explicit verification** | Check URL, title, text, field values, visibility and counts. Known same-document outcomes can be checked inside `tab_act` after its batch, with passing evidence available to the Agent in that call. |
| **Optional response journal** | Use `--capture-network` to inspect bounded responses from owned pages and popups through an eighteenth MCP tool, [`tab_network`](docs/NETWORK.md). Off by default; not a programmable JS/CDP surface. |
| **Optional real video** | Use `--record-video` for private WebM recordings of owned isolated tabs, finalized with SHA-256 at session close. [Recording scope and limits](docs/RECORDING.md). |
| **Optional navigation policy** | [Exact-origin allow/deny rules](docs/NAVIGATION_POLICY.md) for HTTP(S) document requests, including redirects, frames and popups, in owned isolated browsers. No external CDP; not a network firewall. |
### Seventeen tools
| Tool | Use it to |
| --- | --- |
| `tab_open` | Open a page and receive its first snapshot. |
| `tab_snapshot` | Observe the page, changes or a selected frame. |
| `tab_find` | Search visible text while scrolling a page or observed virtual-list container; return a fresh actionable snapshot. |
| `tab_act` | Guarded form input, explicit readonly-input/native-listbox selection, drag/drop, container scrolling, file selection and coordinate actions; optional post-action checks. |
| `tab_click_named` | Click exactly one actionable main-document control by accessible name after a fresh bounded observation; refuse ambiguous matches. |
| `tab_verify` | Test explicit page assertions and guarded form values by ref or CSS selector. |
| `tab_extract` | Read text, links or tables. |
| `tab_capture` | Capture a JPEG screenshot. |
| `tab_list` | Inspect owned sessions. |
| `tab_close` | Close a session and release its resources; return finalized WebM artifact metadata when recording was enabled. |
| `tab_navigate` | Navigate, go back/forward, or reload without losing session state. |
| `tab_tabs` | Open, switch, and close owned tabs, including popups. |
| `tab_downloads` | Inspect download status and local artifacts. |
| `tab_dialog` | Arm a one-shot accept/dismiss response to a native dialog. |
| `tab_state` | Save authentication state for explicit import into a new session. |
| `tab_extract_structured` | Extract typed fields against a JSON schema with DOM source citations. |
| `tab_pdf` | Export a private PDF artifact with source URL and SHA-256 digest. |
## Explore the project
| Guide | Inside |
| --- | --- |
| [Codex integration](docs/CODEX.md) | Copyable configuration, tool arguments and troubleshooting. |
| [Runtime reference](docs/RUNTIME.md#english) | Reference lifetime, batch semantics, browser modes and current limits. |
| [Typed custom tools](docs/CUSTOM_TOOLS.md) | SDK schemas, trusted application context, browser bindings and recovery contracts. |
| [Model providers](docs/PROVIDERS.md) | Codex CLI, native Anthropic/Ollama and compatible HTTP contracts, authentication and usage. |
| [Navigation policy](docs/NAVIGATION_POLICY.md) | Trusted CLI/SDK configuration, document-only scope, transport-loss limits and checkpoint identity. |
| [Scoped credentials](docs/SECRETS.md) | Trusted aliases, exact-origin login fills, redaction limits and recovery. |
| [Real browser recording](docs/RECORDING.md) | Opt-in WebM artifacts, CLI/MCP/SDK access and privacy limits. |
| [Browser Use variants audit](docs/BROWSER_USE_VARIANTS.md) | Distinguish Agent, MCP, Harness, Pi and cloud comparison targets; source audit, not a benchmark. |
| [Benchmark](bench/README.md) | Reproduce the local workload and inspect every raw sample. |
| [Validation evidence](docs/VALIDATION.md) | Real browser, SDK and Codex results, with their measured scope. |
| [Security](SECURITY.md) | Data handling, resource ownership and private reporting. |
| [Release packaging](docs/RELEASE.md) | Build the npm tarball and source archive. |
The [historical 0.1.0 Ubuntu CI run on Node 20 and 22](https://github.com/SweetDianDian/tablaze/actions/runs/35696802909) passed its build, browser/MCP tests and package inspection. The later [Ubuntu Node 20/22 run for commit `c9d091a`](https://github.com/SweetDianDian/tablaze/actions/runs/35736979945), which includes the provider adapters, also passed both jobs. That run predates the navigation-policy increment. Current development validation is recorded [separately](docs/DEVELOPMENT_STATUS.md). To check a source checkout yourself, run `npm test`; use `npm run bench` for the separate local benchmark.
## Contribute
Bring a reproducible browser case, improve a guide, or send a focused fix. [Open an issue](https://github.com/SweetDianDian/tablaze/issues) · [Submit a pull request](https://github.com/SweetDianDian/tablaze/pulls) · [Read the contribution guide](CONTRIBUTING.md)
[MIT licensed](LICENSE) · [Dependency credits and project provenance](NOTICE)
The current development branch adds scoped/viewport snapshots, consistent composed-DOM reading, rich controls, file workflows, tabs, [structured extraction](docs/EXTRACTION.md), and a [model-driven agent loop with checkpoint/resume](docs/AGENT.md). `extractWithPlanner` and `tablaze-extract` use a separately selected model for quote-checked, schema-valid extraction from supplied source text. `tablaze run --extraction-model` also exposes browser-bound extraction to the Agent. These additions have not yet been published to npm. See [the one real Codex extraction check](docs/MODEL_EXTRACTION_20260924.md) and [current validation](docs/DEVELOPMENT_STATUS.md). The [Browser Use comparison](docs/BROWSER_USE_COMPARISON.md) records remaining gaps and unmeasured acceptance criteria; it does not claim superiority.
CLI Agent and stdio MCP uploads use a [trusted file list](docs/FILE_POLICY.md): no host files are available by default, `--available-file` grants specific files, and same-session downloads can be uploaded by ID. For authenticated tasks, `--storage-state-file /absolute/private/state.json` applies a trusted Playwright state file to each new isolated session without disclosing its path to the Agent.
TDQS
Scored across 16 tools
Most tools map cleanly to a distinct browser operation: session lifecycle, navigation, snapshots, actions, extraction, verification, downloads, dialogs, and PDF. The closest overlap is between tab_snapshot/tab_find and tab_extract/tab_extract_structured, but the descriptions clearly separate search-and-scroll from simple read and simple extraction from schema-validated extraction.
Every tool uses a consistent tab_ prefix and snake_case naming, making the set highly predictable. Although a few names like tab_tabs and tab_downloads are noun-based rather than strict verb_noun, the uniform prefix convention removes ambiguity.
At 16 tools, this is at the upper edge of a comfortable browser automation toolkit, but each tool covers a genuinely distinct capability such as dialogs, downloads, PDF, multi-tab management, and storage state. It feels slightly heavy but not bloated for the stated purpose.
The set covers the core browser automation lifecycle: session open/close, navigation, snapshots, actions, verification, extraction, capture, downloads, dialogs, PDF, and state persistence. Minor gaps such as direct cookie/localStorage editing and an explicit wait primitive can be worked around via tab_state and post_checks or tab_verify.