mcp-scraper 0.32.2 → 0.33.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 (36) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +432 -260
  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 +5 -5
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +2 -2
  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 +47 -6
  12. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-stdio-server.js +2 -2
  14. package/dist/bin/paa-harvest.js +1 -1
  15. package/dist/{chunk-MKZIL4EA.js → chunk-AT2PFWHW.js} +5 -5
  16. package/dist/chunk-AT2PFWHW.js.map +1 -0
  17. package/dist/{chunk-AEMABLEL.js → chunk-ERORC7AP.js} +1 -3
  18. package/dist/chunk-IASKABFL.js +7 -0
  19. package/dist/chunk-IASKABFL.js.map +1 -0
  20. package/dist/{chunk-XEED325T.js → chunk-JURXY3DP.js} +48 -7
  21. package/dist/chunk-JURXY3DP.js.map +1 -0
  22. package/dist/index.js +1 -1
  23. package/dist/{server-LTZDJHFG.js → server-RKAKXRAR.js} +378 -247
  24. package/dist/server-RKAKXRAR.js.map +1 -0
  25. package/dist/{worker-ZZCZNY3R.js → worker-JU5FX3NE.js} +2 -2
  26. package/docs/adr/0003-waive-unrecoverable-scheduled-model-cost.md +22 -0
  27. package/docs/adr/README.md +1 -0
  28. package/docs/mcp-tool-manifest.generated.json +170 -13
  29. package/package.json +1 -1
  30. package/dist/chunk-MKZIL4EA.js.map +0 -1
  31. package/dist/chunk-XEED325T.js.map +0 -1
  32. package/dist/chunk-XLO5CZ6T.js +0 -7
  33. package/dist/chunk-XLO5CZ6T.js.map +0 -1
  34. package/dist/server-LTZDJHFG.js.map +0 -1
  35. /package/dist/{chunk-AEMABLEL.js.map → chunk-ERORC7AP.js.map} +0 -0
  36. /package/dist/{worker-ZZCZNY3R.js.map → worker-JU5FX3NE.js.map} +0 -0
@@ -19,7 +19,7 @@ import {
19
19
  } from "./chunk-V73MPRU6.js";
20
20
  import {
21
21
  PACKAGE_VERSION
22
- } from "./chunk-XLO5CZ6T.js";
22
+ } from "./chunk-IASKABFL.js";
23
23
  import {
24
24
  MC_PER_CREDIT
25
25
  } from "./chunk-4767BA2O.js";
@@ -3481,7 +3481,7 @@ var HarvestPaaInputSchema = {
3481
3481
  gl: z.string().length(2).default("us").describe("Google country code inferred from location or user language."),
3482
3482
  hl: z.string().default("en").describe("Google interface/content language inferred from the user request."),
3483
3483
  device: z.enum(["desktop", "mobile"]).default("desktop").describe("SERP device context. Use mobile only for mobile rankings."),
3484
- proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE).describe('Leave unset (clean egress). Do NOT set "location" just because a city was named \u2014 that comes from city-in-query wording. "location" forces residential geo-IP for rank-tracking fidelity, is frequently CAPTCHA-blocked, and accepts failures.'),
3484
+ proxyMode: z.enum(["configured", "none"]).default(DEFAULT_PROXY_MODE).describe("Leave unset for clean egress (the default). Country/region localization comes from gl/hl plus the city or region in the query \u2014 not from a proxy."),
3485
3485
  proxyZip: z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location".'),
3486
3486
  debug: z.boolean().default(false).describe("Include sanitized diagnostics for debugging localization, CAPTCHA, or proxy behavior.")
3487
3487
  };
@@ -3650,7 +3650,7 @@ var MapsSearchInputSchema = {
3650
3650
  hl: z.string().length(2).default("en").describe("Language inferred from user request."),
3651
3651
  maxResults: z.number().int().min(1).max(50).default(10).describe("Number of candidates to return. Default 10, maximum 50."),
3652
3652
  includeServices: z.boolean().default(false).describe("Open each returned business profile to include its configured services and areas served when available. Adds a page visit per business; does not collect review cards."),
3653
- proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE).describe("Leave unset for the default route (stealth browser on the managed ISP proxy, retried on a fresh session when Google blocks). Localization comes from the city in the query plus gl/hl. location forces an explicit residential proxy \u2014 not recommended for Google."),
3653
+ proxyMode: z.enum(["configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE).describe("Leave unset for the default route (stealth browser on the managed ISP proxy, retried on a fresh session when Google blocks). Country/region localization comes from the city or region in the query plus gl/hl \u2014 not from a proxy."),
3654
3654
  proxyZip: z.string().regex(/^\d{5}$/).optional().describe("Optional US ZIP override, only used when proxyMode is location."),
3655
3655
  debug: z.boolean().default(false).describe("Include sanitized browser/proxy diagnostics.")
3656
3656
  };
@@ -3665,7 +3665,7 @@ var DirectoryWorkflowInputSchema = {
3665
3665
  includeZipGroups: z.boolean().default(true).describe("Attach ZIP groups from a configured US ZIPS CSV when available (MCP_SCRAPER_USZIPS_CSV_PATH or usZipsCsvPath)."),
3666
3666
  usZipsCsvPath: z.string().optional().describe("Local/test-only path to a US ZIPS CSV (state_abbr, zipcode, county, city columns). Deployed APIs should use MCP_SCRAPER_USZIPS_CSV_PATH instead. For ZIP enrichment, set MCP_SCRAPER_USZIPS_CSV_PATH on the server, or pass this in local/test mode."),
3667
3667
  saveCsv: z.boolean().default(true).describe("Save a directory-ready CSV of results to the MCP Scraper output directory and return its path."),
3668
- proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE).describe("Proxy behavior per city search. Leave unset for the default route (stealth browser on the managed ISP proxy, retried fresh on a Google block). location forces an explicit residential proxy \u2014 not recommended for Google."),
3668
+ proxyMode: z.enum(["configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE).describe("Proxy behavior per city search. Leave unset for the default route (stealth browser on the managed ISP proxy, retried fresh on a Google block). Country/region localization comes from the city or region in the query plus gl/hl \u2014 not from a proxy."),
3669
3669
  proxyZip: z.string().regex(/^\d{5}$/).optional().describe("Optional ZIP override for proxy targeting; normally omitted."),
3670
3670
  debug: z.boolean().default(false).describe("Include sanitized browser/proxy diagnostics.")
3671
3671
  };
@@ -4505,7 +4505,7 @@ var SearchSerpInputSchema = {
4505
4505
  gl: z.string().length(2).default("us").describe("Google country code inferred from location or user language."),
4506
4506
  hl: z.string().default("en").describe("Google interface/content language inferred from user request."),
4507
4507
  device: z.enum(["desktop", "mobile"]).default("desktop").describe("SERP device context. Use mobile only for mobile rankings."),
4508
- proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE).describe('Leave unset (clean egress). Do NOT set "location" just because a city was named \u2014 that comes from city-in-query wording. "location" forces residential geo-IP for rank-tracking fidelity, is frequently CAPTCHA-blocked, and accepts failures.'),
4508
+ proxyMode: z.enum(["configured", "none"]).default(DEFAULT_PROXY_MODE).describe("Leave unset for clean egress (the default). Country/region localization comes from gl/hl plus the city or region in the query \u2014 not from a proxy."),
4509
4509
  proxyZip: z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location".'),
4510
4510
  debug: z.boolean().default(false).describe("Include sanitized diagnostics for debugging localization, CAPTCHA, or proxy behavior."),
4511
4511
  pages: z.number().int().min(1).max(2).default(1).describe("Number of result pages to fetch (1\u20132).")
@@ -4516,7 +4516,7 @@ var CaptureSerpSnapshotInputSchema = {
4516
4516
  gl: z.string().length(2).default("us").describe("Google country code inferred from the requested market."),
4517
4517
  hl: z.string().default("en").describe("Google interface/content language inferred from the user request."),
4518
4518
  device: z.enum(["desktop", "mobile"]).default("desktop").describe("SERP device context. Use mobile only for mobile rankings/evidence."),
4519
- proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE).describe('Leave unset (clean egress). Do NOT set "location" just because a city was named \u2014 that comes from city-in-query wording. "location" forces residential geo-IP, is frequently CAPTCHA-blocked, and accepts failures.'),
4519
+ proxyMode: z.enum(["configured", "none"]).default(DEFAULT_PROXY_MODE).describe("Leave unset for clean egress (the default). Country/region localization comes from gl/hl plus the city or region in the query \u2014 not from a proxy."),
4520
4520
  proxyZip: z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location".'),
4521
4521
  pages: z.number().int().min(1).max(2).default(1).describe("Google result pages to capture. Use 2 only for deeper ranking evidence."),
4522
4522
  debug: z.boolean().default(false).describe("Include sanitized browser/proxy/location diagnostics."),
@@ -4875,6 +4875,37 @@ var GmailSendMessageOutputSchema = {
4875
4875
  result: z.unknown().optional(),
4876
4876
  error: NullableString
4877
4877
  };
4878
+ var GmailSearchContactsInputSchema = {
4879
+ connectionId: z.string().min(1).describe("A Gmail connectionId from list_service_connections. Read-only \u2014 does not require actionsEnabled."),
4880
+ query: z.string().min(1).max(500).describe('Gmail search syntax, e.g. "from:brandnorth.com after:2026/03/22" or "brandnorth.com".'),
4881
+ maxMessages: z.number().int().min(1).max(150).default(50).describe("Max messages to fetch and aggregate in this call. Paginate with pageToken for more; the response reports totalMatches and truncated so undercoverage is never silent."),
4882
+ pageToken: z.string().optional().describe("Continuation token from a prior response to fetch the next page.")
4883
+ };
4884
+ var GmailSearchContactsOutputSchema = {
4885
+ ok: z.boolean(),
4886
+ totalMatches: z.number().optional().describe("Gmail's estimated total matches for the query, independent of how many were fetched this call."),
4887
+ messagesFetched: z.number().optional(),
4888
+ truncated: z.boolean().optional().describe("True when totalMatches exceeds messagesFetched \u2014 more results exist, use nextPageToken."),
4889
+ nextPageToken: NullableString,
4890
+ messages: z.array(z.object({
4891
+ id: z.string(),
4892
+ date: NullableString,
4893
+ from: NullableString,
4894
+ to: NullableString,
4895
+ subject: NullableString,
4896
+ snippet: NullableString
4897
+ })).optional(),
4898
+ contacts: z.array(z.object({
4899
+ email: z.string(),
4900
+ name: NullableString,
4901
+ domain: NullableString,
4902
+ messageCount: z.number(),
4903
+ firstSeen: NullableString,
4904
+ lastSeen: NullableString,
4905
+ sampleSubjects: z.array(z.string())
4906
+ })).optional().describe("Messages deduped by sender email address, newest-to-oldest within this fetch only \u2014 not the full query result set when truncated."),
4907
+ error: NullableString
4908
+ };
4878
4909
  var GoogleCalendarCreateEventInputSchema = {
4879
4910
  connectionId: z.string().min(1).describe("A Google Calendar connectionId from list_service_connections, with actionsEnabled true."),
4880
4911
  calendarId: z.string().min(1).default("primary").describe('Calendar to create the event in. Default "primary".'),
@@ -5613,6 +5644,13 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
5613
5644
  outputSchema: recordOutputSchema("gmail_send_message", GmailSendMessageOutputSchema),
5614
5645
  annotations: { title: "Send Gmail Message", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }
5615
5646
  }, async (input) => executor.gmailSendMessage(input));
5647
+ server.registerTool("gmail_search_contacts", {
5648
+ title: "Search Gmail Contacts",
5649
+ description: 'Search Gmail with standard Gmail query syntax (e.g. "from:acme.com after:2026/03/22") and get back deduplicated sender contacts (email, name, domain, message count, first/last seen, sample subjects) instead of raw messages. Read-only \u2014 works on any connected Gmail connection from list_service_connections, no actionsEnabled required. Use this instead of looping list-messages/get-message yourself: those return bare message IDs and full raw MIME per message, which does not scale past a handful of messages. Reports totalMatches and truncated so incomplete coverage from a large result set is never silent \u2014 pass the returned nextPageToken to continue.',
5650
+ inputSchema: GmailSearchContactsInputSchema,
5651
+ outputSchema: recordOutputSchema("gmail_search_contacts", GmailSearchContactsOutputSchema),
5652
+ annotations: { title: "Search Gmail Contacts", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }
5653
+ }, async (input) => executor.gmailSearchContacts(input));
5616
5654
  server.registerTool("google_calendar_create_event", {
5617
5655
  title: "Create Calendar Event",
5618
5656
  description: "Create a complete event on a connected, action-enabled Google Calendar connection. Always preserve the supplied purpose in description, include the Zoom join link when available, and include every explicitly named invitee in attendees. Do not create a bare meeting event. Requires a connectionId from list_service_connections with actionsEnabled true.",
@@ -5997,6 +6035,9 @@ var HttpMcpToolExecutor = class {
5997
6035
  gmailSendMessage(input) {
5998
6036
  return this.call("/schedule-connections/actions/gmail/send-message", input);
5999
6037
  }
6038
+ gmailSearchContacts(input) {
6039
+ return this.call("/schedule-connections/actions/gmail/search-contacts", input);
6040
+ }
6000
6041
  googleCalendarCreateEvent(input) {
6001
6042
  return this.call("/schedule-connections/actions/google-calendar/create-event", input);
6002
6043
  }
@@ -10110,4 +10151,4 @@ export {
10110
10151
  MEMORY_TOOL_SCHEMAS,
10111
10152
  registerMemoryMcpTools
10112
10153
  };
10113
- //# sourceMappingURL=chunk-XEED325T.js.map
10154
+ //# sourceMappingURL=chunk-JURXY3DP.js.map