You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
browserbase/mcp-server-browserbase exposes --contextId and --persist flags that bind cookies, storage, cache, and signed-in state to a single opaque handle. The handle can be reattached anywhere, which is a meaningful ergonomic win for fleet / CI / multi-host workflows.
OpenChrome already has every primitive — cookies, storage, http_auth, session_snapshot/session_resume, the pilot-tier handoff token (#793/#794). They are scattered across distinct tools, which means an LLM agent that wants to "carry the same logged-in state to another openchrome instance" needs to compose ~5 tool calls and stitch the result by hand.
This issue does not introduce a new lifecycle abstraction. It adds a single pair of tools, oc_context_export / oc_context_import, that wrap the existing primitives into one envelope. No state machine; no runtime registry; no implicit persistence (P4: facts vs decisions — the host LLM decides when to persist, openchrome only exports/imports on request).
Stays inside core because no outbound network and no LLM calls are introduced. Encryption-at-rest stays in pilot (#794).
What
Add two tools — oc_context_export and oc_context_import — that serialize/deserialize a single tab's auth-relevant state to/from a plaintext JSON envelope. No lifecycle CRUD, no daemon-side storage — the host stores the envelope wherever it wants (file, memory, handoff token).
Boundary: src/tools/oc-context.ts (new). Reuses existing cookies.ts, storage.ts, http-auth.ts internals; no parallel state walker. No new runtime dependency.
Contract
// src/tools/oc-context.tsexportinterfaceContextEnvelope{version: 1;origin: string;// origin the cookies/storage were scoped tocapturedAt: number;userAgent?: string;// captured iff captureUA: trueviewport?: {width: number;height: number};cookies: Cookie[];// same shape as cookies.ts get()localStorage?: Record<string,string>;sessionStorage?: Record<string,string>;httpAuth?: {username: string;password: string};/** SHA-256 of the canonical-JSON form of the above fields, excluding self */integrity: string;}exportinterfaceExportOptions{origin?: string;// default: active tab originincludeStorage?: boolean;// default trueincludeHttpAuth?: boolean;// default false (rarely safe to round-trip)captureUA?: boolean;// default falsetabId?: string;}exportinterfaceImportOptions{envelope: ContextEnvelope;/** if true, mismatch between envelope.origin and active tab origin is an * error; if false (default), import navigates to envelope.origin first */strictOrigin?: boolean;tabId?: string;}exportinterfaceImportResponse{ok: boolean;appliedCookies: number;appliedStorageKeys: number;/** present iff envelope.integrity verification failed */integrityError?: string;}
Invariants:
oc_context_export produces a deterministic envelope ordering (cookies sorted by domain,path,name; storage keys lexicographically). Identical browser state yields byte-identical envelopes modulo capturedAt.
integrity is a SHA-256 over the canonical-JSON form excluding the integrity field itself; oc_context_import re-computes and rejects on mismatch.
oc_context_import is a strict replace, not a merge — existing cookies/storage for the target origin are cleared first. (Merge semantics are a separate, harder problem; not in scope.)
Tools delegate to existing cookies.ts, storage.ts, http-auth.ts internals; no parallel CDP traversal.
Integrity hash verified on import; mismatch returns { ok: false, integrityError } without applying any state.
Strict replace semantics (not merge) — covered by tests/tools/oc-context-replace.test.ts.
Cross-instance round-trip test: export from instance A, import into instance B with isolated user-data-dir, assert authenticated request succeeds against https://httpbin.org/cookies (mirrors the supplied cookies). Lives in tests/e2e/oc-context-roundtrip.test.ts.
Lifecycle CRUD (create/attach/delete of named contexts inside openchrome). Premature abstraction given that the host can store envelopes in any medium.
2026-05-12 r1: Original draft proposed full CRUD lifecycle (create/attach/export/import/delete with daemon-side registry).
2026-05-12 r2: Self-critic pass scoped down to export/import only.
Rationale: a daemon-side registry is a premature abstraction (CLAUDE.md guidance) and overlaps with the pilot handoff token's intended role.
Added explicit strict-replace semantics (no merge) and integrity hash contract so import is auditable.
Stated clearly that the envelope is plaintext — encryption stays in pilot/handoff. This keeps the new code in core without expanding the core tier's responsibilities.
Excluded IndexedDB capture and cross-origin bundles to keep v1 narrow.
Curated scope, overlap handling, and verification checklist
Scope classification
Canonical lane: OpenChrome additive improvement with live-verification guardrails.
Keep this issue aligned with OpenChrome's MCP/CDP-first, additive, deterministic-tool-server direction.
If an existing open PR already implements part of this scope, update that PR or mark the overlap explicitly before starting new work.
Do not absorb adjacent benchmark, dashboard, security, or skill-memory work unless the original issue text requires it.
Implementation checklist
Restate the exact contract for oc_context — portable context handle: export/import only (browserbase adoption C) in code/docs before changing behavior.
Implement the narrow surface named by this issue before broadening to adjacent systems.
Preserve existing behavior by default and gate new behavior with explicit config/tool arguments where appropriate.
Add targeted unit/integration tests for success, failure, compatibility, and bounded output.
Add regression coverage for the issue-specific happy path, failure path, default/disabled path, and artifact/output bounds.
Update user-facing docs or inline tool descriptions when hosts must choose a new flag, mode, policy, or workflow.
Success criteria
The implementation satisfies the primary deliverable without broadening into non-goals.
Existing default behavior remains backward-compatible or the issue explicitly documents the compatibility break.
Failure cases return bounded, actionable diagnostics rather than silent fallback or unbounded dumps.
Tests/benchmarks cover the concrete surface named in this issue, not only helper utilities.
Any produced artifact is deterministic, redacted, and small enough for merge review or stored behind handles.
Post-merge OpenChrome live verification checklist
Run the documented local OpenChrome fixture or smoke path for oc_context — portable context handle: export/import only (browserbase adoption C) and capture the exact command/tool calls.
Verify act behavior matches the issue goal in both the enabled path and the default/disabled compatibility path.
Inspect generated artifacts/logs/responses for bounded size, redaction, source links, and clear failure diagnostics.
Record sanitized output excerpts, artifact paths, and any benchmark/latency/payload numbers in merge verification notes.
Why
browserbase/mcp-server-browserbaseexposes--contextIdand--persistflags that bind cookies, storage, cache, and signed-in state to a single opaque handle. The handle can be reattached anywhere, which is a meaningful ergonomic win for fleet / CI / multi-host workflows.OpenChrome already has every primitive —
cookies,storage,http_auth,session_snapshot/session_resume, the pilot-tier handoff token (#793/#794). They are scattered across distinct tools, which means an LLM agent that wants to "carry the same logged-in state to another openchrome instance" needs to compose ~5 tool calls and stitch the result by hand.This issue does not introduce a new lifecycle abstraction. It adds a single pair of tools,
oc_context_export/oc_context_import, that wrap the existing primitives into one envelope. No state machine; no runtime registry; no implicit persistence (P4: facts vs decisions — the host LLM decides when to persist, openchrome only exports/imports on request).Stays inside core because no outbound network and no LLM calls are introduced. Encryption-at-rest stays in pilot (#794).
What
Add two tools —
oc_context_exportandoc_context_import— that serialize/deserialize a single tab's auth-relevant state to/from a plaintext JSON envelope. No lifecycle CRUD, no daemon-side storage — the host stores the envelope wherever it wants (file, memory, handoff token).Boundary:
src/tools/oc-context.ts(new). Reuses existingcookies.ts,storage.ts,http-auth.tsinternals; no parallel state walker. No new runtime dependency.Contract
Invariants:
oc_context_exportproduces a deterministic envelope ordering (cookies sorted bydomain,path,name; storage keys lexicographically). Identical browser state yields byte-identical envelopes modulocapturedAt.integrityis a SHA-256 over the canonical-JSON form excluding theintegrityfield itself;oc_context_importre-computes and rejects on mismatch.oc_context_importis a strict replace, not a merge — existing cookies/storage for the target origin are cleared first. (Merge semantics are a separate, harder problem; not in scope.)Acceptance criteria
oc_context_exportandoc_context_importregistered under categorystorage(per feat(host): tool category toggle / --slim mode (chrome-devtools-mcp adoption C) #847's taxonomy).cookies.ts,storage.ts,http-auth.tsinternals; no parallel CDP traversal.{ ok: false, integrityError }without applying any state.tests/tools/oc-context-replace.test.ts.https://httpbin.org/cookies(mirrors the supplied cookies). Lives intests/e2e/oc-context-roundtrip.test.ts.npm run build && npm testgreen.Real verification (post-merge, via openchrome MCP)
Two openchrome instances are required. Run them on the same machine with distinct
--user-data-dirand--port.mcp__openchrome__navigate→https://httpbin.org/cookies/set?session=abc123&user=alice. Confirm the page shows the cookies set.mcp__openchrome__oc_context_exportorigin='https://httpbin.org',includeStorage=true.session=abc123anduser=alice;integrityis a 64-char hex string.mcp__openchrome__navigate→https://httpbin.org/cookies(separate fresh profile).mcp__openchrome__oc_context_importwith the envelope from step 2.ok: true,appliedCookies >= 2.mcp__openchrome__navigate→https://httpbin.org/cookies.session=abc123anduser=alice.ok: false,integrityErrornon-empty, no cookies applied (verify by readingmcp__openchrome__cookiesaction=get).capturedAt).mcp__openchrome__oc_journalrecords both export and import with origin summaries.Reproducer script:
scripts/verify/browserbase-C-context-roundtrip.mjs.Out of scope
create/attach/deleteof named contexts inside openchrome). Premature abstraction given that the host can store envelopes in any medium.Dependencies
Effort
S–M (~2–3 dev days). Two tools, integrity hash, fixture-backed e2e.
References
--contextId/--persistflag semantics (BUSL-1.1; not used directly).cookies/storage/http_auth/session_snapshot/ pilot handoff (feat(pilot): handoff token + manager (replaces #754 cherry-pick, in-memory only) #793/feat(pilot): handoff persistence with AES-256-GCM + ephemeral key default (replaces #755 cherry-pick) #794) — primitives reused.Revision history
create/attach/export/import/deletewith daemon-side registry).Curated scope, overlap handling, and verification checklist
Scope classification
act,navigate,oc_context,oc_journal.Overlap and conflict resolution
Implementation checklist
Success criteria
Post-merge OpenChrome live verification checklist