Skip to content

Releases: ikari-software/turboweb-mcp

v1.13.0

Choose a tag to compare

@ikari-pl ikari-pl released this 29 Sep 23:38
4954bf2

1.13.0 (2026-09-29)

Features

  • agents introduce themselves; fix host detection and popup labels (#28) (de93696)

v1.12.1 — self_update extension hot-swap from an installed binary

Choose a tag to compare

@ikari-pl ikari-pl released this 19 Aug 08:11
2e2b0b7

self_update extension hot-swap fix

Fixes self_update not reloading the loaded browser extension when the server runs from an install location away from the repo (e.g. /opt/homebrew/bin). TURBOWEB_EXTENSION_DIR now points at the extension source root (holding dist/chrome and dist/firefox) and is honored in findExtensionDir, so the one override resolves both the Chrome/Arc and Firefox dist dirs (previously only Chrome). Set it in the MCP server env and load the unpacked extension from that root's dist/<browser> to have every connected browser hot-swap on update.

Full notes: CHANGELOG.md

v1.12.0 — Trusted cdp_* into cross-origin frames on Chrome (no BiDi)

Choose a tag to compare

@ikari-pl ikari-pl released this 18 Aug 14:17
2fe0f3c

Trusted input into cross-origin frames on Chrome (no BiDi)

cdp_click / cdp_type / cdp_key / cdp_scroll now reach same- and cross-origin frames on Chrome without BiDi (previously BiDi/Firefox only). The element is resolved inside the frame via the all_frames content script and trusted input is dispatched on the top target, so Chrome's cross-process input router delivers it to the OOPIF. Keys follow focus; clear=true selects all via triple-click (the Meta/Ctrl+A chord doesn't cross the OOPIF boundary); off-screen targets are scrolled into view first. Live-validated same-origin, single-hop, and two-hop cross-origin.

Sticky frame context

frame_set(framePath) / frame_context — scope every subsequent frame-aware call (DOM reads and cdp_*) to one frame until cleared. navigate is excluded on purpose.

Cross-origin frame targeting hardening

resolveFrameContext maps an iframe to its BiDi child context by unique URL → unique origin → count-gated ordinal, and errors loudly on ambiguity instead of silently dispatching trusted input into the wrong frame.

Maintainability, tests, and review fixes

Cross-iframe cleanups, expanded frame test coverage, and fixes from a multi-agent code review (restored navigate empty-url guard, navigate/sticky exclusion, refused cdp_type clear in a frame without a selector, stopped swallowing non-"not found" scroll failures). Agent guidance documents frame_set/frame_context and the no-BiDi cross-origin capability.

Full notes: CHANGELOG.md

v1.11.0 — cross-origin frames, trusted input, humanized typing, connect_bidi

Choose a tag to compare

@ikari-pl ikari-pl released this 26 Jun 11:54
f7c4545

Cross-origin frames

DOM reads and synthetic interaction (extract_text, find_text, query_elements, click, type_text, fill_input, scroll) now reach cross-origin iframes — addressed by a >-separated CSS selector path. The content script runs in every frame.

Trusted input (cdp_*)

  • cdp_key: modifier chords (Meta/Control+A); Backspace/Delete actually delete.
  • cdp_type clear=true works on the Chrome backend.
  • cdp_click clickCount — double-click (word) / triple-click (whole field).
  • cdp_type types at a human cadence by default (wpm, default 110; 0 = instant).
  • type_text/fill_input dispatch a real InputEvent for controlled components.

New tool

  • connect_bidi(port) — attach WebDriver BiDi to a browser you launched yourself with --remote-debugging-port (your real profile). Useful on Firefox/Zen.

Updates & agents

  • check_for_updates / self_update return whatsNew (release notes) so agents can invalidate stale memory.
  • self_update hot-swaps the unpacked extension in place for every connected browser (Chrome and Firefox) plus the MCP binary. Store/AMO installs auto-update via the store / update_url.
  • Tool descriptions steer toward selectors over coordinates.

v1.10.0

Choose a tag to compare

@ikari-pl ikari-pl released this 19 Jun 21:20

Cross-iframe automation

DOM tools no longer stop at iframe boundaries.

  • list_frames — enumerate the frame tree (frameId, framePath, id, name, src, url, origin, isSameOrigin, rect).
  • frame parameter on query_elements, find_text, extract_text, inspect, get_html, page_yaml, get_interactive_map, click, type_text, fill_input, scroll — scopes the call to a same-origin iframe via a >-separated framePath (e.g. #top_frame > #csframe). Reported coordinates are offset to stay viewport-relative, so a query inside a frame round-trips to a later click.
  • Coordinate piercing — click/inspect {x,y} descend through same-origin iframes to the real leaf element instead of resolving to the <iframe> wrapper.
  • Cross-origin frames — cdp_click / cdp_type / cdp_key / cdp_scroll target cross-origin (OOPIF) frames natively via WebDriver BiDi child browsing contexts.

Single-frame navigation

  • navigate gains a frame argument — navigates only that frame and preserves the parent frameset (so geocoders, save handlers, and other frameset-dependent JS keep working). Uses browsingContext.navigate under BiDi, or sets the iframe's src via the content script otherwise.

Fixes

  • fill_input is now wired into the extension dispatcher (previously returned "Unknown action").
  • Zen browser WebDriver BiDi launch detection.

Internal

  • Version now lives in a single VERSION file (read by the Makefile, the binary's ldflags, and the extension build).

macOS binary is notarized and the checksums are cosign-signed by CI.

v1.9.0 — CI notarization

Choose a tag to compare

@ikari-pl ikari-pl released this 28 May 18:11

macOS binaries are now notarized automatically by the release CI workflow — no manual steps needed on first run.

v1.8.5 — signed releases

Choose a tag to compare

@ikari-pl ikari-pl released this 27 May 16:37

What's new

Signed releases (security fix)

All prior releases (v1.8.1–v1.8.4) were missing the SHA256SUMS, SHA256SUMS.sig, and SHA256SUMS.crt files required by SECURITY.md. This meant the self_update MCP tool refused to install any update for end users (it guards against unsigned binaries).

The root cause was that the CI release workflow tried to rebuild artifacts from scratch, which caused AMO to reject the already-submitted Firefox XPI version — the CI job failed before ever reaching the SHA256SUMS / cosign signing steps.

Fix: The release workflow now downloads the pre-built artifacts from the release, generates an authoritative SHA256SUMS, and signs it with Sigstore keyless OIDC. The developer builds and AMO-signs locally; CI's only job is to sign the checksums with a GitHub-OIDC-rooted identity.

Starting with this release:

  • SHA256SUMS, SHA256SUMS.sig, SHA256SUMS.crt, SHA256SUMS.cosign.bundle are present on every release.
  • The self_update MCP tool works correctly.
  • Verify with cosign verify-blob as described in SECURITY.md.

v1.8.4 — extension update tests + /reload-extension endpoint

Choose a tag to compare

@ikari-pl ikari-pl released this 27 May 14:56

What's new

Tests for the extension update path (the "was that published untested?" fix)

v1.8.3 shipped the extension auto-update code without tests. v1.8.4 adds:

  • TestExtractChromeZip — full download→extract cycle via an in-process httptest server; verifies the chrome/ prefix is stripped and the resulting manifest has the right version
  • TestExtractChromeZip_ZipSlipRejected — path traversal entries (chrome/../../evil.txt) are silently skipped, never written outside dest
  • TestExtensionDirVersion — manifest parse, missing file, malformed JSON
  • TestFindChromeExtensionDistDir_EnvOverride — $TURBOWEB_EXTENSION_DIR is now a strict override: if set but pointing at a non-extension directory, returns "" rather than falling back to auto-detect (fail loudly on misconfiguration)

New: /reload-extension HTTP endpoint

curl http://127.0.0.1:18321/reload-extension
# → {"ok":true,"version":"1.8.4","message":"reload_extension broadcast sent to all connected browsers"}

Broadcasts reload_extension to every connected browser extension. Useful after manually updating the extension files on disk, or for scripting reloads without going through self_update.

Included from v1.8.3

  • self_update downloads the chrome extension zip, extracts it in place, and reloads all connected Chromium browsers automatically
  • Popup shows both extension and backend versions (v1.8.4 when matched, amber ext X · srv Y when not)
  • serverVersion injected at build time via -ldflags "-X main.serverVersion=VERSION"

v1.8.3 — self_update updates the extension too + popup shows both versions

Choose a tag to compare

@ikari-pl ikari-pl released this 27 May 14:27

What's new

self_update now also updates the browser extension

When self_update runs, it now handles the full stack:

  1. Binary — downloaded, SHA256-verified, atomically swapped (unchanged)
  2. Chrome extension — locates the load-unpacked extension/dist/chrome directory (next to the binary, or via $TURBOWEB_EXTENSION_DIR), downloads the release chrome zip, extracts it in place
  3. Reload — broadcasts reload_extension over WebSocket; every connected Chromium browser calls chrome.runtime.reload() and picks up the new files immediately, no manual browser action needed
  4. Firefox — handled by AMO auto-update (update_url in the signed manifest, polls daily); no extra step

Popup shows both extension and backend versions

The header version chip now shows:

  • v1.8.3 — when extension and backend match (normal state)
  • ext 1.8.2 · srv 1.8.3 in amber — when they differ (e.g. right after updating one side)

Backend version is sent in every mcp_clients WebSocket push, no extra roundtrip.

Fix: serverVersion was stuck at 1.6.0

The Go binary's serverVersion constant was hardcoded and never updated through the v1.7.x and v1.8.x releases. It's now injected at link time via -ldflags "-X main.serverVersion=VERSION" — the Makefile VERSION is the single source of truth.

Also included (carried from earlier v1.8.x)

  • execute_js falls back to CDP Runtime.evaluate on strict-CSP pages
  • Browser detection via hello push — no "No active tab found" on daemon restart
  • Gemini Flash AI backend (GEMINI_API_KEY)
  • Firefox/Zen BiDi guard, light/dark theme, Zen detection

Install / update

./setup.sh         # full install
self_update        # via MCP tool (updates binary + extension in one step)

v1.8.2 — execute_js works through strict CSP

Choose a tag to compare

@ikari-pl ikari-pl released this 27 May 13:46

What's new

Fix: execute_js works on pages with strict CSP

Pages that set script-src without 'unsafe-eval' (common on SPAs, admin panels, and security-hardened sites) previously caused execute_js to fail with:

{"error":"call to eval() blocked by CSP"}

executeJsMain now detects this and automatically retries via CDP Runtime.evaluate, which operates at the V8 engine level — below the DOM security layer — and bypasses script-src restrictions entirely. No change to the tool's API; it just works.

On Firefox/Zen where chrome.debugger is absent, a clear hint is returned pointing at launch_browser / BiDi.

Also included (from earlier in the v1.8.x series)

  • Browser detection via hello push on connect — no more "No active tab found" on daemon restart
  • Gemini Flash AI backend (GEMINI_API_KEY) with multimodal support
  • Auto cascade: Haiku → Gemini → local Gemini Nano → silent raw
  • Firefox/Zen: clear error when chrome.debugger is not available
  • Suppressed LOCAL_AI_UNAVAILABLE noise in Arc/Chrome
  • Zen Browser detection via window.zen global
  • Light/dark theme + theme_icons for toolbar icon

Install

./setup.sh

Or grab the binary for your platform above.