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/AGENTS.md +1 -1
- package/README.md +5 -2
- package/dist/cli/index.d.mts +2 -0
- package/dist/cli/index.mjs +2 -2
- package/dist/index.d.mts +928 -0
- package/dist/index.mjs +1 -1
- package/dist/mcp/index.d.mts +5 -0
- package/dist/mcp/index.mjs +67 -3
- package/dist/{runtime-CRkUsvhV.mjs → runtime-PnWvjdzU.mjs} +502 -19
- package/package.json +34 -8
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-
|
|
2
|
+
import { i as createMockAgenticBrowserCore, n as createAgenticBrowserCore, t as AgenticBrowserCore } from "./runtime-PnWvjdzU.mjs";
|
|
3
3
|
export { AgenticBrowserCore, createAgenticBrowserCore, createMockAgenticBrowserCore };
|
package/dist/mcp/index.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as createAgenticBrowserCore } from "../runtime-
|
|
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:
|
|
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: [{
|