agentic-browser 2.2.0 → 2.4.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/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { i as createMockAgenticBrowserCore, n as createAgenticBrowserCore, t as AgenticBrowserCore } from "./runtime-CRkUsvhV.mjs";
2
+ import { i as createMockAgenticBrowserCore, n as createAgenticBrowserCore, t as AgenticBrowserCore } from "./runtime-PnWvjdzU.mjs";
3
3
  export { AgenticBrowserCore, createAgenticBrowserCore, createMockAgenticBrowserCore };
@@ -0,0 +1,5 @@
1
+
2
+ //#region src/mcp/index.d.ts
3
+ declare function main(): Promise<void>;
4
+ //#endregion
5
+ export { main };
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { n as createAgenticBrowserCore } from "../runtime-CRkUsvhV.mjs";
2
+ import { n as createAgenticBrowserCore } from "../runtime-PnWvjdzU.mjs";
3
+ import { readFileSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
3
6
  import { z } from "zod";
4
7
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
8
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -186,11 +189,42 @@ function compactMemoryResults(results) {
186
189
  if (Array.isArray(compactAlias.fallbackSelectors) && compactAlias.fallbackSelectors.length === 0) delete compactAlias.fallbackSelectors;
187
190
  return compactAlias;
188
191
  });
192
+ if (compact.siteProfile) {
193
+ const profile = compact.siteProfile;
194
+ compact.siteProfile = {
195
+ selectorPatterns: (profile.selectorPatterns ?? []).map((p) => `${p.pattern} (x${p.frequency})`),
196
+ cookieBanner: profile.cookieBanner,
197
+ visitCount: profile.visitCount
198
+ };
199
+ }
189
200
  return compact;
190
201
  }) };
191
202
  }
192
203
  //#endregion
193
204
  //#region src/mcp/index.ts
205
+ function readPackageVersion() {
206
+ try {
207
+ const dir = dirname(fileURLToPath(import.meta.url));
208
+ for (const rel of ["../../package.json", "../package.json"]) try {
209
+ const pkg = JSON.parse(readFileSync(join(dir, rel), "utf8"));
210
+ if (pkg.version) return pkg.version;
211
+ } catch {}
212
+ } catch {}
213
+ return "0.0.0";
214
+ }
215
+ function classifyError(message) {
216
+ const lower = message.toLowerCase();
217
+ if (lower.includes("not found") || lower.includes("no element")) return "SELECTOR_NOT_FOUND";
218
+ if (lower.includes("covered") || lower.includes("overlay")) return "ELEMENT_COVERED";
219
+ if (lower.includes("not editable") || lower.includes("readonly")) return "ELEMENT_NOT_EDITABLE";
220
+ if (lower.includes("navigation failed")) return "NAVIGATION_FAILED";
221
+ if (lower.includes("navigation") && lower.includes("timeout")) return "NAVIGATION_TIMEOUT";
222
+ if (lower.includes("cdp connection") || lower.includes("websocket")) return "CDP_DISCONNECTED";
223
+ if (lower.includes("session") && (lower.includes("dead") || lower.includes("terminated"))) return "SESSION_DEAD";
224
+ if (lower.includes("dialog")) return "DIALOG_BLOCKING";
225
+ if (lower.includes("timeout")) return "TIMEOUT";
226
+ return "UNKNOWN";
227
+ }
194
228
  let core;
195
229
  let activeSessionId;
196
230
  const DEFAULT_MCP_MAX_CHARS = {
@@ -219,7 +253,7 @@ async function resolveSession(sessionId) {
219
253
  }
220
254
  const server = new McpServer({
221
255
  name: "agentic-browser",
222
- version: "0.1.0"
256
+ version: readPackageVersion()
223
257
  });
224
258
  server.tool("browser_start_session", "Start a new Chrome browser session (or return the existing one if healthy). Sessions auto-start when you call any other browser tool, so you rarely need to call this explicitly. Use this to force a fresh session after stopping the previous one.", {}, async () => {
225
259
  const session = await getCore().startSession();
@@ -246,11 +280,17 @@ server.tool("browser_navigate", "Navigate the browser to a URL. A session is aut
246
280
  const dismissed = await getCore().dismissCookieBanner(sid);
247
281
  if (dismissed.dismissed) cookieBanner = dismissed;
248
282
  } catch {}
283
+ let currentUrl;
284
+ try {
285
+ currentUrl = await getCore().getCurrentUrl(sid);
286
+ } catch {}
249
287
  const compact = {
250
288
  resultStatus: result.resultStatus,
251
289
  resultMessage: result.resultMessage,
290
+ currentUrl,
252
291
  cookieBanner
253
292
  };
293
+ if (result.resultStatus === "failed") compact.errorCode = classifyError(result.resultMessage ?? "");
254
294
  return { content: [{
255
295
  type: "text",
256
296
  text: JSON.stringify(compact)
@@ -297,10 +337,16 @@ server.tool("browser_interact", "Interact with a page element or perform browser
297
337
  type: "interact",
298
338
  payload
299
339
  });
340
+ let currentUrl;
341
+ try {
342
+ currentUrl = await getCore().getCurrentUrl(sid);
343
+ } catch {}
300
344
  const compact = {
301
345
  resultStatus: result.resultStatus,
302
- resultMessage: result.resultMessage
346
+ resultMessage: result.resultMessage,
347
+ currentUrl
303
348
  };
349
+ if (result.resultStatus === "failed") compact.errorCode = classifyError(result.resultMessage ?? "");
304
350
  return { content: [{
305
351
  type: "text",
306
352
  text: JSON.stringify(compact)
@@ -384,6 +430,24 @@ server.tool("browser_dismiss_cookies", "Dismiss cookie consent banners on the cu
384
430
  text: JSON.stringify(result)
385
431
  }] };
386
432
  });
433
+ server.tool("browser_screenshot", "Capture a screenshot of the current page. Returns a base64-encoded image. Useful for visual verification, debugging element discovery failures, or when you need to see what the page looks like. A session is auto-started if needed.", {
434
+ format: z.enum(["jpeg", "png"]).default("jpeg").describe("Image format (jpeg is smaller, png is lossless)"),
435
+ quality: z.number().optional().describe("JPEG quality 0-100 (default 60, ignored for png)"),
436
+ fullPage: z.boolean().default(false).describe("Capture the full scrollable page instead of just the viewport"),
437
+ sessionId: z.string().optional().describe("Session ID (auto-resolved if omitted)")
438
+ }, async ({ format, quality, fullPage, sessionId }) => {
439
+ const sid = await resolveSession(sessionId);
440
+ const result = await getCore().screenshot(sid, {
441
+ format,
442
+ quality,
443
+ fullPage
444
+ });
445
+ return { content: [{
446
+ type: "image",
447
+ data: result.data,
448
+ mimeType: result.mimeType
449
+ }] };
450
+ });
387
451
  server.tool("browser_stop_session", "Stop the browser session and terminate Chrome. The next browser tool call will auto-start a fresh session.", { sessionId: z.string().optional().describe("Session ID (uses active session if omitted)") }, async ({ sessionId }) => {
388
452
  const sid = sessionId ?? activeSessionId;
389
453
  if (!sid) return { content: [{