Repository navigation
perplexity-user-mcp 0.8.42 — Headed Bootstrap reads cookies as anonymous despite successful login (regression from 0.8.41 fix) #5
Description
Product
VS Code extension (perplexity-vscode)
Version
perplexity-user-mcp 0.8.42-universal
MCP Client (if applicable)
Other
Perplexity tier
Pro
OS
Windows 11 Pro 10.0.26200, Node.js: v22.21.1
Browser used by the MCP server
Google Chrome 147.0.7727.139
What happened?
IDE: VS Code with Antigravity extension (Claude Code as MCP client)
Account tier: Pro
Transport: stdio — daemon proxy (http-loopback)
What happened
After updating from 0.8.39 to 0.8.42 (following the fix announced for PR #4 / 0.8.41), performing a clean reinstall, purging the old personal profile, and logging in fresh via Perplexity: Login from the VS Code dashboard (email one-time code, browser window opened and closed correctly after successful authentication), the daemon still reports anonymous mode on every request. perplexity_reason and perplexity_research remain unavailable.
Summary
The vault decrypt fix from PR #4 shipped correctly in 0.8.42 — unseal-verify passes. However, the downstream step (loading the decrypted cookies into the headed bootstrap browser context) still does not work. The daemon's headed Chrome session navigates to perplexity.ai, resolves Cloudflare, checks auth — and consistently sees no session, despite the vault containing valid cookies from a successful Pro login 30 seconds prior.
The PERPLEXITY_HEADLESS_ONLY=1 entries in the log suggest a secondary spawn path where headed sessions are skipped entirely, which may be a separate regression or an incomplete guard in configureDaemonRuntime.
Expected: After a successful Perplexity: Login, the daemon's next reinit should load the session cookies and report tier: Pro.
Actual: Every reinit reports Not authenticated (anonymous mode), regardless of how many times login is repeated.
Doctor output (optional, recommended)
## [OK] vault -- pass
- [OK] encryption -- AES-256-GCM (vault.enc)
- [OK] unseal-path -- env var (keychain unavailable — expected on headless Linux)
- [OK] unseal-verify -- vault.enc decrypts cleanly with the active unseal material
## [X] probe -- fail
- [X] probe-search -- probe returned no sources (latency 3977ms)
- Hint: Session may be anonymous — run login, then --probe again.Relevant logs or errors
1. Login was genuinely successful — meta.json confirms Pro tier and timestamp:
{
"name": "default",
"displayName": "default",
"createdAt": "2026-05-11T05:39:13.636Z",
"loginMode": "manual",
"tier": "Pro",
"lastLogin": "2026-05-11T05:42:18.926Z"
}
vault.enc and meta.json share the same write timestamp 07:42:18 — cookies were saved by the login runner.
2. Vault decrypts cleanly (fix from PR #4 works for this part):
[OK] unseal-verify -- vault.enc decrypts cleanly with the active unseal material
3. But every headed bootstrap immediately after reports anonymous:
[perplexity-mcp] Reinit requested — closing current context and reloading cookies.
[perplexity-mcp] Starting headed bootstrap (solving CF + loading account info)...
[perplexity-mcp] Cloudflare resolved in 1s.
[perplexity-mcp] Not authenticated (anonymous mode). ← always, every reinit
[perplexity-mcp] Headed bootstrap complete.
[perplexity-mcp] Launching headless browser...
[perplexity-mcp] No authenticated session (anonymous mode)
This sequence repeats identically across multiple reinit cycles — Cloudflare resolves fine, but the session check always returns anonymous. The vault was decryptable, the cookies were written, but the daemon's headed bootstrap doesn't load them.
4. PERPLEXITY_HEADLESS_ONLY=1 is set during some spawns:
[perplexity-mcp] Skipping headed session (PERPLEXITY_HEADLESS_ONLY=1).
[perplexity-mcp] No cached account info found.
[perplexity-mcp] Launching headless browser...
[perplexity-mcp] No authenticated session (anonymous mode)
This indicates the daemon was spawned without the ability to run a headed session at all during those cycles — suggesting the passphrase/env injection from buildDaemonEnv still does not reliably reach the daemon on all spawn paths.
5. audit.log confirms all tool calls carry clientId: anon throughout — no authenticated session was ever established, including after the successful login at 05:42.
6. Daemon was running with two different PIDs during this session:
Attached to daemon pid=5116 port=65509 ← first instance
Attached to daemon pid=18172 port=61963 ← second instance after VS Code reload
Port drift still occurs across restarts, which creates stale loopback configs (known issue, tracked for 0.8.43) — but the auth failure is independent and reproducible on both daemon instances.
Steps to reproduce
Fresh install of 0.8.42 on Windows 11 with Antigravity (Claude Code MCP client), stdio-daemon-proxy transport
Run Perplexity: Login from VS Code command palette
Browser opens → enter email one-time code → browser closes (login confirmed successful)
Call perplexity_reason or perplexity_models from Claude Code → Account tier: Anonymous
Perplexity: Login repeated → same result
Activity
ARHAEEM commentedon May 11, 2026
Thanks for the thorough writeup, and you're right that PR #4 missed a path. Reading 0.8.42's code with your symptoms in hand, there are two distinct bugs stacked on top of each other — both worth a 0.8.43 release. Before we ship, I want to confirm which one is biting in your scenario A vs. scenario B because some of the data below distinguishes them.
Bugs identified (high confidence)
Bug 1 —
PERPLEXITY_HEADLESS_ONLY=1leaks from the launcher into the daemon's spawn envThis is the cause of your
Skipping headed session (PERPLEXITY_HEADLESS_ONLY=1)line.packages/extension/src/auto-config/transports/stdio-daemon-proxy.tswritesPERPLEXITY_HEADLESS_ONLY: "1"into the launcher's IDE-config env block.PerplexityClient— it just relays JSON-RPC over HTTP — so the flag is dead weight on the launcher.attachToDaemon→ensureDaemon→spawnDetachedDaemoninherits...process.envdirectly.HEADLESS_ONLY=1leaks straight into the daemon. The daemon'sPerplexityClient.init()then skips the headed bootstrap entirely — which is exactly what needs to refreshcf_clearancefor the headless phase.buildDaemonEnvoverlay from PR fix(vault): unseal hardening for external MCP clients (issue #3) #4 is appended after...process.envinspawnBundledDaemontoo, so even when the extension is the spawner it doesn't strip launcher-scoped flags. It happens to work in the extension-spawner case only because the extension host'sprocess.envdoesn't haveHEADLESS_ONLY=1to begin with — your scenario B is the launcher-spawner case, which does.Bug 2 — Phase 2 (headless) discards Phase 1's fresh
cf_clearanceThis would explain your scenario A (
Headed bootstrap complete → No authenticated session).PerplexityClient.init()says Phase 2 "launches headless with the same persistent profile (now carrying fresh cf_clearance)" — client.ts:892.chromium.launch(...)+getOrCreateContext(...)— non-persistent. So thecf_clearanceflushed tobrowserData/by Phase 1 is never loaded by Phase 2.addCookies— but thecf_clearancein the vault is from login time. If your login was even ~30s ago, that clearance can already be invalid (CF rotates aggressively on UA/IP/fingerprint shifts), and the page navigation in Phase 2 hits the CF challenge and falls back to anonymous beforecheckAuthruns.login-tier-end-to-end.integration.test.jspasses because the mock server has no Cloudflare. In production this is a real handoff gap.Diagnostic gap
Separately,
getSavedCookies()returns[]silently when either (a)vault.encdoesn't exist for the daemon's resolved profile or (b) thecookieskey is missing from a decryptable vault. Combined with the doctor'sunseal-verifypassing, this gives users no signal which of four failure modes they're hitting. We'll add explicit logging.What I need to confirm before writing the fix
I want to be sure scenario A is the cf_clearance handoff and not a separate profile-mismatch issue that would survive Bug 2's fix. Could you attach the following to this issue?
~/.perplexity-mcp/daemon.log(it's the most informative artifact — please redact tokens if you want, the[trace] httplines aren't sensitive but tokens/cookies are).Get-Content $env:USERPROFILE\.perplexity-mcp\active— one-line file containing the active profile name.Get-ChildItem $env:USERPROFILE\.perplexity-mcp\profiles -Recurse -Name— confirms whether there's still a stalepersonal/vault.encnext to the newdefault/vault.enc.echo "%PERPLEXITY_PROFILE%" "%PERPLEXITY_HEADLESS_ONLY%"in a freshcmd(System+User env vars) so I can see whether either is set system-wide.npx perplexity-user-mcp@0.8.42 doctor --json --probe— the full JSON output, not just the failing categories. The full output includesactiveProfileand per-category checks that the truncated version in the issue body doesn't.A fresh
Perplexity: Capture Diagnostics Bundlezip covers 1-4 in one shot and is the easiest way to send everything.What's coming in 0.8.43 once we confirm
Fix 1 (HEADLESS_ONLY leak) — belt-and-suspenders:
PERPLEXITY_HEADLESS_ONLYfromstdio-daemon-proxy.tsauto-config env (it's redundant in proxy mode anyway).PERPLEXITY_HEADLESS_ONLYandPERPLEXITY_NO_DAEMONfromspawnDetachedDaemonANDspawnBundledDaemonenvs, so the daemon can never inherit these launcher-scoped flags from any future leak path.Fix 2 (Phase 2 cookie handoff) — persistent context + headed cookie injection:
chromium.launchPersistentContext(browserData, ...)so the freshcf_clearancefrom Phase 1 carries over to the headless context.Diagnostic gap — add explicit log lines in
getSavedCookies()for both "vault.enc missing" and "cookies key missing" so the next bug report can distinguish silent-empty from decrypt-failure.Will ping back as soon as you drop the diagnostics. Thanks again for the precise repro — both bugs were findable from your logs alone but the daemon.log will tell us whether there's a third thing hiding underneath.
ARHAEEM commentedon May 11, 2026
Both bugs are fixed and in PR #7 — no need to wait for the diagnostics at this point, the root causes were clear enough from the original report.
What was shipped in 0.8.43:
daemon/launcher.ts,extension/src/daemon/runtime.ts,stdio-daemon-proxy.ts). The auto-config for your existing IDE configs will be rewritten on next activation to drop the dead flag.launchPersistentContext(browserData, ...), same directory as Phase 1, so the fresh clearance is on disk when Phase 2 starts. Vault cookies are injected selectively so a freshly-writtencf_clearanceis never overwritten by a stale vault copy.getSavedCookies()now logs a specific message for each silent-empty path (no vault.enc, cookies key absent, JSON parse failure, unseal error) so future bug reports will be much easier to triage.Additionally, as a bonus for this release: the dashboard now shows a live daemon auth status indicator in the hero panel (green when the daemon is authenticated, yellow warning when the daemon sees an anonymous session despite stored credentials). Clicking "Refresh state" in the dashboard will automatically touch the
.reinitsentinel to force a daemon reinit — so if the mismatch happens again after a cold start you can recover without restarting the whole extension.PR: #7 — will close this issue on merge. The VSIX will be attached to the release once smoke passes on Win11 + macOS + Ubuntu.
Merge pull request #7 from Automations-Project/fix/0.8.43-auth-cli-ha…
fix(#8): resolve browser-data singleton-lock deadlock (daemon single-…