# feder-cr/dots: a browser agent shell wrapped around one pinned dependency

> A 2,630-star Python project that advertises a patched Firefox engine but ships eleven files and admits in pyproject.toml that the whole product is a single exact-pinned dependency on another repository.

**feder-cr/dots** — Open-source dots for the web: an AI agent with its own browser, one that does not get blocked.

- Repository: https://github.com/feder-cr/dots
- Stars: 31,953 · Forks: 4,711
- Language: Python
- License: MIT
- Published: 2026-10-08 · Updated: 2026-10-08 · Language: en
- Canonical page: https://hysenlabs.com/projects/feder-cr-dots

## The dependency line that explains the repository

The most revealing text in this repository is not in the README. It is a comment above the single entry in the `dependencies` list of `pyproject.toml`, and it is unusually blunt about what the project is:

```python
dependencies = [
    # THE WHOLE PRODUCT IS THIS LINE.
    "invisible-playwright-mcp==0.70.2",
]
```

The comment goes on to explain that `dots` is the interface of `invisible-playwright-mcp` under another name, that the agent loop, the browser and the page all come from there, and that nothing in this repository re-implements any of it. The version is an exact pin rather than a floor, and the stated reason is that `cli.py` calls into that package's command group, which is not published API, so a new version is adopted on purpose with the test suite run against it.

That is a design decision, not an accident, and it is easy to respect. Depending on an unpublished internal entry point means a dependency release can break you without a breaking change notice, so freezing the version is the correct response. What it also means is that reading this repository tells you very little about how the agent actually works. The tree has eleven entries: `.gitattributes`, `.githooks/`, `.github/`, `.gitignore`, `LICENSE`, `README.md`, `pyproject.toml`, `src/` and `tests/`. There is no browser source here to read.

## Installation from git, because there is no release

The repository has no releases at all. The metadata records zero release entries, and `pyproject.toml` carries `version = "0.1.0"`. That is not a contradiction so much as a consequence of the install method, since both documented commands point at git rather than at a published package version:

```bash
curl -LsFf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env
uvx --from git+https://github.com/feder-cr/dots dots --openrouter-key sk-or-...
```

The Windows path is the same shape through PowerShell and the `uv` installer script. Because there is no tag to point at, `uvx --from git+...` resolves whatever `main` happens to be at the moment you run it, which means two people installing on different days can get different code with the same command. For a project whose whole value is a specific browser build, that is worth thinking about before you rely on it.

The interface itself is a local web page. The README says to open `http://127.0.0.1:8765` and get the conversation on the left and the browser on the right, live. The packaging metadata requires Python 3.11 or newer and classifies the project for Windows and Linux only, with classifier entries for Python 3.11, 3.12 and 3.13. Hatchling is the build backend and the console script maps to `dots.cli:main`.

The test configuration is also candid about its own scope. The pytest markers distinguish `unit`, described as pure logic with no I/O, network, subprocess or browser, from `integration`, described as running the real command in a subprocess with no network and no browser. Neither category exercises a real browser, which is consistent with the browser living in the dependency rather than in this tree.

## The patched Firefox claim and the repository that would contain it

The README's central claim is about the browser. It says the fingerprint is decided inside the engine rather than painted over with JavaScript that a page can inspect, that there is no WebDriver flag, no DevTools protocol and no automation globals in the page, that the pointer travels to what it clicks and keys are pressed one at a time so every event the page receives is a trusted one.

None of that can be checked here. The declared language is Python, the largest source file in the tree is `pyproject.toml`, and the README itself points elsewhere for the engine: `invisible_playwright_mcp` is linked as the repository that gives Claude Code, Codex, Gemini CLI or any MCP client this browser as a server, and the README describes `dots` as its interface. So the C++ patching, the seed-derived identity and the trusted-event input model are all claims about a different repository.

The related searches collected for this project point the same way. Alongside the repository name itself, the related terms are job applier tooling, LinkedIn automation, a LinkedIn jobs API and bot source code, which is roughly the workload profile the README's example request describes: a fares-and-dates lookup across a travel site, read day by day with an instruction not to guess a number when a date has no availability.

A reader should treat the engine claims as claims until they read that other repository. That is not a criticism of `dots`, which is explicit about the split, but it does change what a star count is measuring here. The 2,630 stars are for a name, a UI and a one-line install, not for Firefox patches.

## Seeds, proxies and a profile directory as the identity surface

Setting aside the engine, the README's option list is where the project's actual configuration surface appears, and every flag it names is an identity flag rather than a capability flag. `--seed` is described as giving back the same person on every run, with screen, fonts, GPU, timezone and language agreeing with each other. `--profile-dir` keeps logins and cookies from one run to the next. With `--proxy`, the timezone and the language follow the exit. `--model` changes which OpenRouter model is used.

Read together, those four flags describe a system whose central concern is consistency of identity rather than breadth of task capability. A seed that reproduces a screen size, font set and GPU string is a device fingerprint, and a proxy that carries matching timezone and language is an attempt to keep that fingerprint coherent with the apparent location. `--profile-dir` then extends the same identity across sessions, which is what makes login state reusable rather than re-authenticated each time.

That design has an obvious use and an obvious limit. The use is a research assistant that behaves like the same user on the second day, which the flight-search example needs in order to reuse a session at all. The limit is that this surface is aimed at not tripping detection, and the repository topics make the intent explicit with `anti-detect-browser`, `stealth-browser`, `browser-agent` and `web-agent`. Nothing in the README frames the tool as having a defensive or testing use case, and no ethics or authorization note appears anywhere in it. If you adopt it, the question of whose site you are accessing and with what permission is yours to settle, not the tool's.

## Topics that contradict the project's own disclaimer

The repository topics list nineteen entries, and three of them are about a project that has nothing to do with this one. They include `openai-dots`, `chatgpt` and `dotfiles`. The last is the clearest error, since `dotfiles` is a long-established Unix term and dots is not a collection of shell configuration files. The first two point at OpenAI's discontinued DOTS research preview, which was an adaptive prompting method, not a browser agent.

The README closes with a single line that reads: not affiliated with OpenAI, MIT licensed. That disclaimer and the `openai-dots` topic cannot both be describing the same thing, and the disclaimer is the one the author wrote by hand. The likely explanation is that the topics were chosen at some earlier point to catch search traffic for the word `dots`, and were never revisited. It is a small thing, but it is a useful signal about how much attention the non-code metadata here has received.

The license itself is unambiguous. `LICENSE` exists in the tree, the metadata reports MIT, and `pyproject.toml` declares `license = "MIT"` with `license-files = ["LICENSE"]`. That is the most internally consistent piece of metadata in the repository, which is a reasonable place to start when deciding whether the project is maintained in good order. The repository is not archived and the last push was on 2026-10-03, with 459 forks and a single open issue.

## Where the README stops

The README is short, around 2,400 characters, and covers installation, the six identity claims, one example request and the pointer to the MCP server repository. It ends with a note that `dots --help` lists every option, which is an admission that the option surface is not documented in prose. There is no architecture section, no configuration reference and no troubleshooting guidance. For a tool whose value depends on many interacting identity parameters, that leaves the README pointing outward rather than standing on its own.

The parts of the system that matter for evaluation all live elsewhere. Whether the engine patching is real and how deep it goes is a question for `invisible_playwright_mcp`. Whether the model integration handles streaming, tool calls and failures well is a question about the dependency rather than the wrapper. The one thing this repository tells you with total clarity is its dependency policy, and the comment in `pyproject.toml` is explicit that adopting a new upstream version is a deliberate act backed by the test suite.

So the sensible order is to read `pyproject.toml` first, then decide whether the browser claims are worth chasing in the other repository. Installing first and evaluating later inverts that, and with an unpinned git install there is no version to fall back to once you have seen what you actually got.

## Conclusion

dots is best read as a front end and a distribution wrapper, not as a browser project. The engine story lives in invisible_playwright_mcp, and the pinned exact version in pyproject.toml says the author intends to move that dependency deliberately rather than let a resolver pick it up. If you want the anti-detection browser, evaluate that repository, because that is where the C++ patching claim is either kept or not. If you only want a quick local loop with a browser panel on the right, dots gets you there with one uvx command and a key on the command line. Start by reading the comment above the dependency line in pyproject.toml, because it settles in three sentences what the rest of the repository is for.

## FAQ

### Is feder-cr/dots the same thing as OpenAI's DOTS?

No. OpenAI's DOTS was an adaptive prompting method for language models and is unrelated. The README of this project states plainly that it is not affiliated with OpenAI, although the repository topics still include `openai-dots` and `chatgpt` alongside an unrelated `dotfiles` tag.

### Does dots contain its own patched Firefox build?

Not in this repository. The README describes a Firefox engine patched in C++, but the declared language is Python and `pyproject.toml` states that the loop, the browser and the page all come from `invisible-playwright-mcp`, which the README links as the repository providing the browser as a server.

### How do I install dots, and how do I pick a version?

Both documented commands use `uvx --from git+https://github.com/feder-cr/dots`, so there is no version selection available. The repository has no releases and `pyproject.toml` carries `version = "0.1.0"`, which means each install takes whatever `main` currently holds.

### What do the --seed, --proxy and --profile-dir options actually control?

They control identity rather than capability. The README describes `--seed` as reproducing the same screen, fonts, GPU, timezone and language on every run, `--profile-dir` as keeping logins and cookies between runs, and `--proxy` as making timezone and language follow the exit address.

## Sources

- [feder-cr/dots on GitHub](https://github.com/feder-cr/dots)
- [Issues](https://github.com/feder-cr/dots/issues)
- [License: MIT](https://github.com/feder-cr/dots/blob/main/LICENSE)
- [README](https://github.com/feder-cr/dots/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/feder-cr-dots
