Agent Identity & Multi-Agent Safety
Claudezilla supports multiple Claude Code sessions sharing a single Firefox window. Each session is isolated through agent IDs, tab ownership, and resource coordination mechanisms. ## Agent ID Format Every MCP server instance generates a unique agent ID at startup: ``` agent_<32 hex chars>_<pid> ``` - **Prefix:** `agent_` (literal) - **Entropy:** 16 random bytes (128 bits) encoded as 32 hex characters - **Suffix:** OS process ID of the MCP server **Example:** `agent_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6_12345` The 128-bit entropy prevents ID prediction or collision across concurrent sessions. In logs and error messages, agent IDs are **truncated to 12 characters** for privacy (e.g., `agent_a1b2c3...`). ## Tab Ownership Every tab in the 12-tab pool is tagged with the `agentId` of the session that created it. ### Rules - **Create:** Any agent can open a tab (if pool space is available). - **Read:** Any agent can read content from any tab (`getContent`, `getPageState`, `getAccessibilitySnapshot`). - **Navigate:** Only the owning agent can navigate a tab to a new URL. - **Close:** Only the owning agent can close a tab. - **Evict:** When the pool is full, an agent can only evict its own oldest tab — never another agent's tabs. Ownership violations return a structured error: ``` OWNERSHIP: Cannot navigate tab 42 (owned by agent_e7f8...) ``` Use `getTabs` to inspect ownership across the pool — each tab entry includes an `ownerId` field. ## Screenshot Mutex Only one screenshot can be captured at a time because `captureVisibleTab` operates on the active tab. A promise-chain mutex serializes all screenshot requests. If a screenshot request arrives while another agent holds the mutex for more than 3 seconds, the request fails immediately: ``` MUTEX_BUSY: Screenshot mutex held by another agent. Holder: agent_ec2e... Held for: 6234ms Tab pool: 8/10 Hint: Use getPageState (no mutex) or retry after delay. ``` **Workaround:** Use `firefox_get_page_state` instead — it returns structured JSON without requiring the mutex. For visual inspection, retry the screenshot after a brief delay. ## Tab Pool Coordination (Mercy System) When the 12-tab pool is full and an agent has no tabs of its own to evict, `createWindow` returns a `POOL_FULL` error. The mercy system provides a cooperative way for agents to request space. ### Workflow 1. **Blocked agent** calls `firefox_request_tab_space` to queue a request. 2. **Another agent** (or any agent) calls `firefox_grant_tab_space`, which closes that agent's oldest tab and creates a **30-second slot reservation** for the waiting agent. 3. **Blocked agent** calls `firefox_get_slot_requests` to check if it has a reservation (`youHaveReservation: true`). 4. **Blocked agent** calls `firefox_create_window` during the reservation window — the pool check is bypassed for the reserved agent. Reservations expire after 30 seconds and are automatically cleaned up. Only one reservation can be active at a time. ## Session Cleanup ### Graceful Exit When a Claude Code session ends normally (Ctrl+C, `exit`, task completion), the MCP server intercepts `SIGINT`, `SIGTERM`, `SIGHUP`, and `beforeExit` signals: 1. Sends a `goodbye` command to the native host with its agent ID. 2. The extension immediately closes all tabs owned by that agent. 3. Any slot reservations and pending tab space requests for the agent are removed. ### Orphaned Tab Cleanup (Crash Recovery) If the MCP server is killed without a chance to send `goodbye` (SIGKILL, OOM, power loss), tabs become orphaned. The system detects and cleans these up: - **Heartbeat tracking:** The host records the timestamp of each command per agent. - **Timeout threshold:** An agent is considered orphaned after **2 minutes** (120 seconds) of inactivity. - **Periodic sweep:** The MCP server checks for orphaned agents every 60 seconds. - **Cleanup:** All tabs belonging to an orphaned agent are closed, returning capacity to the pool. This prevents "ghost agents" from permanently consuming tab slots after a crash.Claudezilla supports multiple Claude Code sessions sharing a single Firefox window. Each session is isolated through agent IDs, tab ownership, and resource coordination mechanisms.
Agent ID Format
Section titled “Agent ID Format”Every MCP server instance generates a unique agent ID at startup:
agent_<32 hex chars>_<pid>- Prefix:
agent_(literal) - Entropy: 16 random bytes (128 bits) encoded as 32 hex characters
- Suffix: OS process ID of the MCP server
Example: agent_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6_12345
The 128-bit entropy prevents ID prediction or collision across concurrent sessions. In logs and error messages, agent IDs are truncated to 12 characters for privacy (e.g., agent_a1b2c3...).
Tab Ownership
Section titled “Tab Ownership”Every tab in the 12-tab pool is tagged with the agentId of the session that created it.
- Create: Any agent can open a tab (if pool space is available).
- Read: Any agent can read content from any tab (
getContent,getPageState,getAccessibilitySnapshot). - Navigate: Only the owning agent can navigate a tab to a new URL.
- Close: Only the owning agent can close a tab.
- Evict: When the pool is full, an agent can only evict its own oldest tab — never another agent’s tabs.
Ownership violations return a structured error:
OWNERSHIP: Cannot navigate tab 42 (owned by agent_e7f8...)Use getTabs to inspect ownership across the pool — each tab entry includes an ownerId field.
Screenshot Mutex
Section titled “Screenshot Mutex”Only one screenshot can be captured at a time because captureVisibleTab operates on the active tab. A promise-chain mutex serializes all screenshot requests.
If a screenshot request arrives while another agent holds the mutex for more than 3 seconds, the request fails immediately:
MUTEX_BUSY: Screenshot mutex held by another agent. Holder: agent_ec2e... Held for: 6234ms Tab pool: 8/10 Hint: Use getPageState (no mutex) or retry after delay.Workaround: Use firefox_get_page_state instead — it returns structured JSON without requiring the mutex. For visual inspection, retry the screenshot after a brief delay.
Tab Pool Coordination (Mercy System)
Section titled “Tab Pool Coordination (Mercy System)”When the 12-tab pool is full and an agent has no tabs of its own to evict, createWindow returns a POOL_FULL error. The mercy system provides a cooperative way for agents to request space.
Workflow
Section titled “Workflow”- Blocked agent calls
firefox_request_tab_spaceto queue a request. - Another agent (or any agent) calls
firefox_grant_tab_space, which closes that agent’s oldest tab and creates a 30-second slot reservation for the waiting agent. - Blocked agent calls
firefox_get_slot_requeststo check if it has a reservation (youHaveReservation: true). - Blocked agent calls
firefox_create_windowduring the reservation window — the pool check is bypassed for the reserved agent.
Reservations expire after 30 seconds and are automatically cleaned up. Only one reservation can be active at a time.
Session Cleanup
Section titled “Session Cleanup”Graceful Exit
Section titled “Graceful Exit”When a Claude Code session ends normally (Ctrl+C, exit, task completion), the MCP server intercepts SIGINT, SIGTERM, SIGHUP, and beforeExit signals:
- Sends a
goodbyecommand to the native host with its agent ID. - The extension immediately closes all tabs owned by that agent.
- Any slot reservations and pending tab space requests for the agent are removed.
Orphaned Tab Cleanup (Crash Recovery)
Section titled “Orphaned Tab Cleanup (Crash Recovery)”If the MCP server is killed without a chance to send goodbye (SIGKILL, OOM, power loss), tabs become orphaned. The system detects and cleans these up:
- Heartbeat tracking: The host records the timestamp of each command per agent.
- Timeout threshold: An agent is considered orphaned after 2 minutes (120 seconds) of inactivity.
- Periodic sweep: The MCP server checks for orphaned agents every 60 seconds.
- Cleanup: All tabs belonging to an orphaned agent are closed, returning capacity to the pool.
This prevents “ghost agents” from permanently consuming tab slots after a crash.