Browser-Agent MCP Farm
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Browser-Agent MCP FarmCapture this page, verify the quote 'free returns', and export evidence."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Browser-Agent MCP Farm
한국어 README: README.ko.md
Tamper-evident web evidence for AI agents. An MCP server (plus CLI) that captures what the browser actually saw, SHA-256-registers every artifact, and fails any cited claim that doesn't re-match the registered bytes (cite-or-fail) — then exports a Merkle-rooted, optionally Ed25519-signed bundle that a second agent re-verifies fully offline.
This is not another browser driver. Playwright MCP, Chrome DevTools MCP, and consented in-browser agents already drive the web well. The farm is the verification layer beside them: gather anywhere, then seal the load-bearing few claims here, so "the model said it saw it" becomes "here are the bytes, the hash, the quote inside them, and a bundle you can re-check without trusting me."
30-second code review
Review question | Start here |
Does a fabricated quote fail? | |
Can another agent verify the hand-off offline? | |
Are browser actions bounded? |
|
Are the limits explicit? | |
Is the repository reproducibly green? |
|
The project was built as a solo engineering system, so the public evidence is the implementation, adversarial fixtures, generated status, and reproducible CI rather than claims of team-scale production usage.
Related MCP server: LedgerProof LAIN
Why
Agents browse, then assert. When the output feeds a real decision, document, or dispute, three failure modes matter:
Hallucinated citations — the quoted page never said that.
Silent tampering — the saved evidence changed after capture.
Unverifiable hand-offs — a second agent (or a human reviewer) has no way to re-check the first agent's evidence without redoing the work.
The farm closes these with a deterministic floor: every artifact is
hash-registered at capture; a claim must cite a registered, typed artifact and
(for anchored claims) its quoted text_span must actually exist in the cited
bytes; the run fails on uncited or misquoted claims; the exported bundle is
re-verified at export time and again, offline, by whoever receives it.
Adjacent tools solve adjacent problems: C2PA / Content Credentials signs media assets at creation; WACZ / signed web archives seal page archives; zkTLS / TLSNotary proves TLS sessions. The farm sits in the gap those leave — claim-level, agent-integrated (MCP), locally verifiable web evidence — and is designed to interoperate with them rather than replace them.
What it proves — and what it doesn't
This project treats its own limits as a feature. The short version
(full detail: docs/THREAT_MODEL.md):
Proves | Does NOT prove | |
Claim gate | Every registered artifact's bytes still match their recorded SHA-256 (re-hashed at gate time); every final claim cites a registered, typed artifact; an anchored claim's quote is present in the cited bytes | That the captured bytes faithfully represent the live page (a malicious producer could register fabricated bytes); that an un-anchored claim is true; anything about free-text prose outside the ledger |
Evidence bundle | Offline: every manifest artifact present and hash-matching; Merkle root recomputes; with a public key, the root was signed by the matching private-key holder | That the sealed bytes are a faithful record of the live web — the signature attests who sealed, not what was true |
Read a green gate as "this evidence is internally consistent, byte-stable, and the claims are grounded in it" — never as "this answer is true." For truth, corroborate the highest-stakes numbers across independent sources; for origin-binding (proving bytes came from the origin server), see the opt-in capture-binding tiers below and their honest limits.
Install & 60-second quickstart
Requires Node.js 22+ (CI tests 22 and 24). Chromium is auto-installed on
first serve if missing (opt out with FARM_SKIP_BROWSER_AUTOINSTALL=1).
From npm (recommended): register a portable npx-resolved invocation with
Claude Code and/or Codex — the host config carries no build path, and upgrades
flow through the package manager:
npx -y browser-agent-mcp-farm@latest register-all --npx
# or pin / use a scope: ... register-all --npx --package-spec browser-agent-mcp-farm@0.8.0From a clone (development):
npm ci
npx playwright install --with-deps chromium
npm run build
node ./dist/cli.js register-all # registers the absolute path of this build(./install.ps1 on Windows or sh install.sh on macOS/Linux runs those steps
plus register-all in one go, with timestamped config backups.)
Restart your agent, then verify: claude mcp get browser-agent-mcp-farm. The
tools appear as mcp__browser-agent-mcp-farm__farm_*.
Run one auditable, claim-gated capture from the CLI:
node ./dist/cli.js evidence-run --url https://example.com/ --no-frames --wait-ms 0 --timeout-ms 10000From an agent, call farm_evidence_run with { "url": "https://example.com/" },
then farm_read_report with the returned reportPath. The full agent playbook
lives in skills/browser-agent-mcp-farm/SKILL.md
(installed for Claude automatically by register-all; the copy self-heals on
serve after upgrades).
The core loop: cite-or-fail
The strongest way to use the farm is as a verification layer over research you gathered any way you like:
1. capture / register bytes farm_evidence_run { url } (farm captures)
farm_register_evidence { text | bytesBase64 } (you captured — BYO)
2. author claims against them farm_add_claim { claim, artifactId,
anchor: { type: "text_span", quote } }
3. gate farm_run_claim_gate { strictProvenance: true }
→ a claim whose quote is NOT in the cited bytes FAILS the run
4. seal farm_export_bundle { runDir } (auto-verifies before shipping)
5. hand off farm_verify_bundle — anyone re-checks offlineA hallucinated citation cannot pass step 3: the gate re-reads the registered
bytes and rejects the claim. strictProvenance additionally hard-fails claims
that cite agent-authored "structured data" (self-asserted JSON) instead of
farm-derived extraction — closing the measured "news retyped as JSON" hole.
Worked agent-to-agent verifiable exchange
The self-contained .evb archive lets one agent trust another's evidence by
trusting hashes, not the producer:
# Agent A (captured the evidence, holds a private signing key)
node dist/cli.js export-bundle --run-dir <A-run> --archive-file bundle.evb \
--private-key-env A_SIGNING_KEY
# Agent B receives only bundle.evb + A's PUBLIC key — no run dir, no browser
node dist/cli.js verify-bundle --archive-file bundle.evb --public-key-env A_PUBLIC_KEY
# -> { ok: true, complete: true, merkleMatches: true, signatureValid: true }B re-hashes the embedded bytes, recomputes the Merkle root, and checks A's
signature fully offline. Altered bytes → tamperedArtifacts; an impostor
key → signatureValid: false. The success criterion is "one cooperating second
agent can verify," not "the world converges" — see
tests/evidence-exchange.test.ts for the worked A→B example.
MCP tool surface (32 tools)
Group | Tools |
One-shot workflow |
|
Manual capture |
|
Write actions (lease |
|
Cite-or-fail authoring |
|
Verification (no browser) |
|
Sealing & structure |
|
Research lenses & ops |
|
farm_lens ships declarative claim-type lenses: market_scan
(competitor_price, review_sentiment, and market_figure — the latter
requires corroboration across ≥2 independent registered domains, verified
against each source's bytes) and product_planning (user_pain,
feature_gap, adoption_figure).
CLI
The same engine, scriptable. Highlights (full list: browser-agent-mcp-farm help):
Command | Purpose |
| MCP stdio server / local HTTP job queue ( |
| Full capture → typed artifacts → claims → final gate, one command |
| Re-validate a run; |
| Merkle manifest or self-contained signed |
| Verify gate-verdict / transparency-log hash chains |
| Scan a finished run for secrets-at-rest (non-zero exit if found) |
| Retention: delete, sweep by age/byte budget, or tier-archive runs |
| Consented login profiles (visible browser; or import cookies from your own Chrome via DevTools port) |
| Manage saved profiles |
| Fixture and public-page smoke captures |
| Human-browsable preview of a run's evidence |
| What evidence paths exist for a platform URL; are the needed credential env vars set (never prints token values) |
| Host registration (with |
| Show installed version + upgrade/re-register instructions |
Useful evidence-run options: --http-fetch (browserless tier-0 GET) and
--auto-capture (tier-0 first, escalate to the browser on any decline);
--capture-cache (replay a ≤1h prior capture by content hash, labelled
cached_capture with staleness age); --text-only; --headed; --profile <name> / --persistent-profile; --ocr (+--ocr-language,
--ocr-min-confidence); --dense-sampling (extra frame windows around
transcript-cue / OCR / scene-change hits); --official-api (credentials via
env-var names only); --intent / --intent-scope / --intent-shapes /
--success-criteria (soft intent lock recorded as an intent_profile
artifact). Non-terminal public-page failures fall back to legal public gateways
(Wayback latest snapshot); login/paywall/CAPTCHA/age/region gates stay terminal.
What a run records
evidence-run writes typed, hash-registered artifacts for everything it
derives: page text/HTML/screenshot, timestamped media frame samples (never raw
stream downloads), WebVTT transcript cues, OCR passes (as derivatives of a
registered screenshot, with language/confidence/text-profile metadata),
structured extraction (JSON-LD / Open Graph / typed price+rating), acquisition
method plans, official-API readiness, source strategy, obstruction
classifications (login walls, bot blocks, region/age gates — recorded as
obstructions, not treated as content), overlay-dismissal evidence, and
stage timings. Claims and citations land in append-only ledgers; the final
claim gate runs last and fails the run on any uncited or misquoted claim.
Authenticated capture — consent-first
For sites that need login, the operator logs in manually, once, in a
visible browser (auth-login, or auth-cdp-launch/auth-cdp-import to import
cookies from your own Chrome). Saved profiles live under
~/.gstack/browser-profiles/<profile>/, created owner-only (POSIX 0700 /
Windows ACL). On Windows, FARM_ENCRYPT_STORAGE_STATE=1 wraps the storage
state with DPAPI (CurrentUser) — protecting at-rest/offline copies, not code
running as the same user. One active lease per profile is enforced across
processes by an on-disk lock, so parallel workers never clobber a cookie jar.
Safety boundaries (enforced in code, not prose)
No login / CAPTCHA / paywall / age-gate bypass. Walls are classified and recorded as obstructions; consented profiles are the only authenticated path.
No payment / booking / account-change automation — write actions are blocked on payment-like URLs, selectors, and element text (
checkout,cvv,pay now,결제, …).No raw platform video/audio stream download, and no claim of audio/video understanding without a matching transcript/frame artifact. The farm performs no speech-to-text; captured captions are registered as
transcript_cue, never a fabricated transcription.Every source-registry entry carries a
legalBasis(public_browser_visible,official_api,user_provided,derivative_citation,planning_only) recording the intended lawful-access posture.
Security posture
Least privilege by default: leases are read-only unless
read-writeis requested; domain allowlists per lease; payment guard on all write paths.HTTP mode is authenticated:
serve-httprefuses to start on a non-loopback host without a token; withFARM_HTTP_TOKEN(or--token) set, every request needsAuthorization: Bearer <token>(401 before any route logic). Intended for local orchestration, not as a shared production service.Small supply chain: three runtime dependencies (
@modelcontextprotocol/sdk,playwright,zod) plus optionaltesseract.js;npm auditruns inside the release gate.Secrets: credentials are passed as env-var names, never values, through CLI/MCP/HTTP inputs;
scan-secretschecks finished runs for leaked tokens.Vulnerability reports: see
SECURITY.md.
Opt-in capture-binding tiers
Default captures are plain and unchanged. Opt-in pieces bind a capture closer
to its origin — each documented with what it does and does not prove
(docs/CAPTURE_BINDING.md):
FARM_BIND_TLS=1— record the TLS certificate the final host presents (separate probe): cert pinning / issuer-change detection.FARM_BIND_TLS_SAMECONN=1— record the certificate on the same socket that delivered the bytes (tier-0 HTTP path).export-bundle --anchor-log— append verified Merkle roots to a hash-chained transparency log (proves relative order, not wall-clock time; an RFC-3161 TSA seam is in place for real timestamps).
None of these upgrade trust by themselves — the deterministic gate stays the
trust boundary. Full origin-binding (proving bytes came from the origin server
against a malicious local producer) requires a neutral notary (zkTLS-class);
that boundary is documented, not papered over
(docs/ORIGIN_BINDING_DESIGN.md).
Quality gates
npm run verify = build → typecheck → lint → dependency-boundary guard
(the browser/lease primitives may never import platform logic — build-enforced)
→ tests + coverage (ratcheting floor) → 4 smoke captures → packaged-tarball
test → npm audit → generated status. CI runs the same gate on Ubuntu and
Windows, Node 22 and 24. Current numbers live in the generated
STATUS.md / SCORECARD.md — they are not
restated here by design.
The cite-or-fail boundary itself is regression-tested by a versioned,
seed-deterministic fuzz corpus (npm run qa:fuzz, a hard CI gate): currently
0 hallucination leaks across 1,200 fabrication / near-miss / recombination
trials. New hard cases are added by appending seeds, never removing one.
Architecture (one paragraph)
Thin transports (mcp-server / cli / http-server) → a single facade
(farm-service) → generic browser primitives (lease-manager,
browser-pool) → platform intelligence (source strategy, adapters, OCR,
official API) → run orchestration (evidence-runner) → integrity
(claim-gate). One hard, build-enforced rule: primitives never import the
layers above them (npm run boundaries fails the build otherwise). Details:
docs/ARCHITECTURE.md.
Host integration
Two modes, documented in HOST-ADAPTERS.md:
Mode A — parent-driven (default, safest): the parent agent holds the farm tools, captures, and hands saved artifacts to analyzer subagents.
Mode B — browser-worker subagents: only when the host can grant farm MCP tools to a worker; one task + domain allowlist per worker, own
agentId, release in afinallyblock, never reuse another worker's context token.
Documentation
Doc | What's in it |
The agent-facing playbook (tool flow, lens claim types, refusal lines) | |
Exactly what the gate/bundle prove and do not prove | |
Opt-in provenance pieces, shipped vs deliberately deferred | |
Layering + the build-enforced boundary rule | |
Optional credentialed-API and OCR surfaces | |
The quality gates and how "verified" is defined | |
Full doc index (including development history) | |
Versioned changes (semver) |
Scope & non-goals
In scope: the local capture-and-verify slice — leases, consented capture, hash-registered typed artifacts, claim gating, sealed bundles, host registration, and a local HTTP queue.
Out of scope, permanently: payment actions; DRM bypass or raw platform
video/audio download; login/CAPTCHA/paywall bypass; a production multi-tenant
remote service. (Historical note: a per-site selector/recipe subsystem was
deliberately excised in 2026-06 — selector recipes rot; model vision + a
consented browser replaced them. docs/SELECTOR_STACK_EXCISION.md records the
decision.)
License
Source-available, view/evaluation only — see LICENSE.
© 2026 이지범. All rights reserved. You may read the code and run it locally,
unmodified, to evaluate the author's work; any other use, copying,
modification, or redistribution requires prior written permission
(ezboom1111@gmail.com). Runtime npm dependencies remain under their own
licenses (NOTICE). Versions up to 0.7.0 previously published to
npm under Apache-2.0 remain governed by that license for those copies only.
Licensing history and release process: docs/PUBLIC_RELEASE.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
Did it really happen? Independent signed receipts for AI agents: page, domain, email, heartbeat.
Machine-native utility network: verified evidence services for autonomous agents.
Verified memory for AI agents. Signed assertions, billing attestation, session continuity.
Tamper-evident proof creation and verification for AI agents via MCP, A2A, and REST.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to query cryptographically verified facts with zero-knowledge proofs, selective disclosure, and tamper-evident provenance.481 npm1Apache 2.0
- FlicenseNot gradedqualityCmaintenanceCryptographically anchored, tamper-evident evidence receipts for AI agents — verified run receipts, existence-at-time proofs, and cited answers from an anchored public record. Remote MCP with proof-gated settlement; attests existence and integrity, never truth.-
- AlicenseAqualityBmaintenanceProvides cryptographic truth infrastructure for AI agents, enabling them to seal content with SHA-256 and Ed25519, verify receipts, anchor them to Bitcoin via OpenTimestamps, generate citations, and audit chains of receipts.526 npm1MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to create verifiable, replayable citations, search private knowledge bases, and publish Markdown with verified citation markers.MIT