Conversation
Exports cookies from a local Chrome browser (via CDP) and injects them into a new Browserbase cloud session, enabling authenticated browsing with full session replay and observability. Integrates with Browserbase Contexts for persistent cookie reuse across sessions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When Chrome is launched with --remote-debugging-port (which requires --user-data-dir and doesn't create a DevToolsActivePort file), users can now set CDP_URL=ws://127.0.0.1:9222 instead of hacking a fake DevToolsActivePort file. This is the only working path on Chrome stable until chrome://flags/#allow-remote-debugging lands. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The allow-remote-debugging flag is only available in Chrome Beta/Dev/Canary as of March 2026. Updated SKILL.md description and prerequisites so the agent clearly communicates this limitation to users. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- --domains flag to selectively sync cookies for specific sites - --stealth flag for Browserbase advanced stealth mode - --proxy "City,ST,US" for residential proxy with geolocation - --persist / --context CLI flags (replaces env-var-only config) - addUrlsToCookies() fix: secure cookies (e.g. Google auth) were silently dropped by Network.setCookies without a URL field - Chrome 146+ version check with actionable error message Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 4 potential issues.
There are 6 total unresolved issues (including 2 from previous reviews).
Autofix Details
Bugbot Autofix prepared fixes for all 4 issues found in the latest run.
- ✅ Fixed: Documented
CDP_URLenv var is never read- Added early return in getLocalWsUrl() to check and return process.env.CDP_URL if set, enabling the documented fallback for Chrome < 146.
- ✅ Fixed: Version check hard-exits for valid older Chrome
- Modified checkChromeVersion() to skip version check when CDP_URL or CDP_PORT_FILE env vars are set, allowing older Chrome versions with custom debugging configurations.
- ✅ Fixed:
getDebugUrlfunction is defined but never called- Removed the unused getDebugUrl function definition to eliminate dead code.
- ✅ Fixed: Documented
BROWSERBASE_CONTEXT_IDenv var is never read- Added fallback to process.env.BROWSERBASE_CONTEXT_ID when CLI.contextId is not provided, enabling the documented env var approach.
Or push these changes by commenting:
@cursor push 6979b9d909
Preview (6979b9d909)
diff --git a/skills/cookie-sync/scripts/cookie-sync.mjs b/skills/cookie-sync/scripts/cookie-sync.mjs
--- a/skills/cookie-sync/scripts/cookie-sync.mjs
+++ b/skills/cookie-sync/scripts/cookie-sync.mjs
@@ -74,6 +74,10 @@
// ---------------------------------------------------------------------------
function getLocalWsUrl() {
+ if (process.env.CDP_URL) {
+ return process.env.CDP_URL;
+ }
+
const home = homedir();
const IS_WINDOWS = process.platform === 'win32';
@@ -249,10 +253,6 @@
});
}
-async function getDebugUrl(sessionId) {
- return bbFetch(`/sessions/${sessionId}/debug`);
-}
-
async function waitForSessionRunning(sessionId, maxWaitMs = 30000) {
const start = Date.now();
while (Date.now() - start < maxWaitMs) {
@@ -268,6 +268,10 @@
// ---------------------------------------------------------------------------
function checkChromeVersion() {
+ if (process.env.CDP_URL || process.env.CDP_PORT_FILE) {
+ return;
+ }
+
const chromePaths = [
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
'/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta',
@@ -331,7 +335,7 @@
}
// Step 3: Set up context (create new, reuse existing, or skip)
- let contextId = CLI.contextId;
+ let contextId = CLI.contextId || process.env.BROWSERBASE_CONTEXT_ID;
if (!contextId && CLI.persist) {
const ctx = await createContext();This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
- Read CDP_URL env var in getLocalWsUrl() for Chrome < 146 fallback - Clear dangling timeouts in CDP send() on resolve/reject - Detect terminal session states (ERROR/TIMED_OUT/FAILED) in polling loop - Skip Chrome version check when CDP_URL or CDP_PORT_FILE is set - Read BROWSERBASE_CONTEXT_ID env var as fallback for --context flag - Remove unused getDebugUrl function Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
shrey150
commented
Mar 24, 2026
Replace hand-rolled CDP client and raw fetch API calls with @browserbasehq/stagehand for browser connections (local + cloud) and @browserbasehq/sdk for context creation. This dogfoods our own SDKs and removes ~200 lines of boilerplate. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pass model as { modelName, apiKey } object to match Stagehand v3 API.
Cookie sync only uses browser connection, not AI features, so a dummy
API key suffices.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
WSS://host was being converted to httpS://host instead of https://host because the regex matched case-insensitively but didn't handle the trailing 's' in wss. Now matches the full wss/ws prefix and maps to https/http correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Stagehand defaults to openai/gpt-4.1-mini when no model is passed, but the LLM client is created lazily and never invoked for cookie-only operations (context.cookies / context.addCookies). The apiKey: 'unused' hack was unnecessary — verified by tracing the constructor: the AI SDK model object is only called when act/extract/observe are used. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Stagehand API client (api.ts:213) requires modelApiKey during BROWSERBASE init, but this is only used for server-side AI features we don't need. Setting disableAPI: true skips the API client entirely (v3.ts:928) while still creating the BB session and CDP connection. Tested e2e with OPENAI_API_KEY and ANTHROPIC_API_KEY both unset — cookies exported from local Chrome and injected into cloud session. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ersion check - Use /\r?\n/ split for DevToolsActivePort to handle Windows CRLF - Add Linux Chrome binary names to version check (google-chrome, chromium, etc.) - Remove existsSync gate so PATH-resolved binaries are found via execSync Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The API key is scoped to a project, so project ID is redundant. Removed from script, SKILL.md, REFERENCE.md, and EXAMPLES.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Kylejeong2
approved these changes
Mar 25, 2026
Cookie-sync now always creates a persistent context and closes the temp session after injecting cookies. This lets users browse authenticated sites with `browse open <url> --context-id <id> --persist` instead of the raw `node -e` WebSocket hack. - Remove --persist flag (contexts are always created) - Remove keepAlive: true (session closes after injection) - Replace node -e navigation docs with browse CLI workflow - Add troubleshooting tip for stealth/proxy Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
cookie-syncskill that exports cookies from a local Chrome browser (via CDP) and injects them into a Browserbase cloud sessionWhat's in the skill
SKILL.mdscripts/cookie-sync.mjsREFERENCE.mdEXAMPLES.mdLICENSE.txtContext integration (new vs Shub's original)
The original script creates a plain
keepAlivesession. This version also creates a Browserbase Context withpersist: true, so:BROWSERBASE_CONTEXT_IDenv varMarked as Experimental because
--remote-debugging-portflagTest plan
🤖 Generated with Claude Code
Note
Medium Risk
Adds a new script that exports sensitive local browser cookies and injects them into a persistent Browserbase context/session, so misconfiguration or misuse could expose credentials. Also introduces new Node dependencies and a large lockfile that may affect supply-chain/update risk.
Overview
Adds a new experimental
cookie-syncskill that exports cookies from a locally running Chromium-based browser (via CDP) and injects them into a persistent Browserbase context for reuse with thebrowseCLI.Includes a new Node.js CLI script (
scripts/cookie-sync.mjs) with flags for domain filtering, reusing an existing context, and optional advanced stealth and geolocated residential proxy settings, plus supporting docs (SKILL.md,REFERENCE.md,EXAMPLES.md) and new npm manifests (package.json/package-lock.json) underskills/cookie-sync.Written by Cursor Bugbot for commit 89bc7f2. This will update automatically on new commits. Configure here.