@shiplightai/mcp 0.1.45 → 0.1.46

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.
@@ -0,0 +1,103 @@
1
+ # Shiplight AI Extension
2
+
3
+ Chrome extension for attaching Shiplight to your existing Chrome tabs via CDP relay.
4
+
5
+ ## Installation
6
+
7
+ ### Development (Load Unpacked)
8
+
9
+ 1. Open Chrome and navigate to `chrome://extensions`
10
+ 2. Enable "Developer mode" (toggle in top right)
11
+ 3. Click "Load unpacked"
12
+ 4. Select the `chrome-extension` directory: `packages/mcp-tools/chrome-extension`
13
+ 5. Extension appears with Shiplight icon
14
+
15
+ ### Configuration
16
+
17
+ 1. Click extension Options (right-click icon → Options, or go to chrome://extensions and click "Details" → "Extension options")
18
+ 2. Set **Relay Server Port**: `18792` (default)
19
+ 3. Set **Gateway Token**: Get from MCP server startup logs or call `get_relay_status` tool
20
+ 4. Click "Save Settings"
21
+
22
+ ## Usage
23
+
24
+ ### From Developer Workflow
25
+
26
+ 1. **Start MCP server** (relay server starts automatically when needed)
27
+ 2. **Open your app** in Chrome (e.g., `http://localhost:3000`)
28
+ 3. **Click extension icon** on the tab you want to control
29
+ 4. **Badge shows "ON"** - tab is attached
30
+ 5. **From coding agent**: Call `attach_to_current_tab()` MCP tool
31
+ 6. **Control the tab** using `get_dom()`, `act()`, etc.
32
+ 7. **Detach when done**: Click icon again or call `detach_from_tab()`
33
+
34
+ ### Badge Indicators
35
+
36
+ - **No badge**: Extension not active on this tab
37
+ - **ON** (orange): Tab attached and connected to relay
38
+ - **…** (yellow): Relay reconnecting
39
+ - **!** (red): Error - check extension options
40
+
41
+ ### Extension Options
42
+
43
+ - **Relay Server Port**: Default 18792 (must match MCP server)
44
+ - **Gateway Token**: Token for authentication with relay server
45
+
46
+ ## How It Works
47
+
48
+ ```
49
+ Chrome Tab (Your App)
50
+
51
+ chrome.debugger API (CDP)
52
+
53
+ Extension (background.js)
54
+
55
+ WebSocket to Relay Server (localhost:18792)
56
+
57
+ SessionManager (creates Playwright session)
58
+
59
+ MCP Tools (get_dom, act, etc.)
60
+ ```
61
+
62
+ ## Features
63
+
64
+ - **Zero setup time**: Control existing tabs without recreating state
65
+ - **SSO/OAuth support**: Test authenticated apps without manual login
66
+ - **Auto-reconnect**: Survives relay server restarts
67
+ - **Auto-reattach**: Persists across page navigations
68
+ - **MV3 compatible**: Service worker with session state persistence
69
+
70
+ ## Troubleshooting
71
+
72
+ ### "Relay server not reachable"
73
+ - Check MCP server is running
74
+ - Verify port matches (default 18792)
75
+ - Check firewall/antivirus not blocking localhost
76
+
77
+ ### "Missing gatewayToken"
78
+ - Go to extension Options
79
+ - Get token from MCP server logs or `get_relay_status` tool
80
+ - Save settings and try again
81
+
82
+ ### Badge shows "!" error
83
+ - Right-click extension icon → "Inspect popup"
84
+ - Check console for error messages
85
+ - Verify relay server is running
86
+
87
+ ## Development
88
+
89
+ ### Files
90
+
91
+ - `manifest.json` - Extension manifest (MV3)
92
+ - `background.js` - Service worker (main logic)
93
+ - `background-utils.js` - Token derivation, reconnect helpers
94
+ - `options.html` - Settings UI
95
+ - `options.js` - Settings logic
96
+ - `icons/` - Extension icons
97
+
98
+ ### Testing
99
+
100
+ 1. Make changes to extension files
101
+ 2. Go to `chrome://extensions`
102
+ 3. Click "Reload" button for Shiplight AI
103
+ 4. Test changes
@@ -0,0 +1,24 @@
1
+ export function reconnectDelayMs(
2
+ attempt,
3
+ opts = { baseMs: 1000, maxMs: 30000, jitterMs: 1000, random: Math.random },
4
+ ) {
5
+ const baseMs = Number.isFinite(opts.baseMs) ? opts.baseMs : 1000;
6
+ const maxMs = Number.isFinite(opts.maxMs) ? opts.maxMs : 30000;
7
+ const jitterMs = Number.isFinite(opts.jitterMs) ? opts.jitterMs : 1000;
8
+ const random = typeof opts.random === "function" ? opts.random : Math.random;
9
+ const safeAttempt = Math.max(0, Number.isFinite(attempt) ? attempt : 0);
10
+ const backoff = Math.min(baseMs * 2 ** safeAttempt, maxMs);
11
+ return backoff + Math.max(0, jitterMs) * random();
12
+ }
13
+
14
+ export function buildRelayWsUrl(port) {
15
+ return `ws://127.0.0.1:${port}/extension`;
16
+ }
17
+
18
+ export function isRetryableReconnectError(err) {
19
+ const message = err instanceof Error ? err.message : String(err || "");
20
+ if (message.includes("No relay port configured")) {
21
+ return false;
22
+ }
23
+ return true;
24
+ }