@automatebrowser/mcp 0.3.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.
@@ -0,0 +1,211 @@
1
+ // src/vendor/config.ts
2
+ var appConfig = {
3
+ name: "@automatebrowser/mcp",
4
+ version: "0.3.0",
5
+ server: {
6
+ name: "@automatebrowser/mcp",
7
+ version: "0.3.0"
8
+ }
9
+ };
10
+ function resolveWsPortRange() {
11
+ const raw = process.env.AUTOMATE_BROWSER_WS_PORT_RANGE;
12
+ const m = raw?.match(/^\s*(\d+)\s*-\s*(\d+)\s*$/);
13
+ if (m) {
14
+ const start = Number(m[1]);
15
+ const end = Number(m[2]);
16
+ if (start > 0 && end >= start) return [start, end];
17
+ }
18
+ return [9009, 9013];
19
+ }
20
+ var mcpConfig = {
21
+ server: {
22
+ name: "@automatebrowser/mcp",
23
+ version: "0.3.0"
24
+ },
25
+ transport: {
26
+ type: "stdio"
27
+ },
28
+ defaultWsPort: 9009,
29
+ wsPortRange: resolveWsPortRange(),
30
+ /**
31
+ * WS round-trip budgets. Kept short so a wedged page/element fails fast with a
32
+ * clear error instead of stalling the agent for 30-60s. Genuinely slow
33
+ * operations (navigation waits for load, ARIA walk on huge pages) get their
34
+ * own, larger budget below.
35
+ */
36
+ timeouts: {
37
+ /** Default for quick ops: click, type, hover, eval, tab management, … */
38
+ default: 8e3,
39
+ /** ARIA snapshot can be heavy on very large pages. */
40
+ snapshot: 15e3,
41
+ /** captureVisibleTab + PNG encode. */
42
+ screenshot: 2e4,
43
+ /** Navigation: the extension resolves only after the page finishes loading. */
44
+ navigation: 2e4
45
+ },
46
+ errors: {
47
+ noConnectedTab: "No connected tab found"
48
+ }
49
+ };
50
+ function snapshotEachAction() {
51
+ const v = process.env.AUTOMATE_BROWSER_SNAPSHOT_EACH_ACTION;
52
+ return v === "1" || v === "true" || v === "yes";
53
+ }
54
+
55
+ // src/utils/log.ts
56
+ var LEVELS = { debug: 10, info: 20, warn: 30, error: 40 };
57
+ function resolveLevel() {
58
+ const raw = (process.env.AUTOMATE_BROWSER_LOG_LEVEL ?? "info").toLowerCase();
59
+ return LEVELS[raw] ?? LEVELS.info;
60
+ }
61
+ var minLevel = resolveLevel();
62
+ function emit(level, args) {
63
+ if (LEVELS[level] < minLevel) return;
64
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
65
+ console.error(`[${ts}] [${level}]`, ...args);
66
+ }
67
+ var log = {
68
+ debug: (...args) => emit("debug", args),
69
+ info: (...args) => emit("info", args),
70
+ warn: (...args) => emit("warn", args),
71
+ error: (...args) => emit("error", args)
72
+ };
73
+ var debugLog = (...args) => emit("info", args);
74
+
75
+ // src/utils/auth.ts
76
+ import { createHmac, randomBytes, timingSafeEqual } from "crypto";
77
+ function getAuthToken() {
78
+ const t = process.env.AUTOMATE_BROWSER_TOKEN;
79
+ return t && t.trim() ? t.trim() : void 0;
80
+ }
81
+ function createAuthChallenge() {
82
+ return {
83
+ scheme: "hmac-sha256",
84
+ challenge: randomBytes(24).toString("base64url")
85
+ };
86
+ }
87
+ function signAuthChallenge(token, challenge) {
88
+ return {
89
+ scheme: "hmac-sha256",
90
+ challenge,
91
+ response: createHmac("sha256", token).update(challenge).digest("base64url")
92
+ };
93
+ }
94
+ function verifyAuthResponse(token, expectedChallenge, auth) {
95
+ if (!auth || typeof auth !== "object") return false;
96
+ const payload = auth;
97
+ if (payload.scheme !== "hmac-sha256" || payload.challenge !== expectedChallenge || typeof payload.response !== "string" || payload.response.length === 0) {
98
+ return false;
99
+ }
100
+ const expected = signAuthChallenge(token, expectedChallenge).response;
101
+ const a = Buffer.from(expected);
102
+ const b = Buffer.from(payload.response);
103
+ return a.length === b.length && timingSafeEqual(a, b);
104
+ }
105
+
106
+ // src/relay/probe.ts
107
+ import { WebSocket } from "ws";
108
+
109
+ // src/utils/frame.ts
110
+ function parseFrame(raw) {
111
+ let parsed;
112
+ try {
113
+ parsed = JSON.parse(String(raw));
114
+ } catch {
115
+ return void 0;
116
+ }
117
+ return parsed !== null && typeof parsed === "object" ? parsed : void 0;
118
+ }
119
+
120
+ // src/relay/probe.ts
121
+ function probePort(port, timeoutMs = 800, host = "127.0.0.1") {
122
+ return new Promise((resolve) => {
123
+ let settled = false;
124
+ let socket;
125
+ const done = (r) => {
126
+ if (settled) return;
127
+ settled = true;
128
+ clearTimeout(timer);
129
+ try {
130
+ socket?.close();
131
+ } catch {
132
+ }
133
+ resolve(r);
134
+ };
135
+ const timer = setTimeout(() => done(null), timeoutMs);
136
+ try {
137
+ socket = new WebSocket(`ws://${host}:${port}`);
138
+ } catch {
139
+ done(null);
140
+ return;
141
+ }
142
+ socket.on("message", (raw) => {
143
+ const msg = parseFrame(raw);
144
+ if (msg?.type === "hello" && msg.payload) done(msg.payload);
145
+ });
146
+ socket.on("error", () => done(null));
147
+ });
148
+ }
149
+
150
+ // src/utils/host.ts
151
+ function isLoopbackHost(host) {
152
+ const h = host.trim().toLowerCase().replace(/^\[|\]$/g, "");
153
+ return h === "127.0.0.1" || h === "localhost" || h === "::1" || h.startsWith("127.");
154
+ }
155
+
156
+ // src/relay/control.ts
157
+ var RELAY_ROLE = "relay";
158
+ function isControlHello(msg) {
159
+ return msg.type === "control.hello" && !!msg.payload && msg.payload.role === "controller";
160
+ }
161
+ function isControlSend(msg) {
162
+ return msg.type === "control.send" && !!msg.payload && typeof msg.payload.requestId === "string" && typeof msg.payload.toolType === "string";
163
+ }
164
+ function isControlClaim(msg) {
165
+ return msg.type === "control.claim" && !!msg.payload && typeof msg.payload.requestId === "string" && typeof msg.payload.browserId === "string";
166
+ }
167
+ function isControlRelease(msg) {
168
+ return msg.type === "control.release" && !!msg.payload && typeof msg.payload.requestId === "string" && (msg.payload.browserId === void 0 || typeof msg.payload.browserId === "string");
169
+ }
170
+
171
+ // src/relay/types.ts
172
+ var WHOLE_TAB = -1;
173
+
174
+ // src/utils/log-dir.ts
175
+ import { mkdirSync } from "fs";
176
+ import { homedir, tmpdir } from "os";
177
+ import { join } from "path";
178
+ var dir = (() => {
179
+ const preferred = join(homedir(), ".automate-browser");
180
+ try {
181
+ mkdirSync(preferred, { recursive: true });
182
+ return preferred;
183
+ } catch {
184
+ return tmpdir();
185
+ }
186
+ })();
187
+ function logPath(name) {
188
+ return join(dir, name);
189
+ }
190
+
191
+ export {
192
+ appConfig,
193
+ mcpConfig,
194
+ snapshotEachAction,
195
+ log,
196
+ debugLog,
197
+ getAuthToken,
198
+ createAuthChallenge,
199
+ signAuthChallenge,
200
+ verifyAuthResponse,
201
+ parseFrame,
202
+ RELAY_ROLE,
203
+ isControlHello,
204
+ isControlSend,
205
+ isControlClaim,
206
+ isControlRelease,
207
+ probePort,
208
+ WHOLE_TAB,
209
+ logPath,
210
+ isLoopbackHost
211
+ };