The agent workspace
Local AI agents, such as Claude Code, Codex, opencode or GitHub Copilot, can use Vimma through vimma-ctl mcp, an MCP server. They reach one workspace only, agent, with its own cookies and logins, and every request asks you first.
off until you turn it on
Agents cannot reach Vimma until you type :mcp on and answer y. They never see your other workspaces, the private workspace or your logins there, and :mcp off disconnects them at once.
Connect an agent
- Build
vimma-ctland put it on yourPATH(vimma-ctl, step 2). - In Vimma, type
:mcp onand press y. - Add the server to your agent's tool. For Claude Code:
claude mcp add --transport stdio --scope user vimma -- vimma-ctl mcp; for Codex:codex mcp add vimma -- vimma-ctl mcp. Other tools take the same command,vimma-ctl mcp, in their MCP settings. - Ask the agent to open a page in Vimma's agent workspace. Its request appears at the foot of the window, and nothing happens until you answer.
Answer a request
Each request names the agent, the tool and what it touches: the tab's title and address, or the address it wants to open.
| To | Press |
|---|---|
| Allow it once | y |
| Allow this tool for this agent for 15 minutes (a bare a: 10) | 15a |
| Deny it | n, Esc or Enter |
| Deny it and ignore this agent until it reconnects | x |
| Answer a request that is waiting | ctrl+b shift+a |
The question never interrupts your typing: while you type, or with focus in a text field, it waits, and the status bar says ◇ agent 1?. An unanswered request is denied after 50 seconds.
What an agent can do
- List the agent workspace's tabs, read a tab's text (marked as untrusted web content), open an
httporhttpsaddress there, and close one of its tabs. - Download files, each after a question; they go to
~/Downloads/vimma-agent/only, and Vimma never opens them. - Nothing else: pages there get no permission prompts and no pop-ups, and links to other apps open nothing.
To share a page of yours with an agent, move its tab to the agent workspace (m in the ctrl+b w picker). It is reopened with the agent workspace's cookies, never yours. :mcp revoke ends every grant, and :mcp forget clears the agent workspace's logins.
All the keys for this page
The default bindings, as Vimma's own ctrl+b ? overlay lists them. Name is the action's name, which you use to remap it or to run it as a : command. Every key is on the keys page.
Agents (3)
| Action | Keys | Name |
|---|---|---|
| Agents (MCP): :mcp on, off or forget | no default key | mcp_command |
| Answer the waiting agent request (none: revoke grants) | ctrl+b shift+a | agent_prompt |
| Full control for a while: :control on <minutes>, off | no default key | control_command |
Details
Everything below is Vimma's own user guide for this topic, in full: every edge case and exception. You do not need it to get started.
Agent workspace
Every profile has a workspace named agent, for local AI agents (Claude Code, Codex, opencode, Copilot) to use through vimma-ctl mcp. It is a workspace like the others, with a container of its own, so its cookies and logins are apart from main, work and the rest. An agent only ever reaches this workspace, and every request asks you first. To let one in, see Connecting an agent's tool.
- Made for you. A new profile gets it after
main; an existing one at its next start. It is cyan, with the fingerprint icon. It has no tabs until you move one in (or an agent opens one), so it loads nothing. If you already have a workspace namedagent(your own, or one in[workspaces]), that one is used and no second one is made. - Not in the cycle.
ctrl+b )/ctrl+b (,]w/[w,:wn/:wpskip it, and thectrl+^of another workspace never lands on it. You go there on purpose: the workspace picker, where it is the last normal row (◇ agent), or:ws agent. In it,ctrl+^goes back to where you came from. It always sorts last, so:ws 1…:ws Nkeep their places. - Emptied, never deleted.
ctrl+b shift+din it asksClose the 2 tabs of "agent"? It stays, with its cookies and logins (:mcp forget clears them). y/N: its tabs close and its container stays. It never counts as the last workspace, somain(or your last other one) stays too. Renaming it is refused (its name is [mcp] workspace in config.toml); to use another name, set[mcp] workspace. The old one then becomes an ordinary workspace. - Sharing a tab with an agent is moving it there (
min the picker, or:wsmove agent), after ay/N. The tab is reopened with the agent workspace's cookies, never yours.
| Command | What it does |
|---|---|
:mcp | Says whether agents are on or off, which workspace is theirs, and how many agents, questions and grants. |
:mcp on | Asks Let local AI agents ask to use the "agent" workspace? Every request asks you first. y/N, then on. |
:mcp off | Turns agents off, without a question. Connected agents are disconnected and their grants end. |
:mcp revoke | Ends every time-limited grant you gave agents, at once. |
:mcp forget | Asks, then deletes the agent workspace's cookies and site data (its logins). The workspace stays. |
ctrl+b shift+a | Answers the waiting agent request; with none, offers to end every grant. |
:control on 15 | Turns full control (vimma-ctl) on for 15 minutes, after a y/N; :control off ends it now. |
- When the agent workspace is one of yours rather than one Vimma made,
:mcp onwarns:"agent" is your own workspace (3 tabs, its own logins). Agents will be able to read it. y/N. :mcp on|offis remembered in the prefvimma.mcp.enabled.[mcp] enabledinconfig.tomlwins over it; then:mcp on|offchanges nothing and says to edit the file.- about:vimma's Agents (MCP) section shows the switch, full control's state and the agent workspace's tab count.
Connecting an agent's tool
vimma-ctl mcp is the MCP server your agent's tool starts. It speaks MCP over its standard input and output, connects to Vimma as an agent (never with full control), and offers four tools:
| Tool | What the agent can do |
|---|---|
vimma_tabs | List the agent workspace's tabs: id, address, title, whether it is loading. |
vimma_read_page | Read a tab's text, as Markdown or plain text, marked as untrusted web content. |
vimma_open | Open an http or https address in a new background tab there, or in one of its tabs. |
vimma_close_tab | Close one of its tabs. |
Build
vimma-ctl(Scripting with vimma-ctl, step 2) and put it on yourPATH.In Vimma,
:mcp onandy. Full control (vimma.control.enabled) can stay off: agents do not need it, and it is safer off.Add the server to your tool. Claude Code (tested with 2.1.287):
claude mcp add --transport stdio --scope user vimma -- vimma-ctl mcpCodex CLI (the line checked with 0.160.0):
codex mcp add vimma -- vimma-ctl mcp. Other tools (opencode, GitHub Copilot) take the same command,vimma-ctl mcp, in their MCP server settings. For a profile other than your default one:vimma-ctl --profile DIR mcp.
- Ask the agent, for example "open https://example.com in Vimma's agent workspace and tell me its heading". Each call waits for your answer on the question line; the agent says it is waiting.
- What the agent gets. A read comes back as a line saying where the text is from and that it is untrusted, then the text between
<untrusted-web-content>delimiters a page cannot close. A denial comes back asThe user denied this request in Vimma., and a question nobody answers within[mcp] ask_timeout(50 s) asNo answer in Vimma within 50 s; treated as denied.Codex gives up on a tool call after 60 s by default (tool_timeout_sec): raise it if you raiseask_timeout. - When it cannot reach Vimma, the call says what to do:
Vimma is not running…,MCP is off in Vimma: run :mcp on…, orThis Vimma is too old for MCP….initializeand the tool list work without Vimma, so the tool shows the server as connected either way. - One connection per agent session. It opens at the agent's first call and stays while the session runs;
◇ agentin the status bar shows it. Grants belong to it: when the session ends (or Vimma restarts), they end, and the next session asks again. - Cancelling a call in the agent (
Escin Claude Code) takes its question off the line.
Answering an agent
Each request an agent makes appears as one line at the foot of the window, above the status bar:
◇ claude-code wants vimma_read_page: 2 "Pull requests · vimma-browser/vimma" github.com/vimma-browser/vimma/pulls y once · 10a for 10 min · n deny · x mute
It names the agent (as the agent calls itself), the tool, and what it touches: the tab's place, title and address for a read or a close, the whole address for an open (its host in bold), the number of agent tabs for the tab list.
| Key | Answer |
|---|---|
y | Allow this request once. |
a count, then a | Allow this agent's use of this tool for that many minutes (15a); a bare a gives 10. |
n, Esc or Enter | Deny it. |
x | Deny it and everything else this agent asked, and ignore it until it reconnects. |
Backspace | Take back a digit of the count. |
- Nothing else answers. Any other key does nothing and the line stays; a key held down from before never counts; and for its first second the line takes no key at all (the hint appears when it is ready), so a key meant for something else cannot answer it. That second starts again whenever the window comes to the front or leaves it, and with every key pressed before it is up. A prompt, picker or the command line you open over the line gets your keys; the question waits and comes back when it closes.
- It never interrupts your typing. It opens by itself only when the window is in front, focus is not in a text field, you have not pressed a key for 1.5 s, and no other prompt, picker or panel is open. Otherwise it waits, and the status bar says
◇ agent 1?; pressctrl+b shift+ato answer it then. It never takes focus: answer, and you carry on where you were. If you click into a text field while it shows, it goes back to waiting. - One at a time, oldest first. An agent may have 4 waiting, and all agents 16. With no answer within 50 s (
[mcp] ask_timeout) the request is denied (agent request timed out (denied)). Three noes in a row from one agent ignore it for a minute. - Not in front? When Vimma's window is not the one you are using, it is marked urgent (on Hyprland, the workspace is highlighted) and a desktop notification says, for example,
claude-code asks to use Vimma's agent workspace (read a page). It carries no address or title and no buttons: you answer in Vimma.[mcp] notify = falseturns the notification off. - Grants show.
◇ agent 14mcounts down the shortest one, and each request a grant lets through shows a notice (claude-code read "Pull requests · vimma-browser/vimma" (grant, 14m left)).:mcp revoke, orctrl+b shift+awith nothing waiting and theny, ends them all. A grant also ends when the agent disconnects or:mcp offruns, and is never written to disk.
Full control while agents are on
An agent with a shell can read the control socket's token like any program of yours. So while agents are on (:mcp on), each new vimma-ctl connection with full control (keys in your window, every workspace) asks in the same line: ◇ vimma-ctl wants full control — y/N. y lets that one connection in, anything else from n, Esc, Enter or x refuses it, and nothing is remembered: the next one asks again. The line shows the code vimma-ctl printed in your terminal (vimma-ctl with code 7F3K wants full control): answer y only if it is the same, since another program could have asked at the same moment. vimma-ctl waits for your answer and says so; refused, it prints full control refused and exits 4. With agents off, nothing asks.
:control on 15 turns full control (the pref vimma.control.enabled) on for 15 minutes after a y/N, and then off again, even across a restart; :control off turns it off now, and :control says whether it is on and how long is left. Turning it on in about:config sets no end time.
What pages in the agent workspace may do
Pages there run with nobody watching, so they get less than yours:
- No permission prompts. A request for your location, notifications, camera, microphone, screen, MIDI, persistent storage, the local network and the rest is refused without a prompt.
- No pop-ups.
window.openand links that open a new window or tab do nothing there. - No other apps. A link to
mailto:,zoommtg:or another app's protocol opens nothing. - Downloads ask, and are kept apart. See Downloads from the agent workspace.
- If you change
[mcp] workspace, the new agent workspace's open tabs are reloaded once, so these rules apply to the pages already in them.
Downloads from the agent workspace
An agent (or a page in the agent workspace) may download files, but each one asks first, in the same line as every other request:
◇ claude-code wants vimma_download: "report.pdf" 2.1 MB application/pdf (.pdf) from example.com
It shows the file's name, its size (or unknown size), its type and extension and the site it comes from, never the full address. y, n, x and a count with a work as for any request; a vimma_download grant lets that agent's next downloads through without asking. A download counts as the agent's only when it is the address the agent itself opened (vimma_open), right then. Anything else, such as a page the agent opened downloading something later, says a page in the agent workspace wants vimma_download and takes only y or n, whatever grants you gave.
- Kept apart. Files are saved only to
~/Downloads/vimma-agent/([mcp] download_dir), never to your Downloads folder, with mode 0600: no one else can read them and nothing can run them. Until a file has passed every check it keeps a.partname there. The folder itself is kept private (mode 0700). It may not be your home folder, your Downloads folder, a hidden folder of your home (such as~/.local/bin), or/tmp,/var/tmpor/dev/shm. If the folder is not yours or cannot be made private, every agent download is refused, with a notice that says why. - Never opened. Vimma never opens an agent's download, offers no "open with", and refuses to open one from the downloads list later (
agent downloads are never opened by Vimma). Open it yourself from the folder once you trust it. - **Dangerous files ask with
!.** Programs and libraries (ELF, Windows and macOS programs, also found by their first bytes), scripts (.sh,.py,.js,.desktop, a#!line …), installers and packages (.deb,.rpm,.AppImage,.flatpak,.msi,.dmg…), and archives Vimma cannot look inside (.tar.gz,.7z,.rar…) end the question with— ⚠ a script(or what it is).yand grants do nothing there: only!allows that one file. A.zipis checked by the entries it lists (it is never unpacked). If one is a dangerous file, has an exec bit, is a symbolic link, or would unpack outside its folder (../,/…), the zip asks with!. Some dangers show only once the file is in: an ELF nameddata.bin, or a program inside what was allowed as a script. Then a second question asks before the file gets its name, andndeletes it. - https only. A download over plain
http:, or one a page's script made (blob:,data:), is refused (refused download "a.txt": not https). - A size cap. Over
[mcp] download_max_mb(200 MB by default, 1 to 4096) it is refused, or stopped and deleted once it grows past it when the server did not say its size. - ClamAV, if you have it (below). Each file is scanned before it leaves its
.partname, and a file ClamAV flags is deleted (deleted download "a.zip": ClamAV found …). Sometimes ClamAV fails, takes over five minutes, or cannot look inside a file (encrypted, or over its limits). Then the line asks— ⚠ not scanned: ClamAV failed; keep it?:ykeeps it unscanned, anything else deletes it. The notice sayssaved "report.pdf" to ~/Downloads/vimma-agent, scanned (ClamAV),not fully scanned (ClamAV)ornot scanned. Vimma has no download reputation service of its own: Firefox's Safe Browsing checks downloads only in a build with a Google key. - Your own saves are yours. Save Page (
ctrl+s), Save Link As and Save Image As in an agent tab ask nothing and save where you choose, as in any workspace: an agent cannot press them.
[mcp]
download_dir = "~/Downloads/vimma-agent" # ~/… or /…; never ~ or your Downloads folder itself
download_max_mb = 200
Virus scanning with ClamAV
ClamAV is optional, and Vimma does not ship it. If the system's clamscan is installed, Vimma uses it on every agent download. That means /usr/bin/clamscan or /usr/local/bin/clamscan, owned by root, never a copy found on your PATH. Without it, the notices say not scanned. Vimma does not update ClamAV or its virus definitions: your system's freshclam does.
On Omarchy and Arch:
sudo pacman -S clamav
sudo freshclam # the first download of the definitions
sudo systemctl enable --now clamav-freshclam # keeps them up to date
On Debian and Ubuntu, install clamav; the clamav-freshclam service keeps the definitions current. On Fedora, install clamav clamav-update and run sudo freshclam.
Two limits for now, both planned follow-ups:
- Vimma does not yet notice stale definitions. Keep
freshclamrunning, or scans use whatever definitions you last downloaded. clamscanloads its whole database for each file. A scan takes a while and about 1 GB of memory.
The guide at the top is written for this site; the details are built from Vimma's docs/guide.md at 52f2481 (2026-10-15), and the keys from docs/bindings.json at 52f2481 (2026-10-15).