web-agent-bridge 1.2.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.ar.md +572 -446
- package/README.md +968 -933
- package/bin/agent-runner.js +465 -0
- package/bin/cli.js +138 -80
- package/bin/wab.js +80 -80
- package/examples/bidi-agent.js +119 -119
- package/examples/mcp-agent.js +94 -94
- package/examples/next-app-router/README.md +44 -0
- package/examples/puppeteer-agent.js +108 -108
- package/examples/saas-dashboard/README.md +55 -0
- package/examples/shopify-hydrogen/README.md +74 -0
- package/examples/vision-agent.js +171 -171
- package/examples/wordpress-elementor/README.md +77 -0
- package/package.json +71 -78
- package/public/.well-known/ai-assets.json +59 -0
- package/public/admin/login.html +84 -84
- package/public/ai.html +196 -0
- package/public/cookies.html +208 -208
- package/public/css/premium.css +317 -0
- package/public/css/styles.css +1235 -1235
- package/public/dashboard.html +704 -704
- package/public/demo.html +259 -0
- package/public/docs.html +585 -585
- package/public/feed.xml +89 -0
- package/public/index.html +581 -332
- package/public/js/auth-nav.js +31 -31
- package/public/js/auth-redirect.js +12 -12
- package/public/js/cookie-consent.js +56 -56
- package/public/js/wab-demo-page.js +721 -0
- package/public/js/ws-client.js +74 -74
- package/public/llms-full.txt +309 -0
- package/public/llms.txt +85 -0
- package/public/login.html +83 -83
- package/public/openapi.json +580 -0
- package/public/premium-dashboard.html +2487 -0
- package/public/premium.html +791 -0
- package/public/privacy.html +295 -295
- package/public/register.html +103 -103
- package/public/robots.txt +87 -0
- package/public/script/wab-consent.d.ts +36 -0
- package/public/script/wab-consent.js +104 -0
- package/public/script/wab-schema.js +131 -0
- package/public/script/wab.d.ts +108 -0
- package/public/script/wab.min.js +405 -0
- package/public/sitemap.xml +93 -0
- package/public/sovereign.html +660 -0
- package/public/terms.html +254 -254
- package/public/video/tutorial.mp4 +0 -0
- package/script/ai-agent-bridge.js +1558 -1513
- package/sdk/README.md +55 -55
- package/sdk/index.d.ts +118 -0
- package/sdk/index.js +257 -203
- package/sdk/package.json +14 -14
- package/sdk/schema-discovery.js +83 -0
- package/server/config/secrets.js +94 -92
- package/server/index.js +2 -9
- package/server/middleware/adminAuth.js +30 -30
- package/server/middleware/auth.js +41 -41
- package/server/middleware/rateLimits.js +24 -24
- package/server/migrations/001_add_analytics_indexes.sql +7 -7
- package/server/migrations/002_premium_features.sql +418 -0
- package/server/models/adapters/index.js +33 -33
- package/server/models/adapters/mysql.js +183 -183
- package/server/models/adapters/postgresql.js +172 -172
- package/server/models/adapters/sqlite.js +7 -7
- package/server/models/db.js +561 -561
- package/server/routes/admin-premium.js +671 -0
- package/server/routes/admin.js +247 -247
- package/server/routes/api.js +131 -138
- package/server/routes/auth.js +51 -51
- package/server/routes/billing.js +45 -45
- package/server/routes/discovery.js +406 -329
- package/server/routes/license.js +240 -240
- package/server/routes/noscript.js +543 -543
- package/server/routes/premium-v2.js +686 -0
- package/server/routes/premium.js +724 -0
- package/server/routes/sovereign.js +307 -0
- package/server/routes/wab-api.js +476 -476
- package/server/services/agent-memory.js +625 -0
- package/server/services/email.js +204 -204
- package/server/services/fairness.js +420 -420
- package/server/services/negotiation.js +439 -0
- package/server/services/plugins.js +747 -0
- package/server/services/premium.js +1883 -0
- package/server/services/reputation.js +465 -0
- package/server/services/self-healing.js +843 -0
- package/server/services/stripe.js +192 -192
- package/server/services/swarm.js +788 -0
- package/server/services/verification.js +481 -0
- package/server/services/vision.js +871 -0
- package/server/utils/cache.js +125 -125
- package/server/utils/migrate.js +81 -81
- package/server/utils/secureFields.js +50 -50
- package/server/ws.js +101 -101
- package/templates/artisan-marketplace.yaml +104 -0
- package/templates/book-price-scout.yaml +98 -0
- package/templates/electronics-price-tracker.yaml +108 -0
- package/templates/flight-deal-hunter.yaml +113 -0
- package/templates/freelancer-direct.yaml +116 -0
- package/templates/grocery-price-compare.yaml +93 -0
- package/templates/hotel-direct-booking.yaml +113 -0
- package/templates/local-services.yaml +98 -0
- package/templates/olive-oil-tunisia.yaml +88 -0
- package/templates/organic-farm-fresh.yaml +101 -0
- package/templates/restaurant-direct.yaml +97 -0
- package/docs/DEPLOY.md +0 -118
- package/docs/SPEC.md +0 -1540
- package/wab-mcp-adapter/README.md +0 -136
- package/wab-mcp-adapter/index.js +0 -555
- package/wab-mcp-adapter/package.json +0 -17
package/docs/SPEC.md
DELETED
|
@@ -1,1540 +0,0 @@
|
|
|
1
|
-
# WAB Protocol Specification
|
|
2
|
-
|
|
3
|
-
**Version:** 1.0
|
|
4
|
-
**Status:** Draft
|
|
5
|
-
**Date:** 2026-03-25
|
|
6
|
-
**Authors:** Web Agent Bridge Contributors
|
|
7
|
-
**License:** MIT
|
|
8
|
-
**Repository:** [github.com/abokenan444/web-agent-bridge](https://github.com/abokenan444/web-agent-bridge)
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Table of Contents
|
|
13
|
-
|
|
14
|
-
1. [Abstract](#1-abstract)
|
|
15
|
-
2. [Terminology](#2-terminology)
|
|
16
|
-
3. [Protocol Overview](#3-protocol-overview)
|
|
17
|
-
4. [Discovery Protocol](#4-discovery-protocol)
|
|
18
|
-
5. [Command Protocol](#5-command-protocol)
|
|
19
|
-
6. [Lifecycle Protocol](#6-lifecycle-protocol)
|
|
20
|
-
7. [Transport Layers](#7-transport-layers)
|
|
21
|
-
8. [Security Model](#8-security-model)
|
|
22
|
-
9. [Fairness Protocol](#9-fairness-protocol)
|
|
23
|
-
10. [MCP Compatibility](#10-mcp-compatibility)
|
|
24
|
-
11. [Conformance](#11-conformance)
|
|
25
|
-
12. [Appendix A: JSON Schema for agent-bridge.json](#appendix-a-json-schema-for-agent-bridgejson)
|
|
26
|
-
13. [Appendix B: Error Codes](#appendix-b-error-codes)
|
|
27
|
-
14. [Appendix C: MIME Types and Headers](#appendix-c-mime-types-and-headers)
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## 1. Abstract
|
|
32
|
-
|
|
33
|
-
The **Web Agent Bridge (WAB) Protocol** is an open protocol that enables AI agents to interact with websites through a standardized command interface. Where `robots.txt` tells bots what they *cannot* do, WAB tells AI agents what they *can* do — and exactly how to do it.
|
|
34
|
-
|
|
35
|
-
WAB functions as **OpenAPI for human-facing pages**. Website owners publish a machine-readable discovery document describing the actions, permissions, and entry points their site exposes. AI agents consume this document, authenticate, and execute commands through a uniform request/response protocol — eliminating the need for DOM scraping, fragile selectors, or reverse-engineered APIs.
|
|
36
|
-
|
|
37
|
-
The protocol is transport-agnostic. A single command schema works identically across in-browser JavaScript globals, WebSocket connections, and HTTP REST endpoints. This allows the same agent logic to operate inside a browser tab, from a remote orchestrator, or within a server-to-server pipeline.
|
|
38
|
-
|
|
39
|
-
### Design Goals
|
|
40
|
-
|
|
41
|
-
- **Declarative:** Sites declare capabilities; agents discover them at runtime.
|
|
42
|
-
- **Secure:** Every interaction is scoped by permissions, rate limits, and session tokens.
|
|
43
|
-
- **Fair:** A neutrality layer ensures small and large sites receive equal agent visibility.
|
|
44
|
-
- **Interoperable:** WAB maps cleanly onto MCP (Model Context Protocol) for LLM tool use.
|
|
45
|
-
- **Simple:** A minimal conforming implementation requires only a JSON file and a `<script>` tag.
|
|
46
|
-
|
|
47
|
-
### Notational Conventions
|
|
48
|
-
|
|
49
|
-
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## 2. Terminology
|
|
54
|
-
|
|
55
|
-
| Term | Definition |
|
|
56
|
-
|---|---|
|
|
57
|
-
| **Agent** | An autonomous or semi-autonomous software entity (typically AI-powered) that discovers, plans, and executes actions on websites via the WAB protocol. |
|
|
58
|
-
| **Bridge** | The runtime layer on a website that exposes the WAB interface. In the reference implementation this is the `ai-agent-bridge.js` script that creates `window.AICommands`. |
|
|
59
|
-
| **Site Owner** | The person or organization that deploys the Bridge on their website and configures its discovery document, permissions, and actions. |
|
|
60
|
-
| **Discovery Document** | A JSON file (`agent-bridge.json` or `/.well-known/wab.json`) that describes a site's WAB capabilities, permissions, transport options, and metadata. |
|
|
61
|
-
| **Command** | A structured JSON message sent by an Agent to a Bridge requesting a specific operation. |
|
|
62
|
-
| **Action** | A named capability exposed by a Bridge (e.g., `search`, `addToCart`, `signup`). Actions are registered by the Site Owner and discovered by Agents at runtime. |
|
|
63
|
-
| **Transport** | The communication channel over which Commands flow between Agent and Bridge. WAB defines three transports: JavaScript Global, WebSocket, and HTTP REST. |
|
|
64
|
-
| **Session** | A time-bounded, authenticated context linking an Agent to a Bridge. Sessions are identified by tokens and scoped by permissions. |
|
|
65
|
-
| **Tier** | The subscription level governing which features and rate limits apply to a site's Bridge instance. Standard tiers are `free`, `starter`, `pro`, and `enterprise`. |
|
|
66
|
-
| **Selector** | A CSS selector string identifying a DOM element. Bridges use selectors to map Actions to page elements. |
|
|
67
|
-
| **BiDi Interface** | The WebDriver BiDi-compatible interface exposed at `window.__wab_bidi` for structured command exchange within a browser context. |
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## 3. Protocol Overview
|
|
72
|
-
|
|
73
|
-
### 3.1 Architecture
|
|
74
|
-
|
|
75
|
-
WAB is organized into three layers:
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
┌─────────────────────────────────────────┐
|
|
79
|
-
│ Protocol Layer (Spec) │ ← This document
|
|
80
|
-
│ Discovery · Commands · Lifecycle │
|
|
81
|
-
├─────────────────────────────────────────┤
|
|
82
|
-
│ Runtime Layer (JS SDK) │ ← ai-agent-bridge.js / WABAgent SDK
|
|
83
|
-
│ Bridge · Actions · Permissions · Logs │
|
|
84
|
-
├─────────────────────────────────────────┤
|
|
85
|
-
│ Transport Layer (Wire) │ ← JS Global / WebSocket / HTTP
|
|
86
|
-
│ window.AICommands · ws:// · /api/wab │
|
|
87
|
-
└─────────────────────────────────────────┘
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
**Protocol Layer** defines the abstract data formats, lifecycle phases, and conformance requirements. It is implementation-agnostic.
|
|
91
|
-
|
|
92
|
-
**Runtime Layer** is a concrete JavaScript SDK that implements the Protocol Layer. The reference implementation provides `ai-agent-bridge.js` (site-side Bridge) and `WABAgent` (agent-side SDK).
|
|
93
|
-
|
|
94
|
-
**Transport Layer** carries serialized Commands and Responses between Agent and Bridge. All three transports MUST implement the identical Command Protocol defined in [Section 5](#5-command-protocol).
|
|
95
|
-
|
|
96
|
-
### 3.2 Lifecycle Summary
|
|
97
|
-
|
|
98
|
-
Every WAB interaction follows a five-phase lifecycle:
|
|
99
|
-
|
|
100
|
-
```
|
|
101
|
-
Discover → Authenticate → Plan → Execute → Confirm
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
1. **Discover** — Agent locates and parses the site's Discovery Document.
|
|
105
|
-
2. **Authenticate** — Agent establishes a Session with the Bridge.
|
|
106
|
-
3. **Plan** — Agent reads available Actions and determines an execution strategy.
|
|
107
|
-
4. **Execute** — Agent sends Commands to perform Actions.
|
|
108
|
-
5. **Confirm** — Agent verifies the results of executed Commands.
|
|
109
|
-
|
|
110
|
-
Each phase is detailed in [Section 6](#6-lifecycle-protocol).
|
|
111
|
-
|
|
112
|
-
### 3.3 Design Principles
|
|
113
|
-
|
|
114
|
-
1. **Opt-in only.** No site is WAB-enabled unless the Site Owner explicitly deploys a Bridge.
|
|
115
|
-
2. **Least privilege.** Agents receive only the permissions the Site Owner grants.
|
|
116
|
-
3. **Transport symmetry.** A Command sent over HTTP MUST produce the same result as the same Command sent over WebSocket or the JS global.
|
|
117
|
-
4. **Graceful degradation.** If a transport is unavailable, the Agent SHOULD fall back to an alternative transport listed in the Discovery Document.
|
|
118
|
-
5. **Neutrality.** The protocol includes a Fairness Protocol ([Section 9](#9-fairness-protocol)) to prevent concentration of agent traffic.
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## 4. Discovery Protocol
|
|
123
|
-
|
|
124
|
-
### 4.1 Discovery Document Location
|
|
125
|
-
|
|
126
|
-
A WAB-enabled site MUST serve its Discovery Document at one or both of the following locations:
|
|
127
|
-
|
|
128
|
-
| Priority | URL | Content-Type |
|
|
129
|
-
|---|---|---|
|
|
130
|
-
| 1 (primary) | `https://{host}/agent-bridge.json` | `application/json` |
|
|
131
|
-
| 2 (fallback) | `https://{host}/.well-known/wab.json` | `application/json` |
|
|
132
|
-
|
|
133
|
-
An Agent MUST attempt the primary URL first. If it returns a non-2xx status, the Agent SHOULD attempt the fallback URL. If both fail, the site MUST be treated as non-WAB-enabled.
|
|
134
|
-
|
|
135
|
-
The Discovery Document MAY also be referenced via an HTML `<meta>` tag:
|
|
136
|
-
|
|
137
|
-
```html
|
|
138
|
-
<meta name="wab-discovery" content="/agent-bridge.json">
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### 4.2 Discovery Document Format
|
|
142
|
-
|
|
143
|
-
The Discovery Document is a JSON object with the following top-level fields:
|
|
144
|
-
|
|
145
|
-
```json
|
|
146
|
-
{
|
|
147
|
-
"wab_version": "1.0",
|
|
148
|
-
"provider": {
|
|
149
|
-
"name": "Acme Restaurant",
|
|
150
|
-
"category": "restaurant",
|
|
151
|
-
"url": "https://acme-restaurant.com",
|
|
152
|
-
"location": {
|
|
153
|
-
"city": "Amman",
|
|
154
|
-
"country": "JO",
|
|
155
|
-
"support_local": true
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
"capabilities": {
|
|
159
|
-
"commands": [
|
|
160
|
-
{
|
|
161
|
-
"name": "viewMenu",
|
|
162
|
-
"description": "View the restaurant menu",
|
|
163
|
-
"trigger": "navigate",
|
|
164
|
-
"params": [],
|
|
165
|
-
"requiresAuth": false
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
"name": "placeOrder",
|
|
169
|
-
"description": "Place a food order",
|
|
170
|
-
"trigger": "fill_and_submit",
|
|
171
|
-
"params": [
|
|
172
|
-
{ "name": "items", "type": "array", "required": true, "description": "List of menu item IDs" },
|
|
173
|
-
{ "name": "address", "type": "string", "required": true, "description": "Delivery address" }
|
|
174
|
-
],
|
|
175
|
-
"requiresAuth": true
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
"name": "searchMenu",
|
|
179
|
-
"description": "Search menu items by keyword",
|
|
180
|
-
"trigger": "api",
|
|
181
|
-
"params": [
|
|
182
|
-
{ "name": "query", "type": "string", "required": true, "description": "Search term" }
|
|
183
|
-
],
|
|
184
|
-
"requiresAuth": false
|
|
185
|
-
}
|
|
186
|
-
],
|
|
187
|
-
"permissions": {
|
|
188
|
-
"readContent": true,
|
|
189
|
-
"click": true,
|
|
190
|
-
"fillForms": true,
|
|
191
|
-
"scroll": true,
|
|
192
|
-
"navigate": false,
|
|
193
|
-
"apiAccess": true,
|
|
194
|
-
"automatedLogin": false,
|
|
195
|
-
"extractData": false
|
|
196
|
-
},
|
|
197
|
-
"tier": "starter"
|
|
198
|
-
},
|
|
199
|
-
"agent_access": {
|
|
200
|
-
"preferred_entry_point": "/menu",
|
|
201
|
-
"api_fallback": "https://api.acme-restaurant.com/v1",
|
|
202
|
-
"selectors": {
|
|
203
|
-
"menu": "#main-menu",
|
|
204
|
-
"cart": "#shopping-cart",
|
|
205
|
-
"searchInput": "input[name='search']",
|
|
206
|
-
"orderForm": "#order-form"
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
"fairness_metrics": {
|
|
210
|
-
"commission_rate": "0%",
|
|
211
|
-
"direct_benefit": "Orders go directly to the restaurant",
|
|
212
|
-
"is_independent": true
|
|
213
|
-
},
|
|
214
|
-
"trust_signatures": [
|
|
215
|
-
"sha256:abc123...",
|
|
216
|
-
"wab-registry:verified"
|
|
217
|
-
],
|
|
218
|
-
"transport": {
|
|
219
|
-
"js_global": {
|
|
220
|
-
"enabled": true,
|
|
221
|
-
"interface": "window.AICommands"
|
|
222
|
-
},
|
|
223
|
-
"websocket": {
|
|
224
|
-
"enabled": true,
|
|
225
|
-
"url": "wss://acme-restaurant.com/ws/wab"
|
|
226
|
-
},
|
|
227
|
-
"http": {
|
|
228
|
-
"enabled": true,
|
|
229
|
-
"base_url": "/api/wab"
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
|
-
"security": {
|
|
233
|
-
"require_origin_match": true,
|
|
234
|
-
"session_ttl": 3600,
|
|
235
|
-
"max_rate": 60
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### 4.3 Field Definitions
|
|
241
|
-
|
|
242
|
-
#### 4.3.1 `wab_version` (REQUIRED)
|
|
243
|
-
|
|
244
|
-
A string indicating the WAB protocol version. For this specification, the value MUST be `"1.0"`.
|
|
245
|
-
|
|
246
|
-
#### 4.3.2 `provider` (REQUIRED)
|
|
247
|
-
|
|
248
|
-
Metadata about the site and its owner.
|
|
249
|
-
|
|
250
|
-
| Field | Type | Required | Description |
|
|
251
|
-
|---|---|---|---|
|
|
252
|
-
| `name` | string | REQUIRED | Human-readable name of the site or business. |
|
|
253
|
-
| `category` | string | REQUIRED | Business category (e.g., `"restaurant"`, `"ecommerce"`, `"saas"`, `"news"`). |
|
|
254
|
-
| `url` | string | REQUIRED | Canonical URL of the site. |
|
|
255
|
-
| `location` | object | OPTIONAL | Physical location. Contains `city` (string), `country` (ISO 3166-1 alpha-2), and `support_local` (boolean). |
|
|
256
|
-
|
|
257
|
-
#### 4.3.3 `capabilities` (REQUIRED)
|
|
258
|
-
|
|
259
|
-
Describes what the Bridge can do.
|
|
260
|
-
|
|
261
|
-
| Field | Type | Required | Description |
|
|
262
|
-
|---|---|---|---|
|
|
263
|
-
| `commands` | array | REQUIRED | List of Action definitions. See [Section 4.4](#44-action-definition). |
|
|
264
|
-
| `permissions` | object | REQUIRED | Map of permission names to booleans. See [Section 4.5](#45-permissions). |
|
|
265
|
-
| `tier` | string | OPTIONAL | Subscription tier: `"free"`, `"starter"`, `"pro"`, or `"enterprise"`. Defaults to `"free"`. |
|
|
266
|
-
|
|
267
|
-
#### 4.3.4 `agent_access` (RECOMMENDED)
|
|
268
|
-
|
|
269
|
-
Hints for agents on how to interact with the site.
|
|
270
|
-
|
|
271
|
-
| Field | Type | Required | Description |
|
|
272
|
-
|---|---|---|---|
|
|
273
|
-
| `preferred_entry_point` | string | OPTIONAL | URL path the agent SHOULD navigate to first. |
|
|
274
|
-
| `api_fallback` | string | OPTIONAL | Base URL for a REST API the agent MAY use when DOM interaction is unavailable. |
|
|
275
|
-
| `selectors` | object | OPTIONAL | Map of logical names to CSS selectors for key page elements. |
|
|
276
|
-
|
|
277
|
-
#### 4.3.5 `fairness_metrics` (RECOMMENDED)
|
|
278
|
-
|
|
279
|
-
Transparency data for the Fairness Protocol ([Section 9](#9-fairness-protocol)).
|
|
280
|
-
|
|
281
|
-
| Field | Type | Required | Description |
|
|
282
|
-
|---|---|---|---|
|
|
283
|
-
| `commission_rate` | string | OPTIONAL | Commission charged to the site (e.g., `"0%"`, `"15%"`). |
|
|
284
|
-
| `direct_benefit` | string | OPTIONAL | Human-readable description of how the site benefits. |
|
|
285
|
-
| `is_independent` | OPTIONAL | boolean | Whether the site is independently owned. |
|
|
286
|
-
|
|
287
|
-
#### 4.3.6 `trust_signatures` (OPTIONAL)
|
|
288
|
-
|
|
289
|
-
An array of strings representing cryptographic or registry-based trust attestations. Agents MAY use these to verify the authenticity of the Discovery Document.
|
|
290
|
-
|
|
291
|
-
#### 4.3.7 `transport` (REQUIRED)
|
|
292
|
-
|
|
293
|
-
Declares available Transport Layers. At least one transport MUST be enabled.
|
|
294
|
-
|
|
295
|
-
| Field | Type | Description |
|
|
296
|
-
|---|---|---|
|
|
297
|
-
| `js_global.enabled` | boolean | Whether the JS global interface is available. |
|
|
298
|
-
| `js_global.interface` | string | Global variable name (default: `"window.AICommands"`). |
|
|
299
|
-
| `websocket.enabled` | boolean | Whether a WebSocket endpoint is available. |
|
|
300
|
-
| `websocket.url` | string | Full WebSocket URL. |
|
|
301
|
-
| `http.enabled` | boolean | Whether an HTTP REST endpoint is available. |
|
|
302
|
-
| `http.base_url` | string | Base URL path for the HTTP transport. |
|
|
303
|
-
|
|
304
|
-
#### 4.3.8 `security` (RECOMMENDED)
|
|
305
|
-
|
|
306
|
-
| Field | Type | Default | Description |
|
|
307
|
-
|---|---|---|---|
|
|
308
|
-
| `require_origin_match` | boolean | `true` | Whether the Bridge validates the requesting origin. |
|
|
309
|
-
| `session_ttl` | integer | `3600` | Session lifetime in seconds. |
|
|
310
|
-
| `max_rate` | integer | `60` | Maximum commands per minute per session. |
|
|
311
|
-
|
|
312
|
-
### 4.4 Action Definition
|
|
313
|
-
|
|
314
|
-
Each entry in `capabilities.commands` MUST conform to:
|
|
315
|
-
|
|
316
|
-
| Field | Type | Required | Description |
|
|
317
|
-
|---|---|---|---|
|
|
318
|
-
| `name` | string | REQUIRED | Unique action identifier (alphanumeric, hyphens, underscores). |
|
|
319
|
-
| `description` | string | REQUIRED | Human-readable description of the action. |
|
|
320
|
-
| `trigger` | string | REQUIRED | Execution method. One of: `"click"`, `"fill_and_submit"`, `"scroll"`, `"api"`, `"navigate"`. |
|
|
321
|
-
| `params` | array | REQUIRED | Array of parameter definitions (MAY be empty). |
|
|
322
|
-
| `requiresAuth` | boolean | OPTIONAL | Whether the action requires an authenticated session. Defaults to `false`. |
|
|
323
|
-
|
|
324
|
-
Each parameter definition:
|
|
325
|
-
|
|
326
|
-
| Field | Type | Required | Description |
|
|
327
|
-
|---|---|---|---|
|
|
328
|
-
| `name` | string | REQUIRED | Parameter name. |
|
|
329
|
-
| `type` | string | REQUIRED | JSON Schema type: `"string"`, `"number"`, `"boolean"`, `"array"`, `"object"`. |
|
|
330
|
-
| `required` | boolean | REQUIRED | Whether the parameter is mandatory. |
|
|
331
|
-
| `description` | string | RECOMMENDED | Human-readable description. |
|
|
332
|
-
| `default` | any | OPTIONAL | Default value if not provided. |
|
|
333
|
-
| `enum` | array | OPTIONAL | Allowed values. |
|
|
334
|
-
|
|
335
|
-
### 4.5 Permissions
|
|
336
|
-
|
|
337
|
-
The `permissions` object uses the following standard keys:
|
|
338
|
-
|
|
339
|
-
| Permission | Type | Description |
|
|
340
|
-
|---|---|---|
|
|
341
|
-
| `readContent` | boolean | Agent MAY read visible text content from the page. |
|
|
342
|
-
| `click` | boolean | Agent MAY trigger click events on permitted elements. |
|
|
343
|
-
| `fillForms` | boolean | Agent MAY fill and submit form fields. |
|
|
344
|
-
| `scroll` | boolean | Agent MAY scroll the page. |
|
|
345
|
-
| `navigate` | boolean | Agent MAY navigate to different URLs within the site. |
|
|
346
|
-
| `apiAccess` | boolean | Agent MAY call the site's API endpoints. |
|
|
347
|
-
| `automatedLogin` | boolean | Agent MAY perform automated authentication flows. |
|
|
348
|
-
| `extractData` | boolean | Agent MAY extract and store structured data from the page. |
|
|
349
|
-
|
|
350
|
-
A Bridge MUST enforce these permissions at runtime. If an Agent attempts an action that requires a permission set to `false`, the Bridge MUST reject the command with error code `PERMISSION_DENIED`.
|
|
351
|
-
|
|
352
|
-
---
|
|
353
|
-
|
|
354
|
-
## 5. Command Protocol
|
|
355
|
-
|
|
356
|
-
### 5.1 Command Format
|
|
357
|
-
|
|
358
|
-
Every command sent from an Agent to a Bridge MUST conform to the following JSON structure:
|
|
359
|
-
|
|
360
|
-
```json
|
|
361
|
-
{
|
|
362
|
-
"id": "cmd_a1b2c3d4",
|
|
363
|
-
"method": "wab.executeAction",
|
|
364
|
-
"params": {
|
|
365
|
-
"name": "searchMenu",
|
|
366
|
-
"data": {
|
|
367
|
-
"query": "vegetarian"
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
"context": {
|
|
371
|
-
"url": "https://acme-restaurant.com/menu",
|
|
372
|
-
"sessionToken": "sess_x9y8z7w6",
|
|
373
|
-
"timestamp": "2026-03-25T12:00:00Z"
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
| Field | Type | Required | Description |
|
|
379
|
-
|---|---|---|---|
|
|
380
|
-
| `id` | string | REQUIRED | Unique identifier for this command. The Bridge MUST echo it in the response. |
|
|
381
|
-
| `method` | string | REQUIRED | The WAB method to invoke. See [Section 5.3](#53-standard-methods). |
|
|
382
|
-
| `params` | object | REQUIRED | Method-specific parameters. MAY be empty `{}`. |
|
|
383
|
-
| `context` | object | OPTIONAL | Execution context. Includes `url`, `sessionToken`, and `timestamp`. |
|
|
384
|
-
|
|
385
|
-
### 5.2 Response Format
|
|
386
|
-
|
|
387
|
-
Every response from a Bridge to an Agent MUST conform to:
|
|
388
|
-
|
|
389
|
-
**Success response:**
|
|
390
|
-
|
|
391
|
-
```json
|
|
392
|
-
{
|
|
393
|
-
"id": "cmd_a1b2c3d4",
|
|
394
|
-
"type": "success",
|
|
395
|
-
"result": {
|
|
396
|
-
"items": [
|
|
397
|
-
{ "name": "Falafel Wrap", "price": 5.99 },
|
|
398
|
-
{ "name": "Veggie Burger", "price": 8.49 }
|
|
399
|
-
],
|
|
400
|
-
"total": 2
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
**Error response:**
|
|
406
|
-
|
|
407
|
-
```json
|
|
408
|
-
{
|
|
409
|
-
"id": "cmd_a1b2c3d4",
|
|
410
|
-
"type": "error",
|
|
411
|
-
"error": {
|
|
412
|
-
"code": "PERMISSION_DENIED",
|
|
413
|
-
"message": "Action 'placeOrder' requires authentication"
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
| Field | Type | Required | Description |
|
|
419
|
-
|---|---|---|---|
|
|
420
|
-
| `id` | string | REQUIRED | Matches the `id` from the originating command. |
|
|
421
|
-
| `type` | string | REQUIRED | Either `"success"` or `"error"`. |
|
|
422
|
-
| `result` | object | CONDITIONAL | Present when `type` is `"success"`. Method-specific result data. |
|
|
423
|
-
| `error` | object | CONDITIONAL | Present when `type` is `"error"`. Contains `code` and `message`. |
|
|
424
|
-
|
|
425
|
-
### 5.3 Standard Methods
|
|
426
|
-
|
|
427
|
-
A conforming WAB Bridge MUST implement the following methods:
|
|
428
|
-
|
|
429
|
-
#### `wab.discover`
|
|
430
|
-
|
|
431
|
-
Returns the site's Discovery Document.
|
|
432
|
-
|
|
433
|
-
- **Params:** None.
|
|
434
|
-
- **Result:** The full Discovery Document object.
|
|
435
|
-
|
|
436
|
-
```json
|
|
437
|
-
{ "id": "1", "method": "wab.discover", "params": {} }
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
#### `wab.getContext`
|
|
441
|
-
|
|
442
|
-
Returns the current Bridge context including version, permissions, and session state.
|
|
443
|
-
|
|
444
|
-
- **Params:** None.
|
|
445
|
-
- **Result:** `{ version, permissions, session, tier, url }`.
|
|
446
|
-
|
|
447
|
-
```json
|
|
448
|
-
{ "id": "2", "method": "wab.getContext", "params": {} }
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
Response:
|
|
452
|
-
|
|
453
|
-
```json
|
|
454
|
-
{
|
|
455
|
-
"id": "2",
|
|
456
|
-
"type": "success",
|
|
457
|
-
"result": {
|
|
458
|
-
"version": "1.0.0",
|
|
459
|
-
"permissions": { "readContent": true, "click": true, "fillForms": false },
|
|
460
|
-
"session": { "authenticated": false, "ttl": 3600 },
|
|
461
|
-
"tier": "free",
|
|
462
|
-
"url": "https://acme-restaurant.com/menu"
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
#### `wab.getActions`
|
|
468
|
-
|
|
469
|
-
Lists all available Actions, optionally filtered by category.
|
|
470
|
-
|
|
471
|
-
- **Params:** `{ "category": "string" }` (OPTIONAL).
|
|
472
|
-
- **Result:** Array of Action definitions.
|
|
473
|
-
|
|
474
|
-
```json
|
|
475
|
-
{ "id": "3", "method": "wab.getActions", "params": { "category": "ordering" } }
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
#### `wab.executeAction`
|
|
479
|
-
|
|
480
|
-
Executes a named Action with the provided parameters.
|
|
481
|
-
|
|
482
|
-
- **Params:** `{ "name": "string", "data": {} }` (REQUIRED).
|
|
483
|
-
- **Result:** Action-specific result object.
|
|
484
|
-
|
|
485
|
-
```json
|
|
486
|
-
{
|
|
487
|
-
"id": "4",
|
|
488
|
-
"method": "wab.executeAction",
|
|
489
|
-
"params": {
|
|
490
|
-
"name": "placeOrder",
|
|
491
|
-
"data": { "items": ["item_01", "item_02"], "address": "123 Main St" }
|
|
492
|
-
},
|
|
493
|
-
"context": { "sessionToken": "sess_x9y8z7w6" }
|
|
494
|
-
}
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
#### `wab.readContent`
|
|
498
|
-
|
|
499
|
-
Reads the text content of a page element identified by a CSS selector.
|
|
500
|
-
|
|
501
|
-
- **Params:** `{ "selector": "string" }` (REQUIRED).
|
|
502
|
-
- **Result:** `{ "text": "string", "html": "string", "selector": "string" }`.
|
|
503
|
-
- **Requires permission:** `readContent`.
|
|
504
|
-
|
|
505
|
-
```json
|
|
506
|
-
{ "id": "5", "method": "wab.readContent", "params": { "selector": "#main-menu" } }
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
#### `wab.getPageInfo`
|
|
510
|
-
|
|
511
|
-
Returns metadata about the current page and Bridge state.
|
|
512
|
-
|
|
513
|
-
- **Params:** None.
|
|
514
|
-
- **Result:** `{ title, url, description, bridgeVersion, actionsCount, permissions }`.
|
|
515
|
-
|
|
516
|
-
```json
|
|
517
|
-
{ "id": "6", "method": "wab.getPageInfo", "params": {} }
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
Response:
|
|
521
|
-
|
|
522
|
-
```json
|
|
523
|
-
{
|
|
524
|
-
"id": "6",
|
|
525
|
-
"type": "success",
|
|
526
|
-
"result": {
|
|
527
|
-
"title": "Acme Restaurant - Menu",
|
|
528
|
-
"url": "https://acme-restaurant.com/menu",
|
|
529
|
-
"description": "Fresh Mediterranean cuisine",
|
|
530
|
-
"bridgeVersion": "1.0.0",
|
|
531
|
-
"actionsCount": 5,
|
|
532
|
-
"permissions": { "readContent": true, "click": true }
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
#### `wab.authenticate`
|
|
538
|
-
|
|
539
|
-
Authenticates an Agent with the Bridge using an API key or token.
|
|
540
|
-
|
|
541
|
-
- **Params:** `{ "apiKey": "string", "meta": {} }` (REQUIRED).
|
|
542
|
-
- **Result:** `{ "sessionToken": "string", "expiresAt": "ISO 8601", "permissions": {} }`.
|
|
543
|
-
|
|
544
|
-
```json
|
|
545
|
-
{
|
|
546
|
-
"id": "7",
|
|
547
|
-
"method": "wab.authenticate",
|
|
548
|
-
"params": {
|
|
549
|
-
"apiKey": "wab_key_abc123",
|
|
550
|
-
"meta": { "agentName": "ShoppingAssistant", "version": "2.1" }
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
Response:
|
|
556
|
-
|
|
557
|
-
```json
|
|
558
|
-
{
|
|
559
|
-
"id": "7",
|
|
560
|
-
"type": "success",
|
|
561
|
-
"result": {
|
|
562
|
-
"sessionToken": "sess_x9y8z7w6",
|
|
563
|
-
"expiresAt": "2026-03-25T13:00:00Z",
|
|
564
|
-
"permissions": { "readContent": true, "click": true, "fillForms": true }
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
#### `wab.subscribe`
|
|
570
|
-
|
|
571
|
-
Subscribes to real-time events from the Bridge. Only available on transports that support push messaging (WebSocket, JS global with event listeners).
|
|
572
|
-
|
|
573
|
-
- **Params:** `{ "events": ["string"] }` (REQUIRED). Valid events: `"actionExecuted"`, `"permissionChanged"`, `"sessionExpired"`, `"error"`.
|
|
574
|
-
- **Result:** `{ "subscriptionId": "string", "events": ["string"] }`.
|
|
575
|
-
|
|
576
|
-
```json
|
|
577
|
-
{
|
|
578
|
-
"id": "8",
|
|
579
|
-
"method": "wab.subscribe",
|
|
580
|
-
"params": { "events": ["actionExecuted", "error"] }
|
|
581
|
-
}
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
#### `wab.ping`
|
|
585
|
-
|
|
586
|
-
Health check. Returns immediately to confirm the Bridge is operational.
|
|
587
|
-
|
|
588
|
-
- **Params:** None.
|
|
589
|
-
- **Result:** `{ "status": "ok", "timestamp": "ISO 8601", "version": "string" }`.
|
|
590
|
-
|
|
591
|
-
```json
|
|
592
|
-
{ "id": "9", "method": "wab.ping", "params": {} }
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
Response:
|
|
596
|
-
|
|
597
|
-
```json
|
|
598
|
-
{
|
|
599
|
-
"id": "9",
|
|
600
|
-
"type": "success",
|
|
601
|
-
"result": { "status": "ok", "timestamp": "2026-03-25T12:00:00Z", "version": "1.0.0" }
|
|
602
|
-
}
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
### 5.4 Command ID Generation
|
|
606
|
-
|
|
607
|
-
Command IDs MUST be unique within a session. Implementations SHOULD use one of:
|
|
608
|
-
|
|
609
|
-
- UUIDv4 (e.g., `"550e8400-e29b-41d4-a716-446655440000"`)
|
|
610
|
-
- Monotonically increasing integers (e.g., `"1"`, `"2"`, `"3"`)
|
|
611
|
-
- Prefixed counters (e.g., `"cmd_001"`, `"cmd_002"`)
|
|
612
|
-
|
|
613
|
-
The Bridge MUST NOT reuse command IDs and MUST reject duplicate IDs within the same session with error code `DUPLICATE_COMMAND_ID`.
|
|
614
|
-
|
|
615
|
-
---
|
|
616
|
-
|
|
617
|
-
## 6. Lifecycle Protocol
|
|
618
|
-
|
|
619
|
-
### 6.1 Lifecycle Phases
|
|
620
|
-
|
|
621
|
-
Every agent-site interaction follows five ordered phases. Agents MUST complete each phase before advancing to the next.
|
|
622
|
-
|
|
623
|
-
```mermaid
|
|
624
|
-
sequenceDiagram
|
|
625
|
-
participant A as Agent
|
|
626
|
-
participant B as Bridge
|
|
627
|
-
participant S as Site
|
|
628
|
-
|
|
629
|
-
Note over A,S: Phase 1 — Discovery
|
|
630
|
-
A->>S: GET /agent-bridge.json
|
|
631
|
-
S-->>A: 200 OK (Discovery Document)
|
|
632
|
-
|
|
633
|
-
Note over A,B: Phase 2 — Authentication
|
|
634
|
-
A->>B: wab.authenticate({ apiKey, meta })
|
|
635
|
-
B-->>A: { sessionToken, expiresAt, permissions }
|
|
636
|
-
|
|
637
|
-
Note over A,B: Phase 3 — Planning
|
|
638
|
-
A->>B: wab.getActions()
|
|
639
|
-
B-->>A: [{ name, description, params, ... }]
|
|
640
|
-
A->>B: wab.getPageInfo()
|
|
641
|
-
B-->>A: { title, url, actionsCount, ... }
|
|
642
|
-
Note over A: Agent plans execution strategy
|
|
643
|
-
|
|
644
|
-
Note over A,B: Phase 4 — Execution
|
|
645
|
-
A->>B: wab.executeAction({ name, data })
|
|
646
|
-
B-->>A: { result }
|
|
647
|
-
A->>B: wab.executeAction({ name, data })
|
|
648
|
-
B-->>A: { result }
|
|
649
|
-
|
|
650
|
-
Note over A,B: Phase 5 — Confirmation
|
|
651
|
-
A->>B: wab.readContent({ selector })
|
|
652
|
-
B-->>A: { text, html }
|
|
653
|
-
A->>B: wab.getPageInfo()
|
|
654
|
-
B-->>A: { updated state }
|
|
655
|
-
Note over A: Agent verifies outcomes
|
|
656
|
-
```
|
|
657
|
-
|
|
658
|
-
### 6.2 Phase 1: Discovery
|
|
659
|
-
|
|
660
|
-
The Agent locates the site's Discovery Document by:
|
|
661
|
-
|
|
662
|
-
1. Fetching `https://{host}/agent-bridge.json`.
|
|
663
|
-
2. If unavailable, fetching `https://{host}/.well-known/wab.json`.
|
|
664
|
-
3. Optionally, parsing the HTML `<meta name="wab-discovery">` tag.
|
|
665
|
-
|
|
666
|
-
The Agent MUST validate the document against the WAB JSON Schema ([Appendix A](#appendix-a-json-schema-for-agent-bridgejson)). If the `wab_version` field indicates a version the Agent does not support, it SHOULD terminate gracefully with an informative error.
|
|
667
|
-
|
|
668
|
-
The Agent SHOULD cache the Discovery Document for a reasonable duration (RECOMMENDED: 5 minutes). The response MAY include standard HTTP caching headers (`Cache-Control`, `ETag`).
|
|
669
|
-
|
|
670
|
-
### 6.3 Phase 2: Authentication
|
|
671
|
-
|
|
672
|
-
If the Discovery Document includes actions where `requiresAuth` is `true`, the Agent MUST authenticate before executing those actions.
|
|
673
|
-
|
|
674
|
-
1. The Agent sends a `wab.authenticate` command with its API key and optional metadata.
|
|
675
|
-
2. The Bridge validates the key and returns a `sessionToken` with an expiration time.
|
|
676
|
-
3. The Agent MUST include the `sessionToken` in the `context` field of all subsequent commands.
|
|
677
|
-
|
|
678
|
-
If no actions require authentication, this phase MAY be skipped. The Bridge MUST still accept unauthenticated commands for actions where `requiresAuth` is `false`.
|
|
679
|
-
|
|
680
|
-
**Session renewal:** When a session approaches expiration (RECOMMENDED: within 10% of TTL remaining), the Agent SHOULD re-authenticate to obtain a fresh token. The Bridge MUST NOT invalidate the old token until it naturally expires.
|
|
681
|
-
|
|
682
|
-
### 6.4 Phase 3: Planning
|
|
683
|
-
|
|
684
|
-
The Agent reads the available actions and Bridge context to formulate an execution plan:
|
|
685
|
-
|
|
686
|
-
1. Call `wab.getActions()` to retrieve the full list of available actions.
|
|
687
|
-
2. Call `wab.getContext()` to understand current permissions and state.
|
|
688
|
-
3. Optionally call `wab.getPageInfo()` for page metadata.
|
|
689
|
-
|
|
690
|
-
The Agent SHOULD filter actions by the permissions granted in the session. The Agent MUST NOT attempt to execute actions for which it lacks the required permissions.
|
|
691
|
-
|
|
692
|
-
Planning is internal to the Agent. The protocol does not prescribe a planning algorithm — this is where LLM-powered agents apply their reasoning capabilities.
|
|
693
|
-
|
|
694
|
-
### 6.5 Phase 4: Execution
|
|
695
|
-
|
|
696
|
-
The Agent sends `wab.executeAction` commands to perform the planned actions:
|
|
697
|
-
|
|
698
|
-
1. Each command targets a single action by `name`.
|
|
699
|
-
2. The `data` field contains the action's required and optional parameters.
|
|
700
|
-
3. The Bridge validates the command against the action's parameter schema.
|
|
701
|
-
4. The Bridge executes the action (clicking elements, filling forms, calling APIs, etc.).
|
|
702
|
-
5. The Bridge returns the result or an error.
|
|
703
|
-
|
|
704
|
-
**Sequential vs. parallel:** Agents MAY send multiple commands concurrently if the actions are independent. The Bridge MUST process each command atomically. The Bridge SHOULD document in the Discovery Document if certain actions have ordering dependencies.
|
|
705
|
-
|
|
706
|
-
**Rate limiting:** The Bridge MUST enforce the `max_rate` from the security configuration. If an Agent exceeds the rate limit, the Bridge MUST respond with error code `RATE_LIMITED` and a `Retry-After` value.
|
|
707
|
-
|
|
708
|
-
### 6.6 Phase 5: Confirmation
|
|
709
|
-
|
|
710
|
-
After execution, the Agent verifies that the intended outcomes occurred:
|
|
711
|
-
|
|
712
|
-
1. Call `wab.readContent()` to verify visible page changes.
|
|
713
|
-
2. Call `wab.getPageInfo()` to check updated page state.
|
|
714
|
-
3. Compare actual results against expected results from the plan.
|
|
715
|
-
|
|
716
|
-
Confirmation is RECOMMENDED but not strictly required. Agents that skip confirmation accept the risk of undetected failures.
|
|
717
|
-
|
|
718
|
-
---
|
|
719
|
-
|
|
720
|
-
## 7. Transport Layers
|
|
721
|
-
|
|
722
|
-
WAB defines three Transport Layers. Each transport MUST implement the full Command Protocol from [Section 5](#5-command-protocol). A conforming Bridge MUST support at least one transport. A conforming Agent SHOULD support all three.
|
|
723
|
-
|
|
724
|
-
### 7.1 JavaScript Global Transport
|
|
725
|
-
|
|
726
|
-
**Identifier:** `js_global`
|
|
727
|
-
**Scope:** In-browser (same page as the Bridge)
|
|
728
|
-
**Interface:** `window.AICommands` and `window.__wab_bidi`
|
|
729
|
-
|
|
730
|
-
This is the primary transport for agents running inside a browser (Puppeteer, Playwright, browser extensions).
|
|
731
|
-
|
|
732
|
-
#### 7.1.1 `window.AICommands` (High-Level)
|
|
733
|
-
|
|
734
|
-
The `AICommands` object exposes convenience methods that map to WAB standard methods:
|
|
735
|
-
|
|
736
|
-
```javascript
|
|
737
|
-
// Get all available actions
|
|
738
|
-
const actions = await window.AICommands.getActions();
|
|
739
|
-
|
|
740
|
-
// Get a specific action
|
|
741
|
-
const action = await window.AICommands.getAction('searchMenu');
|
|
742
|
-
|
|
743
|
-
// Execute an action
|
|
744
|
-
const result = await window.AICommands.execute('searchMenu', { query: 'vegetarian' });
|
|
745
|
-
|
|
746
|
-
// Read page content
|
|
747
|
-
const content = await window.AICommands.readContent('#main-menu');
|
|
748
|
-
|
|
749
|
-
// Get page info
|
|
750
|
-
const info = await window.AICommands.getPageInfo();
|
|
751
|
-
|
|
752
|
-
// Authenticate
|
|
753
|
-
const session = await window.AICommands.authenticate('wab_key_abc123', { agentName: 'MyAgent' });
|
|
754
|
-
```
|
|
755
|
-
|
|
756
|
-
All methods MUST return Promises. Errors MUST be thrown as JavaScript `Error` objects with a `code` property matching the WAB error codes ([Appendix B](#appendix-b-error-codes)).
|
|
757
|
-
|
|
758
|
-
#### 7.1.2 `window.__wab_bidi` (BiDi Protocol)
|
|
759
|
-
|
|
760
|
-
The BiDi interface provides a lower-level, WebDriver BiDi-compatible transport:
|
|
761
|
-
|
|
762
|
-
```javascript
|
|
763
|
-
const response = await window.__wab_bidi.send({
|
|
764
|
-
id: 1,
|
|
765
|
-
method: 'wab.executeAction',
|
|
766
|
-
params: { name: 'searchMenu', data: { query: 'vegetarian' } }
|
|
767
|
-
});
|
|
768
|
-
```
|
|
769
|
-
|
|
770
|
-
The BiDi interface MUST:
|
|
771
|
-
- Accept the standard Command format from [Section 5.1](#51-command-format).
|
|
772
|
-
- Return the standard Response format from [Section 5.2](#52-response-format).
|
|
773
|
-
- Expose a `getContext()` method returning the current Bridge context.
|
|
774
|
-
- Support event subscriptions via `subscribe(events, callback)`.
|
|
775
|
-
|
|
776
|
-
#### 7.1.3 Bridge Readiness
|
|
777
|
-
|
|
778
|
-
The Bridge MUST signal readiness by dispatching a custom DOM event:
|
|
779
|
-
|
|
780
|
-
```javascript
|
|
781
|
-
window.dispatchEvent(new CustomEvent('wab:ready', {
|
|
782
|
-
detail: { version: '1.0.0', transport: 'js_global' }
|
|
783
|
-
}));
|
|
784
|
-
```
|
|
785
|
-
|
|
786
|
-
Agents SHOULD listen for this event or poll for the existence of `window.AICommands` / `window.__wab_bidi`.
|
|
787
|
-
|
|
788
|
-
### 7.2 WebSocket Transport
|
|
789
|
-
|
|
790
|
-
**Identifier:** `websocket`
|
|
791
|
-
**Scope:** Remote agents, real-time bidirectional communication
|
|
792
|
-
**URL:** Declared in `transport.websocket.url`
|
|
793
|
-
|
|
794
|
-
#### 7.2.1 Connection
|
|
795
|
-
|
|
796
|
-
The Agent establishes a WebSocket connection to the URL specified in the Discovery Document:
|
|
797
|
-
|
|
798
|
-
```javascript
|
|
799
|
-
const ws = new WebSocket('wss://acme-restaurant.com/ws/wab');
|
|
800
|
-
```
|
|
801
|
-
|
|
802
|
-
Upon connection, the Agent SHOULD send a `wab.authenticate` command as the first message if authentication is required.
|
|
803
|
-
|
|
804
|
-
#### 7.2.2 Message Format
|
|
805
|
-
|
|
806
|
-
All messages are JSON-encoded text frames. Binary frames MUST NOT be used.
|
|
807
|
-
|
|
808
|
-
**Agent → Bridge (Command):**
|
|
809
|
-
|
|
810
|
-
```json
|
|
811
|
-
{ "id": "cmd_001", "method": "wab.getActions", "params": {} }
|
|
812
|
-
```
|
|
813
|
-
|
|
814
|
-
**Bridge → Agent (Response):**
|
|
815
|
-
|
|
816
|
-
```json
|
|
817
|
-
{ "id": "cmd_001", "type": "success", "result": [...] }
|
|
818
|
-
```
|
|
819
|
-
|
|
820
|
-
**Bridge → Agent (Push Event):**
|
|
821
|
-
|
|
822
|
-
```json
|
|
823
|
-
{ "id": null, "type": "event", "event": "actionExecuted", "data": { "name": "searchMenu" } }
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
Push events have a `null` id and `type` set to `"event"`.
|
|
827
|
-
|
|
828
|
-
#### 7.2.3 Connection Lifecycle
|
|
829
|
-
|
|
830
|
-
- The Bridge SHOULD send a `wab.ping` response every 30 seconds as a heartbeat.
|
|
831
|
-
- If the Agent receives no messages for 60 seconds, it SHOULD close and reconnect.
|
|
832
|
-
- The Bridge MUST close the connection when the session expires.
|
|
833
|
-
- The close frame SHOULD include a reason code: `4001` (session expired), `4002` (rate limited), `4003` (authentication failed).
|
|
834
|
-
|
|
835
|
-
### 7.3 HTTP REST Transport
|
|
836
|
-
|
|
837
|
-
**Identifier:** `http`
|
|
838
|
-
**Scope:** Server-to-server, stateless interactions
|
|
839
|
-
**Base URL:** Declared in `transport.http.base_url`
|
|
840
|
-
|
|
841
|
-
#### 7.3.1 Endpoint Mapping
|
|
842
|
-
|
|
843
|
-
Each WAB method maps to an HTTP endpoint:
|
|
844
|
-
|
|
845
|
-
| WAB Method | HTTP Method | Path |
|
|
846
|
-
|---|---|---|
|
|
847
|
-
| `wab.discover` | GET | `{base}/discover` |
|
|
848
|
-
| `wab.getContext` | GET | `{base}/context` |
|
|
849
|
-
| `wab.getActions` | GET | `{base}/actions` |
|
|
850
|
-
| `wab.executeAction` | POST | `{base}/execute` |
|
|
851
|
-
| `wab.readContent` | POST | `{base}/read` |
|
|
852
|
-
| `wab.getPageInfo` | GET | `{base}/page-info` |
|
|
853
|
-
| `wab.authenticate` | POST | `{base}/authenticate` |
|
|
854
|
-
| `wab.subscribe` | POST | `{base}/subscribe` |
|
|
855
|
-
| `wab.ping` | GET | `{base}/ping` |
|
|
856
|
-
|
|
857
|
-
#### 7.3.2 Request Format
|
|
858
|
-
|
|
859
|
-
**GET requests** pass parameters as query strings:
|
|
860
|
-
|
|
861
|
-
```http
|
|
862
|
-
GET /api/wab/actions?category=ordering HTTP/1.1
|
|
863
|
-
Host: acme-restaurant.com
|
|
864
|
-
Authorization: Bearer sess_x9y8z7w6
|
|
865
|
-
X-WAB-Version: 1.0
|
|
866
|
-
```
|
|
867
|
-
|
|
868
|
-
**POST requests** pass parameters as JSON bodies:
|
|
869
|
-
|
|
870
|
-
```http
|
|
871
|
-
POST /api/wab/execute HTTP/1.1
|
|
872
|
-
Host: acme-restaurant.com
|
|
873
|
-
Content-Type: application/json
|
|
874
|
-
Authorization: Bearer sess_x9y8z7w6
|
|
875
|
-
X-WAB-Version: 1.0
|
|
876
|
-
|
|
877
|
-
{
|
|
878
|
-
"name": "placeOrder",
|
|
879
|
-
"data": { "items": ["item_01"], "address": "123 Main St" }
|
|
880
|
-
}
|
|
881
|
-
```
|
|
882
|
-
|
|
883
|
-
#### 7.3.3 Response Format
|
|
884
|
-
|
|
885
|
-
HTTP responses use standard status codes and return the WAB Response format in the body:
|
|
886
|
-
|
|
887
|
-
| HTTP Status | WAB Type | Meaning |
|
|
888
|
-
|---|---|---|
|
|
889
|
-
| 200 | `success` | Command executed successfully. |
|
|
890
|
-
| 400 | `error` | Invalid command or parameters. |
|
|
891
|
-
| 401 | `error` | Authentication required or failed. |
|
|
892
|
-
| 403 | `error` | Permission denied. |
|
|
893
|
-
| 404 | `error` | Action not found. |
|
|
894
|
-
| 429 | `error` | Rate limited. Includes `Retry-After` header. |
|
|
895
|
-
| 500 | `error` | Internal Bridge error. |
|
|
896
|
-
|
|
897
|
-
#### 7.3.4 Required Headers
|
|
898
|
-
|
|
899
|
-
| Header | Direction | Required | Description |
|
|
900
|
-
|---|---|---|---|
|
|
901
|
-
| `X-WAB-Version` | Request | REQUIRED | WAB protocol version (`1.0`). |
|
|
902
|
-
| `Authorization` | Request | CONDITIONAL | `Bearer {sessionToken}` for authenticated methods. |
|
|
903
|
-
| `Content-Type` | Request | CONDITIONAL | `application/json` for POST requests. |
|
|
904
|
-
| `X-WAB-Request-Id` | Request | RECOMMENDED | Unique request ID for tracing. |
|
|
905
|
-
| `X-WAB-Request-Id` | Response | RECOMMENDED | Echoed from request. |
|
|
906
|
-
| `Retry-After` | Response | CONDITIONAL | Seconds to wait (on 429 responses). |
|
|
907
|
-
|
|
908
|
-
---
|
|
909
|
-
|
|
910
|
-
## 8. Security Model
|
|
911
|
-
|
|
912
|
-
### 8.1 Permission Model
|
|
913
|
-
|
|
914
|
-
The Bridge enforces a layered permission model:
|
|
915
|
-
|
|
916
|
-
1. **Discovery-level permissions** — Declared in `capabilities.permissions`. These are the maximum permissions the site grants.
|
|
917
|
-
2. **Session-level permissions** — Returned in the `wab.authenticate` response. These MAY be a subset of discovery-level permissions based on the Agent's tier or API key.
|
|
918
|
-
3. **Action-level requirements** — Each action's `requiresAuth` field determines whether a session is needed.
|
|
919
|
-
|
|
920
|
-
Permission enforcement is multiplicative: an action is permitted only if ALL applicable permission layers allow it.
|
|
921
|
-
|
|
922
|
-
### 8.2 Sandbox Execution
|
|
923
|
-
|
|
924
|
-
Commands that trigger DOM interactions (click, fill, scroll) MUST be executed within a security sandbox:
|
|
925
|
-
|
|
926
|
-
1. **Selector validation:** The Bridge MUST verify that the target selector is not in the `blockedSelectors` list and, if `allowedSelectors` is non-empty, is in the `allowedSelectors` list.
|
|
927
|
-
2. **Action isolation:** Each action MUST be executed atomically. A failure in one action MUST NOT corrupt the state of other pending actions.
|
|
928
|
-
3. **Output sanitization:** The Bridge MUST sanitize all content returned via `wab.readContent` to prevent injection attacks (strip `<script>` tags, event handlers, etc.).
|
|
929
|
-
|
|
930
|
-
### 8.3 Audit Logging
|
|
931
|
-
|
|
932
|
-
A conforming Bridge SHOULD maintain an audit log of all commands received and responses sent. Each log entry MUST include:
|
|
933
|
-
|
|
934
|
-
| Field | Description |
|
|
935
|
-
|---|---|
|
|
936
|
-
| `timestamp` | ISO 8601 timestamp. |
|
|
937
|
-
| `commandId` | The command's `id` field. |
|
|
938
|
-
| `method` | The WAB method invoked. |
|
|
939
|
-
| `agentId` | Identifier for the Agent (from session or API key). |
|
|
940
|
-
| `origin` | The requesting origin (for JS global and HTTP transports). |
|
|
941
|
-
| `status` | `"success"` or `"error"`. |
|
|
942
|
-
| `errorCode` | Error code if applicable. |
|
|
943
|
-
| `latencyMs` | Time to process the command in milliseconds. |
|
|
944
|
-
|
|
945
|
-
Audit logs SHOULD be retained for at least 30 days. Enterprise-tier implementations MAY retain logs for up to 7 years for compliance purposes.
|
|
946
|
-
|
|
947
|
-
### 8.4 Session-Based Authentication
|
|
948
|
-
|
|
949
|
-
Sessions provide the primary authentication mechanism:
|
|
950
|
-
|
|
951
|
-
1. An Agent authenticates via `wab.authenticate` with an API key.
|
|
952
|
-
2. The Bridge returns a `sessionToken` with a bounded TTL (default: 3600 seconds).
|
|
953
|
-
3. The Agent includes the token in all subsequent commands.
|
|
954
|
-
4. The Bridge MUST reject commands with expired or invalid tokens with error code `SESSION_EXPIRED` or `INVALID_TOKEN`.
|
|
955
|
-
|
|
956
|
-
Session tokens MUST be:
|
|
957
|
-
- At least 128 bits of entropy.
|
|
958
|
-
- Opaque to the Agent (no embedded claims that the Agent can decode).
|
|
959
|
-
- Transmitted only over secure channels (HTTPS, WSS).
|
|
960
|
-
|
|
961
|
-
### 8.5 Origin Validation
|
|
962
|
-
|
|
963
|
-
When `security.require_origin_match` is `true`:
|
|
964
|
-
|
|
965
|
-
1. The Bridge MUST validate the `Origin` header on HTTP requests.
|
|
966
|
-
2. The Bridge MUST validate the `document.referrer` or `window.location` for JS global transport.
|
|
967
|
-
3. Commands from non-matching origins MUST be rejected with error code `ORIGIN_MISMATCH`.
|
|
968
|
-
|
|
969
|
-
### 8.6 Rate Limiting
|
|
970
|
-
|
|
971
|
-
The Bridge MUST enforce rate limits as declared in `security.max_rate`:
|
|
972
|
-
|
|
973
|
-
1. Rate limits are per-session (authenticated) or per-origin (unauthenticated).
|
|
974
|
-
2. When the limit is exceeded, the Bridge MUST return error code `RATE_LIMITED`.
|
|
975
|
-
3. The response MUST include a `retryAfter` field (seconds) or `Retry-After` HTTP header.
|
|
976
|
-
4. The Bridge SHOULD use a sliding window algorithm for rate calculation.
|
|
977
|
-
|
|
978
|
-
### 8.7 Escalation Protection
|
|
979
|
-
|
|
980
|
-
The Bridge MUST prevent privilege escalation:
|
|
981
|
-
|
|
982
|
-
1. An Agent MUST NOT gain permissions beyond those granted at authentication.
|
|
983
|
-
2. Re-authentication MUST NOT expand permissions without Site Owner configuration change.
|
|
984
|
-
3. Session tokens MUST NOT be transferable between Agents.
|
|
985
|
-
4. The Bridge MUST detect and reject replayed commands (duplicate `id` within a session).
|
|
986
|
-
|
|
987
|
-
### 8.8 Command Signing (OPTIONAL)
|
|
988
|
-
|
|
989
|
-
For high-security environments, the Bridge MAY require command signing:
|
|
990
|
-
|
|
991
|
-
```json
|
|
992
|
-
{
|
|
993
|
-
"id": "cmd_001",
|
|
994
|
-
"method": "wab.executeAction",
|
|
995
|
-
"params": { "name": "transferFunds", "data": { "amount": 100 } },
|
|
996
|
-
"context": { "sessionToken": "sess_abc" },
|
|
997
|
-
"signature": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
|
998
|
-
}
|
|
999
|
-
```
|
|
1000
|
-
|
|
1001
|
-
The `signature` field is an HMAC-SHA256 of the canonical JSON representation of `method` + `params`, keyed with a shared secret established during authentication.
|
|
1002
|
-
|
|
1003
|
-
---
|
|
1004
|
-
|
|
1005
|
-
## 9. Fairness Protocol
|
|
1006
|
-
|
|
1007
|
-
### 9.1 The Neutrality Layer
|
|
1008
|
-
|
|
1009
|
-
The WAB Fairness Protocol is a unique feature that addresses a critical problem in AI-driven commerce: **the tendency for AI agents to preferentially route traffic to large, well-known brands at the expense of small and independent businesses.**
|
|
1010
|
-
|
|
1011
|
-
The Fairness Protocol establishes a set of rules and mechanisms that ensure WAB-enabled sites are treated equitably by AI agents, regardless of the site's size, brand recognition, or advertising budget.
|
|
1012
|
-
|
|
1013
|
-
### 9.2 Equal Treatment Requirement
|
|
1014
|
-
|
|
1015
|
-
Agents that implement the WAB protocol MUST adhere to the following fairness rules:
|
|
1016
|
-
|
|
1017
|
-
1. **No preferential routing.** An Agent MUST NOT preferentially route users to one WAB-enabled site over another based solely on brand size, popularity metrics, or commercial arrangements between the Agent operator and the site.
|
|
1018
|
-
2. **Capability-based ranking.** When an Agent selects between multiple WAB-enabled sites that can fulfill a user's request, selection MUST be based on **relevance to the user's query**, **capability match** (which site's actions best fulfill the request), and **quality signals** (user ratings, response time, error rate).
|
|
1019
|
-
3. **Transparency of selection.** An Agent SHOULD be able to explain why it selected one site over another. The explanation MUST reference objective criteria, not commercial relationships.
|
|
1020
|
-
|
|
1021
|
-
### 9.3 Discovery Registry
|
|
1022
|
-
|
|
1023
|
-
To ensure equal visibility, the WAB ecosystem defines a **Discovery Registry** — a public, decentralized index of WAB-enabled sites:
|
|
1024
|
-
|
|
1025
|
-
1. Any site with a valid Discovery Document MAY register with the Discovery Registry.
|
|
1026
|
-
2. The Registry MUST accept all registrations that pass schema validation and trust verification.
|
|
1027
|
-
3. The Registry MUST NOT charge differential fees based on site size or traffic volume.
|
|
1028
|
-
4. Agents SHOULD use the Discovery Registry as their primary source for finding WAB-enabled sites.
|
|
1029
|
-
|
|
1030
|
-
Registry entries contain:
|
|
1031
|
-
|
|
1032
|
-
```json
|
|
1033
|
-
{
|
|
1034
|
-
"url": "https://acme-restaurant.com",
|
|
1035
|
-
"provider": { "name": "Acme Restaurant", "category": "restaurant" },
|
|
1036
|
-
"location": { "city": "Amman", "country": "JO" },
|
|
1037
|
-
"capabilities_summary": ["viewMenu", "placeOrder", "searchMenu"],
|
|
1038
|
-
"fairness_metrics": { "commission_rate": "0%", "is_independent": true },
|
|
1039
|
-
"trust_level": "verified",
|
|
1040
|
-
"registered_at": "2026-01-15T00:00:00Z"
|
|
1041
|
-
}
|
|
1042
|
-
```
|
|
1043
|
-
|
|
1044
|
-
### 9.4 Priority Scoring
|
|
1045
|
-
|
|
1046
|
-
When multiple sites can fulfill a request, Agents SHOULD use the following scoring model:
|
|
1047
|
-
|
|
1048
|
-
| Factor | Weight | Description |
|
|
1049
|
-
|---|---|---|
|
|
1050
|
-
| Relevance | 40% | How well the site's capabilities match the user's intent. |
|
|
1051
|
-
| Proximity | 20% | Geographic proximity to the user (for location-based services). |
|
|
1052
|
-
| Capability depth | 15% | Number and richness of exposed actions. |
|
|
1053
|
-
| Quality | 15% | Historical success rate, response time, uptime. |
|
|
1054
|
-
| Freshness | 10% | How recently the Discovery Document was updated. |
|
|
1055
|
-
|
|
1056
|
-
The following factors MUST NOT influence priority:
|
|
1057
|
-
|
|
1058
|
-
- Brand recognition or popularity metrics (Alexa rank, domain authority, etc.).
|
|
1059
|
-
- Paid placement or advertising spend.
|
|
1060
|
-
- Commercial agreements between the Agent operator and the site.
|
|
1061
|
-
- Site traffic volume.
|
|
1062
|
-
|
|
1063
|
-
### 9.5 Commission Transparency
|
|
1064
|
-
|
|
1065
|
-
The `fairness_metrics.commission_rate` field provides transparency about intermediary costs:
|
|
1066
|
-
|
|
1067
|
-
1. Sites MUST accurately report their commission rate.
|
|
1068
|
-
2. Agents SHOULD present commission information to users when relevant (e.g., comparing ordering platforms).
|
|
1069
|
-
3. Agents SHOULD prefer direct-to-business sites (commission_rate = "0%") when quality and relevance are equal.
|
|
1070
|
-
4. The `direct_benefit` field SHOULD explain in plain language how the interaction benefits the site owner.
|
|
1071
|
-
|
|
1072
|
-
### 9.6 Independent Verification
|
|
1073
|
-
|
|
1074
|
-
To prevent gaming of the Fairness Protocol:
|
|
1075
|
-
|
|
1076
|
-
1. Discovery Documents MAY be signed with a cryptographic key registered in the Discovery Registry.
|
|
1077
|
-
2. Third-party auditors MAY verify that Agent implementations comply with the fairness rules.
|
|
1078
|
-
3. The `trust_signatures` field in the Discovery Document allows sites to present third-party attestations.
|
|
1079
|
-
4. Agents SHOULD log their site selection decisions for auditability.
|
|
1080
|
-
|
|
1081
|
-
### 9.7 Compliance Reporting
|
|
1082
|
-
|
|
1083
|
-
Agent operators SHOULD publish periodic fairness reports including:
|
|
1084
|
-
|
|
1085
|
-
- Distribution of traffic across site sizes (small / medium / large).
|
|
1086
|
-
- Percentage of traffic routed to independent vs. chain businesses.
|
|
1087
|
-
- Average commission rate of selected sites.
|
|
1088
|
-
- Selection algorithm transparency (open-source or audited).
|
|
1089
|
-
|
|
1090
|
-
---
|
|
1091
|
-
|
|
1092
|
-
## 10. MCP Compatibility
|
|
1093
|
-
|
|
1094
|
-
### 10.1 Overview
|
|
1095
|
-
|
|
1096
|
-
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) provides a standard interface for LLMs to access external tools, resources, and prompts. WAB is designed to be fully compatible with MCP, enabling WAB-enabled sites to be exposed as MCP tools to any LLM.
|
|
1097
|
-
|
|
1098
|
-
### 10.2 WAB → MCP Tool Mapping
|
|
1099
|
-
|
|
1100
|
-
Each WAB action maps to an MCP tool:
|
|
1101
|
-
|
|
1102
|
-
| WAB Concept | MCP Concept |
|
|
1103
|
-
|---|---|
|
|
1104
|
-
| Action | Tool |
|
|
1105
|
-
| Action name | Tool name |
|
|
1106
|
-
| Action params | Tool input schema (JSON Schema) |
|
|
1107
|
-
| Action result | Tool output |
|
|
1108
|
-
| Discovery Document | Resource |
|
|
1109
|
-
| Bridge context | Resource |
|
|
1110
|
-
|
|
1111
|
-
A WAB action:
|
|
1112
|
-
|
|
1113
|
-
```json
|
|
1114
|
-
{
|
|
1115
|
-
"name": "searchMenu",
|
|
1116
|
-
"description": "Search menu items by keyword",
|
|
1117
|
-
"trigger": "api",
|
|
1118
|
-
"params": [
|
|
1119
|
-
{ "name": "query", "type": "string", "required": true, "description": "Search term" }
|
|
1120
|
-
]
|
|
1121
|
-
}
|
|
1122
|
-
```
|
|
1123
|
-
|
|
1124
|
-
Maps to an MCP tool:
|
|
1125
|
-
|
|
1126
|
-
```json
|
|
1127
|
-
{
|
|
1128
|
-
"name": "acme_restaurant__searchMenu",
|
|
1129
|
-
"description": "Search menu items by keyword on Acme Restaurant",
|
|
1130
|
-
"inputSchema": {
|
|
1131
|
-
"type": "object",
|
|
1132
|
-
"properties": {
|
|
1133
|
-
"query": { "type": "string", "description": "Search term" }
|
|
1134
|
-
},
|
|
1135
|
-
"required": ["query"]
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
```
|
|
1139
|
-
|
|
1140
|
-
### 10.3 WAB Discovery → MCP Resources
|
|
1141
|
-
|
|
1142
|
-
The Discovery Document is exposed as an MCP resource:
|
|
1143
|
-
|
|
1144
|
-
```json
|
|
1145
|
-
{
|
|
1146
|
-
"uri": "wab://acme-restaurant.com/discovery",
|
|
1147
|
-
"name": "Acme Restaurant WAB Discovery",
|
|
1148
|
-
"mimeType": "application/json",
|
|
1149
|
-
"description": "WAB capabilities for Acme Restaurant"
|
|
1150
|
-
}
|
|
1151
|
-
```
|
|
1152
|
-
|
|
1153
|
-
Bridge context is exposed as a second resource:
|
|
1154
|
-
|
|
1155
|
-
```json
|
|
1156
|
-
{
|
|
1157
|
-
"uri": "wab://acme-restaurant.com/context",
|
|
1158
|
-
"name": "Acme Restaurant Bridge Context",
|
|
1159
|
-
"mimeType": "application/json"
|
|
1160
|
-
}
|
|
1161
|
-
```
|
|
1162
|
-
|
|
1163
|
-
### 10.4 Bidirectional Bridge
|
|
1164
|
-
|
|
1165
|
-
A WAB-MCP bridge implementation MUST support both directions:
|
|
1166
|
-
|
|
1167
|
-
**WAB → MCP (Site as Tool Provider):**
|
|
1168
|
-
1. Read the site's Discovery Document.
|
|
1169
|
-
2. For each action, generate an MCP tool definition.
|
|
1170
|
-
3. When the LLM calls a tool, translate it to a `wab.executeAction` command.
|
|
1171
|
-
4. Return the WAB response as the MCP tool output.
|
|
1172
|
-
|
|
1173
|
-
**MCP → WAB (LLM as Agent):**
|
|
1174
|
-
1. The LLM receives WAB tools via MCP.
|
|
1175
|
-
2. The LLM decides which tool to call based on the user's request.
|
|
1176
|
-
3. The MCP server translates the tool call to a WAB command.
|
|
1177
|
-
4. The WAB response is returned to the LLM.
|
|
1178
|
-
|
|
1179
|
-
### 10.5 MCP Server Implementation
|
|
1180
|
-
|
|
1181
|
-
A reference MCP server for WAB SHOULD implement:
|
|
1182
|
-
|
|
1183
|
-
```typescript
|
|
1184
|
-
interface WABMCPServer {
|
|
1185
|
-
// List WAB sites as MCP tools
|
|
1186
|
-
listTools(): Tool[];
|
|
1187
|
-
|
|
1188
|
-
// Execute a WAB action via MCP tool call
|
|
1189
|
-
callTool(name: string, arguments: object): ToolResult;
|
|
1190
|
-
|
|
1191
|
-
// List WAB discovery documents as MCP resources
|
|
1192
|
-
listResources(): Resource[];
|
|
1193
|
-
|
|
1194
|
-
// Read a WAB resource
|
|
1195
|
-
readResource(uri: string): ResourceContent;
|
|
1196
|
-
}
|
|
1197
|
-
```
|
|
1198
|
-
|
|
1199
|
-
The MCP server MUST:
|
|
1200
|
-
- Namespace tool names to avoid collisions (e.g., `{site}__{action}`).
|
|
1201
|
-
- Map WAB error codes to MCP error responses.
|
|
1202
|
-
- Respect WAB rate limits and propagate `Retry-After` information.
|
|
1203
|
-
- Cache Discovery Documents according to [Section 6.2](#62-phase-1-discovery).
|
|
1204
|
-
|
|
1205
|
-
---
|
|
1206
|
-
|
|
1207
|
-
## 11. Conformance
|
|
1208
|
-
|
|
1209
|
-
### 11.1 Conformance Levels
|
|
1210
|
-
|
|
1211
|
-
This specification defines two conformance levels:
|
|
1212
|
-
|
|
1213
|
-
| Level | Role | Description |
|
|
1214
|
-
|---|---|---|
|
|
1215
|
-
| **WAB Bridge** | Site-side | A site that implements the WAB protocol for agent consumption. |
|
|
1216
|
-
| **WAB Agent** | Agent-side | An agent that consumes WAB-enabled sites according to the protocol. |
|
|
1217
|
-
|
|
1218
|
-
### 11.2 Bridge Conformance Requirements
|
|
1219
|
-
|
|
1220
|
-
A conforming WAB Bridge:
|
|
1221
|
-
|
|
1222
|
-
1. MUST serve a valid Discovery Document at `/agent-bridge.json` or `/.well-known/wab.json`.
|
|
1223
|
-
2. MUST support at least one transport layer (JS global, WebSocket, or HTTP).
|
|
1224
|
-
3. MUST implement all standard methods defined in [Section 5.3](#53-standard-methods).
|
|
1225
|
-
4. MUST enforce the permission model defined in [Section 8.1](#81-permission-model).
|
|
1226
|
-
5. MUST enforce rate limits as declared in the Discovery Document.
|
|
1227
|
-
6. MUST return responses conforming to the Response Format in [Section 5.2](#52-response-format).
|
|
1228
|
-
7. MUST reject commands with invalid or expired session tokens.
|
|
1229
|
-
8. MUST use error codes from [Appendix B](#appendix-b-error-codes).
|
|
1230
|
-
9. SHOULD implement audit logging as described in [Section 8.3](#83-audit-logging).
|
|
1231
|
-
10. SHOULD implement sandbox execution as described in [Section 8.2](#82-sandbox-execution).
|
|
1232
|
-
11. MAY implement the WebSocket and HTTP transports in addition to the JS global.
|
|
1233
|
-
12. MAY implement command signing as described in [Section 8.8](#88-command-signing-optional).
|
|
1234
|
-
|
|
1235
|
-
### 11.3 Agent Conformance Requirements
|
|
1236
|
-
|
|
1237
|
-
A conforming WAB Agent:
|
|
1238
|
-
|
|
1239
|
-
1. MUST discover sites via the Discovery Document before interacting.
|
|
1240
|
-
2. MUST respect all permissions declared in the Discovery Document.
|
|
1241
|
-
3. MUST NOT execute actions for which it lacks permission.
|
|
1242
|
-
4. MUST authenticate before executing actions that require authentication.
|
|
1243
|
-
5. MUST respect rate limits and honor `Retry-After` directives.
|
|
1244
|
-
6. MUST follow the lifecycle phases defined in [Section 6](#6-lifecycle-protocol).
|
|
1245
|
-
7. MUST use the Command Format from [Section 5.1](#51-command-format).
|
|
1246
|
-
8. SHOULD support all three transport layers.
|
|
1247
|
-
9. SHOULD implement the Fairness Protocol from [Section 9](#9-fairness-protocol).
|
|
1248
|
-
10. SHOULD cache Discovery Documents to reduce load on sites.
|
|
1249
|
-
11. SHOULD implement graceful degradation across transport layers.
|
|
1250
|
-
12. MAY implement command signing for high-security interactions.
|
|
1251
|
-
|
|
1252
|
-
### 11.4 RFC 2119 Requirement Summary
|
|
1253
|
-
|
|
1254
|
-
| Keyword | Count | Meaning |
|
|
1255
|
-
|---|---|---|
|
|
1256
|
-
| MUST | Core requirements | The implementation is non-conforming if violated. |
|
|
1257
|
-
| MUST NOT | Prohibitions | The implementation is non-conforming if this occurs. |
|
|
1258
|
-
| SHOULD | Strong recommendations | May be ignored with good reason, but implications must be understood. |
|
|
1259
|
-
| SHOULD NOT | Discouraged practices | May be done with good reason, but implications must be understood. |
|
|
1260
|
-
| MAY | Optional features | Truly optional; implementations may include or omit. |
|
|
1261
|
-
|
|
1262
|
-
---
|
|
1263
|
-
|
|
1264
|
-
## Appendix A: JSON Schema for agent-bridge.json
|
|
1265
|
-
|
|
1266
|
-
```json
|
|
1267
|
-
{
|
|
1268
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1269
|
-
"$id": "https://webagentbridge.com/schemas/agent-bridge.json",
|
|
1270
|
-
"title": "WAB Discovery Document",
|
|
1271
|
-
"description": "Schema for the Web Agent Bridge discovery document (agent-bridge.json)",
|
|
1272
|
-
"type": "object",
|
|
1273
|
-
"required": ["wab_version", "provider", "capabilities", "transport"],
|
|
1274
|
-
"properties": {
|
|
1275
|
-
"wab_version": {
|
|
1276
|
-
"type": "string",
|
|
1277
|
-
"const": "1.0",
|
|
1278
|
-
"description": "WAB protocol version"
|
|
1279
|
-
},
|
|
1280
|
-
"provider": {
|
|
1281
|
-
"type": "object",
|
|
1282
|
-
"required": ["name", "category", "url"],
|
|
1283
|
-
"properties": {
|
|
1284
|
-
"name": { "type": "string", "minLength": 1 },
|
|
1285
|
-
"category": { "type": "string", "minLength": 1 },
|
|
1286
|
-
"url": { "type": "string", "format": "uri" },
|
|
1287
|
-
"location": {
|
|
1288
|
-
"type": "object",
|
|
1289
|
-
"properties": {
|
|
1290
|
-
"city": { "type": "string" },
|
|
1291
|
-
"country": { "type": "string", "pattern": "^[A-Z]{2}$" },
|
|
1292
|
-
"support_local": { "type": "boolean" }
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
},
|
|
1297
|
-
"capabilities": {
|
|
1298
|
-
"type": "object",
|
|
1299
|
-
"required": ["commands", "permissions"],
|
|
1300
|
-
"properties": {
|
|
1301
|
-
"commands": {
|
|
1302
|
-
"type": "array",
|
|
1303
|
-
"items": {
|
|
1304
|
-
"type": "object",
|
|
1305
|
-
"required": ["name", "description", "trigger", "params"],
|
|
1306
|
-
"properties": {
|
|
1307
|
-
"name": {
|
|
1308
|
-
"type": "string",
|
|
1309
|
-
"pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$"
|
|
1310
|
-
},
|
|
1311
|
-
"description": { "type": "string", "minLength": 1 },
|
|
1312
|
-
"trigger": {
|
|
1313
|
-
"type": "string",
|
|
1314
|
-
"enum": ["click", "fill_and_submit", "scroll", "api", "navigate"]
|
|
1315
|
-
},
|
|
1316
|
-
"params": {
|
|
1317
|
-
"type": "array",
|
|
1318
|
-
"items": {
|
|
1319
|
-
"type": "object",
|
|
1320
|
-
"required": ["name", "type", "required"],
|
|
1321
|
-
"properties": {
|
|
1322
|
-
"name": { "type": "string" },
|
|
1323
|
-
"type": { "type": "string", "enum": ["string", "number", "boolean", "array", "object"] },
|
|
1324
|
-
"required": { "type": "boolean" },
|
|
1325
|
-
"description": { "type": "string" },
|
|
1326
|
-
"default": {},
|
|
1327
|
-
"enum": { "type": "array" }
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
},
|
|
1331
|
-
"requiresAuth": { "type": "boolean", "default": false }
|
|
1332
|
-
}
|
|
1333
|
-
}
|
|
1334
|
-
},
|
|
1335
|
-
"permissions": {
|
|
1336
|
-
"type": "object",
|
|
1337
|
-
"properties": {
|
|
1338
|
-
"readContent": { "type": "boolean" },
|
|
1339
|
-
"click": { "type": "boolean" },
|
|
1340
|
-
"fillForms": { "type": "boolean" },
|
|
1341
|
-
"scroll": { "type": "boolean" },
|
|
1342
|
-
"navigate": { "type": "boolean" },
|
|
1343
|
-
"apiAccess": { "type": "boolean" },
|
|
1344
|
-
"automatedLogin": { "type": "boolean" },
|
|
1345
|
-
"extractData": { "type": "boolean" }
|
|
1346
|
-
}
|
|
1347
|
-
},
|
|
1348
|
-
"tier": {
|
|
1349
|
-
"type": "string",
|
|
1350
|
-
"enum": ["free", "starter", "pro", "enterprise"],
|
|
1351
|
-
"default": "free"
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
},
|
|
1355
|
-
"agent_access": {
|
|
1356
|
-
"type": "object",
|
|
1357
|
-
"properties": {
|
|
1358
|
-
"preferred_entry_point": { "type": "string" },
|
|
1359
|
-
"api_fallback": { "type": "string", "format": "uri" },
|
|
1360
|
-
"selectors": {
|
|
1361
|
-
"type": "object",
|
|
1362
|
-
"additionalProperties": { "type": "string" }
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
},
|
|
1366
|
-
"fairness_metrics": {
|
|
1367
|
-
"type": "object",
|
|
1368
|
-
"properties": {
|
|
1369
|
-
"commission_rate": { "type": "string" },
|
|
1370
|
-
"direct_benefit": { "type": "string" },
|
|
1371
|
-
"is_independent": { "type": "boolean" }
|
|
1372
|
-
}
|
|
1373
|
-
},
|
|
1374
|
-
"trust_signatures": {
|
|
1375
|
-
"type": "array",
|
|
1376
|
-
"items": { "type": "string" }
|
|
1377
|
-
},
|
|
1378
|
-
"transport": {
|
|
1379
|
-
"type": "object",
|
|
1380
|
-
"required": [],
|
|
1381
|
-
"properties": {
|
|
1382
|
-
"js_global": {
|
|
1383
|
-
"type": "object",
|
|
1384
|
-
"properties": {
|
|
1385
|
-
"enabled": { "type": "boolean" },
|
|
1386
|
-
"interface": { "type": "string", "default": "window.AICommands" }
|
|
1387
|
-
}
|
|
1388
|
-
},
|
|
1389
|
-
"websocket": {
|
|
1390
|
-
"type": "object",
|
|
1391
|
-
"properties": {
|
|
1392
|
-
"enabled": { "type": "boolean" },
|
|
1393
|
-
"url": { "type": "string", "format": "uri" }
|
|
1394
|
-
}
|
|
1395
|
-
},
|
|
1396
|
-
"http": {
|
|
1397
|
-
"type": "object",
|
|
1398
|
-
"properties": {
|
|
1399
|
-
"enabled": { "type": "boolean" },
|
|
1400
|
-
"base_url": { "type": "string" }
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
},
|
|
1404
|
-
"anyOf": [
|
|
1405
|
-
{ "properties": { "js_global": { "properties": { "enabled": { "const": true } } } } },
|
|
1406
|
-
{ "properties": { "websocket": { "properties": { "enabled": { "const": true } } } } },
|
|
1407
|
-
{ "properties": { "http": { "properties": { "enabled": { "const": true } } } } }
|
|
1408
|
-
]
|
|
1409
|
-
},
|
|
1410
|
-
"security": {
|
|
1411
|
-
"type": "object",
|
|
1412
|
-
"properties": {
|
|
1413
|
-
"require_origin_match": { "type": "boolean", "default": true },
|
|
1414
|
-
"session_ttl": { "type": "integer", "minimum": 60, "default": 3600 },
|
|
1415
|
-
"max_rate": { "type": "integer", "minimum": 1, "default": 60 }
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
```
|
|
1421
|
-
|
|
1422
|
-
---
|
|
1423
|
-
|
|
1424
|
-
## Appendix B: Error Codes
|
|
1425
|
-
|
|
1426
|
-
All WAB error responses MUST use one of the following standard error codes:
|
|
1427
|
-
|
|
1428
|
-
| Code | HTTP Status | Description |
|
|
1429
|
-
|---|---|---|
|
|
1430
|
-
| `INVALID_COMMAND` | 400 | The command is malformed or missing required fields. |
|
|
1431
|
-
| `INVALID_PARAMS` | 400 | One or more parameters are invalid or missing. |
|
|
1432
|
-
| `INVALID_METHOD` | 400 | The specified method is not recognized. |
|
|
1433
|
-
| `AUTHENTICATION_REQUIRED` | 401 | The command requires authentication but no session token was provided. |
|
|
1434
|
-
| `INVALID_TOKEN` | 401 | The provided session token is invalid. |
|
|
1435
|
-
| `SESSION_EXPIRED` | 401 | The session token has expired. |
|
|
1436
|
-
| `PERMISSION_DENIED` | 403 | The Agent lacks permission to perform this action. |
|
|
1437
|
-
| `ORIGIN_MISMATCH` | 403 | The request origin does not match the allowed origins. |
|
|
1438
|
-
| `ACTION_NOT_FOUND` | 404 | The specified action name does not exist. |
|
|
1439
|
-
| `SELECTOR_NOT_FOUND` | 404 | The target DOM element could not be found. |
|
|
1440
|
-
| `RATE_LIMITED` | 429 | The Agent has exceeded the rate limit. |
|
|
1441
|
-
| `DUPLICATE_COMMAND_ID` | 409 | A command with this ID was already processed in this session. |
|
|
1442
|
-
| `SELECTOR_BLOCKED` | 403 | The target selector is in the blocked list. |
|
|
1443
|
-
| `EXECUTION_FAILED` | 500 | The action was attempted but failed during execution. |
|
|
1444
|
-
| `BRIDGE_ERROR` | 500 | An internal Bridge error occurred. |
|
|
1445
|
-
| `TRANSPORT_ERROR` | 502 | The transport layer encountered an error. |
|
|
1446
|
-
| `TIMEOUT` | 504 | The command timed out before completing. |
|
|
1447
|
-
| `UNSUPPORTED_VERSION` | 400 | The requested WAB protocol version is not supported by this Bridge. |
|
|
1448
|
-
| `SANDBOX_VIOLATION` | 403 | The command attempted an operation outside the security sandbox. |
|
|
1449
|
-
| `SIGNATURE_INVALID` | 401 | The command signature failed verification. |
|
|
1450
|
-
|
|
1451
|
-
Error response structure:
|
|
1452
|
-
|
|
1453
|
-
```json
|
|
1454
|
-
{
|
|
1455
|
-
"id": "cmd_001",
|
|
1456
|
-
"type": "error",
|
|
1457
|
-
"error": {
|
|
1458
|
-
"code": "RATE_LIMITED",
|
|
1459
|
-
"message": "Rate limit exceeded. Maximum 60 requests per minute.",
|
|
1460
|
-
"retryAfter": 12
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
```
|
|
1464
|
-
|
|
1465
|
-
The `error` object:
|
|
1466
|
-
|
|
1467
|
-
| Field | Type | Required | Description |
|
|
1468
|
-
|---|---|---|---|
|
|
1469
|
-
| `code` | string | REQUIRED | One of the standard error codes above. |
|
|
1470
|
-
| `message` | string | REQUIRED | Human-readable error description. |
|
|
1471
|
-
| `retryAfter` | integer | CONDITIONAL | Seconds to wait before retrying (on `RATE_LIMITED`). |
|
|
1472
|
-
| `details` | object | OPTIONAL | Additional error context for debugging. |
|
|
1473
|
-
|
|
1474
|
-
---
|
|
1475
|
-
|
|
1476
|
-
## Appendix C: MIME Types and Headers
|
|
1477
|
-
|
|
1478
|
-
### C.1 MIME Types
|
|
1479
|
-
|
|
1480
|
-
| MIME Type | Usage |
|
|
1481
|
-
|---|---|
|
|
1482
|
-
| `application/json` | Discovery Document, Command/Response bodies. |
|
|
1483
|
-
| `application/vnd.wab+json` | Formal WAB media type (OPTIONAL). Implementations MAY use this for stricter content negotiation. |
|
|
1484
|
-
| `text/event-stream` | Server-Sent Events fallback for subscriptions over HTTP (OPTIONAL). |
|
|
1485
|
-
|
|
1486
|
-
### C.2 Standard Headers
|
|
1487
|
-
|
|
1488
|
-
#### Request Headers
|
|
1489
|
-
|
|
1490
|
-
| Header | Required | Description |
|
|
1491
|
-
|---|---|---|
|
|
1492
|
-
| `X-WAB-Version` | REQUIRED | Protocol version. Value: `1.0`. |
|
|
1493
|
-
| `X-WAB-Request-Id` | RECOMMENDED | Unique request identifier (UUIDv4). |
|
|
1494
|
-
| `X-WAB-Agent-Name` | OPTIONAL | Human-readable name of the Agent. |
|
|
1495
|
-
| `X-WAB-Agent-Version` | OPTIONAL | Version of the Agent software. |
|
|
1496
|
-
| `Authorization` | CONDITIONAL | `Bearer {sessionToken}` for authenticated requests. |
|
|
1497
|
-
| `Content-Type` | CONDITIONAL | `application/json` for POST/PUT requests. |
|
|
1498
|
-
| `Accept` | RECOMMENDED | `application/json` or `application/vnd.wab+json`. |
|
|
1499
|
-
|
|
1500
|
-
#### Response Headers
|
|
1501
|
-
|
|
1502
|
-
| Header | Required | Description |
|
|
1503
|
-
|---|---|---|
|
|
1504
|
-
| `X-WAB-Version` | REQUIRED | Protocol version supported by the Bridge. |
|
|
1505
|
-
| `X-WAB-Request-Id` | RECOMMENDED | Echoed from request for correlation. |
|
|
1506
|
-
| `X-WAB-Rate-Remaining` | RECOMMENDED | Number of requests remaining in the current rate window. |
|
|
1507
|
-
| `X-WAB-Rate-Reset` | RECOMMENDED | Unix timestamp when the rate window resets. |
|
|
1508
|
-
| `Retry-After` | CONDITIONAL | Seconds to wait (on 429 responses). |
|
|
1509
|
-
| `Content-Type` | REQUIRED | `application/json`. |
|
|
1510
|
-
|
|
1511
|
-
### C.3 CORS Configuration
|
|
1512
|
-
|
|
1513
|
-
Bridges serving the HTTP transport MUST configure CORS headers to allow agent access:
|
|
1514
|
-
|
|
1515
|
-
```http
|
|
1516
|
-
Access-Control-Allow-Origin: *
|
|
1517
|
-
Access-Control-Allow-Methods: GET, POST, OPTIONS
|
|
1518
|
-
Access-Control-Allow-Headers: Content-Type, Authorization, X-WAB-Version, X-WAB-Request-Id, X-WAB-Agent-Name, X-WAB-Agent-Version
|
|
1519
|
-
Access-Control-Expose-Headers: X-WAB-Version, X-WAB-Request-Id, X-WAB-Rate-Remaining, X-WAB-Rate-Reset, Retry-After
|
|
1520
|
-
Access-Control-Max-Age: 86400
|
|
1521
|
-
```
|
|
1522
|
-
|
|
1523
|
-
If `security.require_origin_match` is `true`, the Bridge SHOULD replace the wildcard `*` with explicit allowed origins.
|
|
1524
|
-
|
|
1525
|
-
### C.4 Discovery Document HTTP Headers
|
|
1526
|
-
|
|
1527
|
-
When serving the Discovery Document, the server SHOULD include:
|
|
1528
|
-
|
|
1529
|
-
```http
|
|
1530
|
-
Content-Type: application/json
|
|
1531
|
-
Cache-Control: public, max-age=300
|
|
1532
|
-
ETag: "v1-abc123"
|
|
1533
|
-
X-WAB-Version: 1.0
|
|
1534
|
-
```
|
|
1535
|
-
|
|
1536
|
-
---
|
|
1537
|
-
|
|
1538
|
-
*End of WAB Protocol Specification v1.0*
|
|
1539
|
-
|
|
1540
|
-
*Copyright 2026 Web Agent Bridge Contributors. Licensed under MIT.*
|