@yusufffararatt/dombridge-mcp 2.7.5
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 +559 -0
- package/bin/cli.js +88 -0
- package/package.json +54 -0
- package/src/bridge/http-server.js +290 -0
- package/src/bridge/middleware.js +56 -0
- package/src/bridge/routes.js +1003 -0
- package/src/bridge-daemon.js +172 -0
- package/src/cli/auto-config.js +120 -0
- package/src/constants.js +13 -0
- package/src/index.js +279 -0
- package/src/mcp-bridge.js +136 -0
- package/src/metrics/error-codes.js +44 -0
- package/src/metrics/index.js +3 -0
- package/src/metrics/metrics-db.js +269 -0
- package/src/metrics/metrics-recorder.js +240 -0
- package/src/metrics/metrics-report.js +146 -0
- package/src/profiles/profile-db.js +159 -0
- package/src/profiles/profile-enricher.js +333 -0
- package/src/profiles/profile-manager.js +563 -0
- package/src/profiles/profile-repo.js +183 -0
- package/src/state/bridge-client.js +272 -0
- package/src/state/bridge-persistence.js +205 -0
- package/src/state/cache.js +38 -0
- package/src/state/extension-state.js +321 -0
- package/src/tools/action_tools.js +218 -0
- package/src/tools/analyze-page.js +247 -0
- package/src/tools/debug-mcp-state.js +172 -0
- package/src/tools/discover-apis.js +186 -0
- package/src/tools/execute-js.js +284 -0
- package/src/tools/export-session.js +171 -0
- package/src/tools/extract-data.js +395 -0
- package/src/tools/get-element.js +281 -0
- package/src/tools/get-network-trace.js +471 -0
- package/src/tools/index.js +110 -0
- package/src/tools/manage-site-profile.js +153 -0
- package/src/tools/paginate.js +444 -0
- package/src/tools/quick-scan.js +418 -0
- package/src/tools/screenshot_tools.js +117 -0
- package/src/utils/circuit-breaker.js +112 -0
- package/src/utils/extract-density.js +21 -0
- package/src/utils/logger.js +31 -0
- package/src/utils/paginate-detector.js +24 -0
- package/src/utils/rate-limiter.js +244 -0
- package/src/utils/run-script.js +37 -0
- package/src/utils/selector-validator.js +95 -0
- package/src/utils/state-validator.js +354 -0
- package/src/utils/tab-resolver.js +70 -0
- package/src/utils/workflow-helper.js +292 -0
- package/src/utils/workflow-state.js +177 -0
package/README.md
ADDED
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
# DOMBridge - MCP Server
|
|
2
|
+
|
|
3
|
+
Model Context Protocol (MCP) server for the DOMBridge Chrome extension. Provides programmatic access to extension features via 13 MCP tools for AI assistants and automation workflows.
|
|
4
|
+
|
|
5
|
+
**Version:** 2.7.5
|
|
6
|
+
**Protocol:** MCP 1.0
|
|
7
|
+
**License:** Proprietary - All Rights Reserved
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
This MCP server acts as a bridge between AI assistants and the DOMBridge extension. It exposes **13 tools** that enable:
|
|
12
|
+
|
|
13
|
+
- DOM element selection and analysis
|
|
14
|
+
- Network request tracing (REST, WebSocket, GraphQL)
|
|
15
|
+
- Data source detection (API, SSR, Initial State)
|
|
16
|
+
- JavaScript execution in page or background context (with opt-in CSP bypass)
|
|
17
|
+
- Autonomous RPA actions (click, type, scroll, pressKey)
|
|
18
|
+
- Site profiling and change detection
|
|
19
|
+
- Session export for Playwright handoff
|
|
20
|
+
- Screenshot capture
|
|
21
|
+
|
|
22
|
+
The server works with any MCP-compatible client (Claude Desktop, Cursor, Windsurf, custom MCP clients, etc.).
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- **13 Smart Tools**: Context-aware API for web analysis, RPA, site profiling, and session management
|
|
27
|
+
- **CLI Support**: Professional command-line interface (`npx @yusufffararatt/dombridge-mcp`)
|
|
28
|
+
- **HTTP Bridge**: REST endpoint for extension communication (port 3101)
|
|
29
|
+
- **Heartbeat System**: 15s interval connection monitoring with stale detection
|
|
30
|
+
- **Singleton Gateway**: Prevents port conflicts between multiple agent instances
|
|
31
|
+
- **Circuit Breakers**: CLOSED→OPEN after 3 failures, auto-recovery after 30s, per-tool isolation
|
|
32
|
+
- **Graceful Shutdown**: Clean process termination on SIGINT/SIGTERM
|
|
33
|
+
- **Workflow Validation**: Built-in validators prevent common usage errors
|
|
34
|
+
- **Rate Limiting**: Protects against request flooding
|
|
35
|
+
- **Auto-Config**: One command to configure Claude/Cursor/Windsurf (`--init`)
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
### Prerequisites
|
|
40
|
+
|
|
41
|
+
- Node.js 18 or higher
|
|
42
|
+
- DOMBridge Chrome extension installed
|
|
43
|
+
|
|
44
|
+
### Setup
|
|
45
|
+
|
|
46
|
+
**Option A: NPM (Recommended)**
|
|
47
|
+
```bash
|
|
48
|
+
# Run directly with npx (no installation needed)
|
|
49
|
+
npx @yusufffararatt/dombridge-mcp
|
|
50
|
+
|
|
51
|
+
# Or auto-configure your AI agent config files
|
|
52
|
+
npx @yusufffararatt/dombridge-mcp --init
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Option B: From Source**
|
|
56
|
+
```bash
|
|
57
|
+
cd mcp-server
|
|
58
|
+
npm install
|
|
59
|
+
npm start
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### CLI Options
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
@yusufffararatt/dombridge-mcp # Start with default port (3101)
|
|
66
|
+
@yusufffararatt/dombridge-mcp --port 3200 # Start on custom port
|
|
67
|
+
@yusufffararatt/dombridge-mcp --init # Auto-configure AI agent config files
|
|
68
|
+
@yusufffararatt/dombridge-mcp --debug # Enable verbose logging
|
|
69
|
+
@yusufffararatt/dombridge-mcp --version # Show version
|
|
70
|
+
@yusufffararatt/dombridge-mcp --help # Show help
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Environment Variables
|
|
74
|
+
|
|
75
|
+
- `MCP_PORT` or `PORT`: HTTP bridge port (default: 3101)
|
|
76
|
+
- `MCP_DEBUG`: Enable debug logging (`1` to enable)
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
### Starting the Server
|
|
81
|
+
|
|
82
|
+
**IMPORTANT: Do NOT start the server manually with `npm start`.**
|
|
83
|
+
|
|
84
|
+
The MCP server is designed to be started automatically by AI assistants (Claude Code, Cursor, Antigravity, etc.) when they launch. Starting it manually will cause port conflicts.
|
|
85
|
+
|
|
86
|
+
The server will auto-start when your AI assistant launches:
|
|
87
|
+
```
|
|
88
|
+
[MCP Server] DOMBridge MCP server started successfully
|
|
89
|
+
[MCP Server] Version: 2.7.5
|
|
90
|
+
[MCP Server] Available tools: 13
|
|
91
|
+
[MCP Bridge] HTTP server started on port 3101 (PRIMARY)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Connection Requirement:** For the extension to connect to the MCP server, you must select an element in the browser first. Open any webpage, click the extension icon, click "Select Element", and click any element on the page.
|
|
95
|
+
|
|
96
|
+
### Connecting MCP Clients
|
|
97
|
+
|
|
98
|
+
The server uses stdio transport for MCP communication. Configure your MCP client to auto-start the server.
|
|
99
|
+
|
|
100
|
+
**Claude Code / Claude Desktop:**
|
|
101
|
+
|
|
102
|
+
Edit `~/.config/claude/mcp.json` (macOS/Linux) or `%APPDATA%\Claude\mcp.json` (Windows):
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"mcpServers": {
|
|
107
|
+
"dombridge": {
|
|
108
|
+
"command": "npx",
|
|
109
|
+
"args": ["-y", "@yusufffararatt/dombridge-mcp"]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Cursor / Other MCP Clients:**
|
|
116
|
+
|
|
117
|
+
Configure your client's MCP settings to execute:
|
|
118
|
+
```bash
|
|
119
|
+
npx -y @yusufffararatt/dombridge-mcp
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Available Tools (13)
|
|
123
|
+
|
|
124
|
+
| Tool Name | Description | Workflow Position |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| `quick_scan` | One-call context bootstrap — analyze + profile check + discovery in one step | First Step |
|
|
127
|
+
| `analyze_page` | Detect frameworks, SSR data, element counts (+ inline APIs with `includeApis:true`) | Autonomous |
|
|
128
|
+
| `discover_apis` | Full API list with filtering — use when analyze_page isn't enough | Autonomous |
|
|
129
|
+
| `extract_data` | Auto-extract `window.__*__PROPS` / SSR data / stores → JSON Schema + paths | Autonomous |
|
|
130
|
+
| `export_session` | Export cookies + auth tokens → Playwright handoff | Autonomous |
|
|
131
|
+
| `manage_site_profile` | Unified profile CRUD: `action` = load \| save \| check \| delete \| list \| update (replaces 3 old profile tools) | Profiling |
|
|
132
|
+
| `get_element` | Programmatic (css/xpath/text) OR manual element retrieval — unified | Element |
|
|
133
|
+
| `get_network_trace` | REST (default) or WebSocket (`protocol:'ws'`) trace for selected element | Tracing |
|
|
134
|
+
| `execute_js` | Run custom JavaScript in page or background context | Advanced |
|
|
135
|
+
| `execute_action` | RPA: click / type / scroll / pressKey | RPA |
|
|
136
|
+
| `paginate` | Multi-page / infinite scroll navigation (auto, button, scroll, url_increment) | Navigation |
|
|
137
|
+
| `capture_screenshot` | Viewport screenshot (use when actions fail visually) | Visual |
|
|
138
|
+
| `debug_mcp_state` | Internal state + tab IDs + circuit breaker status — troubleshooting only | Debug |
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Tool Reference
|
|
143
|
+
|
|
144
|
+
### `analyze_page`
|
|
145
|
+
|
|
146
|
+
Detect page structure, frameworks, SSR markers, and inline APIs.
|
|
147
|
+
|
|
148
|
+
**Parameters:**
|
|
149
|
+
- `includeApis` (boolean, optional): Include captured API list in output (default: false)
|
|
150
|
+
- `tabId` (number, optional): Target a specific tab. Omit for active tab.
|
|
151
|
+
|
|
152
|
+
### `discover_apis`
|
|
153
|
+
|
|
154
|
+
Get the full list of captured XHR/fetch/WebSocket calls with filtering.
|
|
155
|
+
|
|
156
|
+
**Parameters:**
|
|
157
|
+
- `urlPattern` (string, optional): Filter by URL substring or regex
|
|
158
|
+
- `method` (string, optional): Filter by HTTP method (`GET`, `POST`, `all`)
|
|
159
|
+
- `limit` (number, optional): Max results (default: 3, max: 20)
|
|
160
|
+
- `includeBody` (boolean, optional): Include request/response bodies
|
|
161
|
+
- `tabId` (number, optional): Target a specific tab
|
|
162
|
+
|
|
163
|
+
### `extract_data`
|
|
164
|
+
|
|
165
|
+
Auto-extract embedded data (`window.__*__PROPS`, SSR, Redux store) into JSON Schema with access paths.
|
|
166
|
+
|
|
167
|
+
**Parameters:**
|
|
168
|
+
- `tabId` (number, optional): Target a specific tab
|
|
169
|
+
|
|
170
|
+
### `export_session`
|
|
171
|
+
|
|
172
|
+
Export cookies and localStorage auth tokens for Playwright handoff.
|
|
173
|
+
|
|
174
|
+
**Parameters:**
|
|
175
|
+
- `tabId` (number, optional): Target a specific tab
|
|
176
|
+
|
|
177
|
+
### `manage_site_profile`
|
|
178
|
+
|
|
179
|
+
Unified profile management. Single tool with 6 actions: `load | save | check | delete | list | update`.
|
|
180
|
+
|
|
181
|
+
**Actions:**
|
|
182
|
+
- `load` — Read profile detail (with `domain`) or list all (no `domain`)
|
|
183
|
+
- `save` — Persist captured endpoints + notes/framework/pageType to DB. **BUG #1 fix:** endpoints whose hostname ≠ `domain` are dropped with a warn log
|
|
184
|
+
- `check` — Compare live capture vs saved profile → new/missing endpoints
|
|
185
|
+
- `delete` — Remove profile (cascade endpoints + paths)
|
|
186
|
+
- `list` — Most recently seen profiles (with `limit` param)
|
|
187
|
+
- `update` — Patch `notes` / `framework` / `pageType` without overwriting endpoints
|
|
188
|
+
|
|
189
|
+
**Parameters:**
|
|
190
|
+
- `action` (string, required): One of the 6 actions above
|
|
191
|
+
- `domain` (string, required for save/check/delete/update): Target domain
|
|
192
|
+
- `notes` (string, optional): For save/update
|
|
193
|
+
- `framework` (string, optional): For save/update
|
|
194
|
+
- `pageType` (string, optional): For save/update
|
|
195
|
+
- `limit` (number, optional, default 20): For list
|
|
196
|
+
|
|
197
|
+
**Storage:** SQLite at `~/.dombridge/profiles.db` (override with `PROFILE_DB_PATH` env).
|
|
198
|
+
|
|
199
|
+
### `get_element`
|
|
200
|
+
|
|
201
|
+
Unified tool: programmatically select an element by CSS/XPath/text, or retrieve the manually selected element.
|
|
202
|
+
|
|
203
|
+
**Parameters:**
|
|
204
|
+
- `css` (string, optional): CSS selector — preferred method
|
|
205
|
+
- `xpath` (string, optional): XPath expression
|
|
206
|
+
- `text` (string, optional): Exact visible text content (last resort — unreliable on nested DOM)
|
|
207
|
+
- `tabId` (number, optional): Target a specific tab
|
|
208
|
+
- `triggerNetworkTrace` (boolean, optional): Trigger network trace on selection (default: true)
|
|
209
|
+
|
|
210
|
+
Note: `selectorInfo` object is also accepted for backward compatibility:
|
|
211
|
+
- `selectorInfo.css` / `selectorInfo.xpath` / `selectorInfo.text`
|
|
212
|
+
|
|
213
|
+
**Returns:** Element data including CSS selector, XPath, tag, attributes, stable selector with confidence score.
|
|
214
|
+
|
|
215
|
+
### `get_network_trace`
|
|
216
|
+
|
|
217
|
+
Find API calls or WebSocket messages that populate the selected element.
|
|
218
|
+
|
|
219
|
+
**Prerequisites:** `get_element` must be called first.
|
|
220
|
+
|
|
221
|
+
**Parameters:**
|
|
222
|
+
- `protocol` (string, optional): `rest` (default), `ws`, or `all`
|
|
223
|
+
- `limit` (number, optional): Max results (default: 3)
|
|
224
|
+
- `minConfidence` (number, optional): Minimum confidence score (0.0–1.0, default: 0.5)
|
|
225
|
+
|
|
226
|
+
### `execute_js`
|
|
227
|
+
|
|
228
|
+
Execute custom JavaScript in the active tab's page context or in the extension service worker.
|
|
229
|
+
|
|
230
|
+
**Parameters:**
|
|
231
|
+
- `code` (string, required): JavaScript code to execute (max 10KB)
|
|
232
|
+
- `timeout` (number, optional): Timeout in ms (default: 5000, max: 30000)
|
|
233
|
+
- `context` (string, optional): `page` (default) or `background`. Background context: no DOM access, no CORS restrictions, can use `fetch` with credentials.
|
|
234
|
+
- `tabId` (number, optional): Target a specific tab
|
|
235
|
+
- `cspBypass` (boolean, optional): Enable domain-specific CSP bypass when the site blocks `new Function()`. Reloads the tab once and strips CSP headers for that domain only. Only use after a CSP error — do not set by default.
|
|
236
|
+
|
|
237
|
+
**Security:**
|
|
238
|
+
- Blocks `eval()` and `Function()`
|
|
239
|
+
- Blocks `setInterval` (memory leak risk)
|
|
240
|
+
- Size limit: 10KB
|
|
241
|
+
- Execution timeout enforced
|
|
242
|
+
|
|
243
|
+
**Note:** This tool is BLOCKING. It waits up to the configured timeout for the result from Chrome. You do not need a separate call to retrieve results.
|
|
244
|
+
|
|
245
|
+
### `execute_action`
|
|
246
|
+
|
|
247
|
+
Perform safe, autonomous interactions with a Chrome tab.
|
|
248
|
+
|
|
249
|
+
**Parameters:**
|
|
250
|
+
- `actionType` (string, required): `click`, `type`, `scroll`, or `pressKey`
|
|
251
|
+
- `selectorInfo` (object, required): `{ css?: string, xpath?: string, text?: string }`. Prefer `css` or `xpath`.
|
|
252
|
+
- `url` (string, required): Current page URL (for safety validation)
|
|
253
|
+
- `text` (string, optional): Text to type (only for `actionType: 'type'`)
|
|
254
|
+
|
|
255
|
+
**Best Practice:** Always call `execute_js` first to validate your selector before calling `execute_action`.
|
|
256
|
+
|
|
257
|
+
**Security:** Blocked from password fields, banking, and crypto pipeline environments.
|
|
258
|
+
|
|
259
|
+
### `capture_screenshot`
|
|
260
|
+
|
|
261
|
+
Capture a viewport screenshot of the active tab.
|
|
262
|
+
|
|
263
|
+
**Parameters:**
|
|
264
|
+
- `tabId` (number, optional): Target a specific tab
|
|
265
|
+
|
|
266
|
+
### `debug_mcp_state`
|
|
267
|
+
|
|
268
|
+
Return the MCP server's internal state: connection status, selected element, network trace summary, tab IDs, circuit breaker status.
|
|
269
|
+
|
|
270
|
+
**Parameters:** None
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Common Workflows
|
|
275
|
+
|
|
276
|
+
**REST API Discovery (autonomous):**
|
|
277
|
+
```
|
|
278
|
+
analyze_page({ includeApis: true })
|
|
279
|
+
→ get_element({ css: '.price' })
|
|
280
|
+
→ get_network_trace()
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**SSR / Embedded Data Extraction:**
|
|
284
|
+
```
|
|
285
|
+
analyze_page()
|
|
286
|
+
→ extract_data() # list window.__*__PROPS paths
|
|
287
|
+
→ execute_js({ code: "window.__PATH__.fieldName" }) # extract value
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**SSR fallback (when get_network_trace has no match):**
|
|
291
|
+
```
|
|
292
|
+
get_element({ css: '.price' })
|
|
293
|
+
→ get_network_trace() # returns "no match"
|
|
294
|
+
→ extract_data() # instead, list SSR paths
|
|
295
|
+
→ manage_site_profile({ action: 'save', domain: 'x.com' }) # persist schema
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**WebSocket Sites (Binance, X.com, TradingView):**
|
|
299
|
+
```
|
|
300
|
+
get_element()
|
|
301
|
+
→ get_network_trace({ protocol: 'ws' })
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**RPA Automation:**
|
|
305
|
+
```
|
|
306
|
+
execute_js({ code: "document.querySelector('button.submit') !== null" })
|
|
307
|
+
→ execute_action({ actionType: 'click', selectorInfo: { css: 'button.submit' }, url: '...' })
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**Multi-Page Scraping:**
|
|
311
|
+
```
|
|
312
|
+
paginate({ strategy: 'auto', limit: 10 })
|
|
313
|
+
→ execute_js({ code: "..." }) # extract data per page
|
|
314
|
+
→ manage_site_profile({ action: 'save', domain: 'x.com' }) # persist collected schema
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Session Export → Playwright Handoff:**
|
|
318
|
+
```
|
|
319
|
+
export_session()
|
|
320
|
+
# Returns: cookies + localStorage + sessionStorage
|
|
321
|
+
# Use in Playwright:
|
|
322
|
+
await context.addCookies(session.cookies);
|
|
323
|
+
await page.evaluate(ls => Object.entries(ls).forEach(...), session.localStorage);
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Multi-Tab:** Call `debug_mcp_state()` first to get tab IDs → pass `tabId: <n>` to any tool.
|
|
327
|
+
|
|
328
|
+
**Strict-CSP Sites (X.com, GitHub):**
|
|
329
|
+
```
|
|
330
|
+
execute_js({ code: "...", cspBypass: true })
|
|
331
|
+
# WARNING: tab reloads once, loses SPA state
|
|
332
|
+
# Only use after confirmed CSP error
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
**Timeout Recovery:**
|
|
336
|
+
```
|
|
337
|
+
# When execute_js times out on heavy DOM pages:
|
|
338
|
+
1. Lower timeout: execute_js({ code: "...", timeout: 3000 })
|
|
339
|
+
2. Use background context: execute_js({ code: "...", context: "background" })
|
|
340
|
+
3. Simplify code: break complex queries into steps
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Architecture
|
|
344
|
+
|
|
345
|
+
### Modular Structure
|
|
346
|
+
|
|
347
|
+
```
|
|
348
|
+
mcp-server/src/
|
|
349
|
+
├── index.js # Thin MCP client — connects to bridge daemon, registers 13 tools
|
|
350
|
+
├── bridge-daemon.js # Standalone bridge process (auto-spawned by index.js)
|
|
351
|
+
├── tools/ # Tool implementations
|
|
352
|
+
│ ├── analyze-page.js
|
|
353
|
+
│ ├── discover-apis.js
|
|
354
|
+
│ ├── extract-data.js
|
|
355
|
+
│ ├── export-session.js
|
|
356
|
+
│ ├── manage-site-profile.js
|
|
357
|
+
│ ├── get-element.js
|
|
358
|
+
│ ├── get-network-trace.js
|
|
359
|
+
│ ├── execute-js.js
|
|
360
|
+
│ ├── action_tools.js # execute_action
|
|
361
|
+
│ ├── screenshot_tools.js # capture_screenshot
|
|
362
|
+
│ ├── quick-scan.js # quick_scan
|
|
363
|
+
│ ├── paginate.js
|
|
364
|
+
│ ├── debug-mcp-state.js
|
|
365
|
+
│ └── index.js # Tool registry (allTools array)
|
|
366
|
+
├── bridge/ # HTTP server for extension communication
|
|
367
|
+
│ ├── http-server.js
|
|
368
|
+
│ ├── routes.js
|
|
369
|
+
│ └── middleware.js
|
|
370
|
+
├── state/ # State management
|
|
371
|
+
│ ├── extension-state.js # In-memory state (bridge daemon only)
|
|
372
|
+
│ ├── bridge-client.js # HTTP client — mirrors extensionData interface
|
|
373
|
+
│ └── bridge-persistence.js # Disk persistence (debounced write, atomic write)
|
|
374
|
+
└── utils/ # Shared utilities
|
|
375
|
+
├── circuit-breaker.js
|
|
376
|
+
├── state-validator.js
|
|
377
|
+
├── rate-limiter.js
|
|
378
|
+
├── run-script.js
|
|
379
|
+
├── tab-resolver.js
|
|
380
|
+
├── workflow-helper.js
|
|
381
|
+
├── workflow-state.js
|
|
382
|
+
├── selector-validator.js
|
|
383
|
+
└── logger.js
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### HTTP Bridge Endpoints
|
|
387
|
+
|
|
388
|
+
The server runs an Express HTTP server on port 3101 for extension communication:
|
|
389
|
+
|
|
390
|
+
| Method | Endpoint | Purpose |
|
|
391
|
+
|--------|----------|---------|
|
|
392
|
+
| `GET` | `/health` | Health check — returns connection status, data state, uptime |
|
|
393
|
+
| `GET` | `/api/sync-state` | Get full server state for secondary instance reconnect |
|
|
394
|
+
| `GET` | `/api/pending-requests` | Extension polls this to retrieve queued requests |
|
|
395
|
+
| `GET` | `/api/connection-status` | Connection status (connected, stale, heartbeat info) |
|
|
396
|
+
| `GET` | `/api/selected-element` | Selected element data |
|
|
397
|
+
| `GET` | `/api/page-analysis` | Page analysis data |
|
|
398
|
+
| `GET` | `/api/network-trace` | Network trace data |
|
|
399
|
+
| `GET` | `/api/websocket-trace` | WebSocket trace data |
|
|
400
|
+
| `GET` | `/api/state` | All state fields (including request/result for validation) |
|
|
401
|
+
| `GET` | `/api/result/:type` | Result polling with consume-on-read (atomic read + delete) |
|
|
402
|
+
| `POST` | `/api/element-selected` | Extension pushes selected element data |
|
|
403
|
+
| `POST` | `/api/network-trace` | Extension pushes REST network trace |
|
|
404
|
+
| `POST` | `/api/websocket-trace` | Extension pushes WebSocket trace |
|
|
405
|
+
| `POST` | `/api/saved-selections` | Extension pushes saved selections |
|
|
406
|
+
| `POST` | `/api/sync-all` | Extension syncs full state at once |
|
|
407
|
+
| `POST` | `/api/full-sync` | Extension pushes all state after detecting server restart |
|
|
408
|
+
| `POST` | `/api/ping` | Extension connection test |
|
|
409
|
+
| `POST` | `/api/heartbeat` | Extension heartbeat (every 15s) — returns pending request count, `needsRestore` flag |
|
|
410
|
+
| `POST` | `/api/disconnect` | Extension signals page unload or tab close |
|
|
411
|
+
| `POST` | `/api/page-analysis` | Extension pushes page analysis result |
|
|
412
|
+
| `POST` | `/api/execute-js` | Queue JS execution request / receive result |
|
|
413
|
+
| `POST` | `/api/execute-action` | Queue RPA action request / receive result |
|
|
414
|
+
| `POST` | `/api/capture-screenshot` | Queue screenshot request / receive result |
|
|
415
|
+
| `POST` | `/api/raw-network-requests` | Queue `discover_apis` request / receive result |
|
|
416
|
+
| `POST` | `/api/select-element` | Queue programmatic element selection / receive result |
|
|
417
|
+
| `POST` | `/api/export-session` | Queue session export request / receive result |
|
|
418
|
+
| `POST` | `/api/tabs` | Queue tab list request / receive result |
|
|
419
|
+
| `POST` | `/api/clear-request` | Extension signals a specific request was processed |
|
|
420
|
+
| `POST` | `/api/clear-all-requests` | Clear all pending content-script requests (on SW restart) |
|
|
421
|
+
| `POST` | `/api/die` | Graceful shutdown (localhost/extension origin only) |
|
|
422
|
+
|
|
423
|
+
### Health Check
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
curl http://localhost:3101/health
|
|
427
|
+
# Response: {"status":"ok","isConnected":true,...}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## Validation System
|
|
433
|
+
|
|
434
|
+
The server implements three validation layers:
|
|
435
|
+
|
|
436
|
+
1. **StateValidator**: Ensures data freshness (selected element expires after 10 minutes)
|
|
437
|
+
2. **RateLimiter**: Prevents request flooding
|
|
438
|
+
3. **WorkflowHelper**: Validates tool dependencies and execution order
|
|
439
|
+
|
|
440
|
+
When a validation error is returned, read the error message — it includes "REQUIRED STEPS" with explicit instructions on how to fix the issue.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Tool Response Format
|
|
445
|
+
|
|
446
|
+
All tools return:
|
|
447
|
+
```json
|
|
448
|
+
{
|
|
449
|
+
"content": [{ "type": "text", "text": "Tool output" }],
|
|
450
|
+
"isError": false
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
On error:
|
|
455
|
+
```json
|
|
456
|
+
{
|
|
457
|
+
"content": [{ "type": "text", "text": "Error: Description\nREQUIRED STEPS:\n1. ..." }],
|
|
458
|
+
"isError": true
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Adding a New Tool
|
|
465
|
+
|
|
466
|
+
1. Create `src/tools/my-new-tool.js`:
|
|
467
|
+
```javascript
|
|
468
|
+
export const myNewTool = {
|
|
469
|
+
name: 'my_new_tool',
|
|
470
|
+
description: 'What this tool does',
|
|
471
|
+
inputSchema: {
|
|
472
|
+
type: 'object',
|
|
473
|
+
properties: {
|
|
474
|
+
param1: { type: 'string', description: 'Parameter description' }
|
|
475
|
+
},
|
|
476
|
+
required: ['param1']
|
|
477
|
+
},
|
|
478
|
+
handler: async (args, bridgeClient) => {
|
|
479
|
+
// Use bridgeClient.refreshState() to get fresh state (called by index.js before each tool)
|
|
480
|
+
// Use bridgeClient.queueRequest(endpoint, data) to send requests
|
|
481
|
+
// Use bridgeClient.waitForResult(type, requestId, timeout) to poll for results
|
|
482
|
+
return { content: [{ type: 'text', text: 'Result' }] };
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
2. Register in `src/tools/index.js` → add to `allTools` array.
|
|
488
|
+
|
|
489
|
+
3. Document in this README's tools table.
|
|
490
|
+
|
|
491
|
+
4. Run `npm run sync-version` from the project root — auto-updates tool count in all docs.
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## Troubleshooting
|
|
496
|
+
|
|
497
|
+
### Extension Not Connected
|
|
498
|
+
|
|
499
|
+
`debug_mcp_state` returns `"extension": "disconnected"`:
|
|
500
|
+
1. Ensure Chrome extension is loaded: `chrome://extensions/`
|
|
501
|
+
2. Refresh the webpage where the extension is active
|
|
502
|
+
3. Select any element using the extension popup
|
|
503
|
+
4. Verify server is running: `curl http://localhost:3101/health`
|
|
504
|
+
|
|
505
|
+
### Port Already in Use
|
|
506
|
+
|
|
507
|
+
```
|
|
508
|
+
Error: listen EADDRINUSE: address already in use :::3101
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
# macOS/Linux
|
|
513
|
+
lsof -i :3101
|
|
514
|
+
# Windows
|
|
515
|
+
netstat -ano | findstr :3101
|
|
516
|
+
|
|
517
|
+
# Use a different port
|
|
518
|
+
export MCP_PORT=3200
|
|
519
|
+
npm start
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Stale Data Error
|
|
523
|
+
|
|
524
|
+
"Selected element data is stale (>10 minutes old)": call `get_element` again to refresh.
|
|
525
|
+
|
|
526
|
+
### CSP Errors on Strict-CSP Sites
|
|
527
|
+
|
|
528
|
+
`execute_js` returns a CSP error on X.com, GitHub, etc.: retry with `cspBypass: true`. This reloads the tab once and strips CSP headers for that domain only.
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## Performance
|
|
533
|
+
|
|
534
|
+
- **Tool Execution**: <100ms for most tools
|
|
535
|
+
- **Network Trace**: <500ms for typical traces (10–50 requests)
|
|
536
|
+
- **JavaScript Execution**: 100ms–5000ms depending on code complexity
|
|
537
|
+
- **State Freshness**: 10-minute cache for selected element data
|
|
538
|
+
|
|
539
|
+
## Security
|
|
540
|
+
|
|
541
|
+
- **Code Validation**: JavaScript executor blocks `eval()`, `Function()`, `setInterval`, XSS vectors, `globalThis['chrome']` bracket bypass
|
|
542
|
+
- **Timeout Enforcement**: Hard timeout on all JS execution (max 30s)
|
|
543
|
+
- **Size Limits**: Code max 10KB, result max 100KB
|
|
544
|
+
- **Rate Limiting**: Prevents request flooding
|
|
545
|
+
- **RPA Safety Guard**: Blocks password fields and sensitive environments
|
|
546
|
+
|
|
547
|
+
## License
|
|
548
|
+
|
|
549
|
+
This software is proprietary. All rights reserved.
|
|
550
|
+
|
|
551
|
+
Unauthorized copying, distribution, or modification is prohibited.
|
|
552
|
+
|
|
553
|
+
For licensing inquiries: dom.selector.api@gmail.com
|
|
554
|
+
|
|
555
|
+
## Support
|
|
556
|
+
|
|
557
|
+
- **Main README**: [../README.md](../README.md)
|
|
558
|
+
- **MCP Protocol**: [Model Context Protocol Specification](https://modelcontextprotocol.io)
|
|
559
|
+
- **Contact**: dom.selector.api@gmail.com
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* DOMBridge - MCP Server CLI
|
|
6
|
+
* Professional CLI entry point for the MCP server
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx @yusufffararatt/dombridge-mcp
|
|
10
|
+
* npx @yusufffararatt/dombridge-mcp --port 3200
|
|
11
|
+
* npx @yusufffararatt/dombridge-mcp --init
|
|
12
|
+
* npx @yusufffararatt/dombridge-mcp --debug
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { parseArgs } from 'node:util';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
import { dirname, join } from 'node:path';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = dirname(__filename);
|
|
22
|
+
const pkgPath = join(__dirname, '..', 'package.json');
|
|
23
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
24
|
+
|
|
25
|
+
// Parse CLI arguments
|
|
26
|
+
const { values: flags } = parseArgs({
|
|
27
|
+
options: {
|
|
28
|
+
port: { type: 'string', short: 'p', default: '3101' },
|
|
29
|
+
debug: { type: 'boolean', short: 'd', default: false },
|
|
30
|
+
version: { type: 'boolean', short: 'v', default: false },
|
|
31
|
+
help: { type: 'boolean', short: 'h', default: false },
|
|
32
|
+
init: { type: 'boolean', default: false },
|
|
33
|
+
},
|
|
34
|
+
strict: false,
|
|
35
|
+
allowPositionals: true,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// --version
|
|
39
|
+
if (flags.version) {
|
|
40
|
+
console.log(`dombridge-mcp v${pkg.version}`);
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// --help
|
|
45
|
+
if (flags.help) {
|
|
46
|
+
console.log(`
|
|
47
|
+
${pkg.name} v${pkg.version}
|
|
48
|
+
MCP Server for the DOMBridge Chrome extension
|
|
49
|
+
|
|
50
|
+
Usage:
|
|
51
|
+
npx ${pkg.name} Start with default port (3101)
|
|
52
|
+
npx ${pkg.name} --port 3200 Start on custom port
|
|
53
|
+
npx ${pkg.name} --init Auto-configure AI agent config files
|
|
54
|
+
npx ${pkg.name} --debug Enable verbose logging
|
|
55
|
+
|
|
56
|
+
Options:
|
|
57
|
+
-p, --port <number> HTTP bridge port (default: 3101)
|
|
58
|
+
-d, --debug Enable debug logging
|
|
59
|
+
-v, --version Show version
|
|
60
|
+
-h, --help Show this help
|
|
61
|
+
--init Auto-add to Claude/Cursor MCP config files
|
|
62
|
+
|
|
63
|
+
Environment Variables:
|
|
64
|
+
MCP_PORT Override HTTP port (same as --port)
|
|
65
|
+
MCP_DEBUG Enable debug mode (same as --debug)
|
|
66
|
+
|
|
67
|
+
More info: https://github.com/yusuf-ararat/dombridge
|
|
68
|
+
`);
|
|
69
|
+
process.exit(0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// --init: Auto-configure agent config files
|
|
73
|
+
if (flags.init) {
|
|
74
|
+
const { runAutoConfig } = await import('../src/cli/auto-config.js');
|
|
75
|
+
await runAutoConfig(pkg);
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Set environment variables from CLI flags
|
|
80
|
+
const port = parseInt(flags.port || process.env.MCP_PORT || '3101', 10);
|
|
81
|
+
process.env.MCP_PORT = String(port);
|
|
82
|
+
|
|
83
|
+
if (flags.debug || process.env.MCP_DEBUG) {
|
|
84
|
+
process.env.MCP_DEBUG = '1';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Start the MCP server
|
|
88
|
+
await import('../src/index.js');
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yusufffararatt/dombridge-mcp",
|
|
3
|
+
"version": "2.7.5",
|
|
4
|
+
"description": "DOMBridge MCP Server — AI-agent bridge for the DOMBridge Chrome extension, with CLI support",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"dombridge-mcp": "bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node src/index.js",
|
|
12
|
+
"dev": "node --watch src/index.js",
|
|
13
|
+
"bridge": "node src/bridge-daemon.js",
|
|
14
|
+
"bridge:dev": "node --watch src/bridge-daemon.js",
|
|
15
|
+
"inspect": "npx @modelcontextprotocol/inspector node src/index.js",
|
|
16
|
+
"cli": "node bin/cli.js",
|
|
17
|
+
"cli:debug": "node bin/cli.js --debug",
|
|
18
|
+
"init": "node bin/cli.js --init",
|
|
19
|
+
"prepublishOnly": "node ../scripts/check-all-docs.js"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"mcp",
|
|
23
|
+
"dombridge",
|
|
24
|
+
"api-tracer",
|
|
25
|
+
"web-scraping",
|
|
26
|
+
"ai-agent",
|
|
27
|
+
"chrome-extension",
|
|
28
|
+
"browser-automation",
|
|
29
|
+
"model-context-protocol"
|
|
30
|
+
],
|
|
31
|
+
"author": "Yusuf Ararat <dom.selector.api@gmail.com>",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"files": [
|
|
34
|
+
"bin/",
|
|
35
|
+
"src/",
|
|
36
|
+
"README.md"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/yusuf-ararat/dombridge.git"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
47
|
+
"better-sqlite3": "^12.10.0",
|
|
48
|
+
"cors": "^2.8.5",
|
|
49
|
+
"express": "^4.21.2"
|
|
50
|
+
},
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
}
|
|
54
|
+
}
|