Open Source

The browser
built for AI

Veil decomposes webpages into Behavior Graphs — structured maps of interactive elements, their events, API calls, and semantic purpose. So your AI agent can see, understand, and act on the web.

Terminal
$ veil open instagram.com Session: 8d060512-c7e1-4418-99fd-0312aeb2c487 $ veil graph 8d06 PAGE https://instagram.com "Instagram" STATE route:/ NODES textbox-username [textbox] "Phone number, username, or email" on:change {auth:input} textbox-password [textbox] "Password" on:change {auth:input} button-log-in [button] "Log in" on:clickPOST /api/v1/web/accounts/login/ajax/ {auth:login}
99.9%
Reduction
50K → 40
Lines
265
Tests Passing
9
MCP Tools
The Problem
AI agents are flying blind

Current approaches to web automation are built for humans, not language models. LLMs need structure, not pixels.

📸
50K+

Screenshots waste tokens

A single page screenshot costs 50K+ tokens to process. Veil gives the LLM 40 lines of structured, actionable text instead.

🌀
3,000+

DOM is noise

Thousands of nested divs, CSS classes, invisible elements, tracking pixels. Veil filters to 50–300 meaningful behavior nodes.

🔗
0

Selectors break

CSS selectors are fragile — one redesign and they're gone. Veil uses semantic IDs like button-log-in that survive changes.

How It Works
From 50,000 lines to 40

Every webpage passes through Veil's decomposition pipeline. Humans see rendered pixels — LLMs receive structured behavior.

What humans see — rendered pixels
Sign In
username or email
password
Log In
Forgot password?
+ 3,000 invisible DOM nodes, CSS, fonts, images...
What the LLM receives — compact text
PAGE https://example.com/login "Sign In" STATE route:/login NODES textbox-username [textbox] "Username or email" on:change {auth:input} textbox-password [textbox] "Password" on:change {auth:input} button-log-in [button] "Log In" on:click {auth:login} link-forgot [link] "Forgot?" NETWORK POST /api/auth/loginbutton-log-in COMPONENTS LoginForm → textbox-username, textbox-password, button-log-in
The Reduction Funnel
Raw Source
~50K
lines of HTML
<!-- What the browser downloads --> <html> <body> <div class="css-1dbjc4n r-1awozwy..."> <div class="css-1dbjc4n r-18u37iz..."> ...3000+ nested divs...
CDP: Accessibility.getFullAXTree()
AXTree
3K–10K
accessibility nodes
// Chrome's accessibility tree { nodeId: "284", role: "textbox", name: "Phone number, username, or email" } { nodeId: "285", role: "generic" } ← filtered out { nodeId: "287", role: "button", name: "Log In" }
shouldKeep() → 22 interactive roles
Filtered
50–300
behavior nodes
// Only interactive + container roles KEPT: textbox, button, link, checkbox, radio, combobox, slider, switch, tab, menuitem... DROPPED: generic, none, InlineTextBox, paragraph, LineBreak, StaticText... (95% of nodes)
Events + Network + Components + Semantics
Compact Text
~40
lines for LLM
PAGE https://instagram.com "Instagram" NODES textbox-username [textbox] "Phone number..." on:change {auth:input} button-log-in [button] "Log in" on:clickPOST /api/v1/web/accounts/login/ajax/ {auth:login}
50,000 lines → 40 lines · 99.9% reduction · zero information loss for actions
Features
Everything an AI agent needs

From raw CDP connection to semantic inference — Veil handles the entire web understanding stack so your agent doesn't have to.

Core Engine

5-Stage Decomposition Pipeline

Every webpage passes through five stages — from raw accessibility tree to semantically labeled behavior graph. Each stage enriches the graph with deeper understanding.

1AXTree
2Events
3Network
4Components
5Semantics
Integration

MCP Native

Works with Claude Desktop, Cursor, Windsurf, or any MCP-compatible host. 9 structured tools out of the box — no CLI needed.

veil_open · veil_graph · veil_interact
veil_navigate · veil_find · veil_inspect
veil_auth · veil_sessions · veil_close
Persistence

Session Persistence

Multi-step workflows that survive across calls. Login flows, form filling, navigation — cookies, localStorage, and DOM state all persist.

1. veil open instagram.com
2. veil do type textbox-username
3. veil do type textbox-password
4. veil do click button-log-in
5. → 2FA page, session preserved
DX

Human-Readable IDs

Forget opaque node IDs. Veil generates semantic display IDs that LLMs can reason about and reference naturally in tool calls.

button-log-in textbox-username link-forgot-password checkbox-remember-me
Real-time

Live Graph Updates

MutationWatcher detects DOM changes — AJAX loads, SPA navigations, animations — and patches the graph incrementally. No full rebuilds.

Low-level

Raw CDP

No Playwright. No Puppeteer. Direct Chrome DevTools Protocol for fine-grained control over every browser capability. Zero abstraction overhead.

Use Cases
What you can build

Veil gives AI agents structured web understanding. Here's what becomes possible.

🤖

AI Web Agents

Give Claude, GPT, or custom agents the ability to browse, understand, and interact with any website. Login to accounts, fill forms, navigate multi-step flows — through structured behavior graphs, not fragile selectors or expensive screenshots.

🧪

Semantic Testing

Write tests against behavior, not implementation. Assert that "the login button submits credentials to the auth API" — not that #btn-3f2a exists. Tests survive complete redesigns because they test what things do, not where they are.

📡

API Discovery

Automatically map which UI elements trigger which API endpoints. Veil extracts request/response shapes, URL patterns like /users/{id}, and status codes — without reading a single line of source code.

📊

Web Intelligence

Understand how any website works from the outside. What forms submit where, how components are grouped, what frameworks are used. Extract structured data through behavior graphs instead of brittle CSS selectors.

🔄

Regression Detection

Compare behavior graphs across page versions to detect functional changes. A button that used to call POST /api/v1/login now calls POST /api/v2/auth? Veil catches it — no visual diffing needed.

🌐

Cross-Site Pattern Learning

Discover common interaction patterns across websites — login flows, search behaviors, checkout processes. Behavior graphs normalize different implementations into comparable semantic structures.

Why Veil
The only browser that thinks in behavior

Existing tools give AI agents raw DOM or pixels. Veil gives them structured understanding of what a page does — not just what it looks like.

Capability Playwright / Puppeteer browser-use / Stagehand Veil
What AI receives Raw DOM (3K+ nodes) Annotated screenshots Behavior Graph (50-300 nodes)
Token cost per page ~50K tokens ~50K tokens (image) ~800 tokens (compact text)
Knows what buttons do No No Yes — event handlers classified
Maps UI → API calls No No Yes — stack trace correlation
React Fiber traversal No No Yes — finds real handlers
Semantic node IDs CSS selectors XY coordinates button-log-in
Session persistence Per-script only Limited Background daemon
API shape extraction No No {email: string, password: string}
Protocol Abstracted CDP Playwright wrapper Raw CDP (zero overhead)
MCP native No Some 9 tools, stdio transport
70%
fewer tokens

Compact text format vs equivalent JSON. LLM context windows go further.

0
visual computation

Skips Blink rendering (layout, paint). Only runs JS + Accessibility pipeline.

5
enrichment stages

AXTree → Events → Network → Components → Semantics. Each stage adds meaning.

framework support

Explicit React Fiber traversal. Vue/Angular detection. Vanilla heuristics for everything else.

"browser-use migrated from Playwright to raw CDP for exactly these reasons — Playwright's Node.js relay adds a network hop on every CDP call, prohibitive when making thousands of calls for event listeners, accessibility tree queries, and network monitoring."

— Project Veil Architecture Decision Record
Integrate
Three ways to connect

MCP server for AI hosts, CLI for scripting, TypeScript SDK for embedding. Pick what fits your workflow.

🔌

MCP Server

stdio
{ "mcpServers": { "veil": { "command": "node", "args": ["veil-mcp"] } } }

CLI

bash
# Install globally npm install -g @veil/cli # Open and explore veil open github.com/login veil graph $SID veil do $SID click button-sign-in
📦

TypeScript SDK

esm
import { Veil } from "@veil/core"; const veil = new Veil(); const page = await veil.open("github.com"); const graph = await page.getGraph(); const text = await page.toCompactText();
Quick Start
Get started in 30 seconds

Install the CLI, open a page, and see the behavior graph.

# Install $ npm install -g @veil/cli # Open any page $ veil open github.com/login → 8d060512-c7e1-4418-99fd-0312aeb2c487 # See the behavior graph $ veil graph 8d06 → PAGE, NODES, NETWORK, COMPONENTS... # Interact with elements $ veil do 8d06 click button-sign-in