looking-glass-mcp 2.2.0 → 3.0.1
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/README.md +333 -219
- package/build/index.js +5723 -2536
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -2,47 +2,69 @@
|
|
|
2
2
|
<img src=".github/assets/looking-glass-logo.png" alt="Looking Glass" width="600" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<h1 align="center">Looking Glass</h1>
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>The AI-native browser for agents.</strong><br/>
|
|
9
|
+
72 MCP tools. Self-healing interactions. Semantic change detection. Structured extraction. Credential vault. Enterprise-grade security. Deploy anywhere.
|
|
10
|
+
</p>
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="#quickstart">Quickstart</a> |
|
|
14
|
+
<a href="#intelligence-layer">Intelligence</a> |
|
|
15
|
+
<a href="#tools">Tools</a> |
|
|
16
|
+
<a href="#deploy-to-azure">Deploy to Azure</a> |
|
|
17
|
+
<a href="#security">Security</a> |
|
|
18
|
+
<a href="#configuration">Configuration</a>
|
|
19
|
+
</p>
|
|
10
20
|
|
|
11
21
|
---
|
|
12
22
|
|
|
13
|
-
##
|
|
23
|
+
## What's New in v3.0
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
Looking Glass v3.0 transforms from a browser automation tool into an **AI-native intelligence platform**. The browser now thinks alongside the agent.
|
|
16
26
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
This is not a mock. Not a simulation. Claude controls a real browser, sees real screenshots, and reads real DOM trees.
|
|
27
|
+
- **Semantic change detection** -- after every action, the browser tells you *what changed* (modal opened, form validation failed, content added), not just the raw page state
|
|
28
|
+
- **Self-healing interactions** -- every `browser_click`, `browser_type`, and `browser_hover` now has the test runner's self-healing: CSS selector fails? Automatic fallback to semantic resolution with confidence scoring
|
|
29
|
+
- **Structured data extraction** -- `browser_extract` takes a schema and returns structured JSON from tables, repeated elements, or single-entity pages
|
|
30
|
+
- **Intent-based navigation** -- `browser_go "settings page"` figures out how to get there
|
|
31
|
+
- **Semantic waiting** -- `browser_wait_for "search results loaded"` instead of guessing CSS selectors
|
|
32
|
+
- **Workflow tracking** -- every response includes page type, form progress, breadcrumbs, modal state, and step indicators
|
|
33
|
+
- **Credential vault** -- AES-256-GCM encrypted credentials with PBKDF2 key derivation and blind injection (the agent never sees passwords)
|
|
34
|
+
- **HTTP transport** -- deploy as a cloud service with `StreamableHTTPServerTransport`
|
|
35
|
+
- **Docker + Terraform** -- one-command Azure deployment with Key Vault, managed identity, and hardened security
|
|
36
|
+
- **Enterprise security** -- timing-safe auth, rate limiting, auth lockout, deep audit logging, non-root containers
|
|
28
37
|
|
|
29
38
|
---
|
|
30
39
|
|
|
31
|
-
##
|
|
40
|
+
## Quickstart
|
|
32
41
|
|
|
33
|
-
**
|
|
42
|
+
**Claude Code:**
|
|
34
43
|
|
|
35
44
|
```bash
|
|
36
45
|
claude mcp add looking-glass -- npx looking-glass-mcp
|
|
37
46
|
```
|
|
38
47
|
|
|
39
|
-
**
|
|
48
|
+
**GitHub Copilot / VS Code:**
|
|
40
49
|
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
Add to `.vscode/mcp.json`:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"servers": {
|
|
55
|
+
"looking-glass": {
|
|
56
|
+
"command": "npx",
|
|
57
|
+
"args": ["looking-glass-mcp"],
|
|
58
|
+
"env": {
|
|
59
|
+
"BROWSER_HEADLESS": "false",
|
|
60
|
+
"BROWSER_SECURITY_PROFILE": "local-dev"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
43
65
|
```
|
|
44
66
|
|
|
45
|
-
**
|
|
67
|
+
**Any MCP client** via `.mcp.json`:
|
|
46
68
|
|
|
47
69
|
```json
|
|
48
70
|
{
|
|
@@ -51,292 +73,384 @@ npm install -g looking-glass-mcp
|
|
|
51
73
|
"command": "npx",
|
|
52
74
|
"args": ["looking-glass-mcp"],
|
|
53
75
|
"env": {
|
|
54
|
-
"BROWSER_HEADLESS": "false"
|
|
76
|
+
"BROWSER_HEADLESS": "false",
|
|
77
|
+
"BROWSER_SECURITY_PROFILE": "local-dev"
|
|
55
78
|
}
|
|
56
79
|
}
|
|
57
80
|
}
|
|
58
81
|
}
|
|
59
82
|
```
|
|
60
83
|
|
|
61
|
-
|
|
84
|
+
**Global install:**
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm install -g looking-glass-mcp
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Once connected, the agent can:
|
|
62
91
|
|
|
63
92
|
```
|
|
64
93
|
"Open localhost:3000 and tell me what you see"
|
|
94
|
+
"Extract all products from this page as JSON with name, price, and rating"
|
|
95
|
+
"Go to the settings page"
|
|
96
|
+
"Wait for the search results to load, then extract the table"
|
|
65
97
|
"Run an accessibility audit on the landing page"
|
|
66
|
-
"
|
|
67
|
-
"Explore the entire site and map all the pages"
|
|
98
|
+
"Log in with vault profile staging-admin"
|
|
68
99
|
```
|
|
69
100
|
|
|
70
101
|
---
|
|
71
102
|
|
|
72
|
-
##
|
|
103
|
+
## Intelligence Layer
|
|
73
104
|
|
|
74
|
-
|
|
105
|
+
These capabilities run **automatically** on every interaction -- no extra tool calls needed.
|
|
75
106
|
|
|
76
|
-
###
|
|
107
|
+
### Semantic Change Detection
|
|
77
108
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
These tools exist because an AI is the operator — they would be useless to a human.
|
|
95
|
-
|
|
96
|
-
| Tool | What it does |
|
|
97
|
-
|------|-------------|
|
|
98
|
-
| `browser_analyze_page` | Returns structured page analysis: type (login, dashboard, form, error), available actions, forms, navigation links, data elements, and page state |
|
|
99
|
-
| `browser_resolve_element` | Finds elements by natural language ("the email input", "third navigation link") with confidence scores, **visibility, enabled state, bounding box, and viewport position** |
|
|
100
|
-
| `browser_smart_click` | Click elements described in plain English instead of fragile CSS selectors. Returns page state envelope with screenshot. |
|
|
101
|
-
| `browser_suggest_actions` | Examines the page and suggests what the agent should do next, with pre-filled tool parameters (returns structured JSON) |
|
|
102
|
-
| `browser_explore` | Autonomously crawls the site within domain boundaries, classifies every page, and returns a complete site map (returns structured JSON) |
|
|
103
|
-
| `browser_wait_until_stable` | Waits for true page readiness using multiple signals: network idle, DOM settled, spinners gone, images loaded |
|
|
104
|
-
| `browser_login` | **Composite action**: navigates to login URL, auto-detects fields, fills credentials, submits, verifies redirect, reports cookies set — all in one call |
|
|
105
|
-
| `browser_fill_and_submit` | **Composite action**: fills form fields by selector or label, submits, returns before/after state with screenshot |
|
|
106
|
-
|
|
107
|
-
### Observation & Debugging
|
|
108
|
-
|
|
109
|
-
| Tool | What it does |
|
|
110
|
-
|------|-------------|
|
|
111
|
-
| `browser_screenshot` | Capture viewport or full-page screenshot (returned inline) |
|
|
112
|
-
| `browser_snapshot` | Get the full accessibility tree as structured text |
|
|
113
|
-
| `browser_evaluate` | Execute arbitrary JavaScript in page context |
|
|
114
|
-
| `browser_console_messages` | Read console logs, warnings, errors |
|
|
115
|
-
| `browser_network_requests` | Monitor all HTTP requests and responses |
|
|
116
|
-
| `browser_diagnose` | One-shot diagnostic bundle: console errors + failed requests + DOM context + screenshot |
|
|
117
|
-
| `browser_error_report` | Catalog of all uncaught JS exceptions and failed resource loads |
|
|
118
|
-
| `browser_snapshot_state` / `browser_diff_state` | Take a before/after snapshot and see exactly what changed on the page |
|
|
119
|
-
| `browser_action_history` | Full journal of every action taken: tool, args, URL before/after, new errors, duration (returns structured JSON) |
|
|
120
|
-
| `browser_clear_history` | Reset the action journal |
|
|
121
|
-
|
|
122
|
-
### Storage & State Inspection
|
|
123
|
-
|
|
124
|
-
| Tool | What it does |
|
|
125
|
-
|------|-------------|
|
|
126
|
-
| `browser_get_cookies` / `browser_set_cookie` | Read and write browser cookies |
|
|
127
|
-
| `browser_get_localstorage` / `browser_set_localstorage` | Read and write localStorage entries |
|
|
128
|
-
| `browser_clear_storage` | Clear cookies, localStorage, sessionStorage, or all at once |
|
|
129
|
-
| `browser_clean_slate` | Nuclear option: wipe cookies, localStorage, sessionStorage, IndexedDB, and Cache API |
|
|
109
|
+
After every click, type, or navigation, the response includes a `Changes Detected` section:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
--- Changes Detected ---
|
|
113
|
+
* Modal appeared: "Confirm Order"
|
|
114
|
+
* 3 table rows added
|
|
115
|
+
* Form validation: Please enter a valid email
|
|
116
|
+
* Loading completed
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The browser captures a page snapshot before and after each action, then categorizes the differences into 11 semantic change types: `url_changed`, `title_changed`, `modal_opened`, `modal_closed`, `alert_appeared`, `form_validation`, `content_added`, `content_removed`, `loading_started`, `loading_finished`, `toast_notification`.
|
|
120
|
+
|
|
121
|
+
### Self-Healing Interactions
|
|
122
|
+
|
|
123
|
+
Every interaction tool (`browser_click`, `browser_type`, `browser_hover`, `browser_select_option`) now uses the same resolution chain as the test runner:
|
|
130
124
|
|
|
131
|
-
|
|
125
|
+
1. Try the CSS selector (fast path, 2s timeout)
|
|
126
|
+
2. If it fails, resolve semantically via the accessibility tree (role, text, label, placeholder matching)
|
|
127
|
+
3. Report which strategy worked and the confidence score
|
|
132
128
|
|
|
133
|
-
|
|
129
|
+
```
|
|
130
|
+
Clicked: "Submit Order" (resolved via getByRole('button', {name: 'Submit Order'}), confidence: 0.92)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
If the CSS selector failed and semantic resolution succeeded:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
Self-healed: selector "#old-btn" failed -> resolved via getByText('Submit') (confidence: 0.85)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Workflow Context
|
|
140
|
+
|
|
141
|
+
Every response includes workflow intelligence:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
--- Workflow ---
|
|
145
|
+
Page: form (populated) | Step: Payment (3/5) | Form: 2/6 filled | Required: phone, address
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Detects: page type (login, dashboard, form, listing, article, error), breadcrumbs, step indicators (wizard/stepper), form progress (filled/remaining/validation errors), active modals, and toast notifications.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Tools
|
|
153
|
+
|
|
154
|
+
Looking Glass ships with **72 tools** across 10 categories.
|
|
155
|
+
|
|
156
|
+
### Browser Control (11 tools)
|
|
157
|
+
|
|
158
|
+
| Tool | Description |
|
|
134
159
|
|------|-------------|
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
|
|
146
|
-
###
|
|
147
|
-
|
|
148
|
-
| Tool |
|
|
160
|
+
| `browser_navigate` | Navigate to a URL |
|
|
161
|
+
| `browser_click` | Click by CSS selector or text (self-healing) |
|
|
162
|
+
| `browser_type` | Fill an input field (self-healing) |
|
|
163
|
+
| `browser_hover` | Hover over an element (self-healing) |
|
|
164
|
+
| `browser_drag` | Drag and drop between elements |
|
|
165
|
+
| `browser_select_option` | Select a dropdown option (self-healing) |
|
|
166
|
+
| `browser_press_key` | Send keyboard input |
|
|
167
|
+
| `browser_scroll` | Scroll the page or to a specific element |
|
|
168
|
+
| `browser_go_back` / `browser_go_forward` | Navigate browser history |
|
|
169
|
+
| `browser_tab_*` | Multi-tab management (new, list, select, close) |
|
|
170
|
+
|
|
171
|
+
### AI Intelligence (13 tools)
|
|
172
|
+
|
|
173
|
+
| Tool | Description |
|
|
149
174
|
|------|-------------|
|
|
150
|
-
| `
|
|
151
|
-
| `
|
|
152
|
-
| `
|
|
175
|
+
| `browser_analyze_page` | Structured page analysis: type, forms, navigation, actions, data elements |
|
|
176
|
+
| `browser_resolve_element` | Semantic element lookup with confidence scoring |
|
|
177
|
+
| `browser_smart_click` | Click by natural language description |
|
|
178
|
+
| `browser_suggest_actions` | Context-aware action recommendations |
|
|
179
|
+
| `browser_explore` | Autonomous site crawl with page classification |
|
|
180
|
+
| `browser_wait_until_stable` | Multi-signal page readiness detection |
|
|
181
|
+
| `browser_login` | Composite login flow with auto-detection |
|
|
182
|
+
| `browser_fill_and_submit` | Composite form fill and submit |
|
|
183
|
+
| `browser_extract` | **NEW** Schema-driven structured data extraction |
|
|
184
|
+
| `browser_go` | **NEW** Intent-based navigation ("go to settings") |
|
|
185
|
+
| `browser_wait_for` | **NEW** Semantic condition waiting ("results loaded") |
|
|
186
|
+
| `browser_workflow` | **NEW** On-demand workflow context |
|
|
187
|
+
|
|
188
|
+
### Credential Vault (5 tools)
|
|
189
|
+
|
|
190
|
+
| Tool | Description |
|
|
191
|
+
|------|-------------|
|
|
192
|
+
| `vault_store` | Store encrypted credential profile (AES-256-GCM + PBKDF2) |
|
|
193
|
+
| `vault_list` | List profile names and timestamps (no values) |
|
|
194
|
+
| `vault_delete` | Delete a credential profile |
|
|
195
|
+
| `vault_login` | Login using a vault profile (blind injection) |
|
|
196
|
+
| `vault_inject` | Fill form fields from vault without submitting |
|
|
153
197
|
|
|
154
|
-
###
|
|
198
|
+
### Observation & Debugging (10 tools)
|
|
155
199
|
|
|
156
|
-
|
|
157
|
-
|------|-------------|
|
|
158
|
-
| `browser_mock_route` | Intercept requests matching a URL pattern and return mock responses |
|
|
159
|
-
| `browser_list_mocks` / `browser_clear_mocks` | Manage active mock routes |
|
|
200
|
+
`browser_screenshot`, `browser_snapshot`, `browser_evaluate`, `browser_console_messages`, `browser_network_requests`, `browser_diagnose`, `browser_error_report`, `browser_snapshot_state` / `browser_diff_state`, `browser_action_history`
|
|
160
201
|
|
|
161
|
-
###
|
|
202
|
+
### Storage & State (6 tools)
|
|
162
203
|
|
|
163
|
-
|
|
164
|
-
|------|-------------|
|
|
165
|
-
| `browser_health_check` | Verify the browser is responsive |
|
|
166
|
-
| `browser_recover` | Auto-recover from crashes by relaunching and restoring the last URL |
|
|
204
|
+
`browser_get_cookies` / `browser_set_cookie`, `browser_get_localstorage` / `browser_set_localstorage`, `browser_clear_storage`, `browser_clean_slate`
|
|
167
205
|
|
|
168
|
-
|
|
206
|
+
### Test Automation (12 tools)
|
|
169
207
|
|
|
170
|
-
|
|
208
|
+
`test_scenario_run`, `test_scenario_status`, `test_assert`, `test_fill_form`, `test_auth_flow`, `test_watch_events` / `test_stop_watch`, `test_accessibility_audit`, `browser_performance_audit`, `test_generate_assertions`, `test_chaos` / `test_chaos_clear`
|
|
171
209
|
|
|
172
|
-
|
|
210
|
+
### Session & Visual (5 tools)
|
|
173
211
|
|
|
174
|
-
|
|
212
|
+
`session_start` / `session_end` / `session_list`, `session_export_playwright`, `visual_baseline` / `visual_compare`
|
|
175
213
|
|
|
176
|
-
|
|
177
|
-
{
|
|
178
|
-
"name": "Login Flow",
|
|
179
|
-
"steps": [
|
|
180
|
-
{ "name": "Navigate", "action": "navigate", "url": "http://localhost:3000/login" },
|
|
181
|
-
{ "name": "Enter email", "action": "type", "selector": "input[type='email']", "value": "user@test.com" },
|
|
182
|
-
{ "name": "Enter password", "action": "type", "selector": "input[type='password']", "value": "secret" },
|
|
183
|
-
{ "name": "Submit", "action": "click", "selector": "button[type='submit']" },
|
|
184
|
-
{ "name": "Verify redirect", "action": "assert", "type": "urlContains", "expected": "/dashboard" },
|
|
185
|
-
{ "name": "Capture result", "action": "screenshot", "screenshotName": "post-login" }
|
|
186
|
-
]
|
|
187
|
-
}
|
|
188
|
-
```
|
|
214
|
+
### Request Mocking (3 tools)
|
|
189
215
|
|
|
190
|
-
|
|
216
|
+
`browser_mock_route`, `browser_list_mocks`, `browser_clear_mocks`
|
|
191
217
|
|
|
192
|
-
|
|
193
|
-
{
|
|
194
|
-
"name": "Login Flow (smart)",
|
|
195
|
-
"steps": [
|
|
196
|
-
{ "name": "Navigate", "action": "navigate", "url": "http://localhost:3000/login" },
|
|
197
|
-
{ "name": "Enter email", "action": "type", "query": "email input", "value": "user@test.com" },
|
|
198
|
-
{ "name": "Enter password", "action": "type", "query": "password field", "value": "secret" },
|
|
199
|
-
{ "name": "Submit", "action": "click", "query": "sign in button" },
|
|
200
|
-
{ "name": "Verify redirect", "action": "assert", "type": "urlContains", "expected": "/dashboard" }
|
|
201
|
-
]
|
|
202
|
-
}
|
|
203
|
-
```
|
|
218
|
+
### Reliability (2 tools)
|
|
204
219
|
|
|
205
|
-
|
|
220
|
+
`browser_health_check`, `browser_recover`
|
|
206
221
|
|
|
207
|
-
|
|
222
|
+
---
|
|
208
223
|
|
|
209
|
-
|
|
210
|
-
{ "name": "Submit", "action": "click", "selector": "button.btn-login", "query": "the login button" }
|
|
211
|
-
```
|
|
224
|
+
## Deploy to Azure
|
|
212
225
|
|
|
213
|
-
|
|
226
|
+
Looking Glass can be deployed as a cloud service on Azure Container Apps with persistent sessions, encrypted credential storage, and enterprise security.
|
|
214
227
|
|
|
215
|
-
|
|
228
|
+
### Prerequisites
|
|
216
229
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
230
|
+
- [Terraform](https://terraform.io) >= 1.5
|
|
231
|
+
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/) authenticated
|
|
232
|
+
- [Docker](https://docker.com)
|
|
220
233
|
|
|
221
|
-
|
|
222
|
-
{ "name": "Fill signup", "action": "fill_form", "fields": { "Email": "test@co.com", "Name": "Jane" }, "selector": "button.submit" }
|
|
223
|
-
```
|
|
234
|
+
### Quick Deploy
|
|
224
235
|
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
|
|
236
|
+
```bash
|
|
237
|
+
# 1. Build and push the Docker image
|
|
238
|
+
cd deploy/azure
|
|
239
|
+
cp terraform.tfvars.example terraform.tfvars
|
|
240
|
+
# Edit terraform.tfvars with your API key (32+ chars required)
|
|
228
241
|
|
|
229
|
-
|
|
242
|
+
terraform init
|
|
243
|
+
terraform apply
|
|
230
244
|
|
|
231
|
-
|
|
245
|
+
# 2. Build and push the image to ACR
|
|
246
|
+
bash build-and-push.sh
|
|
232
247
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
"name": "Login with {{role}} user",
|
|
236
|
-
"steps": [
|
|
237
|
-
{ "name": "Enter email", "action": "type", "query": "email input", "value": "{{username}}" },
|
|
238
|
-
{ "name": "Enter password", "action": "type", "query": "password field", "value": "{{password}}" },
|
|
239
|
-
{ "name": "Submit", "action": "click", "query": "sign in button" },
|
|
240
|
-
{ "name": "Verify", "action": "assert", "type": "urlContains", "expected": "{{expectedUrl}}" }
|
|
241
|
-
],
|
|
242
|
-
"dataSets": [
|
|
243
|
-
{ "label": "admin", "variables": { "role": "admin", "username": "admin@co.com", "password": "Admin1!", "expectedUrl": "/dashboard" } },
|
|
244
|
-
{ "label": "viewer", "variables": { "role": "viewer", "username": "view@co.com", "password": "View1!", "expectedUrl": "/readonly" } },
|
|
245
|
-
{ "label": "invalid", "variables": { "role": "invalid", "username": "bad@co.com", "password": "wrong", "expectedUrl": "/login" } }
|
|
246
|
-
]
|
|
247
|
-
}
|
|
248
|
+
# 3. Access your instance
|
|
249
|
+
terraform output container_app_url
|
|
248
250
|
```
|
|
249
251
|
|
|
250
|
-
###
|
|
252
|
+
### What Gets Deployed
|
|
251
253
|
|
|
252
|
-
|
|
254
|
+
| Resource | Purpose |
|
|
255
|
+
|----------|---------|
|
|
256
|
+
| Azure Container Registry | Docker image storage |
|
|
257
|
+
| Azure Container Apps | Runs Looking Glass (scale-to-zero) |
|
|
258
|
+
| Azure Key Vault | Stores API key and vault encryption key |
|
|
259
|
+
| Azure Files | Persistent session data and credentials |
|
|
260
|
+
| Log Analytics | Container logs (90-day retention) |
|
|
261
|
+
| Managed Identity | Secure auth between services (no passwords) |
|
|
253
262
|
|
|
254
|
-
|
|
263
|
+
### Security Features
|
|
255
264
|
|
|
256
|
-
**
|
|
265
|
+
- **HTTPS** -- Azure Container Apps provides automatic TLS termination
|
|
266
|
+
- **API key required** -- 32+ character key, stored in Key Vault
|
|
267
|
+
- **Managed Identity** -- ACR pull and Key Vault access without stored credentials
|
|
268
|
+
- **Non-root container** -- Runs as unprivileged `lglass` user
|
|
269
|
+
- **Rate limiting** -- 120 req/min per IP, auth lockout after 5 failures
|
|
270
|
+
- **Audit logging** -- Every tool call, auth event, and session lifecycle logged
|
|
257
271
|
|
|
258
|
-
|
|
272
|
+
### Docker (standalone)
|
|
259
273
|
|
|
260
|
-
|
|
274
|
+
```bash
|
|
275
|
+
docker build -t looking-glass .
|
|
276
|
+
docker run -p 8080:8080 \
|
|
277
|
+
-e MCP_API_KEY=your-secret-key-at-least-32-chars \
|
|
278
|
+
-v looking-glass-data:/data \
|
|
279
|
+
looking-glass
|
|
280
|
+
```
|
|
261
281
|
|
|
262
|
-
|
|
282
|
+
---
|
|
263
283
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
| `BROWSER_ENGINE` | `chromium` | Browser engine: `chromium`, `firefox`, or `webkit` |
|
|
268
|
-
| `BROWSER_VIEWPORT_WIDTH` | `1280` | Viewport width in pixels |
|
|
269
|
-
| `BROWSER_VIEWPORT_HEIGHT` | `720` | Viewport height in pixels |
|
|
270
|
-
| `BROWSER_TIMEOUT` | `30000` | Default operation timeout (ms) |
|
|
271
|
-
| `BROWSER_SESSIONS_DIR` | `.browser-sessions` | Where screenshots, sessions, and audit logs are stored |
|
|
272
|
-
| `BROWSER_SECURITY_PROFILE` | `local-dev` | Security profile (see below) |
|
|
273
|
-
| `BROWSER_CHANNEL` | — | Specific browser channel (`chrome`, `msedge`) |
|
|
274
|
-
| `BROWSER_PROXY_URL` | — | HTTP/HTTPS/SOCKS5 proxy for corporate environments |
|
|
275
|
-
| `BROWSER_CA_CERT_PATH` | — | Path to custom CA certificate |
|
|
284
|
+
## Security
|
|
285
|
+
|
|
286
|
+
See [SECURITY.md](SECURITY.md) for the full security model.
|
|
276
287
|
|
|
277
288
|
### Security Profiles
|
|
278
289
|
|
|
279
290
|
| Profile | URL Access | JS Execution | Tool Access | Rate Limit |
|
|
280
291
|
|---------|-----------|--------------|-------------|------------|
|
|
292
|
+
| `restricted` (default) | localhost only | Blocked | Observation only | 30/min |
|
|
281
293
|
| `local-dev` | All HTTP/HTTPS | Allowed | All tools | 60/min |
|
|
282
|
-
| `restricted` | localhost only | Blocked | Observation only | 30/min |
|
|
283
294
|
| `open` | Everything | Allowed | All tools | 120/min |
|
|
295
|
+
| `sandbox` | Blocked | Blocked | Observation only | 10/min |
|
|
296
|
+
|
|
297
|
+
### HTTP Transport Security
|
|
298
|
+
|
|
299
|
+
- API key **required** in HTTP mode (server exits if unset)
|
|
300
|
+
- Timing-safe key comparison (no side-channel leakage)
|
|
301
|
+
- Per-IP rate limiting with auth failure lockout (5 failures = 60s ban)
|
|
302
|
+
- Session IDs via cryptographic `randomUUID()`
|
|
303
|
+
|
|
304
|
+
### Credential Vault
|
|
305
|
+
|
|
306
|
+
- AES-256-GCM encryption with PBKDF2 key derivation (100k iterations, SHA-512)
|
|
307
|
+
- Field names and values encrypted together (no metadata leakage)
|
|
308
|
+
- Vault file permissions restricted to owner (`0600`)
|
|
309
|
+
- Agent never sees plaintext credentials -- blind injection only
|
|
310
|
+
- `createdAt` and `lastUsedAt` tracking per profile
|
|
284
311
|
|
|
285
|
-
|
|
312
|
+
### Audit Trail
|
|
313
|
+
|
|
314
|
+
Every operation is logged to `audit/audit-YYYY-MM-DD.jsonl`:
|
|
315
|
+
- Tool calls with deep-redacted arguments
|
|
316
|
+
- Auth successes and failures (with client IP)
|
|
317
|
+
- Session start/end events
|
|
318
|
+
- Policy violations
|
|
319
|
+
- 20+ sensitive field patterns redacted recursively
|
|
286
320
|
|
|
287
321
|
---
|
|
288
322
|
|
|
289
|
-
##
|
|
323
|
+
## Configuration
|
|
290
324
|
|
|
291
|
-
|
|
292
|
-
graph TD
|
|
293
|
-
A[Claude Code] -->|MCP stdio| B[Looking Glass]
|
|
294
|
-
B -->|Playwright API| C[Browser Engine]
|
|
295
|
-
C -->|Screenshots + DOM| B
|
|
296
|
-
B -->|Inline images + text| A
|
|
325
|
+
All configuration is through environment variables.
|
|
297
326
|
|
|
298
|
-
|
|
299
|
-
D --> E[Audit Logger]
|
|
300
|
-
D --> F[RBAC Policy]
|
|
327
|
+
### Browser
|
|
301
328
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
329
|
+
| Variable | Default | Description |
|
|
330
|
+
|----------|---------|-------------|
|
|
331
|
+
| `BROWSER_HEADLESS` | `true` | Set to `false` to display the browser window |
|
|
332
|
+
| `BROWSER_ENGINE` | `chromium` | `chromium`, `firefox`, or `webkit` |
|
|
333
|
+
| `BROWSER_VIEWPORT_WIDTH` | `1280` | Viewport width in pixels |
|
|
334
|
+
| `BROWSER_VIEWPORT_HEIGHT` | `720` | Viewport height in pixels |
|
|
335
|
+
| `BROWSER_TIMEOUT` | `30000` | Default operation timeout (ms) |
|
|
336
|
+
| `BROWSER_SESSIONS_DIR` | `.browser-sessions` | Directory for data storage |
|
|
337
|
+
| `BROWSER_SECURITY_PROFILE` | `restricted` | Security profile |
|
|
338
|
+
| `BROWSER_CHANNEL` | | Browser channel (`chrome`, `msedge`) |
|
|
339
|
+
| `BROWSER_ENGINE` | `chromium` | Browser engine |
|
|
340
|
+
| `BROWSER_PROXY_URL` | | HTTP/HTTPS/SOCKS5 proxy |
|
|
341
|
+
| `BROWSER_VISUAL_THRESHOLD` | `0.1` | Pixel comparison threshold (increase for Firefox/WebKit) |
|
|
342
|
+
| `BROWSER_PERSISTENT_CONTEXT` | `false` | Persist cookies/localStorage across restarts |
|
|
343
|
+
| `BROWSER_USER_DATA_DIR` | `.browser-data` | User data directory for persistent context |
|
|
344
|
+
|
|
345
|
+
### Transport
|
|
346
|
+
|
|
347
|
+
| Variable | Default | Description |
|
|
348
|
+
|----------|---------|-------------|
|
|
349
|
+
| `MCP_TRANSPORT` | `stdio` | `stdio` (local) or `http` (cloud) |
|
|
350
|
+
| `MCP_HTTP_PORT` | `8080` | HTTP server port |
|
|
351
|
+
| `MCP_API_KEY` | | **Required in HTTP mode.** Minimum 32 characters. |
|
|
305
352
|
|
|
306
|
-
|
|
353
|
+
### Vault
|
|
354
|
+
|
|
355
|
+
| Variable | Default | Description |
|
|
356
|
+
|----------|---------|-------------|
|
|
357
|
+
| `VAULT_ENCRYPTION_KEY` | | Passphrase for credential encryption (32+ chars). Key derived via PBKDF2. |
|
|
307
358
|
|
|
308
359
|
---
|
|
309
360
|
|
|
310
|
-
##
|
|
361
|
+
## Test Scenarios
|
|
362
|
+
|
|
363
|
+
`test_scenario_run` executes multi-step test flows defined in JSON with three targeting strategies:
|
|
311
364
|
|
|
312
|
-
|
|
365
|
+
- **`selector`** -- CSS selectors (fast, exact)
|
|
366
|
+
- **`query`** -- natural language resolution via accessibility tree (resilient to DOM changes)
|
|
367
|
+
- **Both** -- self-healing: selector tried first, query as fallback
|
|
313
368
|
|
|
314
|
-
|
|
369
|
+
### Example: Self-Healing Login
|
|
315
370
|
|
|
371
|
+
```json
|
|
372
|
+
{
|
|
373
|
+
"name": "Login Flow",
|
|
374
|
+
"steps": [
|
|
375
|
+
{ "name": "Navigate", "action": "navigate", "url": "http://localhost:3000/login" },
|
|
376
|
+
{ "name": "Email", "action": "type", "selector": "input[type='email']", "query": "email input", "value": "user@test.com" },
|
|
377
|
+
{ "name": "Password", "action": "type", "selector": "input[type='password']", "query": "password field", "value": "secret" },
|
|
378
|
+
{ "name": "Submit", "action": "click", "selector": "button[type='submit']", "query": "sign in button" },
|
|
379
|
+
{ "name": "Verify", "action": "assert", "type": "urlContains", "expected": "/dashboard" }
|
|
380
|
+
]
|
|
381
|
+
}
|
|
316
382
|
```
|
|
317
|
-
|
|
383
|
+
|
|
384
|
+
### Data-Driven Testing
|
|
385
|
+
|
|
386
|
+
```json
|
|
387
|
+
{
|
|
388
|
+
"name": "Login as {{role}}",
|
|
389
|
+
"steps": [
|
|
390
|
+
{ "name": "Email", "action": "type", "query": "email input", "value": "{{username}}" },
|
|
391
|
+
{ "name": "Password", "action": "type", "query": "password field", "value": "{{password}}" },
|
|
392
|
+
{ "name": "Submit", "action": "click", "query": "sign in button" },
|
|
393
|
+
{ "name": "Verify", "action": "assert", "type": "urlContains", "expected": "{{expectedUrl}}" }
|
|
394
|
+
],
|
|
395
|
+
"dataSets": [
|
|
396
|
+
{ "label": "admin", "variables": { "role": "admin", "username": "admin@co.com", "password": "Admin1!", "expectedUrl": "/dashboard" } },
|
|
397
|
+
{ "label": "viewer", "variables": { "role": "viewer", "username": "view@co.com", "password": "View1!", "expectedUrl": "/readonly" } }
|
|
398
|
+
]
|
|
399
|
+
}
|
|
318
400
|
```
|
|
319
401
|
|
|
320
|
-
|
|
402
|
+
**18 step actions:** `navigate`, `click`, `type`, `select`, `hover`, `scroll`, `press`, `waitForSelector`, `waitForText`, `waitForNavigation`, `waitForNetworkIdle`, `assert`, `screenshot`, `evaluate`, `sleep`, `login`, `fill_form`, `wait_stable`
|
|
321
403
|
|
|
322
|
-
|
|
404
|
+
**12 assertion types:** `exists`, `notExists`, `textContains`, `textEquals`, `hasAttribute`, `hasClass`, `isVisible`, `isEnabled`, `urlContains`, `urlEquals`, `countEquals`, `consoleNoErrors`
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Architecture
|
|
323
409
|
|
|
324
410
|
```
|
|
325
|
-
|
|
411
|
+
MCP Client (Claude, Copilot, etc.)
|
|
412
|
+
|
|
|
413
|
+
| stdio or HTTP (StreamableHTTP)
|
|
414
|
+
v
|
|
415
|
+
+-------------------------------------------+
|
|
416
|
+
| Looking Glass v3.0 |
|
|
417
|
+
| |
|
|
418
|
+
| Middleware Layer (automatic) |
|
|
419
|
+
| - Change Detection (pre/post snapshot) |
|
|
420
|
+
| - Workflow Tracking (page state machine) |
|
|
421
|
+
| - Self-Healing Resolution |
|
|
422
|
+
| - Audit Logging (deep redaction) |
|
|
423
|
+
| - RBAC Policy Enforcement |
|
|
424
|
+
| |
|
|
425
|
+
| 72 Tools |
|
|
426
|
+
| - Intelligence (extract, go, wait_for) |
|
|
427
|
+
| - Interaction (click, type, hover) |
|
|
428
|
+
| - Observation (screenshot, snapshot) |
|
|
429
|
+
| - Testing (scenarios, assertions) |
|
|
430
|
+
| - Vault (store, inject, login) |
|
|
431
|
+
| |
|
|
432
|
+
| Browser Manager |
|
|
433
|
+
| - Playwright (Chromium/Firefox/WebKit) |
|
|
434
|
+
| - Persistent context (optional) |
|
|
435
|
+
| - Console/network tracking |
|
|
436
|
+
+-------------------------------------------+
|
|
437
|
+
|
|
|
438
|
+
| Playwright API
|
|
439
|
+
v
|
|
440
|
+
Browser Engine
|
|
326
441
|
```
|
|
327
442
|
|
|
328
|
-
It will navigate, screenshot, discover pages, run assertions, check for JS errors, audit accessibility, and generate a pass/fail report.
|
|
329
|
-
|
|
330
443
|
---
|
|
331
444
|
|
|
332
445
|
## Development
|
|
333
446
|
|
|
334
447
|
```bash
|
|
335
|
-
git clone
|
|
336
|
-
cd
|
|
448
|
+
git clone https://github.com/Sahib-Sawhney-WH/LookingGlass.git
|
|
449
|
+
cd LookingGlass
|
|
337
450
|
npm install
|
|
338
451
|
npx playwright install chromium
|
|
339
452
|
npm run build
|
|
453
|
+
npm test
|
|
340
454
|
npm start
|
|
341
455
|
```
|
|
342
456
|
|