Octoweb Has Its Own Home — and It Still Runs on Your Models, Not Ours
Three weeks ago we introduced Octoweb — the keyboard-first WebKit browser we'd quietly been living in since March. The response was better than we expected, and it arrived with one question attached, asked in half a dozen different tones:
So it only works with your cloud, right?
It's a fair thing to assume. The sidebar runs on Octomind, which is also the name of our paid cloud. The post said "install Octomind and sign in," and a reasonable reader concludes the browser is a funnel — that switching browsers means renting a model from us.
It doesn't, and it never did. That the answer wasn't obvious is a documentation failure we own, starting with the URL: the product page lived at octomind.run/product/octoweb, which says this is a feature of that thing you pay for before you read a word.
So we fixed the URL, and then we fixed the explanation.
Octoweb now lives at octoweb.xyz. Free, Apache-2.0, macOS 13+, no account. And the browser has never called a model provider in its life — it doesn't have the code to.
The new home
- TABKeyboard shortcuts — every bindingoctoweb.xyz/shortcuts⌘1
- TABMCP server — 29 tools your agent can calloctoweb.xyz/mcp⌘2
- HISTORYWhat the browser stores, and what it sendsoctoweb.xyz/privacy⌘3
That's the command palette — ⌘⇧P — fuzzy-matching across open tabs and history, which is how you get anywhere in Octoweb. It's also a fair preview of the site, because the site is mostly reference material rather than marketing:
- /shortcuts — all 48 bindings in six groups, including the ones that only exist inside the palette and the AI prompt box.
- /mcp — every one of the 29 MCP tools, grouped by what they do, with copy-paste config for Claude Code, Claude Desktop, and Cursor.
- /privacy — where each file lands on your disk, what binds to loopback, and an honest note that the website runs Google Analytics while the browser ships no telemetry at all.
- /blog — short, product-shaped posts. This one stays on muvon.io; that one is where release notes will live.
It's a static SvelteKit site on Cloudflare, prerendered, no client-side fetching — the same stack as the page you're reading. It took an evening. We should have done it in March.
The actual answer: whose model is it?
Here is the part that deserved a straight paragraph three weeks ago.
Octoweb's sidebar is not a chat client. When you press ⌘⇧A, the browser spawns a child process — octomind acp octoweb:assistant, sandboxed — and talks to it over the Agent Client Protocol. Every model call in the system is made by that process. Search the browser's 36,000 lines of Rust for an HTTP call to a model provider and you'll come back empty, because there isn't one. The browser knows how to render a conversation. It does not know what OpenAI is.
That matters because it moves the entire "which model" question one process to the left, into Octomind's config — where it's a single string:
[model]
name = "octohub:auto" # Octomind Cloud, one key, we route it
# name = "anthropic:claude-opus-5"
# name = "openrouter:qwen/qwen3-coder"
# name = "local:qwen3-coder-30b" # your box, your GPU, your electricity
Models are always provider:model — a bare name is rejected rather than guessed at. Behind those prefixes, octolib — the provider layer every Muvon tool shares — currently resolves 28 of them: openrouter, openai, anthropic, google-vertex, google-studio, groq, cerebras, deepseek, fireworks, together, xai, moonshot, minimax, nvidia, amazon, cloudflare, zai, alibaba and the rest.
Two of those prefixes are the ones this post is really about:
local:points at any OpenAI-compatible server, defaulting tohttp://localhost:11434/v1/chat/completions. That's Ollama out of the box; setLOCAL_API_URLand it's LM Studio on 1234, LocalAI on 8080, or the vLLM box under your desk. Nothing leaves the machine.cli:drives an agent CLI you already have installed —codex,claude,cursor,gemini— as if it were a model endpoint. If you're already paying for one of those, the sidebar can use it and you don't add a second bill.
And the keys never go in the config file. octomind config --api-key refuses to store one — credentials are read from the environment, then a user-scope .env, then a project-local .env. Your Anthropic key lives where your other keys live.
Where Octomind Cloud fits: it's the easy path, not the required one. octomind login is a device-code flow, like gh auth login. It writes one credential — OCTOHUB_API_KEY — and the default octohub:auto model then routes each call by purpose (main, supervisor, compression) to an appropriate model on our side. One key instead of six, one spend cap you can watch, and a free tier to start on. We think it's a good deal, which is why it's the default. It is also nine characters in a TOML file away from not being your setup at all — and the sidebar's account strip is a dismissible notice, not a gate.
The tag in the sidebar header is editable, so the same window can be talking to octoweb:assistant one minute and your own developer:rust agent the next — and as of 0.14.0 that field autocompletes from the tags your local Octomind actually knows, instead of you typing them blind.
Three weeks, four releases
Since the introduction post, Octoweb shipped 0.11.0 through 0.14.0 — 62 commits. Two of them changed how the thing feels to use.
Workspaces (⌘⇧O). Isolated profiles, and we mean isolated: each workspace gets its own tabs, its own history, its own AI sessions, its own MRU order, its own fast-access slots, and its own WKWebsiteDataStore — so cookies, localStorage and cache never cross. Two accounts on the same site, signed in at the same time, no incognito theatre. This is the feature we didn't know we needed until the day we stopped needing a second browser for the client project.
- ⌘1personal14 tabs
- ⌘2client-acme6 tabs▶ meet.google.com
- ⌘3agent-scratch2 tabsMCP
MCP is now routed per workspace. The single server on localhost:3434/mcp reads an X-Octoweb-Workspace token and acts inside that profile only. Which means an agent can drive a background workspace — logged into a scratch account, on its own cookies — while you keep working in yours, and it can't wander into your session by accident. The capability manifest goes further and refuses to expose the server at all when no token is present, rather than defaulting to whatever workspace is on screen.
The rest, briefly, and all of it in your hands rather than ours:
- Trusted native input. MCP clicks and keystrokes are now real AppKit
NSEvents delivered to the tab'sWKWebView— so pages seeisTrusted=true, a genuine user gesture, working:hover, and native default actions. It works on hidden background tabs without stealing your focus. Synthetic DOM events could never do all four. - Every action answers with what changed. Each tool call returns a one-line effect summary — navigation, SPA URL change, new text on screen, dialogs, network activity, focus moves — or says "no observable change" out loud. The agent stops burning a turn re-reading the page to find out whether its click landed. Sensitive query parameters get scrubbed out of the reported network activity on the way.
- Downloads exist now. A runtime patch makes WebKit honour
Content-Disposition: attachmentin main frames and subframes — that's what Google Drive uses — and the resulting filename shows up in the effect summary even when the page said nothing. browser_dismiss_overlay. Kills cookie and consent banners, and it prefers Reject — it will not auto-accept on your behalf.- A2UI v1.0. The agent can render a real interactive surface in the sidebar — cards, forms, choice pickers, sliders, modals — with data binding and validation, and wait up to half an hour for you to click something. Consequential actions are supposed to route through it: ask, then act.
- Live media tabs. The workspace switcher shows which tabs are playing audio or video or holding a live mic — so the meeting you left running in another profile is findable, not haunting.
Two things we got wrong in August
House rule: when the last post was wrong, the next one says so.
Global shortcuts do not run through CGEventTap. We wrote that they did; the code moved off it back in May. CGEventTap requires macOS Accessibility permission, and asking a browser-shaped thing for keylogger-grade access is a bad trade for a feature nobody asked for. Octoweb uses an AppKit local NSEvent monitor instead — zero permissions, and honestly scoped: it only sees keys when Octoweb is frontmost. "System-wide" was the wrong word for the right design.
Passkeys are not in there. The August post listed WebAuthn among the shipped fundamentals. The commit that added it was reverted in May and we didn't catch it before publishing. It is not in 0.14.0.
Two smaller corrections while we're here: the MCP server is 29 tools, not 26 — browser_fill_form, browser_dismiss_overlay, browser_get_playing_tabs and render_ui arrived since. And the "about 25,000 lines" is now 35,972.
Get it
brew install --cask muvon/tap/octoweb
macOS 13 or later, Apple Silicon or Intel, no account. Or build it yourself, which takes a Rust toolchain and about a minute:
git clone https://github.com/muvon/octoweb
cd octoweb
./build.sh --dev
open dist/Octoweb.app
With no AI configured at all, Octoweb is a browser: palette, slots, workspaces, find-in-page, content blocking, tab hibernation. The sidebar wants Octomind installed alongside it, and from there the model is a one-line decision — octomind login for our cloud, or an exported key and a provider:model string for anything else. We use both, on different machines, depending on what the work is and what the network looks like.
Everything is Apache-2.0: the browser, the runtime, the provider layer. If you run it against a local model and something is slower or dumber than it should be, open an issue — that path gets less testing than the cloud one, and the only fix for that is you telling us.
— Don
Octoweb is open source under Apache-2.0, developed by Muvon Un Limited. It now lives at octoweb.xyz, runs on Octomind, and works with whichever model you point it at. GitHub — issues and pull requests welcome.



