mcp-scraper 0.40.2 → 0.40.3

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.
Files changed (62) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +1517 -236
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +3 -3
  5. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +1 -1
  8. package/dist/bin/mcp-scraper-install.cjs +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  10. package/dist/bin/mcp-scraper-install.js +1 -1
  11. package/dist/bin/mcp-stdio-server.cjs +155 -87
  12. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-stdio-server.js +6 -5
  14. package/dist/bin/mcp-stdio-server.js.map +1 -1
  15. package/dist/bin/paa-harvest.cjs +31 -9
  16. package/dist/bin/paa-harvest.cjs.map +1 -1
  17. package/dist/bin/paa-harvest.js +4 -4
  18. package/dist/{chunk-XORPNO3Z.js → chunk-27DUCRAZ.js} +2 -2
  19. package/dist/{chunk-44HZLHDV.js → chunk-5UN33CGU.js} +38 -1
  20. package/dist/chunk-5UN33CGU.js.map +1 -0
  21. package/dist/{chunk-X2LKCX6H.js → chunk-6J57U6HA.js} +3 -3
  22. package/dist/{chunk-LP6E462I.js → chunk-6SZ52BQ5.js} +49 -101
  23. package/dist/chunk-6SZ52BQ5.js.map +1 -0
  24. package/dist/chunk-BBI7RGOT.js +99 -0
  25. package/dist/chunk-BBI7RGOT.js.map +1 -0
  26. package/dist/{chunk-NVXNEOUQ.js → chunk-CS4HE6QY.js} +47 -11
  27. package/dist/chunk-CS4HE6QY.js.map +1 -0
  28. package/dist/{chunk-3PIWJS6Y.js → chunk-EHES33KB.js} +2 -2
  29. package/dist/{chunk-GUVKHCKE.js → chunk-IQTT7CAB.js} +94 -3
  30. package/dist/chunk-IQTT7CAB.js.map +1 -0
  31. package/dist/{chunk-7XBBFBYY.js → chunk-JVIW4GK2.js} +44 -12
  32. package/dist/chunk-JVIW4GK2.js.map +1 -0
  33. package/dist/chunk-XU4ZLIB2.js +7 -0
  34. package/dist/chunk-XU4ZLIB2.js.map +1 -0
  35. package/dist/{db-W3CP562I.js → db-LVVU6NOK.js} +16 -2
  36. package/dist/{extract-bundle-K4PG3RZJ.js → extract-bundle-SKXEDG4Z.js} +4 -4
  37. package/dist/index.cjs +31 -9
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.js +4 -4
  40. package/dist/{location-data-repository-RLQX6SNM.js → location-data-repository-NBTCOA7B.js} +3 -3
  41. package/dist/{server-KM3CFWCF.js → server-W76RUYD3.js} +1108 -66
  42. package/dist/server-W76RUYD3.js.map +1 -0
  43. package/dist/{site-extract-repository-2SMMFKKL.js → site-extract-repository-6GX72U4N.js} +4 -4
  44. package/dist/{worker-FXAGFYOE.js → worker-5RWLFSAJ.js} +27 -28
  45. package/dist/worker-5RWLFSAJ.js.map +1 -0
  46. package/package.json +1 -1
  47. package/dist/chunk-44HZLHDV.js.map +0 -1
  48. package/dist/chunk-7XBBFBYY.js.map +0 -1
  49. package/dist/chunk-GUVKHCKE.js.map +0 -1
  50. package/dist/chunk-LP6E462I.js.map +0 -1
  51. package/dist/chunk-NVXNEOUQ.js.map +0 -1
  52. package/dist/chunk-ZUJLSICT.js +0 -7
  53. package/dist/chunk-ZUJLSICT.js.map +0 -1
  54. package/dist/server-KM3CFWCF.js.map +0 -1
  55. package/dist/worker-FXAGFYOE.js.map +0 -1
  56. /package/dist/{chunk-XORPNO3Z.js.map → chunk-27DUCRAZ.js.map} +0 -0
  57. /package/dist/{chunk-X2LKCX6H.js.map → chunk-6J57U6HA.js.map} +0 -0
  58. /package/dist/{chunk-3PIWJS6Y.js.map → chunk-EHES33KB.js.map} +0 -0
  59. /package/dist/{db-W3CP562I.js.map → db-LVVU6NOK.js.map} +0 -0
  60. /package/dist/{extract-bundle-K4PG3RZJ.js.map → extract-bundle-SKXEDG4Z.js.map} +0 -0
  61. /package/dist/{location-data-repository-RLQX6SNM.js.map → location-data-repository-NBTCOA7B.js.map} +0 -0
  62. /package/dist/{site-extract-repository-2SMMFKKL.js.map → site-extract-repository-6GX72U4N.js.map} +0 -0
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  harvest
4
- } from "../chunk-7XBBFBYY.js";
4
+ } from "../chunk-JVIW4GK2.js";
5
5
  import {
6
6
  browserServiceApiKey
7
- } from "../chunk-3PIWJS6Y.js";
7
+ } from "../chunk-EHES33KB.js";
8
8
  import "../chunk-K443GQY5.js";
9
9
  import "../chunk-CB5C3BPB.js";
10
- import "../chunk-44HZLHDV.js";
11
- import "../chunk-GUVKHCKE.js";
10
+ import "../chunk-5UN33CGU.js";
11
+ import "../chunk-IQTT7CAB.js";
12
12
 
13
13
  // src/cli.ts
14
14
  import { Command } from "commander";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-G3P3ZDB4.js";
4
4
  import {
5
5
  getDb
6
- } from "./chunk-GUVKHCKE.js";
6
+ } from "./chunk-IQTT7CAB.js";
7
7
 
8
8
  // src/api/location-data-repository.ts
9
9
  import { createHash, randomUUID } from "crypto";
@@ -681,4 +681,4 @@ export {
681
681
  importHostedCensusPlacesCsv,
682
682
  queryHostedLocationMarkets
683
683
  };
684
- //# sourceMappingURL=chunk-XORPNO3Z.js.map
684
+ //# sourceMappingURL=chunk-27DUCRAZ.js.map
@@ -1,5 +1,39 @@
1
1
  // src/errors.ts
2
2
  var RECAPTCHA_INSTRUCTIONS = "Google returned a CAPTCHA. Run with --headless=false to re-warm the browser profile, then retry.";
3
+ var PUBLIC_SERVICE_UNAVAILABLE_MESSAGE = "This operation is temporarily unavailable. Please retry later.";
4
+ var PUBLIC_ERROR_CODES = /* @__PURE__ */ new Set([
5
+ "request_aborted",
6
+ "captcha_exhausted",
7
+ "captcha_or_blocked",
8
+ "location_mismatch",
9
+ "proxy_tunnel_failed",
10
+ "proxy_unavailable",
11
+ "harvest_timeout",
12
+ "mcp_request_timeout",
13
+ "service_unavailable"
14
+ ]);
15
+ function normalizePublicErrorCode(code) {
16
+ return typeof code === "string" && PUBLIC_ERROR_CODES.has(code) ? code : "service_unavailable";
17
+ }
18
+ function publicErrorMessage(code) {
19
+ switch (normalizePublicErrorCode(code)) {
20
+ case "request_aborted":
21
+ return "The request was cancelled before it completed.";
22
+ case "captcha_exhausted":
23
+ case "captcha_or_blocked":
24
+ return "The target site returned a verification challenge. Please retry later.";
25
+ case "location_mismatch":
26
+ return "The target site returned results for a different location. Please retry.";
27
+ case "proxy_tunnel_failed":
28
+ case "proxy_unavailable":
29
+ return "The web request could not establish a working connection. Please retry later.";
30
+ case "harvest_timeout":
31
+ case "mcp_request_timeout":
32
+ return "The request timed out before it completed. Please retry with a smaller request.";
33
+ default:
34
+ return PUBLIC_SERVICE_UNAVAILABLE_MESSAGE;
35
+ }
36
+ }
3
37
  function sanitizeVendorName(message) {
4
38
  return message.replace(/kernel\.sh\s+sessions?/gi, "sessions").replace(/kernel\.sh\s+session/gi, "this session").replace(/kernel\.sh/gi, "the service").replace(/kernel\s+sessions?/gi, "sessions").replace(/kernel\s+session/gi, "this session").replace(/\bkernel\b/gi, "the service").replace(/ +/g, " ").trim();
5
39
  }
@@ -42,6 +76,9 @@ var LocationMismatchError = class extends Error {
42
76
 
43
77
  export {
44
78
  RECAPTCHA_INSTRUCTIONS,
79
+ PUBLIC_SERVICE_UNAVAILABLE_MESSAGE,
80
+ normalizePublicErrorCode,
81
+ publicErrorMessage,
45
82
  sanitizeVendorName,
46
83
  CaptchaError,
47
84
  ExtractionError,
@@ -49,4 +86,4 @@ export {
49
86
  RequestAbortedError,
50
87
  LocationMismatchError
51
88
  };
52
- //# sourceMappingURL=chunk-44HZLHDV.js.map
89
+ //# sourceMappingURL=chunk-5UN33CGU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["export const RECAPTCHA_INSTRUCTIONS = 'Google returned a CAPTCHA. Run with --headless=false to re-warm the browser profile, then retry.'\nexport const PUBLIC_SERVICE_UNAVAILABLE_MESSAGE = 'This operation is temporarily unavailable. Please retry later.'\n\nconst PUBLIC_ERROR_CODES = new Set([\n 'request_aborted',\n 'captcha_exhausted',\n 'captcha_or_blocked',\n 'location_mismatch',\n 'proxy_tunnel_failed',\n 'proxy_unavailable',\n 'harvest_timeout',\n 'mcp_request_timeout',\n 'service_unavailable',\n])\n\nexport function normalizePublicErrorCode(code: unknown): string {\n return typeof code === 'string' && PUBLIC_ERROR_CODES.has(code)\n ? code\n : 'service_unavailable'\n}\n\nexport function publicErrorMessage(code: unknown): string {\n switch (normalizePublicErrorCode(code)) {\n case 'request_aborted':\n return 'The request was cancelled before it completed.'\n case 'captcha_exhausted':\n case 'captcha_or_blocked':\n return 'The target site returned a verification challenge. Please retry later.'\n case 'location_mismatch':\n return 'The target site returned results for a different location. Please retry.'\n case 'proxy_tunnel_failed':\n case 'proxy_unavailable':\n return 'The web request could not establish a working connection. Please retry later.'\n case 'harvest_timeout':\n case 'mcp_request_timeout':\n return 'The request timed out before it completed. Please retry with a smaller request.'\n default:\n return PUBLIC_SERVICE_UNAVAILABLE_MESSAGE\n }\n}\n\nexport function sanitizeVendorName(message: string): string {\n return message\n .replace(/kernel\\.sh\\s+sessions?/gi, 'sessions')\n .replace(/kernel\\.sh\\s+session/gi, 'this session')\n .replace(/kernel\\.sh/gi, 'the service')\n .replace(/kernel\\s+sessions?/gi, 'sessions')\n .replace(/kernel\\s+session/gi, 'this session')\n .replace(/\\bkernel\\b/gi, 'the service')\n .replace(/ +/g, ' ')\n .trim()\n}\n\nexport class CaptchaError extends Error {\n readonly name = 'CaptchaError'\n constructor(public readonly instructions: string) {\n super(`CAPTCHA detected. ${instructions}`)\n }\n}\n\nexport class ExtractionError extends Error {\n readonly name = 'ExtractionError'\n constructor(message: string, public readonly cause?: unknown) {\n super(message)\n }\n}\n\n/**\n * Google Maps sometimes finishes navigation without rendering either result\n * cards or its explicit no-results message. Treating that page as a genuine\n * empty search loses data, so callers should retry it with a fresh browser (and\n * a fresh proxy when location rotation is enabled).\n */\nexport class MapsSearchIncompletePageError extends Error {\n readonly name = 'MapsSearchIncompletePageError'\n\n constructor(public readonly pageState: string) {\n super(`Google Maps search did not reach a complete result state (${pageState})`)\n }\n}\n\nexport class RequestAbortedError extends Error {\n readonly name = 'RequestAbortedError'\n constructor(message = 'Request aborted before harvest completed') {\n super(message)\n }\n}\n\nexport class LocationMismatchError extends Error {\n readonly name = 'LocationMismatchError'\n constructor(message = 'Google returned results for a different location than requested') {\n super(message)\n }\n}\n"],"mappings":";AAAO,IAAM,yBAAyB;AAC/B,IAAM,qCAAqC;AAElD,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,yBAAyB,MAAuB;AAC9D,SAAO,OAAO,SAAS,YAAY,mBAAmB,IAAI,IAAI,IAC1D,OACA;AACN;AAEO,SAAS,mBAAmB,MAAuB;AACxD,UAAQ,yBAAyB,IAAI,GAAG;AAAA,IACtC,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,mBAAmB,SAAyB;AAC1D,SAAO,QACJ,QAAQ,4BAA4B,UAAU,EAC9C,QAAQ,0BAA0B,cAAc,EAChD,QAAQ,gBAAgB,aAAa,EACrC,QAAQ,wBAAwB,UAAU,EAC1C,QAAQ,sBAAsB,cAAc,EAC5C,QAAQ,gBAAgB,aAAa,EACrC,QAAQ,QAAQ,GAAG,EACnB,KAAK;AACV;AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,EAEtC,YAA4B,cAAsB;AAChD,UAAM,qBAAqB,YAAY,EAAE;AADf;AAAA,EAE5B;AAAA,EAF4B;AAAA,EADnB,OAAO;AAIlB;AAEO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAEzC,YAAY,SAAiC,OAAiB;AAC5D,UAAM,OAAO;AAD8B;AAAA,EAE7C;AAAA,EAF6C;AAAA,EADpC,OAAO;AAIlB;AAQO,IAAM,gCAAN,cAA4C,MAAM;AAAA,EAGvD,YAA4B,WAAmB;AAC7C,UAAM,6DAA6D,SAAS,GAAG;AADrD;AAAA,EAE5B;AAAA,EAF4B;AAAA,EAFnB,OAAO;AAKlB;AAEO,IAAM,sBAAN,cAAkC,MAAM;AAAA,EACpC,OAAO;AAAA,EAChB,YAAY,UAAU,4CAA4C;AAChE,UAAM,OAAO;AAAA,EACf;AACF;AAEO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EACtC,OAAO;AAAA,EAChB,YAAY,UAAU,mEAAmE;AACvF,UAAM,OAAO;AAAA,EACf;AACF;","names":[]}
@@ -3,12 +3,12 @@ import {
3
3
  } from "./chunk-SBLGBZZB.js";
4
4
  import {
5
5
  sanitizeVendorName
6
- } from "./chunk-44HZLHDV.js";
6
+ } from "./chunk-5UN33CGU.js";
7
7
  import {
8
8
  CREDIT_LOT_TTL,
9
9
  getDb,
10
10
  settleDebitMcIdempotent
11
- } from "./chunk-GUVKHCKE.js";
11
+ } from "./chunk-IQTT7CAB.js";
12
12
 
13
13
  // src/api/site-extract-repository.ts
14
14
  function extractJobLimitInfo(job) {
@@ -496,4 +496,4 @@ export {
496
496
  failUnfundedExtractJob,
497
497
  settleExtractJob
498
498
  };
499
- //# sourceMappingURL=chunk-X2LKCX6H.js.map
499
+ //# sourceMappingURL=chunk-6J57U6HA.js.map
@@ -10,25 +10,30 @@ import {
10
10
  renderLinkReport,
11
11
  renewPrivateArtifactDownload
12
12
  } from "./chunk-345BQXZH.js";
13
+ import {
14
+ sanitizeOutboundDiagnostics
15
+ } from "./chunk-BBI7RGOT.js";
13
16
  import {
14
17
  browserServiceProfileName,
15
18
  browserServiceProfileSaveChanges,
16
19
  recordVendorUsage,
17
20
  vendorCostUsd
18
- } from "./chunk-3PIWJS6Y.js";
21
+ } from "./chunk-EHES33KB.js";
19
22
  import {
20
23
  DEFAULT_MAPS_PROXY_MODE,
21
24
  DEFAULT_PROXY_MODE
22
25
  } from "./chunk-CB5C3BPB.js";
23
26
  import {
24
27
  PACKAGE_VERSION
25
- } from "./chunk-ZUJLSICT.js";
28
+ } from "./chunk-XU4ZLIB2.js";
26
29
  import {
27
30
  MC_PER_CREDIT
28
31
  } from "./chunk-SBLGBZZB.js";
29
32
  import {
33
+ normalizePublicErrorCode,
34
+ publicErrorMessage,
30
35
  sanitizeVendorName
31
- } from "./chunk-44HZLHDV.js";
36
+ } from "./chunk-5UN33CGU.js";
32
37
 
33
38
  // src/harvest-timeout.ts
34
39
  var VERCEL_FUNCTION_MAX_MS = 3e5;
@@ -44,71 +49,6 @@ function harvestTimeoutBudget(maxQuestions, serpOnly = false) {
44
49
  return { serverMs, clientMs };
45
50
  }
46
51
 
47
- // src/api/outbound-sanitize.ts
48
- var KEY_RENAMES = {
49
- kernel: "browserRuntime",
50
- kernel_session_id: "browser_session_id",
51
- kernel_delete_started: "session_cleanup_started",
52
- kernel_delete_succeeded: "session_cleanup_succeeded",
53
- kernel_delete_error: "session_cleanup_error",
54
- kernelSessionId: "browserSessionId",
55
- kernelDeleteStarted: "sessionCleanupStarted",
56
- kernelDeleteSucceeded: "sessionCleanupSucceeded",
57
- kernelDeleteError: "sessionCleanupError",
58
- kernelProxyId: "proxyId"
59
- };
60
- var SANITIZED_VALUE_KEYS = /error|message/i;
61
- var VENDOR_URL_KEYS = /* @__PURE__ */ new Set([
62
- "hosted_url",
63
- "hostedUrl",
64
- "live_view_url",
65
- "liveViewUrl",
66
- "cdp_ws_url",
67
- "cdpWsUrl",
68
- "browser_live_view_url"
69
- ]);
70
- var VENDOR_URL_RE = /\b(?:wss?|https?):\/\/[^\s"'<>]*\bonkernel\.com[^\s"'<>]*/gi;
71
- function redactVendorUrls(value) {
72
- return value.replace(VENDOR_URL_RE, "[browser-service]");
73
- }
74
- function sanitizeOutboundDiagnostics(value, parentKey = "") {
75
- if (typeof value === "string") {
76
- let out = redactVendorUrls(value);
77
- if (SANITIZED_VALUE_KEYS.test(parentKey) && /kernel/i.test(out)) {
78
- out = sanitizeVendorName(out);
79
- }
80
- return out;
81
- }
82
- if (Array.isArray(value)) return value.map((v) => sanitizeOutboundDiagnostics(v, parentKey));
83
- if (value !== null && typeof value === "object") {
84
- const out = {};
85
- for (const [key, val] of Object.entries(value)) {
86
- const renamed = KEY_RENAMES[key] ?? key;
87
- if (VENDOR_URL_KEYS.has(key)) {
88
- out[renamed] = null;
89
- continue;
90
- }
91
- out[renamed] = sanitizeOutboundDiagnostics(val, key);
92
- }
93
- return out;
94
- }
95
- return value;
96
- }
97
- function sanitizeAttempts(attempts) {
98
- return attempts.map((a) => sanitizeOutboundDiagnostics(a));
99
- }
100
- function sanitizeHarvestResult(result) {
101
- const diagnostics = result?.diagnostics;
102
- if (!diagnostics?.debug) return result;
103
- return {
104
- ...result,
105
- diagnostics: {
106
- ...diagnostics,
107
- debug: sanitizeOutboundDiagnostics(diagnostics.debug)
108
- }
109
- };
110
- }
111
-
112
52
  // src/api/connected-data-artifacts.ts
113
53
  import { createHash, randomUUID } from "crypto";
114
54
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -1335,15 +1275,15 @@ function formatStructuredError(body, fallback) {
1335
1275
  return `Insufficient credits. Balance: ${body.balance_credits} credits. This call requires ${body.required_credits} credits. Top up at ${body.topup_url}`;
1336
1276
  }
1337
1277
  if (body.error === "mcp_request_timeout") {
1338
- return typeof body.message === "string" ? body.message : "MCP Scraper request timed out and was cancelled.";
1278
+ return publicErrorMessage("mcp_request_timeout");
1339
1279
  }
1340
1280
  if (typeof body.error_code === "string") {
1341
- const message = typeof body.error === "string" ? body.error : typeof body.message === "string" ? body.message : fallback;
1281
+ const code = normalizePublicErrorCode(body.error_code);
1282
+ const message = publicErrorMessage(code);
1342
1283
  const retryable = body.retryable === true ? " Retryable: yes." : "";
1343
- return `${body.error_code}: ${message}${retryable}${errorAttemptsSection(body)}`;
1284
+ return `${code}: ${message}${retryable}${errorAttemptsSection(body)}`;
1344
1285
  }
1345
- if (typeof body.error === "string") return body.error;
1346
- return fallback || "Tool error";
1286
+ return publicErrorMessage("service_unavailable");
1347
1287
  }
1348
1288
  function parseData(raw) {
1349
1289
  const first = raw.content.find((b) => b.type === "text");
@@ -1354,7 +1294,7 @@ function parseData(raw) {
1354
1294
  const data = parsed.result ?? parsed;
1355
1295
  return { data };
1356
1296
  } catch {
1357
- if (raw.isError) return { error: sanitizeVendorText(text || "Tool error") };
1297
+ if (raw.isError) return { error: publicErrorMessage("service_unavailable") };
1358
1298
  return { error: "Failed to parse tool response" };
1359
1299
  }
1360
1300
  }
@@ -1396,10 +1336,9 @@ function debugSection(debug) {
1396
1336
  const candidates = Array.isArray(locationEvidence?.candidates) ? locationEvidence.candidates.slice(0, 4).map((c) => `${c.city}, ${c.regionCode} (${c.count})`).join(", ") : "";
1397
1337
  const lines = [
1398
1338
  "\n## Debug",
1399
- `- Proxy mode: ${request.proxyMode ?? kernel.proxyMode ?? "unknown"} \xB7 requested proxy: ${kernel.requestedProxyIdPresent === true ? `yes (${kernel.requestedProxyIdSuffix ?? "redacted"})` : "no"}`,
1400
- `- Proxy resolution: ${proxyResolution.source ?? "unknown"}${proxyResolution.target ? ` \xB7 ${proxyResolution.target.level ?? "city"} ${proxyResolution.target.city}, ${proxyResolution.target.state}` : ""}${proxyResolution.error ? ` \xB7 ${truncate(proxyResolution.error, 180)}` : ""}`,
1401
- `- Browser session: ${kernel.sessionId ?? "unknown"} \xB7 retrieved proxy: ${kernel.retrievedProxyIdPresent === true ? `yes (${kernel.retrievedProxyIdSuffix ?? "redacted"})` : kernel.retrievedProxyIdPresent === false ? "no" : "unknown"}`,
1402
- `- Browser IP geo: ${[network.ip, network.city, network.region, network.country].filter(Boolean).join(" \xB7 ") || network.error || "unknown"}`,
1339
+ `- Proxy mode: ${request.proxyMode ?? kernel.proxyMode ?? "unknown"}`,
1340
+ `- Proxy resolution: ${proxyResolution.target ? `${proxyResolution.target.level ?? "city"} ${proxyResolution.target.city}, ${proxyResolution.target.state}` : proxyResolution.error ? publicErrorMessage("service_unavailable") : "unknown"}`,
1341
+ `- Browser IP geo: ${[network.ip, network.city, network.region, network.country].filter(Boolean).join(" \xB7 ") || (network.error ? publicErrorMessage("service_unavailable") : "unknown")}`,
1403
1342
  `- Google URL: ${truncate(nav.requestedUrl, 240) || "unknown"}`,
1404
1343
  `- Final URL: ${truncate(nav.finalUrl, 240) || "unknown"} \xB7 CAPTCHA: ${nav.captchaDetected === true ? "yes" : nav.captchaDetected === false ? "no" : "unknown"} \xB7 redirected: ${nav.redirected === true ? "yes" : nav.redirected === false ? "no" : "unknown"}`
1405
1344
  ];
@@ -1415,7 +1354,6 @@ function errorAttemptsSection(body) {
1415
1354
  const debug = attempt.debug ?? {};
1416
1355
  const browser = debug.browser ?? {};
1417
1356
  const kernel = browser.browserRuntime ?? browser.kernel ?? {};
1418
- const proxyResolution = kernel.proxyResolution ?? {};
1419
1357
  const network = browser.networkLocation ?? {
1420
1358
  ip: attempt.observedIp ?? attempt.observed_ip,
1421
1359
  city: attempt.observedCity ?? attempt.observed_city,
@@ -1423,10 +1361,7 @@ function errorAttemptsSection(body) {
1423
1361
  };
1424
1362
  const nav = browser.serpNavigation ?? {};
1425
1363
  const geo = [network.ip, network.city, network.region].filter(Boolean).join(" / ") || "geo unknown";
1426
- const sessionId = attempt.browser_session_id ?? attempt.browserSessionIdSuffix ?? attempt.kernel_session_id ?? kernel.sessionId ?? "unknown";
1427
- const cleanupSucceeded = attempt.session_cleanup_succeeded ?? attempt.kernel_delete_succeeded;
1428
- const proxySource = proxyResolution.source ?? attempt.proxyResolutionSource;
1429
- return `- Attempt ${attempt.attempt_number ?? attempt.attemptNumber ?? "?"}: ${attempt.outcome ?? attempt.status ?? "unknown"} \xB7 session ${sessionId} \xB7 proxy ${debug.request?.proxyMode ?? kernel.proxyMode ?? attempt.proxyMode ?? "unknown"}${proxySource ? `/${proxySource}` : ""} \xB7 ${geo} \xB7 CAPTCHA ${nav.captchaDetected === true ? "yes" : nav.captchaDetected === false ? "no" : "unknown"} \xB7 cleanup ${cleanupSucceeded === true ? "yes" : cleanupSucceeded === false ? "no" : "unknown"}`;
1364
+ return `- Attempt ${attempt.attempt_number ?? attempt.attemptNumber ?? "?"}: ${attempt.outcome ?? attempt.status ?? "unknown"} \xB7 proxy mode ${debug.request?.proxyMode ?? kernel.proxyMode ?? attempt.proxyMode ?? "unknown"} \xB7 ${geo} \xB7 verification challenge ${nav.captchaDetected === true ? "yes" : nav.captchaDetected === false ? "no" : "unknown"}`;
1430
1365
  });
1431
1366
  return `
1432
1367
 
@@ -7045,7 +6980,20 @@ async function readResponseData(res) {
7045
6980
  function httpErrorPayload(path, res, data) {
7046
6981
  const objectData = data && typeof data === "object" && !Array.isArray(data) ? data : null;
7047
6982
  const rawCode = objectData?.code ?? objectData?.errorCode ?? objectData?.error_code;
7048
- const safeCode = typeof rawCode === "string" && /^[a-z0-9][a-z0-9_-]{0,99}$/.test(rawCode) ? rawCode : "mcp_http_error";
6983
+ const candidateCode = typeof rawCode === "string" && /^[a-z0-9][a-z0-9_-]{0,99}$/.test(rawCode) ? rawCode : "mcp_http_error";
6984
+ if (res.status >= 500) {
6985
+ const safeCode2 = normalizePublicErrorCode(candidateCode);
6986
+ return {
6987
+ error: safeCode2,
6988
+ error_code: safeCode2,
6989
+ error_type: "http",
6990
+ retryable: true,
6991
+ status: res.status,
6992
+ path,
6993
+ message: publicErrorMessage(safeCode2)
6994
+ };
6995
+ }
6996
+ const safeCode = candidateCode;
7049
6997
  const bodyMessage = objectData ? objectData.message ?? objectData.error ?? rawCode : data;
7050
6998
  return {
7051
6999
  ...objectData ?? { body: data },
@@ -7104,7 +7052,6 @@ var HttpMcpToolExecutor = class {
7104
7052
  }
7105
7053
  return { content: [{ type: "text", text: JSON.stringify(data) }] };
7106
7054
  } catch (err) {
7107
- const msg = err instanceof Error ? err.message : String(err);
7108
7055
  if (err instanceof DOMException && err.name === "TimeoutError") {
7109
7056
  return {
7110
7057
  content: [{
@@ -7121,7 +7068,7 @@ var HttpMcpToolExecutor = class {
7121
7068
  isError: true
7122
7069
  };
7123
7070
  }
7124
- return { content: [{ type: "text", text: msg }], isError: true };
7071
+ return { content: [{ type: "text", text: publicErrorMessage("service_unavailable") }], isError: true };
7125
7072
  }
7126
7073
  }
7127
7074
  async callConnectedMutation(path, body, timeoutMs = this.timeoutMs) {
@@ -7170,9 +7117,8 @@ var HttpMcpToolExecutor = class {
7170
7117
  return { content: [{ type: "text", text: JSON.stringify(httpErrorPayload(path, res, data)) }], isError: true };
7171
7118
  }
7172
7119
  return { content: [{ type: "text", text: JSON.stringify(data) }] };
7173
- } catch (err) {
7174
- const msg = err instanceof Error ? err.message : String(err);
7175
- return { content: [{ type: "text", text: msg }], isError: true };
7120
+ } catch {
7121
+ return { content: [{ type: "text", text: publicErrorMessage("service_unavailable") }], isError: true };
7176
7122
  }
7177
7123
  }
7178
7124
  async getTextArtifact(path, maxBytes, timeoutMs = this.timeoutMs) {
@@ -7186,7 +7132,13 @@ var HttpMcpToolExecutor = class {
7186
7132
  });
7187
7133
  if (!res.ok) {
7188
7134
  const data = await res.json().catch(async () => ({ error: await res.text().catch(() => `HTTP ${res.status}`) }));
7189
- return { content: [{ type: "text", text: JSON.stringify(data) }], isError: true };
7135
+ return {
7136
+ content: [{
7137
+ type: "text",
7138
+ text: JSON.stringify(res.status >= 500 ? httpErrorPayload(path, res, data) : sanitizeOutboundDiagnostics(data))
7139
+ }],
7140
+ isError: true
7141
+ };
7190
7142
  }
7191
7143
  const bytes = Buffer.from(await res.arrayBuffer());
7192
7144
  const sliced = bytes.subarray(0, Math.min(maxBytes, bytes.length));
@@ -7203,8 +7155,7 @@ var HttpMcpToolExecutor = class {
7203
7155
  }]
7204
7156
  };
7205
7157
  } catch (err) {
7206
- const msg = err instanceof Error ? err.message : String(err);
7207
- return { content: [{ type: "text", text: msg }], isError: true };
7158
+ return { content: [{ type: "text", text: publicErrorMessage("service_unavailable") }], isError: true };
7208
7159
  }
7209
7160
  }
7210
7161
  harvestPaa(input) {
@@ -8253,8 +8204,7 @@ function errorResult(tool, value, sessionId = null, replayId = null) {
8253
8204
  tool,
8254
8205
  session_id: sessionId,
8255
8206
  ...replayId !== null ? { replay_id: replayId } : {},
8256
- error: errorMessage(value),
8257
- raw: value && typeof value === "object" ? value : { value }
8207
+ error: errorMessage(value)
8258
8208
  }, true);
8259
8209
  }
8260
8210
  function actionResult(tool, sessionId, ok, data, nextRecommendedTool = "browser_screenshot") {
@@ -8339,8 +8289,8 @@ function registerBrowserAgentMcpTools(server, opts) {
8339
8289
  });
8340
8290
  const data = await res.json().catch(() => ({}));
8341
8291
  return { ok: res.ok, data };
8342
- } catch (err) {
8343
- return { ok: false, data: { error: err instanceof Error ? err.message : String(err) } };
8292
+ } catch {
8293
+ return { ok: false, data: { error: publicErrorMessage("service_unavailable") } };
8344
8294
  }
8345
8295
  }
8346
8296
  async function downloadReplay(sessionId, replayId, filename) {
@@ -8369,8 +8319,8 @@ function registerBrowserAgentMcpTools(server, opts) {
8369
8319
  download_url: `${baseUrl}${path}`
8370
8320
  }
8371
8321
  };
8372
- } catch (err) {
8373
- return { ok: false, data: { error: err instanceof Error ? err.message : String(err) } };
8322
+ } catch {
8323
+ return { ok: false, data: { error: publicErrorMessage("service_unavailable") } };
8374
8324
  }
8375
8325
  }
8376
8326
  const annotations = (title, readOnly = false) => ({
@@ -11522,8 +11472,6 @@ function registerMemoryMcpTools(server, executor) {
11522
11472
 
11523
11473
  export {
11524
11474
  harvestTimeoutBudget,
11525
- sanitizeAttempts,
11526
- sanitizeHarvestResult,
11527
11475
  buildLinkGraph,
11528
11476
  getBlobStore,
11529
11477
  createConnectedDataArtifact,
@@ -11552,4 +11500,4 @@ export {
11552
11500
  MEMORY_TOOL_SCHEMAS,
11553
11501
  registerMemoryMcpTools
11554
11502
  };
11555
- //# sourceMappingURL=chunk-LP6E462I.js.map
11503
+ //# sourceMappingURL=chunk-6SZ52BQ5.js.map