This week
Features
API trigger endpoint now accepts bodyless requests
POST /api/tasks/:id/api no longer requires a JSON body or a Content-Type: application/json header. Requests without a parsed body are treated as {} and the task runs with its default variables. Tools that can’t set request headers on outbound calls (for example, Clay’s HTTP action) can now trigger a task with a bare POST to the endpoint URL.To pass variables, webhookUrl, statelessExecution, or sessionId, keep sending Content-Type: application/json with a JSON body — that path is unchanged.Full endpoint URL and method in the API trigger panel
The task editor’s Trigger via API panel now shows the complete origin-aware endpoint URL (for example,https://your-figranium.example.com/api/tasks/task_1/api) with a POST method badge next to it. The copy button copies the same full URL, so you can paste it straight into external tools without prefixing your instance origin by hand.See REST API Reference — POST /api/tasks/:id/api.Earlier this week
Features
Opt-in CloakBrowser browser engine
Figranium now ships two interchangeable browser engines behind the same Playwright API, and you can switch between them with a single environment variable. Agent, Headful, and CLI-launched tasks all use whichever engine is active — no task edits required.- Default (
USE_CLOAK_ENGINEunset orfalse): Playwright Chromium patched at the JS level withplaywright-extraandpuppeteer-extra-plugin-stealth. Same behavior as previous releases. - Opt-in (
USE_CLOAK_ENGINE=true): the CloakBrowser stealth-patched Chromium binary. Evasions are applied at the binary level rather than injected at runtime, which is harder for modern bot detectors to fingerprint. Use this when the default stack is being detected on a target site — typically CAPTCHA walls that trigger on Playwright/Chromium runtime tells. - License key: set
CLOAKBROWSER_LICENSE_KEYto unlock the latest stealth binary. Without a key, CloakBrowser falls back to the free legacy binary. You can also runnpx cloakbrowser loginto write the key to~/.cloakbrowser/license.key, whichcloakbrowserreads natively. - Lean installs: the CloakBrowser binary is only fetched during
postinstallwhen the flag is enabled, so the default install stays the same size as before.
.env
Automatic cookie-consent dismissal in Agent mode
Agent tasks now click through common cookie-consent banners for you before your first action block runs. Figranium injects the community-maintainedidcac-playwright ruleset (a port of the “I don’t care about cookies” extension) into every page in the Agent browser context on domcontentloaded.- Covers hundreds of providers (OneTrust, Cookiebot, TrustArc, Quantcast, and more). The script always clicks reject or close — never accept.
- Always on in Agent mode. Headful mode is unchanged (it’s for human interaction), and Scrape mode doesn’t render banners because it no longer launches a browser.
- If no matching banner is present, the script silently no-ops so your task runs as usual. If a specific site’s dialog isn’t covered, you can still author an explicit
Clickblock.
Changes
Scrape mode is now browserless (no screenshots or video)
Scrape mode has been rewritten as a lightweight HTTP fetch. It now issues the request throughgot-scraping (with the same proxy pool and user-agent rotation as before) and parses the response with Cheerio, instead of spinning up a Playwright/stealth-Chromium browser for each run.- Faster and cheaper: No browser process means dramatically lower CPU, memory, and cold-start cost per scrape.
- Preserved: Selector extraction, HTML cleanup, link extraction, proxy and user-agent rotation, the headful → scrape cookie handoff, and the sandboxed extraction-worker script pipeline all still work exactly as before.
- Removed: No screenshots and no video recordings in Scrape mode. There is no page to photograph. The Results panel’s Screenshot pane now shows “Scrape mode does not support screenshots” instead of the misleading “Waiting for Frame…” placeholder. If you need visual evidence of the page, run the task in Agent mode.
Earlier this week
Features
Visual field-mapping mode for extraction scripts
The Extraction Script editor (both the canvas block and the Extraction tab in Task Settings) now opens in a new Visual mode by default. You describe the data you want as a list of named fields with a selector, an attribute type (Text, HTML, Input Value, or Attribute), and an optional Multiple (list) toggle. Figranium generates the underlying JavaScript for you and keeps it in sync as you edit — no raw code required for typical scraping tasks.- The mode toggle at the top of the editor flips between Visual and JavaScript. The selected mode now has a solid fill so it’s obvious which one is active.
- Every field has a target icon that hands off to the Headful Browser inspector. Click an element on the page and the selector, plus a row of alternative candidates, get written back into the field.
- Playwright-only
:has-text(...)selector candidates are filtered out of the pick list for extraction fields only. Extraction scripts run through nativedocument.querySelector, which does not understand that pseudo-selector, so surfacing it would have produced selectors that returnednullat extraction time. Action blocks (Click, Type, etc.) still receive the full candidate list because Playwright runs those. - Switching to JavaScript mode surfaces the auto-generated script in the code editor, still fully editable. Existing hand-written extraction scripts open in JavaScript mode automatically so your code is never hidden behind an empty field list.
- The canvas Extraction Script modal no longer closes when you click the backdrop, so a stray click on the dimmed area outside the modal will not throw away in-progress edits. Use the Done button or the close icon in the header to save and dismiss.
Earlier update
Updates
Agent Mode description clarified in Task Settings
The mode picker in the Task Settings cabinet previously described Agent Mode as “Autonomous decision making,” which suggested the runner would decide steps on its own at execution time. That was misleading: Agent Mode runs a fixed sequence of action blocks that you author, and any branching comes from explicit control-flow blocks (If, While, Loop, etc.) on the canvas.- The label under Agent Mode now reads “Custom action sequence with logic.”
- No behavior change. If you were choosing Scraper Mode because you didn’t want the runner making its own decisions, you can safely use Agent Mode — the same author-defined blocks execute in the same order on every run.
- If you want an actual AI-driven, decision-making runner, that lives in MCP Integration, not in Agent Mode.
Earlier update
Updates
headless flag and automatic fallback for POST /api/browser/open
The programmatic browser launch endpoint now accepts a headless boolean and recovers automatically when no display server is available.- Pass
"headless": truein the request body to launch Chromium without a display. This is the right choice when you run Figranium directly on a Mac (outside Docker) or on a headless CI runner. TheHEADLESSenvironment variable is also honored. - If you don’t set
headlessand the initial headful launch fails because there is no display, Figranium retries once in headless mode and returns the running session. External orchestrators no longer have to detectHEADFUL_DISPLAY_UNAVAILABLEand reissue the call themselves. - The display-unavailable detector now also matches
no display server,X11 connection failed,cannot open display, and unexpectedtarget closederrors during launch, so the fallback triggers on Mac hosts where the underlying error text differs from Linux.
POST /api/browser/open for the full request and error schema.Bug fixes
- Headful VNC viewer no longer gets stuck on “Reconnecting…” —
start-vnc.shwas embedding literal double-quote characters into thex11vnc -passwdargument because of unquoted shell word-splitting, so the passwordx11vncactually enforced never matched the one served to the noVNC client. Every connection attempt failed authentication and dropped immediately, which showed up in the UI as an endless reconnect loop. The password is now passed through a bash array as a single unmodified argument. If you were affected, pull the latest image and reopen the headful session — no config change is required. - Proxy credentials pasted as a full URL are now split out on add — Pasting
http://user:pass@host:portinto Settings > Proxies > Add Proxy > Server previously stored the whole URL (credentials included) as theservervalue, which surfaced as a duplicate-looking entry in the list and failed upstream authentication in rotation pools.normalizeProxynow extracts embedded credentials intousernameandpasswordon both the add and bulk-import paths. Existing broken entries self-heal on next read — no manual cleanup needed. See Proxy Rotation — Adding a proxy. - Backdrop blur restored on modals and overlay panels in Dark and Solarized Dark themes — A dark-theme CSS override was force-replacing translucent
bg-black/NNbackgrounds with a fully opaque color, defeatingbackdrop-bluron the Task Settings panel, the confirm modal, and other overlays. The override has been removed, and the confirm modal now uses a translucent theme-aware background instead of a hardcoded opaque one. - Browser open and inspector highlight on Mac — Launching the managed browser session from
POST /api/browser/openand resolving atargetHintthroughPOST /api/inspector/highlightnow work when Figranium runs on macOS. Chromium is launched without the--disable-gpu,--window-position=0,0, and--start-maximizedflags on Darwin, which were causing the process to exit before the first page was ready. The CDPBrowser.setWindowBoundsmaximize call is also skipped on Darwin. Selector generation, XPath resolution, and the top-match highlight overlay for/api/inspector/highlightnow run in a single in-page evaluation, so they don’t lose the element handle to a mid-flight page navigation. - GitHub star prompt no longer appears on first run — The in-app prompt asking you to star the Figranium repo is now gated on both 3+ successful task runs and 3 days since your first run (tracked locally in the browser). It also uses a quick slide-in animation instead of the previous fade so it’s easier to notice when it does appear. Dismissing or clicking through still permanently silences it.
Earlier update
Updates
Single self-theming brand icon
The Figranium mark atpublic/figranium_icon.svg is now a single SVG that adapts to the viewer’s color scheme, instead of shipping as separate dark and light variants.- The mark fills black by default and switches to white inside
@media (prefers-color-scheme: dark), so it stays legible on both light and dark surfaces. - Use this file when you can only supply one logo URL — for example, third-party integrations, README embeds, or partner directories that accept a single
<img src>. - No configuration change is required. Existing embeds keep working; you can drop the separate dark/light variants from your integration if you were maintaining both.
Earlier update
Features
Multi-theme support
Figranium now ships with four selectable UI themes: Dark (default), Light, Solarized Light, and Solarized Dark.- Switch themes from Settings → System → Theme. Each option shows a preview image plus a surface and accent color swatch.
- The choice is stored in the browser’s local storage (
figranium.theme), so it persists across reloads on the same device. - The first time you open Figranium after upgrading, a one-time picker prompts you to choose a theme. Dismissing it also persists locally and it will not appear again.
- Themes are implemented as CSS custom properties (
--app-bg,--app-surface,--app-accent, and the full syntax-highlight palette), so the whole UI — including code blocks — retunes for readability under each background.
Authenticated programmatic browser & inspector API
The programmatic browser endpoints introduced in the previous release now require authentication and are safe to expose to external orchestrators (MCP servers, custom agents, CLIs).POST /api/browser/openlaunches or reattaches a managed headful session and returns{ sessionId, status, wsEndpoint }.POST /api/inspector/highlightactivates the inspect overlay on the active session and, given atargetHint, returns up to five candidate elements with CSS selectors, XPath, confidence scores, and an optional base64 JPEG snapshot of the viewport.PATCH /api/tasks/:idperforms a partial update on a task. Figranium snapshots the current task into the version history before applying the change.DELETE /api/tasks/:idnow also removes any in-process schedule registered for the task, so a scheduled run cannot fire after deletion.
x-api-key, Authorization: Bearer, or an apiKey body field). External callers should use the API-key path.Security
VNC and websockify path hardening
- The noVNC/websockify proxy path now requires authentication before it will accept an upgrade or serve
public/novnc.html. Unauthenticated attempts are dropped. websockifybinds to the IPv4 loopback (127.0.0.1) explicitly, closing a mismatch where Docker on macOS could bind unpredictably across IPv4/IPv6 loopback and leave the VNC stream unreachable or unexpectedly reachable.sessionIdandtaskIdare strictly validated before they are used to look up files on disk, closing a path-traversal edge case.- Raw cron ranges are now validated for correct ordering as well as bounds, so a malformed field cannot slip past the scheduler.
/websockify directly, update it to authenticate with a session cookie or an API key. See Headful browser — Access control and Security — Headful / VNC access control.Bug fixes
- Captures now surface reliably — Runs no longer produce screenshots or recordings that fail to appear in the UI. The capture read path in
server.jsandsrc/server/routes/data.jsnow matches the actual write path, and captures are also served from the alternatepublic/captureslocation used inside Docker. - Captures survive container restarts — Runtime capture artifacts persist to a host volume instead of being lost when the container is recreated.
- Persistent browser session ID — Session IDs are stored across reconnects instead of being regenerated on every new session, so external tooling that pins to a
sessionIdstays valid. - Mac/Docker WebSocket disconnects — Loopback WebSocket connections used by the headful viewer no longer drop on Mac hosts, and the
HeadfulModalno longer flashes its loading state during a normal reconnect. - Apple Silicon headful browser “Connecting… Disconnected” loop — The GHCR publish workflow now builds and pushes a true multi-architecture image (
linux/amd64andlinux/arm64). Apple Silicon Macs pull the native ARM64 image instead of running the AMD64 image under Docker Desktop’s QEMU emulation, where Xvfb and x11vnc were prone to crashing seconds after start. That crash also silently broke the selector-picker SSE stream, which shares the same headful browser session. - Headful viewer auto-reconnect — Xvfb, x11vnc, and websockify each now run inside restart loops (with per-process logs under
data/xvfb.log,data/x11vnc.log, anddata/novnc.log), and the noVNC page auto-reconnects with backoff on RFB disconnect. A quick post-connect drop is now surfaced as “Browser session crashed, retrying…” instead of a plain “Reconnecting…” so a genuine crash is visually distinguishable from a normal reconnect. - Theme contrast fixes — Dot-grid canvas background, theme-accent buttons, and previously hardcoded blue accent text (API keys, Add API Key button) are readable across all four themes; syntax-highlight colors were retuned to meet WCAG AA contrast on every theme’s actual code background.
Updates
Exported task filename
Exported task bundles are now namedfigranium-tasks-<date>.json (previously doppelganger-tasks-...).Font change
The UI now uses Space Mono in place of JetBrains Mono. Custom stylesheets that referenced the old font family should be updated.Under the hood: CAPTCHA detection scaffolding
Figranium 0.14.0 lands the foundation for a future human-handoff CAPTCHA workflow. This release includes only the internal engine layer — a DOM/shadow-DOM/iframe observer that classifies interactive elements (slider, audio, grid, rotational, distorted-text, widget-frame, form), a 2 GB memory guardrail (os.totalmem() plus cgroup v1/v2 limits), and typed handoff interfaces (onCaptchaDetected, pauseForHuman, submitSolution) that pipe an externally supplied solution into the existing human-like mouse trajectory generator.There is no automated solver and no user-facing API for this yet — the module ships as internal scaffolding only. Tasks continue to pause for manual intervention through the headful browser as they do today.Earlier update
Features
Model Context Protocol (MCP) server
Figranium now ships an official MCP server so LLM clients like Claude Desktop, Cursor, and Manus AI can discover, run, inspect, and schedule Figranium tasks directly.- Prebuilt image: pull
ghcr.io/figranium/figranium-mcp:latest— no Node.js install or local clone required. - STDIO transport: works with any MCP-compatible client over the standard STDIO transport.
- Point at your instance: configure
FIGRANIUM_BASE_URLandFIGRANIUM_API_KEYin the client’s MCP server config. Usehttp://host.docker.internal:11345when Figranium runs on the same host. - Registry namespace: clients that support automatic registry resolution can install it as
io.github.figranium/figranium-mcp.
Earlier update
Features
Named session snapshots (sessionId)
Tasks and API-triggered runs now accept a sessionId field that persists browser cookies and local storage to a dedicated snapshot file per name.- Pass
sessionId: "acct-alice"on a run and Figranium loadsdata/sessions/acct-alice.jsonas the browser’s initial storage state. After the run, the current state is written back to the same file. - Different
sessionIdvalues give you fully isolated logged-in identities on the same target — one per customer, tenant, or account, without touching the shared profile directories. sessionIdis sanitized to[a-zA-Z0-9_-]; other characters are stripped for path safety.- Combining
sessionIdwithstatelessExecution: truekeeps the run stateless — the snapshot is not written.
POST /api/tasks/:id/api for the API field.Updates
Async and top-level return in Run JavaScript
The Run JavaScript action block now wraps your code in an async function, so top-level await and top-level return work directly. Existing scripts that used plain expressions or return from eval continue to work — the block falls back to the previous behavior if the async wrapper cannot compile the code.See JavaScript Execution for examples.Earlier update
Security
Hardened VNC and websockify access
Unauthenticated access to the headful browser’s VNC stack is now closed. This affects anyone who was reaching the VNC or noVNC ports directly (for example, from a custom client or an exposed Docker port).- Localhost-only binding: both
x11vnc(port5900) andwebsockify/noVNC (NOVNC_PORT, default54311) now listen on127.0.0.1only. Publishing these ports on the Docker host no longer exposes them. - Password-protected VNC:
x11vncrequires a random password generated on first start and stored atdata/vnc_password.txt. The embedded viewer fetches it automatically from the new authenticated endpointGET /api/headful/vnc-password. - Authenticated
/websockifyupgrades: every WebSocket upgrade to/websockifyon the main Figranium port must pass the IP allowlist, an Origin/Host match (CSWSH protection), and present either a session cookie or an API key. Unauthenticated attempts are dropped and logged.
54311 or 5900, update it to proxy through wss://<host>:11345/websockify with an API key (?apiKey=... or x-api-key header). Retrieve the VNC password from GET /api/headful/vnc-password.See Headful browser — Access control and Security — Headful / VNC access control for the full details.Earlier update
Updates
Expanded PostgreSQL storage
PostgreSQL is now a first-class backend for nearly all Figranium configuration, not just tasks and logs.- More data in Postgres: proxy configuration, saved credentials, AI model selections, and Ollama API keys are now persisted in the database when
DB_TYPE=postgres. - SSL support: a new
DB_POSTGRESDB_SSL=trueenvironment variable enables encrypted connections to managed Postgres providers (RDS, Cloud SQL, Supabase, Neon, etc.). - Longer API keys: API key columns are now
TEXTinstead ofVARCHAR(255), and existing tables are migrated automatically on startup. - Graceful fallback: if the database is unreachable at startup, Figranium falls back to file-based storage.
Expanded SSRF protection
The default SSRF blocklist now covers a much broader set of internal and reserved network addresses, hardening Figranium against requests that target internal infrastructure.- More IPv4 ranges blocked by default: in addition to RFC 1918 private ranges and loopback, Figranium now blocks IETF protocol assignments (
192.0.0.0/24), TEST-NET ranges, benchmarking (198.18.0.0/15), shared CGN space (100.64.0.0/10), multicast, and other reserved space. - Full IPv6 coverage: loopback (
::1/128), unique local (fc00::/7), link-local (fe80::/10), unspecified, and multicast ranges are blocked. - Hostname blocking:
localhost,*.localhost, andhost.docker.internalare blocked unlessALLOW_PRIVATE_NETWORKS=true. - Proxy server validation: proxy URLs added through Settings or the API are validated against the same blocklist. Invalid entries are rejected with
INVALID_URL, and bulk imports fail atomically if any entry is unsafe. - Ollama URL validation: Ollama base URLs are validated both at save time and again at request time, with every redirect hop re-checked and sensitive headers stripped on cross-origin redirects.
- Output provider credentials:
baseUrlvalues (e.g. Baserow) are validated when credentials are saved, rejecting unsafe URLs withINVALID_BASE_URL. - Redirect protection: outbound webhook and output provider requests now validate every hop in an HTTP 3xx chain (up to 5 redirects).
localhost, host.docker.internal, or any private network, you’ll need to set ALLOW_PRIVATE_NETWORKS=true for local development. Production deployments are protected by default with no configuration required.See Security for the full list of blocked ranges and configuration details.Gemini API key transport
Gemini API keys are now sent via thex-goog-api-key HTTP header instead of the ?key= query parameter, preventing keys from leaking through server access logs, reverse-proxy logs, or Referer headers. No configuration is required.If you previously relied on the ?key= form for log inspection or proxy filtering, update your tooling accordingly.