orbotodocs
Agents & AI

Browser for your agents

Any agent that works with orboto can open and use a web browser through the orboto command line - no AI vendor account, short commands, page contents never leave your machine.

Added in v0.205.1 Any agent that works with orboto can open and use a web browser through the orboto command line. It needs no account with an AI vendor. Your agent runs short commands: orboto browser start opens a browser, open <address> loads a page, snapshot --interactive-only lists the buttons, links and fields on it, click and type use them, and screenshot --attach ACME-12 puts a picture of the page on a ticket. Each command prints a few lines. Nothing sits in the agent's memory between commands.

orboto browser start --headless --allowed-hosts localhost
orboto browser open http://localhost:5173/projects/acme
orboto browser snapshot --interactive-only
orboto browser click e12
orboto browser screenshot --attach ACME-12 --alt "the board after the change"
orboto browser stop

Three ways to reach a browser

  • Own profile (--mode profile): orboto starts its own Chromium, with a window or --headless on a server, and keeps its sign-ins between runs under ~/.orboto/browser/. It is a browser of its own, with an empty profile and none of your sign-ins.
  • Attach (--mode attach): orboto drives the Chrome or Edge you already have open. Start that browser once with a debugging port and sign in there; it stays signed in.
    • macOS: open -na "Google Chrome" --args --remote-debugging-port=9222 --user-data-dir="$HOME/.orboto/browser/cdp-chrome"
    • Linux: google-chrome --remote-debugging-port=9222 --user-data-dir="$HOME/.orboto/browser/cdp-chrome"
    • Windows (PowerShell): & "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="$env:USERPROFILE\.orboto\browser\cdp-chrome"
    • Edge works the same way with its own executable.
  • Extension (--mode extension): install the orboto Browser Extension in Chrome, Edge or another Chromium browser, and the agent works in the tabs you share with it. No debugging port, no restart of your browser - see the next section.

orboto browser doctor starts with the mode a session would use and why, then tells you what is missing for it and how to fix it. orboto browser install fetches the browser once.

Which mode a session uses

Added in v0.230.10 If you start a session without --mode, orboto looks at your computer and picks the mode itself, and prints one line saying which and why:

  1. You named a browser that is already running with --cdp: attach.
  2. You asked for --headless: own profile, because that needs a browser orboto starts.
  3. The orboto Browser Extension is installed in Chrome, Edge or Chromium, and somebody can answer: you sit at the terminal, or the extension is paired with your orboto account (or with orboto browser pair) and approves the connection itself: extension, the agent works in your own browser.
  4. Otherwise: own profile. If the extension is installed but nobody can click Allow, for example an agent without a terminal and without a pairing, the session starts the own profile instead of waiting for a click that never comes, and the line says how to use the extension: start with --mode extension and click Allow, or pair it.

If orboto chose the extension and nobody sits at the terminal, it waits at most two minutes for Allow and then ends with "click Allow or use --mode profile". If it falls back to the own profile and Google Chrome is installed, the own profile runs in that Chrome; --mode profile always starts the Chromium orboto manages.

--mode profile, --mode attach and --mode extension always do what they say. An orboto-browser entry that orboto mcp install --browser wrote without --mode used to start the own profile and now follows your computer the same way: it uses the extension when it is installed and paired. orboto mcp status shows what each entry does on your computer. Write --mode profile into the entry to keep the browser orboto starts.

The extension is the mode for logins behind bot protection. It is your own browser, with its own name and version, your sign-ins and your extensions. The browser orboto starts has an empty profile and none of your sign-ins. orboto browser doctor says so for attach and own profile and shows how to switch to the extension. A check that a site asks you to pass stays yours: the agent does not solve it, and orboto changes nothing about how your browser presents itself.

Your own browser without a debug port

Added in v0.206.2 Extension mode lets your agent work in the browser you already use, in the tabs you share with it, through the orboto Browser Extension. It works in Chrome, Edge, Brave and every other Chromium browser. Firefox does not give extensions the debugger access this needs, so there is no Firefox version.

  1. Install the orboto extension (see "Install the orboto Browser Extension" below).
  2. Start a session: orboto browser start --mode extension. Add --browser-name msedge or --browser-name chromium for Edge or Chromium, and --profile-name "Profile 1" if you use several browser profiles. For Brave or another Chromium browser, set ORBOTO_BROWSER_EXECUTABLE to its program file.
  3. An orboto page opens in your browser. It shows who is connecting: you, the session, the ticket, your instance. Choose what to share: the tab you used last, tabs from a list, or a new empty tab. Click Allow.
  4. The shared tabs move into a tab group named after the session. Drag a tab into the group to share it, drag it out to take it back. The agent sees no other tab.
  5. To stop, click the orboto icon in the toolbar and choose Disconnect, or run orboto browser stop.

You do not need a debugging port, and you do not copy a token. orboto browser doctor --mode extension checks whether the extension is installed and names the browser it will open.

Added in v0.230.10 The agent tool sees your browser as it is: the same name, version and user agent that every website sees, read from the browser when the session connects. orboto does not send a user agent of its own, and the name of the orboto relay appears only in the session log and in orboto browser status.

Install the orboto Browser Extension

Added in v0.206.2 The orboto Browser Extension lets an agent session work in the browser you are already signed in to, through the orboto CLI on your computer. It runs in Chrome, Edge, Brave and every other Chromium browser from version 121. Firefox gives extensions no debugger access and is not supported.

Your instance's install page is always https://<your instance>/api/extension. It shows the extension version your instance ships, the store buttons, and for managed browsers the signed package with the policy line.

  • Chrome, Brave and other Chromium browsers: install it from the Chrome Web Store (the button on the install page).

  • Microsoft Edge: install it from Edge Add-ons.

  • Browsers your company manages: your administrator adds this value to the ExtensionInstallForcelist policy. The browser installs the extension from your instance and keeps it up to date:

    lpfkgjagallpeeeicnofiddcmnnefefh;https://<your instance>/api/extension/updates.xml

    On Windows this is Group Policy or the registry, on macOS a configuration profile for com.google.Chrome or com.microsoft.Edge, on Linux the file /etc/opt/chrome/policies/managed/orboto.json.

Then connect it:

  1. Pin the orboto icon to the toolbar.
  2. Click it, open the status page and sign in to your orboto instance.
  3. Run orboto browser start --mode extension. The connect page approves itself for your account.
  4. orboto browser doctor --mode extension checks every piece and tells you when the installed extension is older or newer than your instance.

Pair the orboto extension with your orboto account

Added in v0.206.2 Once you sign in to your orboto account in the orboto extension, connections from your own orboto CLI approve themselves. You do not need to copy a token.

  1. Click the orboto icon in Chrome, Edge or Brave, enter your orboto address (for example acme.example.org) and click Sign in to orboto. Your normal orboto login opens in a small window. The extension stays signed in and renews its access by itself.
  2. Run orboto browser start --mode extension, or use the MCP form. The CLI asks orboto to pair this connection, and the connect page approves itself. The agent then works in a new tab inside its own tab group. To share more tabs, drag them into the group.
  3. orboto notifies you the first time a browser pairs. In some cases the connect page still asks you with Allow and Deny: when you are signed out, when you are signed in to a different orboto account or instance, when the request is more than ten minutes old, or when orboto cannot be reached. The page tells you which of these applies. If a connection does not approve itself within 30 seconds, orboto browser start keeps waiting for your click only when you started it in a terminal; otherwise it stops and tells you what to fix.

To unpair a browser, go to Account -> Security -> Browsers, run orboto browser unpair <id>, or ask your admin to do it under Admin -> Agents -> Browsers. Its connections close at once and the extension signs out.

If you have not signed in to orboto in the extension, you can pair with a code instead. Click the orboto icon and choose Create pairing code. Then run orboto browser pair in a terminal and type the code; it stays hidden while you type. From then on, connections from that CLI into that browser profile approve themselves. Each approval is valid for ten minutes and only once, so a connect page you reopen from the browser history asks you again. New code in the extension makes the old code useless. orboto browser pair --clear removes the code from the CLI.

orboto browser pairings            # your paired browsers: online, offline, last seen
orboto browser unpair <id>         # connections close, the extension signs out
orboto browser pair                # the pairing code, without an orboto sign-in

What you see in the browser

Added in v0.206.2 When your agent works in extension mode, you see what it does and you stay in charge, right in your browser.

  • The side panel. Click the orboto icon in the toolbar. The panel shows who is working (you, the session, the ticket, your orboto instance, since when) and a list of everything the agent did: what it opened, clicked or typed into, whether it worked, how long it took, and a small picture when it took a screenshot. What the agent types is never shown there.
  • On the page. A tab you shared gets a thin teal frame with the name of the session. You see the agent's pointer move across the page, and each element it clicks lights up for a moment. The frame never gets in your way: you can click and type as usual.
  • Allow or Deny. Before the agent pays, deletes, sends or signs something, it stops and asks you in the side panel. The panel says what it wants to do, on which element and site, and the element is marked on the page. Allow lets it go ahead. Deny stops that step, and the agent is told you said no; it cannot repeat that step with --confirmed while the panel is open. If you do not answer within two minutes, the step is not taken.
  • Pause and Stop. Pause holds the agent's next steps until you click Resume. Stop ends the session at once; the agent is told that you stopped it in the browser.
  • Allowed sites. The panel lists the sites the agent may work on. Remove one, or allow the site of the tab you are looking at. The change applies immediately.
  • Tabs. Share the tab you are on, pick tabs from a list, or open a new empty tab for the agent. Unshare a tab to take it back; unsharing the last tab ends the session.

The orboto icon shows how many steps the agent took, and a ! while it waits for your answer.

Your orboto instance keeps the record. Added in v0.206.2 What you change in the side panel is also written to the session on your orboto instance: the sites you allowed or removed, the steps you allowed or denied, Pause, Resume and Stop. Only the site and the kind of step are recorded, never the page or what was typed. The session's list of allowed sites follows your changes, and Admin -> Agents -> Live shows the latest of these events next to the actions the allowlist refused. If your instance cannot be reached for a moment, the agent keeps working and the record catches up.

What stays hidden. Added in v0.209.0 What the agent types into a password or credential field never comes back to it in plain text. When the agent types or selects a value, orboto first asks the page what the target is: a value that goes into a password field, a field for a new or current password, a one-time code, a card number or a card security code, or into something the page cannot identify as a form field, shows as ***** in every later snapshot, error, log line, journal entry and side panel event of that session (values under four characters excepted, they would blank ordinary text). What the agent types into an ordinary text field, a search box or a dropdown stays readable, so it can read results that echo its own input. A snapshot also masks the value of every password and credential field, whoever filled it: the agent, the browser's autofill or the page. The MCP form and a browser driven through the relay go through the same session process and get the same text. Screenshots are the exception: a picture shows what the page shows, so a page that reveals a password shows it in a screenshot too. A page that hides its password fields from orboto's lookup can defeat the field-type rule; what the agent typed is still masked, and a field whose name says password, PIN, code or card is masked in any case.

What it can do and what it cannot

It can open pages, read them, click, type, pick from lists, wait for text and take screenshots. It only acts on the sites you allow: by default that is your orboto address and your own computer (localhost); pass --allowed-hosts for more, or --allowed-hosts '*' --yes for everything. Anything else is refused and recorded. Downloads are off unless you name a folder with --downloads.

Added in v0.230.0 One page call runs at a time, so every call is checked against the page the call before it reported. A click sent while a navigation is still running waits for that navigation, and is refused when the navigation landed on a site outside the list.

orboto never reads your passwords, your browser's saved cookies or other programs' logins. Page contents and full web addresses never leave your machine. Your orboto instance keeps only when a session started and ended, which mode it used, which sites it was allowed, and the site and command of every refused action. You see this under Admin -> Agents -> Live.

Working for you: mouse and keyboard like a person

Added in v0.205.1 orboto can work for you in your own browser when you cannot use it yourself for a while. An agent does what you ask, in your Chrome, signed in to your own accounts. Many pages only react when a mouse really moves: menus open on hover, cards are dragged, sliders follow the pointer. So the agent moves the mouse like a person: along a curve, in a fraction of a second, pressing and releasing the button like a finger would, and typing one key at a time. snapshot --boxes tells the agent where things are, click --at, move, drag and scroll use those positions, and screenshot --grid draws a labelled grid for agents that read the picture.

Before anything you cannot take back (paying, ordering, deleting, sending, signing, cancelling a subscription) the agent stops and shows you exactly what it is about to do: which button, on which site. It only goes ahead once you agree. If you want the agent to act without asking, start with --confirm never.

Nothing is hidden: orboto does not disguise the browser or pretend to be someone else. Sites see your own browser, used on your behalf. If the agent should not touch your open Chrome, orboto browser profile --from-chrome copies your Chrome profile (with Chrome closed) into a separate one. That copy contains your logins, so treat it like the browser itself; orboto never sends it anywhere.

Driving a browser on another machine

Added in v0.205.1 An agent on one computer can use a browser that runs on another computer, through your orboto instance. Nothing has to be opened on the network: both computers only talk to orboto.

  • On the computer with the browser, run orboto browser serve --register --name desk. The browser stays available while that command runs. If the computer is offline for more than ten minutes, it drops off the list and comes back under the same name when you start it again.
  • On the other computer, run orboto browser connect desk, then use the usual browser commands with --remote desk. For Claude Code or Codex, orboto mcp install --browser --remote desk adds it as a tool server.
  • Only one agent drives a browser at a time. If someone else is driving, the command names them and stops. orboto browser release desk hands the browser back.
  • By default only you can drive your browser. orboto browser grant desk --user colleague@example.org lets a colleague drive it; orboto browser revoke desk --user colleague@example.org takes that back. If someone without permission tries, you get a notification.
  • The list of websites the browser may visit is set on the computer that runs it and applies to everyone who drives it.
  • Admin -> Agents -> Live shows every registered browser: the computer, the mode, the owner, who is driving it now, the allowed websites and the last action. Revoke ends it immediately.
  • orboto passes the commands on but stores no page content: it records only the name of the action and the website.

Added in v0.230.0 Every answer is bound to its request and to the driver connection that sent it. A request needs a string or number id that is not waiting for an answer on that browser. If it is, orboto refuses the request with a browser_error frame (status 409, error key errors.agents.browser_relay_request_id_taken, with the refused requestId) and records the refusal on the browser session: it counts as a refused action and is written to the audit log as agent.browser.refused with the action duplicate_request_id (or reserved_request_id for an id in the instance's own orboto-relay-tools- namespace). A frame that is neither such a request nor a notifications/* frame without an id gets browser_error with status 400 and errors.agents.browser_relay_frame_invalid. An answer only reaches the driver whose request waits for it: a second answer for the same id, an answer nobody asked for and the answer to a call of a driver that was replaced in the meantime are dropped, so every answer you receive went through the response budget and was recorded.

When the browser's computer reconnects, every call it had not answered yet ends with JSON-RPC error -32603 ("the relayed browser reconnected before it answered"). Send the call again.

orboto browser connect sends a fresh id for every request, and a call orboto refuses ends with the error key instead of waiting for a timeout. Its MCP form (orboto browser connect desk --as-mcp) refuses a client request whose id is still waiting for an answer with the same -32600 error as the local MCP form described below.

Logging in with a stored login

Added in v0.211.0 An agent can log a site in without ever knowing the password. orboto browser login --credential acme-login takes a login from the credential vault: the browser fetches the username and password from your orboto instance, finds the fields on the page, types them and signs in. When the site then asks for a one-time code, it takes the current code from the login's TOTP secret at that moment. The agent gets one line back, logged in as build@example.org at id.example.org, or why it did not work: wrong credentials, a second factor that is needed but not stored, a code the site refused, no login form, a captcha, a page that is not the login's site, or a site that did not answer. The browser only types a login into the site it belongs to. If the credential has no site address, pass --url with the login page.

  • Nothing to read back. Everything the browser types from the vault shows as ***** in snapshots, errors, the log and the side panel. Only the username stays readable.
  • Every step is recorded. The password, each one-time code and each recovery code count as a reveal of the credential, with the purpose "browser login", the browser session and the agent session. You see them in the credential's reveal history.
  • Three strikes. If the site rejects the password or the code three times in a row, orboto stops browser logins with that credential, so an agent cannot lock the real account. A site that does not answer is not a strike. Check the account on the site, then click Reset on the credential or run orboto credential reset-login acme-login.
  • Recovery codes only when you say so. With --allow-recovery-code the browser may use one of the login's recovery codes when the site refuses the one-time code or the login has none. The code is marked as used and the person who created the credential gets a notification.
  • Second factors the vault does not hold. When the login has recorded factors such as a hardware key and the site asks for one, the login stops with a line that names the factor and your note. It is not a strike.
  • Fields orboto does not find. --user-field, --password-field, --totp-field and --submit point at the right elements.
  • For a lane. orboto credential grant acme-login --browser-session desk lets the registered browser desk use the login, without a person holding a grant for it. It applies when the login reaches that browser from another machine through orboto. At the browser's own computer, including a lane's own browser, the account's own access decides: grant the lane's agent account with orboto credential grant acme-login --user AGENT_ACCOUNT --level reveal.

Passkeys

Added in v0.211.0 The orboto browser can create a passkey on a site and keep it in your credential vault, and it signs later logins with it. No phone, no password manager, and the agent never sees the key.

orboto browser passkey register --credential github-passkey --url https://github.com/settings/security --trigger '#add-passkey' opens the page, clicks the site's "Add a passkey" button and waits until the site has created the passkey. The browser answers the site with a temporary built-in authenticator, stores the new passkey in the vault under the key you named and removes the authenticator again. You get one line back: passkey registered for github.com as github-passkey. Without --trigger, click the button yourself in the open browser within a minute. If the site registers an algorithm the vault does not keep (only ES256 and EdDSA are stored), the vault refuses the passkey; remove it in the site's security settings and try again.

orboto browser login --credential github-passkey then signs in with it: the browser loads the passkey into a fresh authenticator for this one login, clicks the site's passkey button and removes the authenticator afterwards.

  • The key stays in the vault. Nobody can reveal a passkey, not even an administrator. Its private key only leaves the vault into the browser's authenticator, and each time counts as a reveal with the purpose "browser login". While the authenticator is attached, the browser refuses the raw code tool to any other caller, so no one can read the key through it.
  • A login with a passkey on top. Link a login to a passkey (orboto credential update site-login --passkey-key github-passkey, or the Linked passkey field). The browser types the password as before and answers with the passkey when the site asks for one.
  • Stale passkeys. When the site refuses the passkey, for example because it was removed in the site's security settings, the login ends with "the site refused the passkey", the credential shows Stale and the person who created it gets a notification. Register a new passkey there; the mark disappears with the next successful login.
  • The counter. A passkey counts its logins. orboto stores the new count after every login; a login whose count did not go up, for example because another browser used the passkey first, is treated as refused.
  • Code calls end vault steps. Added in v0.211.3 A remote driver never gets the tool that runs code in the browser, in any mode. When a client runs code in the browser session (browser_run_code_unsafe), every later login or passkey step in that session is refused with "a client ran code in this browser session; restart the session before a login or passkey step", whichever way it is started. A new session starts clean. Login and passkey steps started by any caller make the other callers of the session wait until the step is done.
  • Who may register. Registering needs secret:manage in the project the passkey lands in. Using one follows the same grants as a login.

Fill logins from the vault

Added in v0.218.0 The orboto extension can fill logins and one-time codes for you, from the credential vault of the instance it is signed in to. It uses the pairing you already have, so there is no second login and no second store. On a page it offers the logins you may reveal for that site. One click fills the user name and the password. When the login has an authenticator secret, the next page of the same site offers Fill code, and a second click types the current one-time code.

  • Where you see it. An orboto button sits in each password field, in its user name field and in a one-time code field. It opens a menu of the matching logins. Alt+ArrowDown in the field opens the same menu, the arrow keys, Home and End move, Enter picks and Escape closes it. The side panel lists the same logins for the current tab with Fill, Fill code and Copy. Nothing is offered while the vault is locked, and the code offer for a login stays open for five minutes.
  • Which logins are offered. Only logins you may reveal, and only for a matching site. By default a login matches every page of the same registrable domain as its URL (login.example.co.uk and www.example.co.uk match, example.com and examp1e.com do not). On the credential, someone with manage access can narrow that to the exact host, or to the exact host and the pages under the URL's path, and can add alias hosts: up to 20 more hosts that follow the same rule. Frames from another origin than the tab never get an offer.
  • When it refuses, and why. The extension does not fill, and tells you the reason, when the page belongs to another registrable domain than the login, when the page is not served over https (localhost, 127.0.0.1, [::1] and *.localhost are the exceptions), when the form or its submit button posts to another origin, or when the page changed between your click and the fill. The last case matters when the vault asks you for a second-factor code first: if the tab has moved on meanwhile, the menu says the page changed and nothing is typed. Your instance refuses a fill for another site as well, even if the extension were bypassed.
  • Every fill is recorded. A fill is a reveal of the credential with the purpose "browser login", and the audit entry names the credential and the page origin. A one-time code is recorded the same way. You see them in the credential's reveal history and in Admin -> Security -> Credentials -> Reveal audit. Pressing Copy is recorded as a copy, not as a fill.
  • Second factor. If your account has a second factor, the vault asks for an authenticator or backup code before a fill. The prompt appears in the side panel, never on the page, so the page cannot see the code. A confirmation holds for 15 minutes, then the vault asks again. A code that was already used is refused, and five wrong codes lock the second factor for five minutes. An account without a second factor fills without a prompt. An API key cannot confirm.
  • Locking. The vault starts locked. It locks again after the idle time (15 minutes by default), when Chrome reports the screen as locked, and when the extension signs out or switches to another instance or account. Only using the vault counts as use: unlock, fill, code, copy and a confirmed second factor. Opening the side panel or the menu does not extend the time. Unlocking checks the pairing again.
  • Nothing is kept. The extension fetches a secret for each fill, types it into the page and drops it. Nothing from the vault is stored in the browser beyond the pairing. Copy is the one exception, and only when you press it: the value goes to the clipboard and the clipboard is emptied after 30 seconds.

For admins. The idle time is an instance setting under Admin -> Security -> Browser extension vault: 1 to 240 minutes, default 15. It is read each time someone unlocks, so a change applies from the next unlock. Open a login in the credential vault to set Offer this login on (domain, exact host, or host and path) and Also offer it on these hosts under Browser extension; both need manage access on the credential and apply to logins and passwords. The second-factor confirmations are not part of a backup: after a restore each extension asks for a code again on its next fill.

Saving new logins from the browser, a password generator and passkeys in the extension are not part of this release.

In a lane

Added in v0.205.1 In a lane the browser is already running when the agent starts. It opens the preview, checks the page and attaches a screenshot to the ticket, so a UI change always comes with a picture instead of a description. orboto lanes list shows which lanes have a browser and when it was last used.

Why commands and not an MCP server

Command lines are cheaper for agents: an MCP server's tool list is repeated to the AI on every turn (about 6,000 tokens for the browser tools alone), while a command costs only what it prints. A typical check of a project page - open, snapshot --interactive-only, screenshot attached - is about 1,000 tokens.

If your tool prefers an MCP server, orboto mcp install --browser adds the same browser as the orboto-browser server, for Claude Code and (--client codex) for Codex.

Added in v0.230.0 In the MCP form (orboto browser mcp) your client's request ids never reach the browser tool: orboto sends each tool call under an id of its own and answers your client under yours. Use a new id for every request, as the MCP specification requires:

  • A request whose id is still waiting for an answer is answered with JSON-RPC error -32600 (id null, the refused id in data.requestId) and counted as a refused action.
  • An id that starts with orboto-browser- is reserved and gets -32600 under its own id. An id that is not a string or a number gets -32600 with id null.
  • A line that is not one JSON-RPC object (a batch array included) and a request without an id never reach the browser.
  • A call your client cancels, or one the browser does not answer within 90 seconds, is cancelled at the browser too. If its answer still arrives, it only updates the page the next allowlist check uses, and the answer itself is dropped. A notifications/cancelled from your client that names an orboto-browser- id is ignored.

On this page