# Octoweb Has Its Own Home — and It Still Runs on Your Models, Not Ours

> Octoweb, our free keyboard-first browser for macOS, moved out of the Octomind product menu and onto octoweb.xyz. The move is a good moment to answer the question we kept getting: no, it is not locked to our cloud. The browser never calls a model provider at all — a local Octomind agent does, against Octomind Cloud on one key or any of twenty-eight providers, including an Ollama box on your desk. Plus what four releases in three weeks added: workspaces, workspace-routed MCP, trusted native input, and A2UI v1.0. Open source, Apache-2.0.

# Octoweb Has Its Own Home — and It Still Runs on Your Models, Not Ours

Three weeks ago we [introduced Octoweb](/blog/introducing-octoweb-keyboard-first-ai-browser) — 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](https://octomind.run), 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](https://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

<figure class="ow"><div class="ow-bar"><span class="ow-dot ow-red"></span><span class="ow-dot ow-yellow"></span><span class="ow-dot ow-green"></span><span class="ow-omni">octoweb.xyz</span></div><div class="ow-body"><div class="ow-palette"><div class="ow-query">octoweb short<span class="ow-caret"></span></div><ul class="ow-results"><li class="ow-active"><span class="ow-badge">TAB</span><span class="ow-title">Keyboard shortcuts — every binding</span><span class="ow-host">octoweb.xyz/shortcuts</span><span class="ow-key">⌘1</span></li><li><span class="ow-badge">TAB</span><span class="ow-title">MCP server — 29 tools your agent can call</span><span class="ow-host">octoweb.xyz/mcp</span><span class="ow-key">⌘2</span></li><li><span class="ow-badge ow-hist">HISTORY</span><span class="ow-title">What the browser stores, and what it sends</span><span class="ow-host">octoweb.xyz/privacy</span><span class="ow-key">⌘3</span></li></ul><div class="ow-actions"><span>↵ Open</span><span>⌘↵ Navigate</span><span class="ow-ai">⌘⇧↵ Ask AI</span></div></div></div></figure>

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](https://octoweb.xyz/shortcuts)** — all 48 bindings in six groups, including the ones that only exist inside the palette and the AI prompt box.
- **[/mcp](https://octoweb.xyz/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](https://octoweb.xyz/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](https://octoweb.xyz/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](https://github.com/muvon/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:

```toml
[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](/blog/octolib-the-engine-behind-our-ai-stack) — 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 to `http://localhost:11434/v1/chat/completions`. That's Ollama out of the box; set `LOCAL_API_URL` and 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.

<figure class="ow"><div class="ow-bar"><span class="ow-dot ow-red"></span><span class="ow-dot ow-yellow"></span><span class="ow-dot ow-green"></span><span class="ow-omni">github.com/muvon/octoweb/pull/214</span></div><div class="ow-body"><div class="ow-split"><div class="ow-page"><span class="ow-line" style="width:80%"></span><span class="ow-line" style="width:62%"></span><span class="ow-line" style="width:71%"></span><span class="ow-line" style="width:48%"></span><span class="ow-line" style="width:66%"></span></div><aside class="ow-sidebar"><div class="ow-sidebar-head"><span class="ow-agent">octoweb:assistant</span><span class="ow-live">streaming</span></div><div class="ow-model"><span class="ow-model-label">model</span><span class="ow-model-name">local:qwen3-coder-30b</span></div><div class="ow-msg ow-user">What actually changes for our client in this diff?</div><div class="ow-msg"><p>Three things, one of them breaking:</p><span class="ow-line" style="width:88%"></span><span class="ow-line" style="width:63%"></span><div class="ow-a2ui"><span class="ow-a2ui-label">A2UI · approval card</span><span class="ow-btn ow-btn-primary">Open the diff</span><span class="ow-btn">Not now</span></div></div><div class="ow-sidebar-input">Ask about this page… <span class="ow-key">↵</span></div></aside></div></div></figure>

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.

<figure class="ow"><div class="ow-bar"><span class="ow-dot ow-red"></span><span class="ow-dot ow-yellow"></span><span class="ow-dot ow-green"></span><span class="ow-omni">⌘⇧O — workspaces</span></div><div class="ow-body"><ul class="ow-ws"><li class="ow-active"><span class="ow-key">⌘1</span><span class="ow-title">personal</span><span class="ow-host">14 tabs</span></li><li><span class="ow-key">⌘2</span><span class="ow-title">client-acme</span><span class="ow-host">6 tabs</span><span class="ow-media">▶ meet.google.com</span></li><li><span class="ow-key">⌘3</span><span class="ow-title">agent-scratch</span><span class="ow-host">2 tabs</span><span class="ow-badge">MCP</span></li></ul><div class="ow-actions"><span>Separate cookies, history, sessions and slots</span><span class="ow-ai">⌘⇧O to switch</span></div></div></figure>

**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 `NSEvent`s delivered to the tab's `WKWebView` — so pages see `isTrusted=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: attachment` in 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

```bash
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:

```bash
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](https://octomind.run) 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](https://github.com/muvon/octoweb), [the runtime](https://github.com/muvon/octomind), [the provider layer](https://github.com/muvon/octolib). If you run it against a local model and something is slower or dumber than it should be, [open an issue](https://github.com/muvon/octoweb/issues) — 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](https://muvon.io). It now lives at [octoweb.xyz](https://octoweb.xyz), runs on [Octomind](https://octomind.run), and works with whichever model you point it at. [GitHub](https://github.com/muvon/octoweb) — issues and pull requests welcome._
