What runs where
| Part | Where it runs |
|---|---|
| The interface | Your browser — a static React bundle, no server rendering |
| Conversations, documents, settings | IndexedDB, on your device |
| The agent loop | Your browser, in JavaScript |
| Tools | Your browser — WASM, Web APIs, and free public endpoints |
| The model | Your provider, called directly from your browser — or your own machine |
| Our servers | Nothing. There is no application backend. |
Two small exceptions, both honest: a Cloudflare Worker relays requests to providers that refuse cross-origin browser calls, and optional sign-in uses Firebase so your encrypted API keys can follow you between devices. Neither sees your conversations.
The agent loop
When you send a message, the app builds a prompt, attaches a ranked list of relevant tools and streams the model's reply. If the model asks for a tool, the browser runs it — all the calls in one round happen in parallel — and feeds the results back. That repeats until the model answers in prose, with a cap so a confused model cannot loop forever.
A few details matter more than they sound. Tool schemas are ranked and capped per request, because sending all 177 would cost tens of thousands of tokens on every single turn and exceed some providers' limits outright. Models that reject a tools array fall back to a text-based protocol rather than losing their tools. And a turn can never end silently: if the model produces nothing usable, the app asks once more and then summarises the tool results it already has.
Tools without a server
The interesting constraint is that every capability has to exist inside a browser tab. That turns out to be less limiting than it sounds:
Python, really
CPython compiled to WebAssembly via Pyodide, with numpy and pandas loaded on demand. The kernel keeps its variables between messages, like a notebook.
Vision and OCR
Tesseract for text in images and small vision models on your GPU through WebGPU, so a model that cannot see still gets a description.
Video with audio
Frames drawn to canvas, encoded with WebCodecs, narrated by a neural text-to-speech model running on your device, and muxed into a real MP4.
Search over your files
BM25 keyword ranking over locally chunked documents — no embedding download, no vector database, and fast enough to feel instant.
Why this design
- Privacy is structural, not promised. There is no server that could keep your conversations, so no policy is needed to explain what we do with them.
- No subscription. You pay your model provider, at their prices, or nothing at all if you run a local model.
- It survives us. Static files and your own API key. Nothing to shut off, and your data exports to a file you keep.
- Offline where it can be. The interface, your history and the on-device models keep working without a connection.
What it cannot do
A design with no backend has real limits, and it is more useful to state them than to pretend otherwise:
- Some sites cannot be read. Browsers block cross-origin requests, and public relays get rate-limited by big sites. YouTube transcripts, in particular, are not reliably obtainable this way — the app says so rather than inventing one.
- Nothing runs while the tab is closed. Scheduled tasks need the desktop app; a browser cannot keep a timer alive.
- No filesystem or shell in the browser. Those are desktop-only, by the browser's design, not ours.
- Your device does the heavy work. On-device models need a decent GPU and a few hundred megabytes of download, which is why nothing downloads without asking.
Storage and durability
Everything lives in IndexedDB, and browsers may evict storage under pressure. The app requests persistent storage on startup, shows how much space it is using, and can export a full backup — conversations, documents and settings — to a file you keep. API keys are deliberately excluded from that file.
See it for yourself
Nothing to install for the web version, and no account to create.
Open the web app Browse the tools