dots: The AI browser agent that makes the browser the whole product

A thin Python CLI wraps a stealth-patched Firefox engine, deterministic fingerprints, and MCP integration into a local-first way to browse the live web without looking like a bot.

9 min read • View on GitHub • More from feder-cr

A tiny terminal-style control tower sits on top of a much larger browser machine, with layered gears and signal lines underneath. The scene explains the project's central paradox: a minimal CLI front end commanding a heavy stealth browser engine below.
The wrapper is tiny. The browser body is where the real work happens.

The fingerprint is decided inside the engine, not painted over with JavaScript that a page can inspect. One identity per seed. Screen, fonts, GPU, timezone and language agree with each other, and --seed gives back the same person on every run.

Federico C.R., Project Creator / Maintainer · feder-cr/dots README
Key Takeaways

The smallest repo with the biggest browser. That is the trick here. `dots` looks like a thin Python package, but it fronts a much heavier machine: a patched Firefox stack, a deterministic identity model, and an MCP-friendly interface built for hostile web surfaces.

That matters because most browser agents fail for a boring reason. They can reason, but they still show up as a bot. A site does not need to defeat the model if it can reject the browser first.

Why the browser is the real bottleneck

The usual automation stack starts with Playwright, Selenium, or a browser-agent framework, then adds stealth on top. `dots` starts lower. It assumes the browser is the battlefield, and that anti-bot systems are watching the body, not the prompt.

`dots` sits between the model and the browser body. It is a control layer, not the browser itself.

LayerStandard browser automationdots
Primary goalRun pages and scriptsSurvive hostile detection surfaces
Stealth strategyJavaScript shims and patchesEngine-level browser identity
Identity modelOften ad hoc or randomDeterministic and seed-based
User interfaceFramework-firstCLI-first, branded wrapper
Deployment styleGeneric automation stackLocal-first browser persona

dots turns identity into a reproducible system

The most distinctive idea in the repo is not stealth by itself. It is coherence. `--seed` is presented as a way to generate one believable browser person, not a grab bag of spoofed values that happen to dodge one test today.

A central seed token links to a cluster of browser identity parts: timezone, GPU, fonts, screen size, audio profile, cursor speed, and typing cadence. Around the edges are detection surfaces that light up when the signals agree or conflict, showing how one seed produces a coherent browser persona.
The goal is not randomization. It is a stable identity that feels internally consistent.

That distinction is subtle, but it is the whole story. A browser that randomizes everything can look suspicious because it contradicts itself. A browser that keeps GPU, fonts, timezone, screen size, and event timing in agreement looks less like a patchwork and more like a person.

GitHub avatar portrait of Federico C.R., the maintainer of dots. The portrait gives a human face to the project's creator and supports the article's discussion of a vision-led, tightly scoped repo.

The CLI is the product, the engine is the moat

This is where the package earns its shape. The user lands on a clean command line, while the real complexity lives in the dependency chain and the browser engine underneath. The facade is not cosmetic. It is the product boundary.

# src/dots/cli.py
from invisible_playwright_mcp.cli import main as mcp_main

# dots adds a branded entry point and passes the hard work through.
# The command surface stays small even as the browser layer stays complex.

def main():
    mcp_main()

That move is clever because it separates trust from implementation. Users do not need to understand the patched browser internals to benefit from them. They need a stable command, a repeatable identity, and a browser that behaves like it belongs on the site.

A disciplined ecosystem, not just a script

The repo's credibility comes from the boring parts: CI, hooks, tests, and claim-checking. That discipline matters in a stealth product, because promises about browser behavior are easy to oversell and hard to verify.

DisciplineWhat it signalsWhy it matters
Strict testsThe wrapper does what it saysPrevents silent breakage in a fragile stack
Pre-push hooksQuality gates before publishKeeps the repo honest before code ships
Pinned dependenciesControlled runtime surfaceReduces surprise in a browser-sensitive tool
Lean codebaseA narrow product scopeMakes the hidden engine easier to trust

The result is a repository that feels bigger than its line count. It is not bloated, but it is not casual either. It is a carefully narrowed interface around a system that has to stay coherent to work.

How it compares to the rest of the agent stack

`dots` is not trying to be the broadest browser agent. It is trying to be the one that survives on the most hostile surfaces. That puts it in a different class from general-purpose automation tools and cloud-first computer-use products.

Project typeStrengthTrade-off
Playwright or Selenium style agentsGeneral automation and familiar APIsOften easier to detect
Browser-use or SkyvernHigher-level task orchestrationStill depends on the browser layer underneath
Camoufox or invisible-browser toolingStealth at the browser layerLess productized as a user-facing agent
Cloud computer-use productsManaged experience and orchestrationLess local control and less identity coherence
dotsLocal-first stealth wrapper with seedable identityNarrower scope, but stronger fit for hostile live sites

That is the point. `dots` does not win by being a universal agent platform. It wins by focusing on the narrow layer where most agents actually fail. The browser is the body, and this repo is built for the body, not the brain.

The bigger implication: agents need bodies

The broader lesson is simple. Agent tooling is moving past pure reasoning problems. If a model cannot inhabit a browser that looks real enough to pass scrutiny, the rest of the stack barely matters.

`dots` is a reminder that the next wave of agent infrastructure may be less about clever prompts and more about credible embodiment. The browser itself becomes the product, because the browser is where the work gets admitted or denied.