Agents drive real browsers on the target computer. On an enrolled machine the daemon spawns and owns its own browser instances over the Chrome DevTools Protocol (CDP); on your own machine the browser extension provides page access without the daemon spawning anything. This page covers the daemon-spawned sessions: how tabs are managed, how sessions are isolated, and how the cloud agent runtime schedules them when several tasks share one computer.
Sessions and instances
The daemon keeps a pool of browser sessions, keyed by session id. Every session is a fully independent browser instance — its own process, its own profile directory, its own DevTools port. Nothing is shared between instances.
Most browser commands take an optional sessionId. With a single session running, commands target it automatically. With several running, the call must name its session — omitting the id is an error that lists the sessions currently alive, rather than a guess.
Passing newInstance: true when opening a tab starts a brand-new independent instance (fresh process, profile, and port) instead of reusing a pooled one. A tabId can never reference a tab in an instance that was just created by that same call.
Tab management
Four tab operations are available, each scoped to a session:
| Method | Parameters | Returns | Behavior |
|---|---|---|---|
tabs.list |
sessionId? |
session id, channel, tabs | Lists the session's tabs with tabId, URL, title, and which one is active. |
tabs.open |
url?, newInstance?, sessionId? |
session id, tab id, channel | Opens a new tab. The URL must be an http(s) URL; about:blank is also accepted as the canonical empty tab. Navigation only accepts http(s). |
tabs.activate |
tabId, sessionId? |
ok, session id, tab id, channel | Brings an existing tab to the front (creates the target if needed). |
tabs.close |
tabId, sessionId? |
ok, session id, tab id, channel | Closes the tab's CDP target. |
Snapshots and navigation accept a tabId too; when omitted they use the session's currently active tab. The channel field always reports cdp for daemon-spawned sessions, which distinguishes them from extension-channel pages.
Handle rules
- A
sessionIdidentifies a pooled session (its page id). When omitted it resolves to the currently tracked session, or launches a fresh one if none exists. - A
tabIdis a CDP target id within one session. Before activating or closing, the daemon verifies the tab actually belongs to that session — a tab handle from another session (or another computer) does not resolve. browser.closeshuts down one pooled instance and deletes its profile directory. It never touches the extension channel or your own browser.- All tab operations work on daemon-spawned sessions only. On a machine where the only browser is your own (extension channel), tab management fails explicitly rather than acting on your browser.
Session lifecycle
- Idle reclaim — a session idle for more than 10 minutes (and any session whose process has died) is reclaimed by the daemon's reaper. The timeout is an explicit constant; tests and sandboxes can override it with
MAGICFROG_BROWSER_IDLE_TIMEOUT_MS. - Explicit close —
browser.closetears a session down immediately and removes its profile directory. - No orphans — every spawn is recorded in a durable manifest (
~/.magicfrog/browser-sessions.json) before the daemon waits for the port. When the daemon restarts, it sweeps leftovers from previous runs, killing only processes it can verify against the manifest — never on a pid guess.
Browsers run headless where there is no GUI session (an enrolled server, for example), so browser methods stay usable without a desktop. If the computer doesn't declare a browser capability at all, the operation is rejected with an explicit capability error — never silently skipped.
Cloud agent scheduling
When several agent tasks share one computer, a session allocator sits between the tasks and the session pool:
- Per-task binding — each task gets its own session. Reusing another task's session requires an explicit strategy, and a task trying to acquire a session on a computer it isn't bound to fails with a typed error. Sessions, handles, and audit records stay attributable to their own task.
- Concurrency cap — each computer has an explicit cap of 4 concurrent browser sessions. A task arriving at the cap either queues in FIFO order (default; if no slot frees up within the 30-second budget, the acquire fails with a timeout error) or is rejected explicitly, depending on the requested policy. A queued task never silently preempts a running one.
- Terminal-state reclaim — when a task reaches a terminal state (completed, failed, or cancelled), its session is reclaimed. A session the runtime could not close is counted as leaked and shows up in the allocator's stats, so leaks are observable instead of silent.
- Audit — allocation and reclamation events are recorded, each carrying the task and computer it concerns.
The extension channel
On a machine where you use your own browser, the MagicFrog browser extension provides navigation and structured DOM snapshots of pages in that browser — no daemon-spawned browser, no debugging port. The extension channel does not expose tab management, and daemon tab operations never act on it; it is a separate surface from the CDP sessions described above. The channel field in tab responses tells you which surface answered — cdp for daemon-spawned sessions.
For how tool calls reach a specific computer in the first place, see Computer ID Routing; for creating and enrolling the computers themselves, see Cloud Computers.