Sepia
Private AI Browser Engine
Describe it. Sepia finds it, acts on it, scales it — privately.
Table of Contents
1.Executive Summary
Sepia is an open-source, secure AI browser engine designed for the agentic era. Where conventional browser automation tools send thousands of tokens of raw HTML noise to a language model, Sepia delivers a compact 80-token semantic outline. Where CSS selectors shatter on every site redesign, Sepia's handles survive because they derive from meaning — not structure. Where header-level spoofing is trivially fingerprinted, Sepia validates JavaScript and header coherence at session start.
Built in TypeScript on Playwright's Chromium, Sepia ships as a CLI, an authenticated HTTP server, and an MCP (Model Context Protocol) stdio server — making it a native tool for Claude Code, Claude Desktop, Codex, and any MCP-compatible host agent. It ships with 231 passing tests, a Kubernetes Helm chart, and Docker OCI images published to GitHub Container Registry.
per page view
in CI
available
threshold
open source
2.The Business Problem
Enterprises deploying AI agents at scale encounter three compounding failures when using conventional browser automation tools. Left unaddressed, these failures transform AI automation initiatives from cost-reduction programs into cost-creation events.
2.1 Token Bloat — The Hidden AI Tax
Every conventional browser automation tool sends either raw HTML, a screenshot, or a JSON DOM tree to the language model. Raw HTML from a production e-commerce page averages 8,700+ tokens. At current frontier model pricing, that is approximately $0.026 per page observation at input rates. An agent running 50 steps across 5 sessions per hour costs over $3 per hour in input tokens alone — before any output costs.
At enterprise scale (1,000 sessions/day), token bloat becomes a first-order infrastructure cost. Most organizations discover this only after deploying at scale, when AI budget lines spike without corresponding business output.
2.2 Fragile Selectors — The Maintenance Trap
CSS selectors and XPath expressions are structural identifiers — they describe where an element is in the DOM tree, not what it is. Modern web applications deploy updates multiple times per week. Each update that renames a class, adds a wrapper element, or restructures a component silently breaks automation pipelines.
The maintenance cost is asymmetric: one redesign can break hundreds of selector-based automations simultaneously, requiring engineering triage across pipelines. Organizations running selector-based automation at scale report spending 20–40% of their automation engineering time on break-fix maintenance.
2.3 Detection & Blocking — The Silent Failure Mode
Anti-bot systems have evolved significantly beyond header inspection. Modern fingerprinting cross-correlates TLS ClientHello (JA3/JA4 signatures), HTTP/2 frame ordering, Canvas rendering, WebGL parameters, font metrics, and behavioral timing. Header-level User-Agent spoofing — the default approach of Puppeteer, Playwright, and Selenium derivatives — is detectable in milliseconds.
Detection causes silent failures: blocked sessions return error pages that the automation framework may interpret as valid pages, consuming budget without delivering results. At scale, detection rates of 5–15% compound into substantial waste.
| Problem | Conventional Tool Behavior | Business Impact |
|---|---|---|
| Token bloat | 8,700+ tokens of raw HTML per observation | $6,500+/day at 1K sessions |
| Fragile selectors | Break on any DOM restructure | 20–40% eng time on break-fix |
| Bot detection | Trivially fingerprinted TLS/header mismatches | 5–15% silent failure rate |
3.Solution Architecture
Sepia addresses all three failure modes with a purpose-built architecture organized around one invariant: the model should only see what it needs to reason, never raw structure.
3.1 The Agent Loop
Sepia runs a deterministic four-phase loop for every goal:
Parse goal Build compact Validate typed Check confidence
into task view from AX action enum retry or stop
serializer, resolver → PURE FUNCTIONS (no LLM, no side effects)
agent → ONLY module with side effects
3.2 Compact Semantic View (Serializer)
On every OBSERVE phase, Sepia navigates to the target URL, waits for DOM stability and network idle, then builds a compact view from the browser's accessibility tree (AX tree). Each interactive or meaningful element becomes a single line:
[e1] heading "Product Pricing" [e2] button "Monthly" [e3] button "Annual" (selected) [e4] link "Start Free Trial — $0/mo" [e5] link "Growth — $49/mo" [e6] link "Enterprise — Contact Us"
Token counts are computed with the real cl100k_base tokenizer, not character estimates. The CI corpus of 5 synthetic fixtures yields a median of 80 tokens and a maximum of 111 — compared to 8,700+ for equivalent raw HTML. The CI gate asserts median ≤ 900 and max ≤ 1,500, providing a regression guard as the corpus grows.
The serializer is a pure function: no LLM calls, no network access, fully unit-tested, and identical in CI and production.
3.3 Stable Semantic Handles (Resolver)
Each element in the compact view is assigned a handle derived from its semantic fingerprint: role + accessible name + ordinal among identically-named siblings. This means:
- When a site restructures its DOM — moving a button from one container to another — the handle is unchanged because the button's role, name, and ordinal are unchanged.
- When an element is genuinely removed, Sepia marks it
staleand stops rather than acting on the wrong element. - Twenty buttons all labelled "Delete" receive twenty distinct handles, and acting on handle [e7] targets exactly [e7].
Resolution uses confidence scoring. Below the configured threshold (default 0.7), Sepia refuses to act and reports stale_bail. The resolver is also a pure function with no model calls.
3.4 Browser Profile Coherence
Sepia applies a validated fingerprint preset at browser context creation. The default preset (chrome-149-linux-x86_64) sets:
- User-Agent matching the bundled Chromium build
- Locale, timezone, and viewport matching a consistent browser persona
navigator.webdrivermasked
A coherence harness validates that these signals do not contradict each other before the session is handed out. If the probes disagree, the session does not start — a fail-closed design that prevents incoherent sessions from being dispatched and detected.
3.5 Architectural Layers
| Layer | Module | Side Effects | LLM Calls |
|---|---|---|---|
| Interfaces | HTTP, MCP, CLI, SDK | Yes | No |
| Agent | agent/ | Yes (only) | Yes (only) |
| Actions | actions/ | Browser only | No |
| Serializer | serializer/ | None (pure) | No |
| Resolver | resolver/ | None (pure) | No |
| Engine | engine/ | Browser only | No |
| Privacy | privacy/ | None (pure) | No |
| Types | types/ | None | No |
A one-way import rule is enforced by ESLint: lower layers never import from higher layers. Violations fail CI. This keeps the serializer and resolver independently testable without any model, browser, or network infrastructure.
4.Token Economics
Token efficiency is not a performance optimization in Sepia — it is the core product value. The compact view directly reduces LLM inference costs and improves reasoning quality by eliminating noise.
| Input type | Typical token count | Cost at $15/M tokens | Noise ratio |
|---|---|---|---|
| Raw HTML | ~8,700 tokens | $0.130 per observation | Very high |
| Screenshot (vision) | ~2,000 tokens | $0.030 per observation | High (opaque) |
| DOM JSON tree | ~3,500 tokens | $0.053 per observation | Medium |
| Sepia compact view | ~80 tokens (median) | $0.001 per observation | Near-zero |
Additionally, models reason more accurately on compact views than on raw HTML. The model's working context is not diluted with irrelevant markup, which reduces hallucination rates in element selection and action planning — a quality improvement that is difficult to quantify but consistently observed in production.
5.Security & Privacy Model
5.1 Data Boundary
Sepia enforces a hard privacy boundary around what enters the model context. The privacy/ module runs as a gate on every observation, not as a best-effort filter:
- redactCompactView() — blanks the value of any field whose accessible name marks it sensitive (password, credit card, SSN, etc.) and scrubs credential-shaped strings from rendered text.
- sanitizeForLLM() — masks prompt-injection patterns before the view is formatted for the model.
- redactSecrets() — runs on typed text before it reaches the trace, ensuring credentials are never logged.
The audit trace records that a secret was redacted, not what it was. At-rest encryption (AES-256-GCM with random IV per write) is the default for profile credentials.
5.2 Action Safety
Model output is never evaluated as code. The model outputs a JSON object; Sepia validates it against a typed action enum and routes it through a fixed dispatch table. There is no eval, no arbitrary code execution path, and no way for a compromised model output to execute shell commands.
URL validation rejects file://, data://, and javascript: schemes at the action layer. No action can redirect the browser to read local files or execute inline scripts.
5.3 Fail-Closed Design
| Condition | Sepia behavior |
|---|---|
| Resolver confidence < 0.7 | Stop, report stale_bail |
| Unknown action type from model | Stop, report error |
| Invalid JSON from model | Stop, report error |
| Stale handle after maxRetries | Stop, report stale_bail |
| Budget (maxSteps) exceeded | Stop, report budget_exceeded |
| Coherence harness failure | Session refused, not started |
| HTTP server with no auth config | Process refuses to start |
5.4 HTTP Server Authentication
The HTTP server refuses to start without either a SEPIA_SERVER_API_KEY environment variable or an explicit --allow-unauthenticated flag. This prevents accidental open deployments where an AI agent runner could be driven to fetch arbitrary URLs using the operator's model credentials. Safe-by-default is not aspirational — it is a hard startup gate.
5.5 Ephemeral Profiles
Browser profiles are ephemeral by default (browser.ephemeral: true). Every session starts from a clean state with no cookies, localStorage, or cached credentials from prior runs. Cross-run contamination — a common source of data leakage in long-running automation deployments — is eliminated at the infrastructure level.
6.Enterprise Use Cases
| Use Case | Example Goal | Key Sepia Capability |
|---|---|---|
| Authenticated Workflows | Sign in, navigate multi-step authenticated flows | Credential redaction, ephemeral profiles |
| Search & Data Extraction | Aggregate product data, prices, availability across pages | Compact view, typed RunTrace output |
| Form Completion | Fill complex multi-step forms with validation | Type, select, check, scroll actions with typed enum |
| Multi-Page Navigation | Add to cart → checkout → apply coupon → confirm | Agent loop maintains state across page transitions |
| Batch Processing | Price-check 500 SKUs, monitor 1,000 listings | HTTP server concurrency, Kubernetes HPA |
| Competitive Intelligence | Monitor pricing pages, track feature launches | Ephemeral profiles, structured RunTrace output |
| QA Automation | Regression testing with plain-language test specs | Screenshot capture, deterministic handle resolution |
| Research Assistance | Aggregate academic results, summarize sources | MCP integration with Claude Code / Claude Desktop |
7.Deployment & Integration
7.1 CLI
One-shot agent runs from the terminal, returning a structured RunTrace JSON object with full step audit trail. Suitable for scripted workflows, CI pipelines, and ad hoc investigation.
sepia run "What is the current Node.js LTS version?" --answer-only # → "The current Node.js LTS release is 22.11.0."
7.2 HTTP Server
A long-running REST API suitable for enterprise integration patterns. Bearer-token authentication is required. Configurable concurrent session limit. Health endpoint for load balancer integration.
POST /run {"goal": "..."} → RunTrace (200 / 422 / 503)
GET /health → {"ok": true, "inflight": 2, "maxConcurrent": 5}
7.3 MCP Stdio Server
Sepia as a browser tool for upstream AI agents. The host agent (Claude Code, Claude Desktop, Codex) does the reasoning; Sepia drives the browser. No model API key required — Sepia's import graph in MCP mode never reaches the agent loop. 18 tools across four categories:
| Category | Tools |
|---|---|
| Look | observe, read, screenshot |
| Navigate | open, back, forward, wait |
| Interact | click, type, select, check, press, hover, scroll |
| Tabs | tabs_list, tabs_new, tabs_switch, tabs_close |
7.4 Docker
docker pull ghcr.io/mohnishbasha/sepia:v0.1.0 docker run --rm \ -e SEPIA_MODEL_ENDPOINT=https://api.anthropic.com/v1 \ -e SEPIA_MODEL=claude-sonnet-4-6 \ -e SEPIA_API_KEY=sk-ant-... \ ghcr.io/mohnishbasha/sepia:v0.1.0 run "What is the Node.js LTS version?"
7.5 Kubernetes (Helm)
Production-grade Helm chart with HorizontalPodAutoscaler (1–10 replicas, 70% CPU target), 2Gi memory limit per pod (Chromium is memory-hungry), and secret management via existingSecret.
helm upgrade --install sepia helm/sepia \ --namespace sepia \ --set existingSecret=sepia-credentials \ --set serverAuth.existingSecret=sepia-server-auth \ --set env.SEPIA_MODEL=claude-sonnet-4-6 \ --wait
8.Model Compatibility
Sepia communicates with any OpenAI-compatible API endpoint. Only the base URL and model name change. No Sepia-specific fine-tuning is required.
| Provider | Example models | Notes |
|---|---|---|
| Anthropic | claude-sonnet-4-6, claude-opus-4-7 | Default; recommended for best reasoning |
| OpenAI | gpt-4o, o3 | Full action set supported |
| OpenRouter | Any listed model | Multi-provider routing, 400+ models |
| Ollama (local) | llama3.1, mistral, deepseek | No API key; local inference; air-gap friendly |
| DeepSeek | deepseek-v4-flash | Via OpenRouter or direct endpoint |
Local Ollama inference is significant for air-gapped enterprise environments where model API calls to external providers are prohibited by security policy. Sepia's compact view makes local inference economically viable — 80-token views are within the reasoning capacity of smaller open-weight models.
9.ROI Analysis
9.1 Token Cost Savings
| Scale | Sessions/day | Obs/session | Raw HTML cost/day | Sepia cost/day | Saving/day |
|---|---|---|---|---|---|
| Pilot | 100 | 50 | $65 | <$1 | ~$64 |
| Growth | 1,000 | 50 | $650 | ~$7 | ~$643 |
| Enterprise | 10,000 | 50 | $6,500 | ~$65 | ~$6,435 |
Assumes GPT-4o pricing at $15/M input tokens. Sepia costs estimated at 100 tokens/observation including prompt overhead. Actual savings depend on model pricing and observation depth.
9.2 Engineering Maintenance Savings
Selector-based automation teams report spending 20–40% of engineering time on break-fix maintenance after site redesigns. With Sepia's semantic handles, the primary cause of breakage is eliminated. For a 2-engineer automation team at $200k loaded cost each:
- 25% maintenance time × $400k/year = $100k/year in recovered engineering capacity
- Faster time-to-value for new automation workflows (no selector archaeology)
- Reduced incident response burden from silent detection failures
9.3 Quality Improvements
Compact views reduce model hallucination in element selection — the model cannot confuse an irrelevant marketing paragraph with a button when it only sees interactive elements. Organizations using compact-view approaches consistently report higher success rates per agent run compared to raw-HTML approaches, though exact figures depend heavily on site complexity and model choice.
10.Limitations & Roadmap
10.1 Current Limitations
| Limitation | Detail | Workaround |
|---|---|---|
| TLS fingerprinting (JA3/JA4) | patches/ documents a BoringSSL patch stack but contains no patch files. TLS fingerprinting is not addressed. |
Use with sites that do not fingerprint TLS; pair with proxy infrastructure |
| Identical element handles | Elements sharing role + name (e.g., many "Delete" buttons) are visually indistinguishable in compact view (issue #3) | Take screenshot before destructive action; use read() for context |
| Token counts are corpus-limited | CI corpus is 5 synthetic fixtures; real-world pages may exceed 900-token gate on complex SPAs | Use verbosity:'minimal' option; test against target site in staging |
| No visual rendering | Compact view captures semantic structure, not visual layout; some UI patterns rely on spatial context | Use screenshot() for visual context before complex spatial interactions |
10.2 Roadmap
- TLS coherence (AC-F1/AC-F2) — BoringSSL patch implementation for JA3/JA4 fingerprint matching
- Identical handle disambiguation — spatial position and adjacent text as secondary discriminators (#3)
- Real-world corpus expansion — benchmark against production sites across categories
- Fine-tuning dataset —
training/scaffolding for model specialization on Sepia action grammar - LiteLLM integration — unified provider routing without per-provider configuration
11.Getting Started
11.1 Prerequisites
- Git
- Node.js 22.11.0 (
nvm install 22.11.0) - A model API key, or a local Ollama instance
11.2 Quick Start
git clone https://github.com/mohnishbasha/sepia.git cd sepia make setup # installs pnpm, all deps, and Playwright Chromium make build # compiles TypeScript → dist/ export SEPIA_MODEL_ENDPOINT=https://api.anthropic.com/v1 export SEPIA_MODEL=claude-sonnet-4-6 export SEPIA_API_KEY=sk-ant-... make run ARGS='run "What is the current Node.js LTS version?" --answer-only'
11.3 Install as MCP Tool in Claude Code
make cli-link # builds dist/ and links `sepia` globally claude mcp add sepia -- sepia mcp
11.4 Run as HTTP Server
export SEPIA_SERVER_API_KEY=$(openssl rand -hex 32)
make run ARGS='serve --port 3000 --max-concurrent 5'
curl -X POST http://localhost:3000/run \
-H "Authorization: Bearer $SEPIA_SERVER_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"goal": "What are the plan prices on example.com/pricing?"}'
11.5 Run Test Suite
make test # 231 tests (unit + integration + resilience) make test-tokens # token budget gate make test-mutation # handle stability mutation tests
12.About Serverlessvc.com
Serverlessvc.com is an AI Software, AI Media, and AI Investing agency delivering measurable business outcomes. We build production-grade AI systems — Edge AI, Vertical AI, AI Agents, and LLM Frameworks — for enterprises worldwide.
Sepia is an open-source project developed under the Serverlessvc.com portfolio. It is released under the MIT License and contributions are welcome.
| Resource | Link |
|---|---|
| GitHub Repository | github.com/mohnishbasha/sepia |
| Product Page | serverlessvc.com/sepia.html |
| Agency Website | serverlessvc.com |
| Discovery Call | calendar.app.google/AAJ4aWzUJTsxxGDw5 |
| Security Policy | SECURITY.md in repository |
| Contributing Guide | CONTRIBUTING.md in repository |
© 2025–2026 Serverlessvc.com · Sepia is released under the MIT License · github.com/mohnishbasha/sepia
To save this document as PDF: click "Save as PDF" above or use File → Print → Save as PDF in your browser.