mcp-scraper 0.30.0 → 0.32.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.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +93 -41
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +2 -2
  5. package/dist/bin/mcp-scraper-cli.cjs +4 -1
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +3 -3
  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 +38 -34
  12. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-stdio-server.js +3 -3
  14. package/dist/bin/paa-harvest.cjs +26 -4
  15. package/dist/bin/paa-harvest.cjs.map +1 -1
  16. package/dist/bin/paa-harvest.js +2 -2
  17. package/dist/{chunk-KAMKTSJQ.js → chunk-55M5CE5L.js} +2 -2
  18. package/dist/chunk-CPQF3PYW.js +7 -0
  19. package/dist/chunk-CPQF3PYW.js.map +1 -0
  20. package/dist/{chunk-ZQSHKWV4.js → chunk-PTHY7NYD.js} +4 -1
  21. package/dist/chunk-PTHY7NYD.js.map +1 -0
  22. package/dist/{chunk-YH5DRFWQ.js → chunk-RDCCU7CQ.js} +25 -6
  23. package/dist/chunk-RDCCU7CQ.js.map +1 -0
  24. package/dist/{chunk-T2CIPAOK.js → chunk-YOOEAXWP.js} +37 -36
  25. package/dist/chunk-YOOEAXWP.js.map +1 -0
  26. package/dist/index.cjs +26 -4
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +9 -0
  29. package/dist/index.d.ts +9 -0
  30. package/dist/index.js +2 -2
  31. package/dist/{server-PBPXND5G.js → server-OBOTNFD6.js} +40 -10
  32. package/dist/{server-PBPXND5G.js.map → server-OBOTNFD6.js.map} +1 -1
  33. package/dist/{worker-RYP5EOV5.js → worker-7DJYUACV.js} +3 -3
  34. package/docs/mcp-tool-manifest.generated.json +29 -29
  35. package/package.json +2 -2
  36. package/dist/chunk-T2CIPAOK.js.map +0 -1
  37. package/dist/chunk-WQUF7AH7.js +0 -7
  38. package/dist/chunk-WQUF7AH7.js.map +0 -1
  39. package/dist/chunk-YH5DRFWQ.js.map +0 -1
  40. package/dist/chunk-ZQSHKWV4.js.map +0 -1
  41. /package/dist/{chunk-KAMKTSJQ.js.map → chunk-55M5CE5L.js.map} +0 -0
  42. /package/dist/{worker-RYP5EOV5.js.map → worker-7DJYUACV.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -8,6 +8,9 @@ declare const HarvestOptionsSchema: z.ZodObject<{
8
8
  device: z.ZodDefault<z.ZodEnum<["desktop", "mobile"]>>;
9
9
  proxyMode: z.ZodDefault<z.ZodEnum<["location", "configured", "none"]>>;
10
10
  proxyZip: z.ZodOptional<z.ZodString>;
11
+ keepDefaultProxy: z.ZodOptional<z.ZodBoolean>;
12
+ requireUsEgress: z.ZodOptional<z.ZodBoolean>;
13
+ maxAttempts: z.ZodOptional<z.ZodNumber>;
11
14
  debug: z.ZodDefault<z.ZodBoolean>;
12
15
  depth: z.ZodDefault<z.ZodNumber>;
13
16
  maxQuestions: z.ZodDefault<z.ZodNumber>;
@@ -38,6 +41,9 @@ declare const HarvestOptionsSchema: z.ZodObject<{
38
41
  pages: number;
39
42
  location?: string | undefined;
40
43
  proxyZip?: string | undefined;
44
+ keepDefaultProxy?: boolean | undefined;
45
+ requireUsEgress?: boolean | undefined;
46
+ maxAttempts?: number | undefined;
41
47
  profileDir?: string | undefined;
42
48
  proxy?: string | undefined;
43
49
  kernelApiKey?: string | undefined;
@@ -52,6 +58,9 @@ declare const HarvestOptionsSchema: z.ZodObject<{
52
58
  device?: "desktop" | "mobile" | undefined;
53
59
  proxyMode?: "none" | "location" | "configured" | undefined;
54
60
  proxyZip?: string | undefined;
61
+ keepDefaultProxy?: boolean | undefined;
62
+ requireUsEgress?: boolean | undefined;
63
+ maxAttempts?: number | undefined;
55
64
  debug?: boolean | undefined;
56
65
  depth?: number | undefined;
57
66
  maxQuestions?: number | undefined;
package/dist/index.d.ts CHANGED
@@ -8,6 +8,9 @@ declare const HarvestOptionsSchema: z.ZodObject<{
8
8
  device: z.ZodDefault<z.ZodEnum<["desktop", "mobile"]>>;
9
9
  proxyMode: z.ZodDefault<z.ZodEnum<["location", "configured", "none"]>>;
10
10
  proxyZip: z.ZodOptional<z.ZodString>;
11
+ keepDefaultProxy: z.ZodOptional<z.ZodBoolean>;
12
+ requireUsEgress: z.ZodOptional<z.ZodBoolean>;
13
+ maxAttempts: z.ZodOptional<z.ZodNumber>;
11
14
  debug: z.ZodDefault<z.ZodBoolean>;
12
15
  depth: z.ZodDefault<z.ZodNumber>;
13
16
  maxQuestions: z.ZodDefault<z.ZodNumber>;
@@ -38,6 +41,9 @@ declare const HarvestOptionsSchema: z.ZodObject<{
38
41
  pages: number;
39
42
  location?: string | undefined;
40
43
  proxyZip?: string | undefined;
44
+ keepDefaultProxy?: boolean | undefined;
45
+ requireUsEgress?: boolean | undefined;
46
+ maxAttempts?: number | undefined;
41
47
  profileDir?: string | undefined;
42
48
  proxy?: string | undefined;
43
49
  kernelApiKey?: string | undefined;
@@ -52,6 +58,9 @@ declare const HarvestOptionsSchema: z.ZodObject<{
52
58
  device?: "desktop" | "mobile" | undefined;
53
59
  proxyMode?: "none" | "location" | "configured" | undefined;
54
60
  proxyZip?: string | undefined;
61
+ keepDefaultProxy?: boolean | undefined;
62
+ requireUsEgress?: boolean | undefined;
63
+ maxAttempts?: number | undefined;
55
64
  debug?: boolean | undefined;
56
65
  depth?: number | undefined;
57
66
  maxQuestions?: number | undefined;
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  harvest
3
- } from "./chunk-YH5DRFWQ.js";
3
+ } from "./chunk-RDCCU7CQ.js";
4
4
  import {
5
5
  recordVendorUsage
6
6
  } from "./chunk-MTSBI7ZH.js";
7
7
  import "./chunk-K443GQY5.js";
8
- import "./chunk-ZQSHKWV4.js";
8
+ import "./chunk-PTHY7NYD.js";
9
9
  import "./chunk-M2S27J6Z.js";
10
10
  import "./chunk-ICT7DDHL.js";
11
11
 
@@ -16,7 +16,7 @@ import {
16
16
  harvest,
17
17
  normalizeLocation,
18
18
  resolveKernelProxyId
19
- } from "./chunk-YH5DRFWQ.js";
19
+ } from "./chunk-RDCCU7CQ.js";
20
20
  import {
21
21
  HttpMcpToolExecutor,
22
22
  assessTranscriptSignal,
@@ -36,7 +36,7 @@ import {
36
36
  sanitizeAttempts,
37
37
  sanitizeHarvestResult,
38
38
  transcribeMediaUrl
39
- } from "./chunk-T2CIPAOK.js";
39
+ } from "./chunk-YOOEAXWP.js";
40
40
  import {
41
41
  auditImages,
42
42
  buildLinkReport,
@@ -65,7 +65,7 @@ import {
65
65
  workflowOutputBaseDir,
66
66
  workflowStepCount,
67
67
  workflowSupportsSteps
68
- } from "./chunk-KAMKTSJQ.js";
68
+ } from "./chunk-55M5CE5L.js";
69
69
  import "./chunk-K443GQY5.js";
70
70
  import {
71
71
  DEFAULT_MAPS_PROXY_MODE,
@@ -76,8 +76,8 @@ import {
76
76
  RawMapsHoursRowSchema,
77
77
  RawMapsOverviewSchema,
78
78
  RawMapsReviewStatsSchema
79
- } from "./chunk-ZQSHKWV4.js";
80
- import "./chunk-WQUF7AH7.js";
79
+ } from "./chunk-PTHY7NYD.js";
80
+ import "./chunk-CPQF3PYW.js";
81
81
  import {
82
82
  completeExtractJob,
83
83
  countSuccessfulPages,
@@ -129,6 +129,7 @@ import {
129
129
  } from "./chunk-4767BA2O.js";
130
130
  import {
131
131
  CaptchaError,
132
+ ExtractionError,
132
133
  RECAPTCHA_INSTRUCTIONS,
133
134
  sanitizeVendorName
134
135
  } from "./chunk-M2S27J6Z.js";
@@ -13088,6 +13089,12 @@ function buildGoogleLocalResultsUrl(input) {
13088
13089
  if (input.location) params.set("uule", encodeUule(normalizeLocation(input.location)));
13089
13090
  return `https://www.google.com/search?${params.toString()}`;
13090
13091
  }
13092
+ function buildGoogleOrganicSearchUrl(input) {
13093
+ const query = [input.query, input.location].filter(Boolean).join(" ");
13094
+ const params = new URLSearchParams({ q: query, gl: input.gl, hl: input.hl, pws: "0" });
13095
+ if (input.location) params.set("uule", encodeUule(normalizeLocation(input.location)));
13096
+ return `https://www.google.com/search?${params.toString()}`;
13097
+ }
13091
13098
  var MapsSearchExtractor = class {
13092
13099
  constructor(driver) {
13093
13100
  this.driver = driver;
@@ -13096,13 +13103,14 @@ var MapsSearchExtractor = class {
13096
13103
  async extract(options) {
13097
13104
  const startMs = Date.now();
13098
13105
  const searchQuery = [options.query, options.location].filter(Boolean).join(" ");
13099
- const searchUrl = buildGoogleLocalResultsUrl(options);
13106
+ const searchUrl = buildGoogleOrganicSearchUrl(options);
13100
13107
  const config = {
13101
13108
  headless: options.headless,
13102
13109
  kernelApiKey: options.kernelApiKey,
13103
13110
  kernelProxyId: options.kernelProxyId,
13104
13111
  kernelProxyResolution: options.kernelProxyResolution,
13105
13112
  proxyMode: options.proxyMode,
13113
+ keepDefaultProxy: options.proxyMode !== "location" && options.proxyMode !== "configured" && !options.kernelProxyId,
13106
13114
  viewport: { width: 1280, height: 900 },
13107
13115
  locale: `${options.hl}-${options.gl.toUpperCase()}`,
13108
13116
  debug: options.debug
@@ -13113,6 +13121,10 @@ var MapsSearchExtractor = class {
13113
13121
  await page.goto(searchUrl, { waitUntil: "domcontentloaded", timeout: 6e4 });
13114
13122
  await page.waitForTimeout(LOCAL_RESULTS_WAIT_MS);
13115
13123
  if (await this.detectBlock(page)) throw new CaptchaError(RECAPTCHA_INSTRUCTIONS);
13124
+ const reachedFinder = await this.clickIntoLocalFinder(page);
13125
+ if (!reachedFinder) throw new ExtractionError('Google "More businesses" control was not found on the organic results page');
13126
+ await page.waitForTimeout(LOCAL_RESULTS_WAIT_MS);
13127
+ if (await this.detectBlock(page)) throw new CaptchaError(RECAPTCHA_INSTRUCTIONS);
13116
13128
  const results = await this.collectResults(page, options);
13117
13129
  return {
13118
13130
  query: options.query,
@@ -13129,6 +13141,17 @@ var MapsSearchExtractor = class {
13129
13141
  await this.driver.close();
13130
13142
  }
13131
13143
  }
13144
+ async clickIntoLocalFinder(page) {
13145
+ const control = page.getByRole("link", { name: /more (businesses|places|results)/i }).or(page.getByRole("button", { name: /more (businesses|places|results)/i })).first();
13146
+ const visible = await control.isVisible({ timeout: 1e4 }).catch(() => false);
13147
+ if (!visible) return false;
13148
+ await control.click({ timeout: 1e4 }).catch(() => {
13149
+ });
13150
+ await page.waitForTimeout(5e3);
13151
+ return page.evaluate(
13152
+ () => /[?&]udm=1/.test(location.href) || document.querySelectorAll('a[href*="/maps/place/"]').length > 0
13153
+ );
13154
+ }
13132
13155
  async detectBlock(page) {
13133
13156
  return page.evaluate(() => {
13134
13157
  const text2 = document.body.innerText.slice(0, 2e3);
@@ -20698,7 +20721,7 @@ loadChannels();
20698
20721
 
20699
20722
  // src/api/vault-routes.ts
20700
20723
  import { Hono as Hono22 } from "hono";
20701
- var VAULTS = ["People", "Deals", "Projects", "Tasks", "Communications", "Calendar"];
20724
+ var VAULTS = ["People", "Organizations", "Deals", "Projects", "Tasks", "Communications", "Calendar"];
20702
20725
  var PROJECT_TYPES = ["codebase", "personal", "work", "client"];
20703
20726
  var PROJECT_KIND_BY_TYPE = {
20704
20727
  codebase: "codebase",
@@ -20782,6 +20805,7 @@ function normalizeRelationshipProps(vault, props) {
20782
20805
  }
20783
20806
  function defaultType(vault) {
20784
20807
  if (vault === "People" || vault === "Communications") return "unclassified";
20808
+ if (vault === "Organizations") return "organization";
20785
20809
  if (vault === "Deals") return "deal";
20786
20810
  if (vault === "Projects") return "project";
20787
20811
  if (vault === "Tasks") return "task";
@@ -20789,7 +20813,7 @@ function defaultType(vault) {
20789
20813
  return "unclassified";
20790
20814
  }
20791
20815
  function defaultStatus(vault) {
20792
- if (vault === "People") return "active";
20816
+ if (vault === "People" || vault === "Organizations") return "active";
20793
20817
  if (vault === "Deals") return "lead";
20794
20818
  if (vault === "Projects") return "active";
20795
20819
  if (vault === "Tasks") return "to_do";
@@ -20802,6 +20826,12 @@ function nonEmptyStrings(value) {
20802
20826
  function validateNewRecord(vault, props) {
20803
20827
  const type = typeof props.type === "string" ? props.type : "";
20804
20828
  if (vault === "People" && !["person", "organization"].includes(type)) return "People records must be a person or organization";
20829
+ if (vault === "Organizations") {
20830
+ if (type !== "organization") return "Organizations records must have type organization";
20831
+ if (typeof props.organization_name !== "string" || !props.organization_name.trim()) {
20832
+ return "Organizations require organization_name";
20833
+ }
20834
+ }
20805
20835
  if (vault === "Deals") {
20806
20836
  if (type !== "deal") return "Deals records must have type deal";
20807
20837
  if (typeof props.organization_ref !== "string" && nonEmptyStrings(props.person_refs).length === 0) {
@@ -27375,7 +27405,7 @@ app.get("/cron/tick", async (c) => {
27375
27405
  if (!process.env.CRON_SECRET || secret2 !== `Bearer ${process.env.CRON_SECRET}`) {
27376
27406
  return c.json({ error: "Unauthorized" }, 401);
27377
27407
  }
27378
- const { drainQueue } = await import("./worker-RYP5EOV5.js");
27408
+ const { drainQueue } = await import("./worker-7DJYUACV.js");
27379
27409
  const budget = { maxJobs: 10, deadlineMs: Date.now() + 28e4 };
27380
27410
  const workflowDispatchResult = await dispatchDueWorkflowSchedules(`${new URL(c.req.url).protocol}//${new URL(c.req.url).host}`);
27381
27411
  const [results, sweepResult, reapResult, expiredResult, blobCleanup, connectedDataArtifactCleanup] = await Promise.all([
@@ -27578,4 +27608,4 @@ app.get("/blog/:slug/", (c) => {
27578
27608
  export {
27579
27609
  app
27580
27610
  };
27581
- //# sourceMappingURL=server-PBPXND5G.js.map
27611
+ //# sourceMappingURL=server-OBOTNFD6.js.map