← All posts · · by Jop

How to give AI agents persistent browser sessions through MCP

Most AI agent browser stacks lose login state between tool calls. Here's how MCP servers preserve cookies, localStorage, and authentication across an entire agent run — and why that matters for real workflows.

TL;DR. Cloud headless browsers (Browserbase, Hyperbrowser, Anchor) typically discard browser state when a session window closes. For AI workflows that span many tool calls — multi-step research, lead enrichment, multi-tab data collection — that’s painful. Persistent profiles solve it: same --user-data-dir reused across tool calls, cookies and localStorage survive forever. This post shows the mechanics and the trade-offs.

The problem agents actually hit

Here’s a real workflow we’ve seen:

“Through the sarah-recruiter LinkedIn profile, find 50 senior engineers in Berlin, open each one’s profile, extract their email if visible, then send a personalized message.”

A naive automation runs in three phases:

  1. Discovery — search and enumerate candidates (1 page)
  2. Enrichment — visit each profile (50 pages)
  3. Action — send messages (50 actions)

Total: ~100 navigation actions over 10–30 minutes. If your browser session expires mid-flow, you re-login. If you re-login, LinkedIn flags suspicious behavior. If your cookies are wiped between actions, you get challenged with email verification. Each interruption breaks the agent’s plan.

This isn’t unique to LinkedIn. Same pattern on Amazon Seller Central, Twitter Ads, every banking portal, every SaaS dashboard.

Two approaches to session state

Stateless cloud (Browserbase pattern)

agent → MCP call → spin up fresh Chrome → run task → tear down
agent → MCP call → spin up fresh Chrome → run task → tear down

Each tool call gets a fresh browser. Cookies don’t persist by default. You can opt into a “session” that lasts a few minutes, but it has a hard timeout.

Pros: stateless = scalable, infinite parallelism, zero local resources. Cons: every call re-authenticates. For sites that detect re-auth as suspicious, this is fatal.

Persistent profile directory (MultiZen / GoLogin pattern)

agent → MCP call → reuse Chromium with --user-data-dir=/profiles/sarah → run task
agent → MCP call → reuse same Chromium (or relaunch with same dir) → run task

Same profile directory across calls. Chromium reads cookies, localStorage, IndexedDB, cache from disk. Login persists indefinitely.

Pros: looks like a normal returning user. No re-auth. Workflows of any length work. Cons: requires local disk or persistent cloud volume, fewer parallel sessions.

How MCP servers expose this

The cleanest pattern (what MultiZen does):

// MCP tool: launch a profile, return CDP endpoint
server.tool("launch_profile", { profile_id: "string" }, async ({ profile_id }) => {
  const profile = profiles.get(profile_id);

  // If this profile is already running, return its existing endpoint
  if (runningProfiles.has(profile_id)) {
    return { cdp_endpoint: runningProfiles.get(profile_id)!.endpoint };
  }

  // Launch Chromium reusing the persistent --user-data-dir
  const child = spawn(chromiumPath, [
    `--user-data-dir=${profile.dataDir}`,
    `--proxy-server=${profile.proxy}`,
    `--remote-debugging-port=${nextPort()}`,
  ]);

  // Wait for CDP to come up
  const endpoint = await waitForCdp(child);
  runningProfiles.set(profile_id, { child, endpoint });

  return { cdp_endpoint: endpoint };
});

Then navigate, click, extract all reuse the same profile by id. State is automatic — Chromium takes care of cookies/storage on disk.

Critically: the profile keeps running between MCP calls. The agent doesn’t have to re-launch every time. You only close it explicitly via close_profile or when the desktop app shuts down.

Why this matters for AI agents specifically

Compared to a human operator, an AI agent makes many more small tool calls and takes longer overall to complete a workflow. A human might log into LinkedIn once and click around for an hour. An agent might issue 200 individual click and extract MCP calls over the same hour. Stateless sessions multiply re-auth attempts by the count of calls — every one a chance for a CAPTCHA challenge, an email verification, a soft account lock.

Persistent profiles flatten this. The session looks identical to the platform whether the human or the agent is driving.

Beyond cookies: what else needs to persist

StateWhyWhere stored
CookiesAuth, session tokensCookies SQLite in --user-data-dir
localStorage / IndexedDBApp state, drafts, recently-viewedLocal Storage, IndexedDB directories
HTTP cacheSpeed, identical-looking returning userCache/, Code Cache/
Service workersPWA state, offlineService Worker/
Extensions and their dataWallet sessions, password managersExtensions/, Local Extension Settings/
WebAuthn credentialsHardware keys, passkeysOS keychain (we don’t touch this)

A real persistent profile preserves all of this. A naive cookies.json save/restore does not.

Trade-offs to be honest about

Disk usage. Each profile is 50–500 MB depending on usage. 100 profiles = 5–50 GB. Plan storage accordingly.

Concurrency. A single Chromium can only run with one Chromium-process per profile directory at a time. If you need 100 profiles open simultaneously, that’s 100 Chromium processes. RAM matters.

Stale state. Cookies expire. Sessions get invalidated server-side. You’ll occasionally need to re-login. Plan a heuristic in your agent: if the page returns “please log in”, trigger a human-in-the-loop notification.

Profile drift. If you mix manual operator activity with AI agent activity in the same profile, your engagement patterns become inconsistent. Some platforms flag this. Decide profile-by-profile whether it’s AI-only or human-with-AI-help.

Try it

MultiZen’s MCP server preserves all profile state across calls automatically. No special flags. Just launch a profile from Cursor or Claude Desktop, do work, come back tomorrow — login still works.

Download.

Try MultiZen

A browser library for AI agents and human operators. Free, open source (MIT). Self-hosted. macOS, Windows, Linux.

Download — free