bpc-oss

Chrome Faithful

Community bpc-oss
Updated

Faithful control of your real, logged-in Chrome profiles: MCP server + MV3 extension + authenticated localhost bridge. No copied profiles, no debug profile, no remote-debugging port, no Edge.

Chrome Faithful

Faithful control of your real, logged-in Chrome profiles.

An MCP server + MV3 Chrome extension + authenticated localhost bridge that letsAI agents drive the Chrome that already holds your logins, extensions, andhistory. No copied profiles, no debug profile, no --remote-debugging-port,no Edge, no global mouse/keyboard automation.

License: MITCINode

English · 简体中文

Why this exists

Browser-control tools optimize for different jobs:

Approach What you get What you lose
Chrome DevTools MCP (Google) Excellent DevTools, performance, and CDP workflows; Chrome 144+ can autoConnect to a running local browser with user approval Chrome must already be running, and when several profiles are active Chrome chooses the default profile rather than accepting an exact profile name
Playwright / Puppeteer MCP servers Deterministic, isolated browsers that are ideal for CI and repeatable tests Existing logins, extensions, history, and two-factor sessions are not present unless separately provisioned
Extension-based MCPs (BrowserMCP, real-browser-mcp) Control of an existing logged-in browser A strong fit for live sessions; multi-profile setups may require separate server instances and ports, and normally expect Chrome to be running

Chrome Faithful focuses on exact-profile, multi-profile control with afail-closed local bridge:

  • Exact multi-profile routing. Every profile registers with its exactprofileName; duplicate registrations are rejected, so concurrent agentscannot interleave inside one profile.
  • Launches a closed profile. If the target profile — or all of Chrome — isclosed, it starts the exact profile with ordinary Chrome and waits for theexact extension registration before reporting success. No --user-data-dirhacks.
  • Security depth. The bridge binds only 127.0.0.1 and requires agenerated 256-bit secret. Bootstrap uses one-use tokens; sessions use scopedgrants. Configuration is closed-schema and must live outside the sourcetree. Installers are transactional with SHA-256-verified, DPAPI-encryptedbackups (Windows).
  • File upload the honest way. Files are injected as pageFile/DataTransfer objects — not DOM.setFileInputFiles, not an OS filechooser.
  • Media export without leaking URLs. chrome_page_asset streamspage-exposed media using the tab's user agent, referer, and matching profilecookies; signed URLs, cookies, and headers never appear in MCP arguments orresults.
  • Durable virtual-list capture. Scroll capture with asset parity,fail-closed manifests, exclusive cross-process locks, and resume that rewindsthe tab through serialized wheel events — built for infinite-scroll feeds.
  • Works minimized. Locator waits/actions and screenshots use CDP focusemulation, so virtualized controls keep rendering even when the Chromewindow is minimized or obscured.
  • Raw CDP when you need it, with an explicit trust boundary. chrome_cdpevent reads redact Network headers, query strings, and post data; the boundedrequest/response projection actions reject sensitive selected fields. Itssend action is deliberately unrestricted raw CDP and must be exposed onlyto a fully trusted MCP client: it can read authenticated page content,cookies, storage, tokens, URLs, and headers.
  • Structured verification handling. Multi-signal challenge detection thatdistinguishes resolved / pending-render / active challenge states,click-first solving for the common "click once and it passes" cases, and anhonest handoff when a challenge needs a human — seeVerification handling.
  • Codex-compatible JS API. src/agent-browser.mjs implements Codex'sagent.browsers surface (tabs, locators, CUA, Playwright-style selectors,clipboard, dialogs, downloads) so JavaScript agents can use the same runtime.

Architecture

┌─────────────┐   stdio    ┌──────────────────────┐   ws://127.0.0.1    ┌─────────────────────────┐
│ MCP client  │ ─────────► │ src/mcp-server.mjs   │ ──────────────────► │ src/bridge-server.mjs   │
│ (Claude,    │            │ MCP tools (38)       │  (Bearer secret)    │ authenticated localhost  │
│  Codex, …)  │            └──────────────────────┘                     │ multi-profile router    │
└─────────────┘                                                        └───────────┬─────────────┘
                                                                                    │ chrome.debugger
                                                                    ┌───────────────▼──────────────┐
                                                                    │ MV3 extension in EACH exact  │
                                                                    │ profile (offscreen doc owns  │
                                                                    │ the WebSocket)               │
                                                                    └──────────────────────────────┘
  • extension/ — MV3 extension loaded once per controllable profile. Useschrome.debugger; an offscreen document owns the persistent WebSocket soMV3 service-worker suspension never drops the connection.
  • src/bridge-server.mjs — authenticated, localhost-only, multi-profile routerwith resilient failover.
  • src/chrome-profile-launcher.mjs — exact local Profile discovery andordinary Chrome startup with bounded extension-registration confirmation.
  • src/mcp-server.mjs — the MCP tool surface (38 tools).
  • src/agent-browser.mjs — JavaScript agent.browsers compatibility adapter.
  • src/verification/ — challenge detection, hold state machine, handoff,overlay dismissal, humanized input, and the solve pipeline (checkbox /slider / click-first generic / capture-for-backend).
  • src/file-injection.mjs, src/page-asset.mjs, src/scroll-capture.mjs,src/scroll-asset-capture.mjs, src/network-request.mjs,src/network-response.mjs — the feature modules.
  • scripts/ — Windows installers, acceptance harnesses, live-test harness,and codex parity tooling.

Safety model

  1. A caller must select one exact metadata.profileName.
  2. Duplicate live registrations for one profile name are rejected.
  3. The bridge binds only 127.0.0.1 and requires a generated secret.
  4. There is no fallback to a generic profile, port 9222, Edge, or UI automation.
  5. If the target is disconnected, callers use chrome_profile_catalog /chrome_profile_start; a process start succeeds only after the exactextension profileName registers.
  6. A live self-test must pass tabs and Runtime.evaluate before browser work.
  7. Profile and tab failures are returned to the calling agent with nouser-side console inspection required.

chrome_cdp with action=send is outside the safe-projection boundary. It isequivalent to granting the MCP client DevTools access to the selected logged-inprofile. Do not enable this server for untrusted clients or shared MCP hosts.

See SECURITY.md for the full model and reporting policy.

The extension's broad capabilities are intentional and visible: debuggerprovides DevTools-equivalent control; history, downloads, and clipboardpermissions back their corresponding tools. Host access is limited tohttp://127.0.0.1/* for the local bridge. For deterministic, disposable CIbrowsers, use Playwright or Puppeteer instead.

DSH first-class integration

Chrome Faithful ships a first-party DeepSeek Harness bundle inpackages/dsh-plugin-chrome-faithful/. It uses DSH's host-provided MCP clientinstead of duplicating the browser tools, so DSH gets the same exact-profilerouting and security behavior as every other client.

Supported baseline: @deepseek-ai/dsh 0.1.0-rc.6 and Node.js >=22.12.0.DSH remains an RC, so every newer RC requires a composition recheck.

After the core and bundle packages are published, install into the intendedprofile:

dsh plugin --profile web add @bpc-oss/[email protected]

The model sees stable names such asmcp__chrome_faithful__chrome_profiles. The bundle embeds no secret and passesAGENTOS_CHROME_CONFIG only when explicitly set. Initial configuration orresolution failures stop activation instead of leaving a silent zero-toolplugin. See the DSH bundle READMEfor packaging, trust-boundary, and private-acceptance details.

Local vision for text-only models

chrome_visual_extract captures the requested exact-profile tab only whencalled, runs a local backend, and returns text JSON containing screenshotdimensions/SHA-256 plus OCR text, confidence, and normalized coordinates. Itdoes not return or save the PNG. This makes the result useful to DSH modelseven though DSH 0.1.0-rc.6 drops MCP image content.

The default backend is the shipped PP-OCRv5 mobile adapter. Chrome Faithfuldoes not bundle or install Python, PaddleOCR, PaddlePaddle, OpenCV, NumPy, ormodel weights. Install those optional components yourself and configure bothabsolute local model directories so PaddleOCR cannot fall back to downloadingweights:

CHROME_FAITHFUL_PYTHON=C:\Python311\python.exe
CHROME_FAITHFUL_PPOCR_DET_MODEL_DIR=C:\Models\PP-OCRv5_mobile_det
CHROME_FAITHFUL_PPOCR_REC_MODEL_DIR=C:\Models\PP-OCRv5_mobile_rec

Live quality acceptance of the direct production MCP path detected 7/7 blocks,reached 99.43% raw and 100% non-whitespace character accuracy, and returned0.9754 mean / 0.9379 minimum confidence with valid coordinates, reading order,and identical output across three 3.00--3.25 second calls on the accepted AMDRyzen 9 9950X3D host. DSH model consumption of chrome_visual_extract outputwas not evaluated, and the optional VLM was not approved. See theacceptance report.

CHROME_FAITHFUL_OCR_BACKEND may instead be a shell-freecli:["executable","arg"] specification or an exacthttp://127.0.0.1:<port>/... / http://[::1]:<port>/... endpoint.CHROME_FAITHFUL_VLM_BACKEND uses the same formats and is disabled by default;it can point to a user-operated SmolVLM2, Moondream, or compatible localadapter. Remote URLs, redirects, automatic downloads, and cloud fallback arerejected. Normalized OCR coordinates are hints for existing chrome_cuacalls, not authorization to click.

Quick start (Windows)

Prerequisites: Node.js >= 22.12, Chrome, PowerShell (only the installers and the.cmd launcher are Windows-specific; the extension, bridge, and MCP server areplatform-neutral).

npm ci --ignore-scripts
  1. Load the extension in every Chrome profile you want agents to control:chrome://extensions → enable Developer modeLoad unpacked →select extension/. Note the 32-character extension ID and the loadedabsolute path.

  2. Create the bridge config outside the source tree, at%LOCALAPPDATA%\AgentOS\agentos-chrome-cdp\config.json, usingconfig/local.example.json as the non-secret schema reference. The secretmust be a generated 256-bit value, e.g.:

    [Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Max 256 }))
    

    The schema is closed: host (must be 127.0.0.1), port, secret,commandTimeoutMs, profileAliases — plus optional bridge/launcheroverrides. The server refuses a config that lives inside the source tree.

  3. Start the bridge: npm run bridge.

  4. Register the MCP server with your client, pointing node at theabsolute path of src/mcp-server.mjs (or use bin\invoke-chrome-cdp.cmd,which auto-starts the bridge). The in-repo .mcp.json uses paths relativeto the repo root — that form works for Codex project configs; other clientsgenerally want an absolute path.

  5. Verify: call chrome_profiles, then chrome_selftest, then open a tabwith chrome_tabs / navigate with chrome_tabs.

For multi-profile client wiring, secret rotation, DPAPI-encrypted backups, andtransactional rollback, the PowerShell installers automate it:

.\scripts\Install-AgentOsChromeExtension.ps1 -Target <absolute-loaded-extension-path>
.\scripts\Install-AgentOsChromeCdp.ps1 -Clients @('CodeBuddy') -ExtensionId $ExtensionId -ExtensionPath $ExtensionPath -ChromeProfileDirectories $ProfileDirs -ChromeUserDataDir $ChromeUserData

Run them without -Apply first — the default is a dry-run preview.

MCP tools

Group Tools
Profiles & sessions chrome_profiles, chrome_profile_catalog, chrome_profile_start, chrome_selftest, chrome_session_v2
Tabs & navigation chrome_tabs, chrome_session_v2 (finalize), chrome_page_event_v2
Interaction chrome_playwright_v2, chrome_locator, chrome_cua, chrome_dom_cua_v2
Raw CDP & network chrome_cdp, chrome_network_asset_v1
Capture & evidence chrome_screenshot, chrome_visual_extract, chrome_cua_scroll_capture_v1/v2/v3, chrome_cua_scroll_capture_status_v1, chrome_cua_scroll_asset_capture_start/status/cancel_v2
Assets & content chrome_page_asset, chrome_page_asset_v2, chrome_content_v2 (pdf/md/xlsx/csv/docx/pptx)
Verification chrome_verification_detect, chrome_verification_status, chrome_verification_resume, chrome_verification_solve, chrome_verification_solve_checkbox, chrome_verification_solve_slider, chrome_verification_capture, chrome_verification_dismiss_overlays
Utilities chrome_file_inject, chrome_history, chrome_clipboard

Notable behaviors: locator calls wait up to 30 s for visibility and areserialized per profile+tab; fill uses replacement semantics; chrome_locatoraccepts a zero-based index (-1 = last) for multi-match selectors;screenshots accept an optional document-coordinate clip and absolutesavePath and still return the PNG.

Verification handling

Because Chrome Faithful drives your real profile, most bot checks nevertrigger. When a platform still presents a human-verification challenge, theverification module gives agents a structured loop instead of blind retries.

Detection (chrome_verification_detect) classifies three real-worldstates:

State What it means Action
resolved A token is already populated (e.g. invisible challenge completed) Not a blocker — proceed
active provider iframe (reCAPTCHA v2/v3, hCaptcha, Turnstile, GeeTest, vaptcha) A visible challenge widget is present Solve it
pending-render A widget container exists but its challenge iframe never rendered. Field data shows the usual root cause is a stale/expired session, not a network handshake stall Refresh the session (sign out/in), trigger the page's real submit/verify button, reload-and-retry, or hand off

Static markers (the ubiquitous reCAPTCHA badge) are explicitly excluded, so apage that merely loads reCAPTCHA is never reported as a challenge.

Solving (chrome_verification_solve) picks the strategy by type:

  1. Checkbox / token wait — reCAPTCHA v2 / hCaptcha / Turnstile: click thevisible challenge control (provider iframe center preferred) and poll thehidden response token until populated. For silent/interaction-only Turnstilewith no visible checkbox, trigger the page's real submit/verify button witha JS click (btn.click() via page evaluation — locators time out when thebutton is off-screen or covered) so turnstile.execute() runs the actualchallenge; the backend validates the real token, so never monkey-patchwindow.turnstile (fake/empty tokens are rejected, e.g. HTTP 422).
  2. Humanized slider drag — GeeTest / slider: locate the handle, compute thetarget (track end or a backend gap offset), drag with a seeded beziertrajectory (monotonic x, jitter, ease-in-out delays), then verifyacceptance. A gap behind the handle fails closed instead of draggingbackwards.
  3. Click-first generic — text-signal / unknown challenges: click theobvious "Verify you are human" / "验证" / "继续" button (or challengecheckbox) once, wait briefly for a token, and only then escalate.
  4. Capture for backend — image-select / audio challenges: save thechallenge image region and/or audio URL and submit them to an externalOCR/ASR backend.

Hold state machine (chrome_verification_status /chrome_verification_resume) — per-profileidle → challenge_detected → waiting_for_human → cleared with an auditable,bounded transition log. chrome_verification_solve clears the hold on success,hands off on failure, and rolls the hold back if the solver itself crashes.

Humanized input — seeded bezier trajectories with jitter, monotonic-xslider drags, and ease-in-out timing (src/verification/input.mjs),deterministic and testable.

Recognition backends are external and optional. Enable one via theAGENTOS_VERIFICATION_BACKEND environment variable, e.g.cli:python scripts/verification/captcha-backend-adapter.py (a reference JSONadapter for the Python faster-whisper / OCR / opencv stack; it prefers theAgent OS captcha connector when importable and falls back to standalonefaster-whisper / ddddocr / tesseract / opencv otherwise) or an HTTP endpoint.Without a backend, detection, hold/resume, handoff, overlay dismissal, andhumanized interaction all still work. Enabling a backend sends the configuredprocess or endpoint a local capture path and/or a challenge audio URL plus therequested action; an HTTP endpoint may therefore transfer challenge data orcredentials outside this project. Configure only an endpoint you trust andare authorized to use.

Design: docs/superpowers/specs/2026-08-14-verification-handling-design.md

Turnstile truth (field-verified). In a real submission workflow, a"widget rendered but challenge iframe never appears / token stays empty" stateturned out to be a stale session, not an environmental dead-end: aftersigning out and back in on the same profile, the challenge rendered andcompleted normally. The working path is a real front-end click — trigger thepage's actual submit/verify button (a JS btn.click() via page evaluationworks even when the button is off-screen) so turnstile.execute() runs thereal challenge, then let the challenge-complete callback submit the realtoken. In the field case the platform's submit endpoint validated that tokenstrictly (fake/empty → HTTP 422), and monkey-patching window.turnstile(getResponse / render-with-immediate-callback / hidden-input injection) neverproduces one. Escalation order forpending-render: refresh session → trigger real submit → reload-and-retry →hand off.

Live testing

scripts/verification/live-tests/ contains reproducible harnesses that drivereal Chrome profiles through the compliant bridge channel (task tabs only;they are closed after each run):

  • live-verification-test.mjs [url] [profileName] — generic detect → solve →re-detect loop against any URL.
  • live-cf-test.mjs [profileName] — Cloudflare Turnstile with the officialtest sitekeys (1x00000000000000000000AA always-pass,3x00000000000000000000FF forced interactive) plus a click-to-passsimulation fixture. Serve fixtures withpython -m http.server 18999 --directory scripts/verification/live-tests.
  • cf-diagnostic-probe.mjs [profileName] — dumps widget markup / iframe /window.turnstile state for the "widget rendered but challenge iframemissing" (pending-render) state.
  • final-regression.mjs [profileName] — badge-only pages must not bedetected; click-to-pass must still solve.

JavaScript integration

import { startBridge, createAgent } from "./src/index.mjs";

const bridge = await startBridge();
const agent = createAgent(bridge.router);
const targets = await agent.browsers.list();
const browser = await agent.browsers.get(targets[0].id);
const tab = await browser.tabs.new();
await tab.goto("https://example.com/");

Codex compatibility

src/agent-browser.mjs implements the Codex agent.browsers surface. Parityis pinned mechanically: compat/ holds a repository-authored functionalsurface contract, its adapter-map SHA-256, and the adapter map. It does notredistribute bundled product documentation. npm run check:parity andtest/codex-parity-contract.test.mjs fail if any contract member is missing,stubbed, or extra. See compat/README.md anddocs/CODEX_PARITY.md.

The internal identifiers agentos-chrome-cdp, AGENTOS_CHROME_CONFIG, and theexisting AgentOS configuration path are retained for upgrade compatibility;the public display name is Chrome Faithful.

Testing

npm run check          # static gates (structure, JSON validity, generic boundary)
npm test               # mock/unit tests, incl. security contract tests
npm run check:parity   # Codex agent.browsers parity contract
npm run build:extension

Installer transaction tests (Windows): pwsh -NoProfile -File test/installer-transactions.test.ps1.

Static checks and mock tests are necessary but not sufficient. Releaseacceptance additionally requires two concurrently connected real profiles,per-profile selftest, background tab navigation, locator click/fill, raw CDP,screenshot, history, clipboard round-trip with restoration, dry page-Fileinjection, reconnect, and proof that only acceptance-owned tabs were closed —driven by scripts/live-acceptance.mjs,scripts/differential-acceptance.mjs, and the live-test harness above.

Documentation

  • SECURITY.md — safety model and vulnerability reporting
  • CONTRIBUTING.md — development workflow
  • docs/CODEX_PARITY.md — Codex parity design
  • packages/dsh-plugin-chrome-faithful/ — first-party DSH bundle
  • docs/superpowers/specs/ — design specs(profile launch, resilient bridge ownership, verification handling)
  • skills/control-chrome-cdp/SKILL.md —agent-facing operating skill
  • THIRD_PARTY_NOTICES.md — bundled third-party code

Status

Experimental. Windows-first: the installers, DPAPI backups, and .cmd launcherare Windows-only; the extension, bridge, and MCP server are platform-neutralNode.js and should run anywhere Chrome does, but only Windows is exercisedtoday. The bridge controls your real logged-in profiles — review the safetymodel, use exact profiles, and never paste your bridge secret.

License

MIT. Bundled runtime code and development-only verification toolsretain their own MIT, Apache-2.0, or ISC terms — seeTHIRD_PARTY_NOTICES.md.

MCP Server · Populars

MCP Server · New

    JanYork

    LWC — Proactive Memory for AI Agents

    Agent-driven proactive memory CLI for AI agents — autonomously recall, maintain, and evolve persistent, source-grounded knowledge across sessions.

    Community JanYork
    mixelpixx

    Konnect *BETA Release

    AI-assisted PCB design for KiCAD 10. Native KiCAD plugin — a single Rust binary exposing 171 schematic, layout, routing, design-review, and manufacturing tools to Claude, or the LLM of your choosing

    Community mixelpixx
    mixelpixx

    Nimrod

    Web research for Claude over MCP: quality-scored Google search, clean extraction, deep research. Hosted connector for claude.ai/Desktop/Code + Nimrod Desktop toolkit (skills, agent, hooks).

    Community mixelpixx
    Minima-AI-Inc

    minima

    On-premises conversational RAG with configurable containers

    Community Minima-AI-Inc
    Minima-AI-Inc

    minima MCP server

    On-premises conversational RAG with configurable containers

    Community Minima-AI-Inc