Web Agent Bridge (WAB) is an open-source middleware script that creates a standardized interface between AI agents and websites. Instead of forcing AI agents to parse and guess DOM structures, WAB provides a clean, documented command layer that agents can read and execute.
When a website includes the WAB script, it exposes a window.AICommands object that describes
all available actions, their parameters, and how to execute them. AI agents can discover these commands
instantly and interact with the site accurately and securely.
Get your website AI-ready in under 5 minutes.
Sign up at /register and add your site from the dashboard. You'll receive a license key.
Include this in your website's HTML:
<!-- Web Agent Bridge Configuration -->
<script>
window.AIBridgeConfig = {
licenseKey: "WAB-XXXXX-XXXXX-XXXXX-XXXXX",
agentPermissions: {
readContent: true,
click: true,
fillForms: true,
scroll: true
}
};
</script>
<script src="https://yourserver.com/script/ai-agent-bridge.js"></script>
Open your browser console and type window.AICommands. You should see the bridge object with discovered actions.
The bridge is configured through the window.AIBridgeConfig object, which must be set before loading the script.
window.AIBridgeConfig = {
// License key from your dashboard
licenseKey: "WAB-XXXXX-XXXXX-XXXXX-XXXXX",
// Subscription tier (verified server-side)
subscriptionTier: "free",
// What AI agents are allowed to do
agentPermissions: {
readContent: true, // Read page text
click: true, // Click elements
fillForms: false, // Fill and submit forms
scroll: true, // Scroll the page
navigate: false, // Navigate between pages
apiAccess: false, // Call internal APIs (Pro+)
automatedLogin: false, // Automated login (Starter+)
extractData: false // Extract structured data (Pro+)
},
// Access restrictions
restrictions: {
allowedSelectors: [], // Empty = allow all
blockedSelectors: [".private", "[data-private]"],
requireLoginForActions: ["apiAccess"],
rateLimit: { maxCallsPerMinute: 60 }
},
// Activity logging
logging: {
enabled: false,
level: "basic" // "basic" or "detailed"
}
};
Permissions control what AI agents can do on your site. Each permission can be independently toggled.
| Permission | Description | Min Tier |
|---|---|---|
readContent | Read text content from page elements | Free |
click | Click buttons, links, and interactive elements | Free |
scroll | Scroll the page or to specific elements | Free |
fillForms | Fill form fields and submit forms | Free |
navigate | Navigate to different pages | Free |
automatedLogin | Perform automated login flows | Starter |
apiAccess | Call internal REST API endpoints | Pro |
extractData | Extract structured data from the page | Pro |
The window.AICommands object provides the following methods:
getActions(category?)Returns an array of all available actions. Optionally filter by category.
const allActions = window.AICommands.getActions();
const navActions = window.AICommands.getActions("navigation");
// Returns: [{ name, description, trigger, category, requiresAuth, params, fields }]
execute(actionName, params?)Execute a registered action. Returns a Promise with the result.
const result = await window.AICommands.execute("signup");
// → { success: true, action: "click", selector: "#signup-button" }
const formResult = await window.AICommands.execute("fill_contact_form", {
name: "Alice",
email: "alice@example.com"
});
// → { success: true, results: [...] }
readContent(selector)Read text content from a DOM element.
const content = window.AICommands.readContent("h1.title");
// → { success: true, text: "Welcome!", html: "Welcome!", attributes: {...} }
getPageInfo()Get metadata about the current page and bridge state.
const info = window.AICommands.getPageInfo();
// → { title, url, domain, lang, bridgeVersion, tier, permissions, actionsCount, rateLimitRemaining }
waitForElement(selector, timeout?)Wait for a DOM element to appear. Useful for SPAs and dynamically loaded content.
await window.AICommands.waitForElement(".results-loaded", 15000);
// Resolves when the element appears, rejects on timeout
registerAction(actionDef)Register a custom action that AI agents can discover and execute.
window.AICommands.registerAction({
name: "addToCart",
description: "Add the current product to cart",
trigger: "click",
selector: "#add-to-cart-btn",
category: "e-commerce",
metadata: { requiresProduct: true }
});
authenticate(agentKey, agentMeta?)Authenticate an AI agent to access restricted actions.
refresh()Re-scan the page and rebuild the action registry. Call this after significant DOM changes.
onReady(callback)Register a callback for when the bridge finishes initialization.
Actions are the core building blocks of WAB. Each action has:
name — Unique identifierdescription — Human/AI readable descriptiontrigger — Type of action: click, fill_and_submit, scroll, apiselector — CSS selector of the target elementfields — Array of form fields (for fill_and_submit actions)category — Grouping labelrequiresAuth — Whether agent authentication is needed| Trigger | Description | Permission |
|---|---|---|
click | Click on an element | click |
fill_and_submit | Fill form fields and submit | fillForms |
scroll | Scroll to an element or direction | scroll |
api | Call an internal API endpoint | apiAccess |
Subscribe to bridge events for monitoring and integration:
const bridge = window.AICommands;
bridge.events.on('ready', (data) => {
console.log('Bridge ready', data.version);
});
bridge.events.on('action:before', ({ action, params }) => {
console.log(`Executing: ${action}`);
});
bridge.events.on('action:after', ({ action, result }) => {
console.log(`Result: ${result.success}`);
});
bridge.events.on('error', (err) => {
console.error('Bridge error', err);
});
Available events: ready, action:before, action:after, action:registered, action:unregistered, agent:authenticate, error, refresh, destroy
If you're building an AI agent that interacts with websites, here's how to use WAB.
// Check if the site supports WAB
if (window.AICommands) {
const info = window.AICommands.getPageInfo();
console.log(`WAB v${info.bridgeVersion} detected`);
console.log(`${info.actionsCount} actions available`);
console.log(`Tier: ${info.tier}`);
} else {
console.log('No WAB support — fall back to DOM parsing');
}
async function agentWorkflow() {
const bridge = window.AICommands;
// 1. Authenticate (if needed)
bridge.authenticate("agent-key-123", {
name: "MyAssistant",
version: "2.0"
});
// 2. Discover available actions
const actions = bridge.getActions();
// 3. Find the action we need
const loginAction = actions.find(a => a.name.includes('login'));
// 4. Execute it
if (loginAction) {
const result = await bridge.execute(loginAction.name, {
email: "user@example.com",
password: "secure-password"
});
console.log(result);
}
// 5. Wait for navigation
await bridge.waitForNavigation();
// 6. Refresh actions for new page
bridge.refresh();
}
WAB is built with security as a first-class concern:
blockedSelectors to protect sensitive areas (forms with credit cards, admin panels)requireLoginForActions restriction for sensitive operationswindow.AIBridgeConfig = {
licenseKey: "WAB-SHOP-XXXXX-XXXXX",
agentPermissions: {
readContent: true,
click: true,
fillForms: true,
scroll: true
},
restrictions: {
blockedSelectors: ["#checkout-payment", ".credit-card-form"],
rateLimit: { maxCallsPerMinute: 30 }
}
};
// After the bridge loads, add custom actions
document.addEventListener('wab:ready', () => {
window.AICommands.registerAction({
name: "searchProducts",
description: "Search for products by keyword",
trigger: "fill_and_submit",
fields: [{ name: "query", selector: "#search-input", type: "text" }],
submitSelector: "#search-btn",
category: "search"
});
});
window.AIBridgeConfig = {
licenseKey: "WAB-SAAS-XXXXX-XXXXX",
subscriptionTier: "pro",
agentPermissions: {
readContent: true,
click: true,
fillForms: true,
apiAccess: true,
extractData: true
}
};
document.addEventListener('wab:ready', () => {
// Custom API action
window.AICommands.registerAction({
name: "getAnalytics",
description: "Fetch analytics data for the current period",
trigger: "api",
endpoint: "/api/analytics/current",
method: "GET",
requiresAuth: true,
category: "data"
});
// Custom handler action
window.AICommands.registerAction({
name: "exportReport",
description: "Generate and download a PDF report",
trigger: "click",
category: "export",
handler: async () => {
const res = await fetch('/api/report/generate');
const blob = await res.blob();
// trigger download...
return { success: true, message: "Report downloaded" };
}
});
});
The WAB server provides a REST API for managing sites, licenses, and analytics.
| Endpoint | Method | Description |
|---|---|---|
POST /api/auth/register | POST | Create a new account |
POST /api/auth/login | POST | Sign in and receive JWT token |
GET /api/auth/me | GET | Get current user info |
| Endpoint | Method | Description |
|---|---|---|
GET /api/sites | GET | List all your sites |
POST /api/sites | POST | Add a new site |
GET /api/sites/:id | GET | Get site details |
PUT /api/sites/:id/config | PUT | Update site configuration |
PUT /api/sites/:id/tier | PUT | Change subscription tier |
DELETE /api/sites/:id | DELETE | Delete a site |
GET /api/sites/:id/snippet | GET | Get install snippet |
GET /api/sites/:id/analytics | GET | Get analytics data |
| Endpoint | Method | Description |
|---|---|---|
POST /api/license/verify | POST | Verify a license key for a domain |
POST /api/license/track | POST | Record an analytics event |
The core script is open source and free forever. Advanced features like API access, detailed analytics, and automated login require a paid subscription.
WAB works with any agent that can execute JavaScript in a browser context — including Selenium, Puppeteer, Playwright, browser extensions, and AI tools like OpenAI's Operator or Anthropic's Computer Use.
Call bridge.refresh() after navigation events to re-scan for new elements. The waitForElement() method helps agents wait for dynamically loaded content.
Yes. Without a license key, WAB runs in free-tier mode with all basic permissions. The licensing server only validates premium features.