mcp-scraper 0.90.4 → 0.90.6

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 (45) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +2 -2
  3. package/dist/{analytics-repository-UX6VU22H.js → analytics-repository-WNJESD4A.js} +1 -1
  4. package/dist/bin/api-server.js +2 -2
  5. package/dist/bin/mcp-scraper-cli.js +1 -1
  6. package/dist/bin/mcp-scraper-core.js +1 -1
  7. package/dist/bin/mcp-scraper-install.js +1 -1
  8. package/dist/bin/mcp-stdio-server.js +1 -1
  9. package/dist/bin/paa-harvest.js +1 -1
  10. package/dist/{chunk-HR2A2WTL.js → chunk-4OTWTGKC.js} +1 -1
  11. package/dist/{chunk-DKQZNSYM.js → chunk-56UT5M5Y.js} +4 -4
  12. package/dist/{chunk-7QHYBK6U.js → chunk-5MMN27Q6.js} +2 -2
  13. package/dist/{chunk-7AC66V3T.js → chunk-AAJG5OHF.js} +1 -1
  14. package/dist/{chunk-HR2ALIEH.js → chunk-AQSMJCTF.js} +1 -1
  15. package/dist/{chunk-GW6ITK76.js → chunk-AQXYXVOP.js} +8 -8
  16. package/dist/{chunk-JSNFZPPB.js → chunk-BVSK6YHX.js} +1 -1
  17. package/dist/{chunk-LZTDANNZ.js → chunk-COIA4RW4.js} +1 -1
  18. package/dist/{chunk-YEFXVTMJ.js → chunk-CTX3NMZQ.js} +1 -1
  19. package/dist/{chunk-7BEWBRMT.js → chunk-KKHTMYCD.js} +198 -87
  20. package/dist/{chunk-HJ7OGU2J.js → chunk-MADTJXNI.js} +1 -1
  21. package/dist/chunk-NOUHD54C.js +48 -0
  22. package/dist/{chunk-ZMLCK45S.js → chunk-NWRRVZKW.js} +1 -1
  23. package/dist/{chunk-2GRE4BAO.js → chunk-Q5SUDDSQ.js} +1 -1
  24. package/dist/chunk-UM4WSLKQ.js +1 -0
  25. package/dist/{chunk-WTOKMWDS.js → chunk-WDB5CTRY.js} +1 -1
  26. package/dist/chunk-XARSC34L.js +1279 -0
  27. package/dist/{chunk-JVU2THSY.js → chunk-XXK5PLRB.js} +1 -1
  28. package/dist/{chunk-3R5QLQT3.js → chunk-YDOBZMLS.js} +1 -1
  29. package/dist/{db-UKQ74OVT.js → db-XN7YPDGC.js} +1 -1
  30. package/dist/{extract-bundle-7BI2K26D.js → extract-bundle-CP6WBOJI.js} +1 -1
  31. package/dist/{gmail-service-Y2UZX3YW.js → gmail-service-5NH2GVQ5.js} +1 -1
  32. package/dist/index.cjs +46 -46
  33. package/dist/index.js +1 -1
  34. package/dist/{lead-list-enrichment-repository-GPDHJVM3.js → lead-list-enrichment-repository-AIMOP7YM.js} +1 -1
  35. package/dist/{location-data-repository-MXUNVDHW.js → location-data-repository-25D3GHXE.js} +1 -1
  36. package/dist/server-TQJ6Z3ZF.js +4931 -0
  37. package/dist/{site-extract-repository-T23S2T7L.js → site-extract-repository-KG6FQU55.js} +1 -1
  38. package/dist/{stripe-event-worker-HVCB6SF3.js → stripe-event-worker-ZNNQEVK4.js} +1 -1
  39. package/dist/worker-4LFWAEX2.js +1 -0
  40. package/package.json +1 -1
  41. package/dist/chunk-KJA62B7P.js +0 -1
  42. package/dist/chunk-LTT2B7NY.js +0 -1280
  43. package/dist/chunk-PHBU6X5B.js +0 -1
  44. package/dist/server-ZZVUT4N6.js +0 -6517
  45. package/dist/worker-KFILERH3.js +0 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,40 @@ All notable changes to MCP Scraper are documented here. The format is based on [
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.90.6] - 2026-09-22
8
+
9
+ ### Added
10
+
11
+ - Add one immutable SERP/PAA execution plan per attempt, record planned and observed provider identity, and fail closed when runtime provider selection disagrees with the plan.
12
+ - Add normalized provider-cost, billing, refund, retry, and reconciliation evidence to the CEO and CTO reporting path, plus deterministic project-skill projection and repository architecture/topology gates.
13
+ - Add a source-backed incident reconciliation for the 22–23 September SERP and Maps failures, including exact timeout debit outcomes, missing-page and location cases, and the Maps attempt/egress chain.
14
+
15
+ ### Changed
16
+
17
+ - Retire the inactive Personal Assistant from server startup, HTTP and MCP routing, web navigation, Scheduler transitions, generated contracts, and Memory tool registration while preserving its source history, persisted data, secrets, and provider resources behind the verified archive branch.
18
+ - Make two-page SERP capture perform a distinct page-two request, preserve page provenance and query/location intent, and report local-pack evidence as present, absent, incomplete, or unknown instead of silently claiming completeness.
19
+ - Make Maps retries follow one immutable egress plan, retain location intent, close every browser/proxy attempt, and treat an already-gone Option 1 session as successful cleanup.
20
+
21
+ ### Fixed
22
+
23
+ - Replay the original synchronous SERP job and settlement under the same idempotency key after response loss instead of starting and charging replacement work.
24
+ - Return stable extraction and SERP completeness diagnostics for incomplete provider results, duplicate page content, local-pack uncertainty, and provider mismatches.
25
+ - Order provider receipts deterministically within an attempt so reports and incident traces preserve the actual creation sequence.
26
+
27
+ ## [0.90.5] - 2026-09-22
28
+
29
+ ### Added
30
+
31
+ - Add the fixture-tested operation, attempt, provider-receipt, reconciliation, and billing-link foundation needed to trace failed and retried SERP, PAA, Maps, extraction, and transcription work without treating missing provider cost as zero.
32
+ - Add a generated MCP cost-coverage manifest and release gate that tracks every hosted input flag plus each named execution method's retry, timeout, billing, and cost-accounting owner.
33
+ - Trace direct Option 2 SERP requests and Option 2/Option 1 browser attempts into the shared operation timeline, including provider identities, retry or fallback causality, immediate estimates, hourly due-gated Browser API reconciliation, and customer billing links.
34
+ - Add a protected four-cell PAA benchmark runner for Option 1 and Option 2 at 20 and 40 complete questions, with a dry-run contract gate, one paid attempt per cell, sanitized provider evidence, and no automatic replacement run.
35
+ - Add a once-daily due-gated purge of raw provider identifiers and verbose diagnostic errors after 30 days while preserving normalized cost facts and hashed correlation keys.
36
+
37
+ ### Fixed
38
+
39
+ - Skip Option 1 proxy resolution when the active attempt uses Option 2 Browser, removing avoidable Option 1 API traffic from Option 2-first SERP and PAA work.
40
+
7
41
  ## [0.90.4] - 2026-09-22
8
42
 
9
43
  ### Fixed
package/README.md CHANGED
@@ -175,7 +175,7 @@ Build the branded one-click bundle:
175
175
  npm run build:mcpb
176
176
  ```
177
177
 
178
- The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.90.4`, SHA-256 `28437a63b5a6ee6b92b5e3fae425ddea27b31b1ac999873102c197e354c84a5d`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, API-key configuration field, and manually curated current-release message from the bundle manifest.
178
+ The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.90.6`, SHA-256 `c204ca38897d1721efe9291706a01df536de5da485488602fda5c2f84ea4d231`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, API-key configuration field, and manually curated current-release message from the bundle manifest.
179
179
 
180
180
  The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
181
181
 
@@ -351,7 +351,7 @@ The `mcp-scraper` server (and the MCPB bundle, which runs it) exposes both secti
351
351
 
352
352
  All MCP tools return `structuredContent` with the IDs, URLs, CSV paths, transcripts, browser session handles, replay paths, artifacts, recipe fields, or blueprint fields needed by the next step, plus readable text content for compatibility. Runtime `tools/list` omits output schemas so strict clients can register the complete catalog; the generated developer manifest retains every canonical output schema for validation and typed SDK generation. All tools carry MCP annotations; file-writing tools such as replay downloads and annotations state their filesystem side effects.
353
353
 
354
- The canonical tool inventory is generated at `docs/mcp-tool-manifest.generated.json`. The unified server exposes 378 tools: 252 scraper, browser, workflow, billing, connected-service, and personal-assistant tools plus 126 durable-memory tools. The two retired customer credential mutations are no longer advertised. The scraper-side inventory includes complete Gmail selection, message, attachment, export, bulk-action, and Memory-import workflows; governed personal-assistant commands, messaging, approvals, grants, number setup, and execution readback; durable SERP, PAA, and single-page extraction starts and status; rendered site-content similarity; governed Local Sourcebook and Transparent Commons workflows; direct site-export reads; Editorial Reading Room and News Publisher templates; and production X-Ray setup, analytics, seven-model attribution, structured post-purchase surveys, reported impact, truthful view-evidence status, CRM policy and receipt, campaign, export, and scheduled-report tools. Provider setup remains absent until its authorization, ingestion, reconciliation, privacy, canary, cleanup, and deployment receipts are complete. Successful evidence-compiled Local Sourcebook revisions publish automatically to their canonical `localsourcebook.com` category profile and review URLs; administrator controls handle exceptional rejection or unpublishing. Release verification compares the exact local and hosted tool-name sets, not only the count.
354
+ The canonical tool inventory is generated at `docs/mcp-tool-manifest.generated.json`. The unified server exposes 361 tools: 235 scraper, browser, workflow, billing, and connected-service tools plus 126 durable-memory tools. Personal Assistant tools and routes are retired from active builds; their source history and persisted data remain recoverable from the archived pre-retirement branch. The scraper-side inventory includes complete Gmail selection, message, attachment, export, bulk-action, and Memory-import workflows; durable SERP, PAA, and single-page extraction starts and status; rendered site-content similarity; governed Local Sourcebook and Transparent Commons workflows; direct site-export reads; Editorial Reading Room and News Publisher templates; and production X-Ray setup, analytics, seven-model attribution, structured post-purchase surveys, reported impact, truthful view-evidence status, CRM policy and receipt, campaign, export, and scheduled-report tools. Provider setup remains absent until its authorization, ingestion, reconciliation, privacy, canary, cleanup, and deployment receipts are complete. Successful evidence-compiled Local Sourcebook revisions publish automatically to their canonical `localsourcebook.com` category profile and review URLs; administrator controls handle exceptional rejection or unpublishing. Release verification compares the exact local and hosted tool-name sets, not only the count.
355
355
 
356
356
  For contract parity, stdio and MCPB memory calls invoke the matching public tool on the hosted MCP Scraper `/mcp` endpoint. The hosted aggregate runtime owns MCP Scraper-specific billing, scheduling, credential, and in-process cutover policy; its internal `/memory/mcp-call` bridge is a fallback to the standalone Memory service, not a second customer setup path. Existing direct Memory credentials remain compatible for one release, but all new customer setup uses the root endpoint and `MCP_SCRAPER_API_KEY`.
357
357
 
@@ -1 +1 @@
1
- import{$ as L,$a as La,A as k,Aa as ka,B as l,Ba as la,C as m,Ca as ma,D as n,Da as na,E as o,Ea as oa,F as p,Fa as pa,G as q,Ga as qa,H as r,Ha as ra,I as s,Ia as sa,J as t,Ja as ta,K as u,Ka as ua,L as v,La as va,M as w,Ma as wa,N as x,Na as xa,O as y,Oa as ya,P as z,Pa as za,Q as A,Qa as Aa,R as B,Ra as Ba,S as C,Sa as Ca,T as D,Ta as Da,U as E,Ua as Ea,V as F,Va as Fa,W as G,Wa as Ga,X as H,Xa as Ha,Y as I,Ya as Ia,Z as J,Za as Ja,_ as K,_a as Ka,aa as M,ab as Ma,ba as N,bb as Na,ca as O,da as P,ea as Q,fa as R,ga as S,ha as T,ia as U,ja as V,ka as W,la as X,ma as Y,na as Z,oa as _,pa as $,q as a,qa as aa,r as b,ra as ba,s as c,sa as ca,t as d,ta as da,u as e,ua as ea,v as f,va as fa,w as g,wa as ga,x as h,xa as ha,y as i,ya as ia,z as j,za as ja}from"./chunk-HR2A2WTL.js";import"./chunk-2GRE4BAO.js";import"./chunk-7BEWBRMT.js";export{P as ANALYTICS_CONTENT_SORTS,a as AnalyticsRepositoryError,B as ENGAGED_SESSION_MS,A as MAX_ENGAGED_MS,N as analyticsAcquisition,l as analyticsBusinessMetrics,O as analyticsChannelBreakdown,R as analyticsContent,T as analyticsConversions,Ma as analyticsCsvCell,V as analyticsDimensions,S as analyticsEventCounts,m as analyticsForecast,Ja as analyticsHealth,x as analyticsIdentityPromotionAllowed,w as analyticsIdentityResolutionAllowed,L as analyticsOverview,U as analyticsPaths,M as analyticsTimeseries,H as appendAnalyticsAuthoritativeOutcomeVersion,ta as archiveAnalyticsActivationDestination,Y as archiveAnalyticsCampaignLink,ga as assignAnalyticsIdentityNode,fa as backfillAnalyticsConfirmedHistory,oa as claimAnalyticsCrmImportRows,Ea as claimAnalyticsFormDeliveryJobs,c as closeAnalyticsPool,pa as completeAnalyticsCrmImportRow,Ga as completeAnalyticsFormBridgeDelivery,Fa as completeAnalyticsFormDelivery,J as consumeAnalyticsSurveyInvite,ra as createAnalyticsActivationDestination,W as createAnalyticsCampaignLink,K as createAnalyticsConversion,ma as createAnalyticsCrmImport,Na as createAnalyticsExport,_ as createAnalyticsForm,o as createAnalyticsPixel,h as createAnalyticsSite,qa as deferAnalyticsCrmImportRow,Ha as deferAnalyticsFormDelivery,n as deleteAnalyticsSite,ea as deterministicAnalyticsCrmEntityId,ja as enrichAnalyticsExistingCrmIdentity,ua as getAnalyticsActivationDestinationConnectionRef,la as getAnalyticsPersonJourney,b as getAnalyticsPool,aa as getPublicAnalyticsForm,da as identityHmac,F as ingestAnalyticsEvents,G as insertAnalyticsRevenueSetupRevision,Ia as isAnalyticsFormPlacementApproved,ia as linkAnalyticsFormIdentity,ha as linkAnalyticsIdentityInTransaction,sa as listAnalyticsActivationDestinations,xa as listAnalyticsActivationReceipts,X as listAnalyticsCampaignLinks,na as listAnalyticsCrmImports,$ as listAnalyticsForms,t as listAnalyticsHostGroups,ka as listAnalyticsPeople,p as listAnalyticsPixels,i as listAnalyticsSites,d as migrateAnalytics,C as normalizeAnalyticsPath,D as normalizeAnalyticsUrl,Q as normalizeContentOptions,e as normalizeObservedHostname,za as pollAnalyticsActivationDiagnostics,u as prepareAnalyticsLinkerIssue,I as projectAnalyticsAuthoritativeConversion,y as projectAnalyticsPixelEventConsent,Aa as queueAnalyticsActivation,Ca as queueAnalyticsFormBridgeTransaction,Ba as queueAnalyticsFormDelivery,ba as recordAnalyticsFormSubmission,v as redeemAnalyticsLinkerRecord,Ka as refreshAnalyticsDailyRollups,La as refreshAnalyticsDailyRollupsIfDue,f as requireAnalyticsAccess,g as requireAnalyticsEditor,Z as resolveAnalyticsCampaignLink,z as resolveAnalyticsConfirmedActivationIdentity,ya as retryAnalyticsActivationJob,E as sanitizeAnalyticsProperties,ca as sanitizeClickIds,va as setAnalyticsActivationReadiness,r as setAnalyticsPixelDomainState,Da as sweepAnalyticsRestrictedRetention,wa as testAnalyticsActivationDestination,j as updateAnalyticsBusinessModel,q as updateAnalyticsPixel,k as upsertAnalyticsAdSpend,s as upsertAnalyticsHostGroup};
1
+ import{$ as L,$a as La,A as k,Aa as ka,B as l,Ba as la,C as m,Ca as ma,D as n,Da as na,E as o,Ea as oa,F as p,Fa as pa,G as q,Ga as qa,H as r,Ha as ra,I as s,Ia as sa,J as t,Ja as ta,K as u,Ka as ua,L as v,La as va,M as w,Ma as wa,N as x,Na as xa,O as y,Oa as ya,P as z,Pa as za,Q as A,Qa as Aa,R as B,Ra as Ba,S as C,Sa as Ca,T as D,Ta as Da,U as E,Ua as Ea,V as F,Va as Fa,W as G,Wa as Ga,X as H,Xa as Ha,Y as I,Ya as Ia,Z as J,Za as Ja,_ as K,_a as Ka,aa as M,ab as Ma,ba as N,bb as Na,ca as O,da as P,ea as Q,fa as R,ga as S,ha as T,ia as U,ja as V,ka as W,la as X,ma as Y,na as Z,oa as _,pa as $,q as a,qa as aa,r as b,ra as ba,s as c,sa as ca,t as d,ta as da,u as e,ua as ea,v as f,va as fa,w as g,wa as ga,x as h,xa as ha,y as i,ya as ia,z as j,za as ja}from"./chunk-4OTWTGKC.js";import"./chunk-Q5SUDDSQ.js";import"./chunk-KKHTMYCD.js";export{P as ANALYTICS_CONTENT_SORTS,a as AnalyticsRepositoryError,B as ENGAGED_SESSION_MS,A as MAX_ENGAGED_MS,N as analyticsAcquisition,l as analyticsBusinessMetrics,O as analyticsChannelBreakdown,R as analyticsContent,T as analyticsConversions,Ma as analyticsCsvCell,V as analyticsDimensions,S as analyticsEventCounts,m as analyticsForecast,Ja as analyticsHealth,x as analyticsIdentityPromotionAllowed,w as analyticsIdentityResolutionAllowed,L as analyticsOverview,U as analyticsPaths,M as analyticsTimeseries,H as appendAnalyticsAuthoritativeOutcomeVersion,ta as archiveAnalyticsActivationDestination,Y as archiveAnalyticsCampaignLink,ga as assignAnalyticsIdentityNode,fa as backfillAnalyticsConfirmedHistory,oa as claimAnalyticsCrmImportRows,Ea as claimAnalyticsFormDeliveryJobs,c as closeAnalyticsPool,pa as completeAnalyticsCrmImportRow,Ga as completeAnalyticsFormBridgeDelivery,Fa as completeAnalyticsFormDelivery,J as consumeAnalyticsSurveyInvite,ra as createAnalyticsActivationDestination,W as createAnalyticsCampaignLink,K as createAnalyticsConversion,ma as createAnalyticsCrmImport,Na as createAnalyticsExport,_ as createAnalyticsForm,o as createAnalyticsPixel,h as createAnalyticsSite,qa as deferAnalyticsCrmImportRow,Ha as deferAnalyticsFormDelivery,n as deleteAnalyticsSite,ea as deterministicAnalyticsCrmEntityId,ja as enrichAnalyticsExistingCrmIdentity,ua as getAnalyticsActivationDestinationConnectionRef,la as getAnalyticsPersonJourney,b as getAnalyticsPool,aa as getPublicAnalyticsForm,da as identityHmac,F as ingestAnalyticsEvents,G as insertAnalyticsRevenueSetupRevision,Ia as isAnalyticsFormPlacementApproved,ia as linkAnalyticsFormIdentity,ha as linkAnalyticsIdentityInTransaction,sa as listAnalyticsActivationDestinations,xa as listAnalyticsActivationReceipts,X as listAnalyticsCampaignLinks,na as listAnalyticsCrmImports,$ as listAnalyticsForms,t as listAnalyticsHostGroups,ka as listAnalyticsPeople,p as listAnalyticsPixels,i as listAnalyticsSites,d as migrateAnalytics,C as normalizeAnalyticsPath,D as normalizeAnalyticsUrl,Q as normalizeContentOptions,e as normalizeObservedHostname,za as pollAnalyticsActivationDiagnostics,u as prepareAnalyticsLinkerIssue,I as projectAnalyticsAuthoritativeConversion,y as projectAnalyticsPixelEventConsent,Aa as queueAnalyticsActivation,Ca as queueAnalyticsFormBridgeTransaction,Ba as queueAnalyticsFormDelivery,ba as recordAnalyticsFormSubmission,v as redeemAnalyticsLinkerRecord,Ka as refreshAnalyticsDailyRollups,La as refreshAnalyticsDailyRollupsIfDue,f as requireAnalyticsAccess,g as requireAnalyticsEditor,Z as resolveAnalyticsCampaignLink,z as resolveAnalyticsConfirmedActivationIdentity,ya as retryAnalyticsActivationJob,E as sanitizeAnalyticsProperties,ca as sanitizeClickIds,va as setAnalyticsActivationReadiness,r as setAnalyticsPixelDomainState,Da as sweepAnalyticsRestrictedRetention,wa as testAnalyticsActivationDestination,j as updateAnalyticsBusinessModel,q as updateAnalyticsPixel,k as upsertAnalyticsAdSpend,s as upsertAnalyticsHostGroup};
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{readFileSync as a}from"fs";function c(){try{for(let t of a(".env","utf8").split(`
3
- `)){let o=t.indexOf("=");if(o<1||t.trimStart().startsWith("#"))continue;let e=t.slice(0,o).trim();process.env[e]||(process.env[e]=t.slice(o+1).trim())}}catch{}}c();async function p(){let[{serve:t},{app:o,personalAssistantProductionStartup:e},{startWorker:i},{migrate:n}]=await Promise.all([import("@hono/node-server"),import("../server-ZZVUT4N6.js"),import("../worker-KFILERH3.js"),import("../db-UKQ74OVT.js")]),s=parseInt(process.env.PORT??"3001");try{if(await e,await n(),process.env.ANALYTICS_DATABASE_URL){let{migrateAnalytics:r}=await import("../analytics-repository-UX6VU22H.js");await r()}i(),t({fetch:o.fetch,port:s},r=>{console.log(`[server] http://localhost:${r.port}`),console.log(`[server] admin auth: ${process.env.ADMIN_KEY?"configured":"not configured"}`)})}catch(r){console.error("[startup] server preflight failed",r instanceof Error?r.name:"unknown_error"),process.exit(1)}}p();
2
+ import{readFileSync as s}from"fs";function c(){try{for(let r of s(".env","utf8").split(`
3
+ `)){let o=r.indexOf("=");if(o<1||r.trimStart().startsWith("#"))continue;let e=r.slice(0,o).trim();process.env[e]||(process.env[e]=r.slice(o+1).trim())}}catch{}}c();async function a(){let[{serve:r},{app:o},{startWorker:e},{migrate:i}]=await Promise.all([import("@hono/node-server"),import("../server-TQJ6Z3ZF.js"),import("../worker-4LFWAEX2.js"),import("../db-XN7YPDGC.js")]),n=parseInt(process.env.PORT??"3001");try{if(await i(),process.env.ANALYTICS_DATABASE_URL){let{migrateAnalytics:t}=await import("../analytics-repository-WNJESD4A.js");await t()}e(),r({fetch:o.fetch,port:n},t=>{console.log(`[server] http://localhost:${t.port}`),console.log(`[server] admin auth: ${process.env.ADMIN_KEY?"configured":"not configured"}`)})}catch(t){console.error("[startup] server preflight failed",t instanceof Error?t.name:"unknown_error"),process.exit(1)}}a();
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{b as E,c as N,d as M,e as L,f as T,j as U}from"../chunk-JHMI6HEO.js";import"../chunk-KJQXUZ4Y.js";import"../chunk-2TZBO52D.js";import{g as v,j as b,k as D,l as K,m as H}from"../chunk-WO3N5FH2.js";import"../chunk-HE45FFBU.js";import"../chunk-2PXP7TMY.js";import{a as P}from"../chunk-KJA62B7P.js";import{Command as he}from"commander";import{spawn as ne}from"child_process";import{mkdir as ke,writeFile as Pe}from"fs/promises";import{basename as Ce,join as Z}from"path";function se(e){return e.apiKey?.trim()||"sk_live_your_key"}function ce(e){return e.packageSpec?.trim()||"mcp-scraper@latest"}function A(e={}){return["-y","--package",ce(e),"mcp-scraper"]}function pe(e){let n={MCP_SCRAPER_API_KEY:se(e)},c=e.browserProfileName?.trim();return c&&(n.BROWSER_AGENT_PROFILE_NAME=c),e.browserProfileSaveChanges===!0&&(n.BROWSER_AGENT_PROFILE_SAVE_CHANGES="true"),n}function q(){return["mcp","remove","mcp-scraper","-s","user"]}function J(){return["mcp","get","mcp-scraper"]}function B(e){let n=e.match(/^\s*Command:\s*(.+?)\s*$/m)?.[1];if(!n)return null;let c=e.match(/^\s*Args:\s*(.*?)\s*$/m)?.[1]??"",i=c.length?c.split(/\s+/):[],p={},u=e.split(/^\s*Environment:\s*$/m)[1];if(u)for(let a of u.split(`
2
+ import{b as E,c as N,d as M,e as L,f as T,j as U}from"../chunk-JHMI6HEO.js";import"../chunk-KJQXUZ4Y.js";import"../chunk-2TZBO52D.js";import{g as v,j as b,k as D,l as K,m as H}from"../chunk-WO3N5FH2.js";import"../chunk-HE45FFBU.js";import"../chunk-2PXP7TMY.js";import{a as P}from"../chunk-UM4WSLKQ.js";import{Command as he}from"commander";import{spawn as ne}from"child_process";import{mkdir as ke,writeFile as Pe}from"fs/promises";import{basename as Ce,join as Z}from"path";function se(e){return e.apiKey?.trim()||"sk_live_your_key"}function ce(e){return e.packageSpec?.trim()||"mcp-scraper@latest"}function A(e={}){return["-y","--package",ce(e),"mcp-scraper"]}function pe(e){let n={MCP_SCRAPER_API_KEY:se(e)},c=e.browserProfileName?.trim();return c&&(n.BROWSER_AGENT_PROFILE_NAME=c),e.browserProfileSaveChanges===!0&&(n.BROWSER_AGENT_PROFILE_SAVE_CHANGES="true"),n}function q(){return["mcp","remove","mcp-scraper","-s","user"]}function J(){return["mcp","get","mcp-scraper"]}function B(e){let n=e.match(/^\s*Command:\s*(.+?)\s*$/m)?.[1];if(!n)return null;let c=e.match(/^\s*Args:\s*(.*?)\s*$/m)?.[1]??"",i=c.length?c.split(/\s+/):[],p={},u=e.split(/^\s*Environment:\s*$/m)[1];if(u)for(let a of u.split(`
3
3
  `)){let l=a.match(/^\s{2,}([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);if(!l){if(a.trim().length&&!/^\s{2,}/.test(a))break;continue}p[l[1]]=l[2]}return{command:n,args:i,env:p}}function j(e){let n=["mcp","add","mcp-scraper","--scope","user"];for(let[c,i]of Object.entries(e.env))n.push("--env",`${c}=${i}`);return n.push("--",e.command,...e.args),n}function G(e={}){let n=["mcp","add","mcp-scraper","--scope","user"];for(let[c,i]of Object.entries(pe(e)))n.push("--env",`${c}=${i}`);return n.push("--","npx",...A(e)),n}function O(e){if(e==="claude-code")return"claude";if(e==="claude"||D.hosts.some(n=>n.id===e))return e;throw new Error('Unknown host "'+e+'". Use: codex, claude, claude-code, claude-desktop, cursor, windsurf, cline, or user-action-only')}function ue(e){return K(e==="claude"?"claude-code":e)}function W(e,n={}){let c=O(e),i=ue(c),p="Restart the MCP client so it starts a fresh npx process.",u='MCP_SCRAPER_API_KEY="$MCP_SCRAPER_API_KEY" npx -y -p mcp-scraper@latest mcp-scraper-cli agent install claude --apply',a=`X-Ray install protocol: ${v} (${b})`;return c==="codex"?["# Codex MCP config",a,i.exactConfig,"",`Continuation: ${i.continuation}`,`Rollback: ${i.rollback}`,"",p].join(`
4
4
  `):c==="claude"?["# Claude Code command",a,i.exactConfig,"","# One-command Claude Code setup",u,"",`Continuation: ${i.continuation}`,`Rollback: ${i.rollback}`,"",p].join(`
5
5
  `):c==="claude-desktop"?["# Claude Desktop config",a,i.exactConfig,"","Desktop Extension: https://mcpscraper.dev/downloads/mcp-scraper.mcpb",`Continuation: ${i.continuation}`,`Rollback: ${i.rollback}`,p].join(`
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{a as e}from"../chunk-HR2ALIEH.js";import"../chunk-LTT2B7NY.js";import"../chunk-W2BVJ7S2.js";import"../chunk-TMB56NCA.js";import"../chunk-HUV2WTRW.js";import"../chunk-D6BTAT5Y.js";import"../chunk-7AC66V3T.js";import"../chunk-YEFXVTMJ.js";import"../chunk-4FROKQJN.js";import"../chunk-DKQZNSYM.js";import"../chunk-7QHYBK6U.js";import"../chunk-WO3N5FH2.js";import"../chunk-HE45FFBU.js";import"../chunk-2PXP7TMY.js";import"../chunk-KJA62B7P.js";import"../chunk-7BEWBRMT.js";var _=["harvest_paa","search_serp","extract_url","diff_page","map_site_urls","map_wayback_snapshots","extract_site","analyze_site_similarity","audit_site","check_site_export","site_export_read","site_export_image","archive_read","youtube_harvest","youtube_transcribe","facebook_page_intel","facebook_ad_search","reddit_thread","reddit_trending","video_frame_analysis","video_frame_analysis_status","facebook_ad_transcribe","google_ads_search","google_ads_page_intel","google_ads_transcribe","facebook_video_transcribe","instagram_profile_content","instagram_media_download","maps_place_intel","maps_search","trustpilot_reviews","g2_reviews","capture_serp_snapshot","capture_serp_page_snapshots"];e({toolsets:new Set(["paa","serp"]),allowedToolNames:_});
2
+ import{a as e}from"../chunk-AQSMJCTF.js";import"../chunk-XARSC34L.js";import"../chunk-W2BVJ7S2.js";import"../chunk-TMB56NCA.js";import"../chunk-HUV2WTRW.js";import"../chunk-D6BTAT5Y.js";import"../chunk-AAJG5OHF.js";import"../chunk-CTX3NMZQ.js";import"../chunk-4FROKQJN.js";import"../chunk-56UT5M5Y.js";import"../chunk-5MMN27Q6.js";import"../chunk-WO3N5FH2.js";import"../chunk-HE45FFBU.js";import"../chunk-2PXP7TMY.js";import"../chunk-UM4WSLKQ.js";import"../chunk-KKHTMYCD.js";var _=["harvest_paa","search_serp","extract_url","diff_page","map_site_urls","map_wayback_snapshots","extract_site","analyze_site_similarity","audit_site","check_site_export","site_export_read","site_export_image","archive_read","youtube_harvest","youtube_transcribe","facebook_page_intel","facebook_ad_search","reddit_thread","reddit_trending","video_frame_analysis","video_frame_analysis_status","facebook_ad_transcribe","google_ads_search","google_ads_page_intel","google_ads_transcribe","facebook_video_transcribe","instagram_profile_content","instagram_media_download","maps_place_intel","maps_search","trustpilot_reviews","g2_reviews","capture_serp_snapshot","capture_serp_page_snapshots"];e({toolsets:new Set(["paa","serp"]),allowedToolNames:_});
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{a as s}from"../chunk-7QHYBK6U.js";import{a as e}from"../chunk-KJA62B7P.js";var r=process.argv.includes("--no-color")||process.env.NO_COLOR!==void 0||process.env.FORCE_COLOR==="0"||!process.stdout.isTTY,n=process.argv.includes("--help")||process.argv.includes("-h");n&&(process.stdout.write(["Usage: mcp-scraper-install [--no-color]","","Prints the branded MCP Scraper terminal install card and copyable install commands.","mcp-scraper prints the same card in a human terminal and runs as the MCP stdio server in clients.",""].join(`
2
+ import{a as s}from"../chunk-5MMN27Q6.js";import{a as e}from"../chunk-UM4WSLKQ.js";var r=process.argv.includes("--no-color")||process.env.NO_COLOR!==void 0||process.env.FORCE_COLOR==="0"||!process.stdout.isTTY,n=process.argv.includes("--help")||process.argv.includes("-h");n&&(process.stdout.write(["Usage: mcp-scraper-install [--no-color]","","Prints the branded MCP Scraper terminal install card and copyable install commands.","mcp-scraper prints the same card in a human terminal and runs as the MCP stdio server in clients.",""].join(`
3
3
  `)),process.exit(0));process.stdout.write(s({version:e,color:!r,apiKeyConfigured:!!process.env.MCP_SCRAPER_API_KEY?.trim()}));
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{a as r}from"../chunk-HR2ALIEH.js";import"../chunk-LTT2B7NY.js";import"../chunk-W2BVJ7S2.js";import"../chunk-TMB56NCA.js";import"../chunk-HUV2WTRW.js";import"../chunk-D6BTAT5Y.js";import"../chunk-7AC66V3T.js";import"../chunk-YEFXVTMJ.js";import"../chunk-4FROKQJN.js";import"../chunk-DKQZNSYM.js";import"../chunk-7QHYBK6U.js";import"../chunk-WO3N5FH2.js";import"../chunk-HE45FFBU.js";import"../chunk-2PXP7TMY.js";import"../chunk-KJA62B7P.js";import"../chunk-7BEWBRMT.js";r();
2
+ import{a as r}from"../chunk-AQSMJCTF.js";import"../chunk-XARSC34L.js";import"../chunk-W2BVJ7S2.js";import"../chunk-TMB56NCA.js";import"../chunk-HUV2WTRW.js";import"../chunk-D6BTAT5Y.js";import"../chunk-AAJG5OHF.js";import"../chunk-CTX3NMZQ.js";import"../chunk-4FROKQJN.js";import"../chunk-56UT5M5Y.js";import"../chunk-5MMN27Q6.js";import"../chunk-WO3N5FH2.js";import"../chunk-HE45FFBU.js";import"../chunk-2PXP7TMY.js";import"../chunk-UM4WSLKQ.js";import"../chunk-KKHTMYCD.js";r();
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{w as t}from"../chunk-GW6ITK76.js";import"../chunk-M5QHXNFZ.js";import{a as r}from"../chunk-4FROKQJN.js";import"../chunk-DKQZNSYM.js";import"../chunk-2TZBO52D.js";import"../chunk-2PXP7TMY.js";import"../chunk-7BEWBRMT.js";import{Command as s,Option as a}from"commander";var i=new s;i.name("paa-harvest").description("Recursively extract Google People Also Ask questions").requiredOption("-q, --query <query>","Seed query").option("-l, --location <location>",'Location name (e.g. "austin" or "Austin,Texas,United States")').option("--gl <gl>","Google country code","us").option("--hl <hl>","Google language code","en").option("-d, --depth <depth>","BFS depth (1-30)","3").option("-m, --max-questions <n>","Max questions to harvest","100").option("-o, --output <dir>","Output directory","./paa-output").option("-f, --format <format>","Output format: json, csv, or both","both").option("--headless","Run browser in headless mode",!1).option("--profile <dir>","Persistent browser profile directory").option("--proxy <url>","Proxy server URL").option("--browser-api-key <key>","Browser service API key (or set BROWSER_SERVICE_API_KEY env var)").addOption(new a("--\u006b\u0065\u0072\u006e\u0065\u006c-api-key <key>").hideHelp()).action(async e=>{try{let o=await t({query:e.query,location:e.location,gl:e.gl,hl:e.hl,depth:parseInt(e.depth,10),maxQuestions:parseInt(e.maxQuestions,10),outputDir:e.output,format:e.format,headless:e.headless,profileDir:e.profile,proxy:e.proxy,\u006b\u0065\u0072\u006e\u0065\u006cApiKey:e.browserApiKey??e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey??r()});console.log(JSON.stringify({totalQuestions:o.totalQuestions,outputDir:o.stats.seed}))}catch(o){console.error(o instanceof Error?o.message:String(o)),process.exit(1)}});async function n(){await i.parseAsync()}n();
2
+ import{w as t}from"../chunk-AQXYXVOP.js";import"../chunk-M5QHXNFZ.js";import{a as r}from"../chunk-4FROKQJN.js";import"../chunk-56UT5M5Y.js";import"../chunk-2TZBO52D.js";import"../chunk-2PXP7TMY.js";import"../chunk-KKHTMYCD.js";import{Command as s,Option as a}from"commander";var i=new s;i.name("paa-harvest").description("Recursively extract Google People Also Ask questions").requiredOption("-q, --query <query>","Seed query").option("-l, --location <location>",'Location name (e.g. "austin" or "Austin,Texas,United States")').option("--gl <gl>","Google country code","us").option("--hl <hl>","Google language code","en").option("-d, --depth <depth>","BFS depth (1-30)","3").option("-m, --max-questions <n>","Max questions to harvest","100").option("-o, --output <dir>","Output directory","./paa-output").option("-f, --format <format>","Output format: json, csv, or both","both").option("--headless","Run browser in headless mode",!1).option("--profile <dir>","Persistent browser profile directory").option("--proxy <url>","Proxy server URL").option("--browser-api-key <key>","Browser service API key (or set BROWSER_SERVICE_API_KEY env var)").addOption(new a("--\u006b\u0065\u0072\u006e\u0065\u006c-api-key <key>").hideHelp()).action(async e=>{try{let o=await t({query:e.query,location:e.location,gl:e.gl,hl:e.hl,depth:parseInt(e.depth,10),maxQuestions:parseInt(e.maxQuestions,10),outputDir:e.output,format:e.format,headless:e.headless,profileDir:e.profile,proxy:e.proxy,\u006b\u0065\u0072\u006e\u0065\u006cApiKey:e.browserApiKey??e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey??r()});console.log(JSON.stringify({totalQuestions:o.totalQuestions,outputDir:o.stats.seed}))}catch(o){console.error(o instanceof Error?o.message:String(o)),process.exit(1)}});async function n(){await i.parseAsync()}n();
@@ -1,4 +1,4 @@
1
- import{a as Q,d as Se}from"./chunk-2GRE4BAO.js";import{createHash as pe,createHmac as Yt,randomBytes as P,randomUUID as y}from"crypto";import{Pool as Wt}from"pg";var ct=[[/perplexity/i,"llm","Perplexity"],[/chatgpt|chat\.openai|openai/i,"llm","ChatGPT"],[/claude|anthropic/i,"llm","Claude"],[/\bgrok\b|xai/i,"llm","Grok"],[/ai[ _-]?overview|google[ _-]?ai|\bsge\b|gemini/i,"llm","Google AI Overview"],[/instagram/i,"social","Instagram"],[/facebook|\bfb\b|meta/i,"social","Facebook"],[/linkedin/i,"social","LinkedIn"],[/tiktok/i,"social","TikTok"],[/youtube|youtu\.be/i,"social","YouTube"],[/twitter|x\.com/i,"social","X"],[/\bg2\b|g2\.com/i,"review","G2"],[/trustpilot/i,"review","Trustpilot"],[/\bbbb\b|better business bureau/i,"review","BBB"],[/capterra/i,"review","Capterra"],[/yelp/i,"review","Yelp"],[/google|bing|duckduckgo|yahoo/i,"search","Search"]];function q(e,t=240){return typeof e=="string"&&e.trim()?e.trim().slice(0,t):null}function Ce(e){try{return e?new URL(e).hostname.replace(/^www\./,""):""}catch{return""}}function Re(e){let t=e.properties??{},i=q(e.source,180)||Ce(e.referrer)||"(direct)",n=q(e.medium,180)||(i==="(direct)"?"(none)":"referral"),s=e.clickIds??{},a=`${i} ${n} ${Ce(e.referrer)}`,r=i==="(direct)"?"direct":/email|newsletter/i.test(n)?"email":"referral",o=i==="(direct)"?"Direct":i;for(let[d,_,u]of ct)if(d.test(a)){r=_,o=u;break}return s.fbclid?(r="social",o=/instagram/i.test(a)?"Instagram":"Facebook"):s.ttclid?(r="social",o="TikTok"):s.rdt_cid?(r="social",o="Reddit"):s.gclid||s.gbraid||s.wbraid?(r="search",o="Google"):s.msclkid&&(r="search",o="Microsoft Ads"),{channelFamily:r,platform:o,source:i,medium:n,campaign:q(e.campaign),campaignId:q(t.campaign_id??t.utm_id),adSetId:q(t.adset_id??t.ad_set_id??t.adgroup_id??t.ad_group_id),adId:q(t.ad_id),creativeId:q(t.creative_id),placement:q(t.placement),term:q(t.utm_term),content:q(t.utm_content)}}import{createHash as yt,randomUUID as ee}from"crypto";import{createCipheriv as _t,createDecipheriv as ut,createHmac as fe,randomBytes as Et,scryptSync as lt,timingSafeEqual as Nt}from"crypto";var Z="xray1";function mt(){return process.env.ANALYTICS_RESTRICTED_DATA_SECRET?.trim()||Q()}function _e(e){return lt(mt(),`xray-restricted:${e}:v1`,32)}function De(e,t){let i=t.trim().slice(0,80);if(!i)throw new Error("analytics encryption purpose required");let n=Et(12),s=_t("aes-256-gcm",_e(i),n);s.setAAD(Buffer.from(`${Z}:${i}`,"utf8"));let a=Buffer.concat([s.update(e,"utf8"),s.final()]),r=s.getAuthTag();return[Z,Buffer.from(i,"utf8").toString("base64url"),n.toString("base64url"),r.toString("base64url"),a.toString("base64url")].join(".")}function Ue(e,t){try{let[i,n,s,a,r]=e.split(".");if(i!==Z||!n||!s||!a||!r)return null;let o=Buffer.from(n,"base64url").toString("utf8");if(o!==t)return null;let d=ut("aes-256-gcm",_e(o),Buffer.from(s,"base64url"));return d.setAAD(Buffer.from(`${Z}:${o}`,"utf8")),d.setAuthTag(Buffer.from(a,"base64url")),Buffer.concat([d.update(Buffer.from(r,"base64url")),d.final()]).toString("utf8")}catch{return null}}function bi(e,t){return fe("sha256",_e(`identity:${e}`)).update(t.trim().toLowerCase()).digest("hex")}function hi(e,t,i,n){return fe("sha256",n).update(`${e}.${t}.${i}`).digest("hex")}function xi(e,t){if(!e||e.length!==t.length)return!1;try{return Nt(Buffer.from(e),Buffer.from(t))}catch{return!1}}var we="enhanced_matching",pt=90,Tt=10,H=class extends Error{constructor(i,n,s){super(n);this.code=i;this.status=s;this.name="AnalyticsIdentityProfileError"}code;status};function te(e,t){return e?.trim().replace(/\s+/g," ").slice(0,t)||null}function Lt(e){if(!e)return null;let[t,i]=e.split("@");return!t||!i?null:`${t.slice(0,1)}${"*".repeat(Math.min(6,Math.max(2,t.length-1)))}@${i}`}function At(e){if(!e)return null;let t=e.replace(/\D/g,"");return t.length<4?null:`***-***-${t.slice(-4)}`}function ue(e){return yt("sha256").update(e).digest("hex")}async function ie(e,t){if(!t.signals.length)return;let i=t.signals.map(a=>a.kind),n=t.signals.map(a=>a.valueHmac);if((await e.query(`SELECT 1 FROM analytics_identity_tombstones
1
+ import{a as Q,d as Se}from"./chunk-Q5SUDDSQ.js";import{createHash as pe,createHmac as Yt,randomBytes as P,randomUUID as y}from"crypto";import{Pool as Wt}from"pg";var ct=[[/perplexity/i,"llm","Perplexity"],[/chatgpt|chat\.openai|openai/i,"llm","ChatGPT"],[/claude|anthropic/i,"llm","Claude"],[/\bgrok\b|xai/i,"llm","Grok"],[/ai[ _-]?overview|google[ _-]?ai|\bsge\b|gemini/i,"llm","Google AI Overview"],[/instagram/i,"social","Instagram"],[/facebook|\bfb\b|meta/i,"social","Facebook"],[/linkedin/i,"social","LinkedIn"],[/tiktok/i,"social","TikTok"],[/youtube|youtu\.be/i,"social","YouTube"],[/twitter|x\.com/i,"social","X"],[/\bg2\b|g2\.com/i,"review","G2"],[/trustpilot/i,"review","Trustpilot"],[/\bbbb\b|better business bureau/i,"review","BBB"],[/capterra/i,"review","Capterra"],[/yelp/i,"review","Yelp"],[/google|bing|duckduckgo|yahoo/i,"search","Search"]];function q(e,t=240){return typeof e=="string"&&e.trim()?e.trim().slice(0,t):null}function Ce(e){try{return e?new URL(e).hostname.replace(/^www\./,""):""}catch{return""}}function Re(e){let t=e.properties??{},i=q(e.source,180)||Ce(e.referrer)||"(direct)",n=q(e.medium,180)||(i==="(direct)"?"(none)":"referral"),s=e.clickIds??{},a=`${i} ${n} ${Ce(e.referrer)}`,r=i==="(direct)"?"direct":/email|newsletter/i.test(n)?"email":"referral",o=i==="(direct)"?"Direct":i;for(let[d,_,u]of ct)if(d.test(a)){r=_,o=u;break}return s.fbclid?(r="social",o=/instagram/i.test(a)?"Instagram":"Facebook"):s.ttclid?(r="social",o="TikTok"):s.rdt_cid?(r="social",o="Reddit"):s.gclid||s.gbraid||s.wbraid?(r="search",o="Google"):s.msclkid&&(r="search",o="Microsoft Ads"),{channelFamily:r,platform:o,source:i,medium:n,campaign:q(e.campaign),campaignId:q(t.campaign_id??t.utm_id),adSetId:q(t.adset_id??t.ad_set_id??t.adgroup_id??t.ad_group_id),adId:q(t.ad_id),creativeId:q(t.creative_id),placement:q(t.placement),term:q(t.utm_term),content:q(t.utm_content)}}import{createHash as yt,randomUUID as ee}from"crypto";import{createCipheriv as _t,createDecipheriv as ut,createHmac as fe,randomBytes as Et,scryptSync as lt,timingSafeEqual as Nt}from"crypto";var Z="xray1";function mt(){return process.env.ANALYTICS_RESTRICTED_DATA_SECRET?.trim()||Q()}function _e(e){return lt(mt(),`xray-restricted:${e}:v1`,32)}function De(e,t){let i=t.trim().slice(0,80);if(!i)throw new Error("analytics encryption purpose required");let n=Et(12),s=_t("aes-256-gcm",_e(i),n);s.setAAD(Buffer.from(`${Z}:${i}`,"utf8"));let a=Buffer.concat([s.update(e,"utf8"),s.final()]),r=s.getAuthTag();return[Z,Buffer.from(i,"utf8").toString("base64url"),n.toString("base64url"),r.toString("base64url"),a.toString("base64url")].join(".")}function Ue(e,t){try{let[i,n,s,a,r]=e.split(".");if(i!==Z||!n||!s||!a||!r)return null;let o=Buffer.from(n,"base64url").toString("utf8");if(o!==t)return null;let d=ut("aes-256-gcm",_e(o),Buffer.from(s,"base64url"));return d.setAAD(Buffer.from(`${Z}:${o}`,"utf8")),d.setAuthTag(Buffer.from(a,"base64url")),Buffer.concat([d.update(Buffer.from(r,"base64url")),d.final()]).toString("utf8")}catch{return null}}function bi(e,t){return fe("sha256",_e(`identity:${e}`)).update(t.trim().toLowerCase()).digest("hex")}function hi(e,t,i,n){return fe("sha256",n).update(`${e}.${t}.${i}`).digest("hex")}function xi(e,t){if(!e||e.length!==t.length)return!1;try{return Nt(Buffer.from(e),Buffer.from(t))}catch{return!1}}var we="enhanced_matching",pt=90,Tt=10,H=class extends Error{constructor(i,n,s){super(n);this.code=i;this.status=s;this.name="AnalyticsIdentityProfileError"}code;status};function te(e,t){return e?.trim().replace(/\s+/g," ").slice(0,t)||null}function Lt(e){if(!e)return null;let[t,i]=e.split("@");return!t||!i?null:`${t.slice(0,1)}${"*".repeat(Math.min(6,Math.max(2,t.length-1)))}@${i}`}function At(e){if(!e)return null;let t=e.replace(/\D/g,"");return t.length<4?null:`***-***-${t.slice(-4)}`}function ue(e){return yt("sha256").update(e).digest("hex")}async function ie(e,t){if(!t.signals.length)return;let i=t.signals.map(a=>a.kind),n=t.signals.map(a=>a.valueHmac);if((await e.query(`SELECT 1 FROM analytics_identity_tombstones
2
2
  WHERE site_id=$1 AND (kind,value_hmac) IN (
3
3
  SELECT * FROM unnest($2::text[],$3::text[])
4
4
  ) LIMIT 1`,[t.siteId,i,n])).rowCount)throw new H("analytics_identity_deleted","This identity cannot be automatically recreated.",410)}async function ne(e,t){let i=te(t.displayName,160),n=te(t.email,320)?.toLowerCase()??null,s=te(t.phone,40);if(!i&&!n&&!s)return!1;let r=(await e.query(`SELECT p.public_ref FROM analytics_people p
@@ -1,4 +1,4 @@
1
- import{t as _}from"./chunk-7BEWBRMT.js";import{AsyncLocalStorage as N}from"async_hooks";var C="MCP_SCRAPER_ALLOW_HEADLESS_HARVEST_TEST",d=new N;function D(e,t){return d.run(e,t)}function l(){return d.getStore()}import{randomUUID as T}from"crypto";var p=166667e-10,L=.0001333336,h=new Set(["serp","fb_search","fb_ad","instagram"]),A=.00111,R=4,g=4e-4;function n(e,t){let r=process.env[e]?.trim();if(!r)return t;let o=Number(r);return Number.isFinite(o)&&o>=0?o:t}var m=n("NANGO_USD_PER_CONNECTION_MONTH",1),U=n("NANGO_USD_PER_FUNCTION_RUN",1e-4),O=n("NANGO_USD_PER_PROXY_REQUEST",1e-4),S=n("NANGO_USD_PER_COMPUTE_SEC",2e-4),b=n("\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041_BROWSER_USD_PER_GB",8);function u(e,t){return Math.max(0,e)/1e3*(t?L:p)}function i(e,t){return e==="fal_wizper"?Math.max(0,t)/R*A:e==="deepinfra_qwen"?Math.max(0,t)/1e3*g:e==="openrouter"||e==="mcp_memory_video"||e==="mcp_memory_ai"?Math.max(0,t):e==="nango_connection"?Math.max(0,t)*m:e==="nango_function_run"?Math.max(0,t)*U:e==="nango_proxy_request"?Math.max(0,t)*O:e==="nango_compute"?Math.max(0,t)*S:e==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061_browser_api"?Math.max(0,t)/1e9*b:0}var E=!1,s=null;async function c(){if(!E)return s||(s=x().finally(()=>{s=null}),s)}async function x(){let e=_(),t=await e.execute(`
1
+ import{t as _}from"./chunk-KKHTMYCD.js";import{AsyncLocalStorage as N}from"async_hooks";var D="MCP_SCRAPER_ALLOW_HEADLESS_HARVEST_TEST",i=new N;function C(e,t){return i.run(e,t)}function l(){return i.getStore()}var p=166667e-10,L=.0001333336,h=new Set(["serp","fb_search","fb_ad","instagram"]),A=.00111,R=4,g=4e-4;function o(e,t){let r=process.env[e]?.trim();if(!r)return t;let n=Number(r);return Number.isFinite(n)&&n>=0?n:t}var m=o("NANGO_USD_PER_CONNECTION_MONTH",1),U=o("NANGO_USD_PER_FUNCTION_RUN",1e-4),S=o("NANGO_USD_PER_PROXY_REQUEST",1e-4),O=o("NANGO_USD_PER_COMPUTE_SEC",2e-4),b=o("\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041_BROWSER_USD_PER_GB",8),f=o("\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041_SERP_USD_PER_REQUEST",.002836168);function u(e,t){return Math.max(0,e)/1e3*(t?L:p)}function d(e,t){return e==="fal_wizper"?Math.max(0,t)/R*A:e==="deepinfra_qwen"?Math.max(0,t)/1e3*g:e==="openrouter"||e==="mcp_memory_video"||e==="mcp_memory_ai"?Math.max(0,t):e==="nango_connection"?Math.max(0,t)*m:e==="nango_function_run"?Math.max(0,t)*U:e==="nango_proxy_request"?Math.max(0,t)*S:e==="nango_compute"?Math.max(0,t)*O:e==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061_browser_api"?Math.max(0,t)/1e9*b:0}import{randomUUID as T}from"crypto";var E=!1,s=null;async function c(){if(!E)return s||(s=I().finally(()=>{s=null}),s)}async function I(){let e=_(),t=await e.execute(`
2
2
  SELECT
3
3
  (SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name IN ('\u006b\u0065\u0072\u006e\u0065\u006c_session_log', 'vendor_usage_log', 'cost_probe_runs')) = 3
4
4
  AND (SELECT COUNT(*) FROM pragma_table_info('\u006b\u0065\u0072\u006e\u0065\u006c_session_log') WHERE name IN ('proxy_source', 'proxy_type', 'method')) = 3
@@ -66,8 +66,8 @@ import{t as _}from"./chunk-7BEWBRMT.js";import{AsyncLocalStorage as N}from"async
66
66
  margin_usd_headful_starter REAL NOT NULL DEFAULT 0,
67
67
  notes TEXT
68
68
  )
69
- `),await e.execute("CREATE INDEX IF NOT EXISTS cost_probe_runs_tool ON cost_probe_runs(tool)");try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN units REAL")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN unit_type TEXT")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN mode TEXT")}catch{}E=!0}async function w(e){try{await c();let t=l(),r=Math.max(0,e.closedAtMs-e.openedAtMs);await _().execute({sql:`INSERT INTO \u006b\u0065\u0072\u006e\u0065\u006c_session_log
69
+ `),await e.execute("CREATE INDEX IF NOT EXISTS cost_probe_runs_tool ON cost_probe_runs(tool)");try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN units REAL")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN unit_type TEXT")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN mode TEXT")}catch{}E=!0}async function F(e){try{await c();let t=l(),r=Math.max(0,e.closedAtMs-e.openedAtMs);await _().execute({sql:`INSERT INTO \u006b\u0065\u0072\u006e\u0065\u006c_session_log
70
70
  (id, \u006b\u0065\u0072\u006e\u0065\u006c_session_id, op, source, probe_run_id, user_id, stealth, headless_sent, proxy_used, proxy_source, proxy_type, fallback, opened_at, closed_at, duration_ms, est_cost_usd_headless, est_cost_usd_headful, error, method)
71
- VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[T(),e.\u006b\u0065\u0072\u006e\u0065\u006cSessionId??null,t?.op??null,e.source,t?.probeRunId??null,t?.userId??null,a(e.stealth),a(e.headlessSent),a(e.proxyUsed),e.proxySource??null,e.proxyType??null,e.fallback?1:0,new Date(e.openedAtMs).toISOString(),new Date(e.closedAtMs).toISOString(),r,u(r,!1),u(r,!0),e.error??null,t?.subOp??null]})}catch(t){console.warn("[cost-telemetry] record\u004b\u0065\u0072\u006e\u0065\u006cSession failed:",t instanceof Error?t.message:String(t))}}async function F(e){try{await c();let t=l();return(await _().execute({sql:`INSERT OR IGNORE INTO vendor_usage_log
71
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[T(),e.\u006b\u0065\u0072\u006e\u0065\u006cSessionId??null,t?.op??null,e.source,t?.probeRunId??null,t?.userId??null,a(e.stealth),a(e.headlessSent),a(e.proxyUsed),e.proxySource??null,e.proxyType??null,e.fallback?1:0,new Date(e.openedAtMs).toISOString(),new Date(e.closedAtMs).toISOString(),r,u(r,!1),u(r,!0),e.error??null,t?.subOp??null]})}catch(t){console.warn("[cost-telemetry] record\u004b\u0065\u0072\u006e\u0065\u006cSession failed:",t instanceof Error?t.message:String(t))}}async function P(e){try{await c();let t=l();return(await _().execute({sql:`INSERT OR IGNORE INTO vendor_usage_log
72
72
  (id, op, probe_run_id, user_id, vendor, model, units, unit_type, est_cost_usd, error, method, source_key, provider_duration_ms, provider_captcha, provider_status)
73
- VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[T(),e.op??t?.op??null,e.probeRunId??t?.probeRunId??null,e.userId??t?.userId??null,e.vendor,e.model??null,e.units,e.unitType,i(e.vendor,e.units),e.error??null,e.method??t?.subOp??null,e.sourceKey??null,e.providerDurationMs??null,a(e.providerCaptcha),e.providerStatus??null]})).rowsAffected===1}catch(t){return console.warn("[cost-telemetry] recordVendorUsage failed:",t instanceof Error?t.message:String(t)),!1}}function a(e){return e==null?null:e?1:0}export{C as a,D as b,l as c,h as d,i as e,c as f,w as g,F as h};
73
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[T(),e.op??t?.op??null,e.probeRunId??t?.probeRunId??null,e.userId??t?.userId??null,e.vendor,e.model??null,e.units,e.unitType,d(e.vendor,e.units),e.error??null,e.method??t?.subOp??null,e.sourceKey??null,e.providerDurationMs??null,a(e.providerCaptcha),e.providerStatus??null]})).rowsAffected===1}catch(t){return console.warn("[cost-telemetry] recordVendorUsage failed:",t instanceof Error?t.message:String(t)),!1}}function a(e){return e==null?null:e?1:0}export{D as a,C as b,l as c,L as d,h as e,f,u as g,d as h,c as i,F as j,P as k};
@@ -1,4 +1,4 @@
1
- var s={message:"Scheduled analytics retries now use valid timestamp arithmetic, preventing the production scheduler from rejecting retry updates."};var _={reset:"\x1B[0m",cyan:"\x1B[36m",lime:"\x1B[32m",amber:"\x1B[33m",red:"\x1B[31m",muted:"\x1B[90m",bold:"\x1B[1m"};function r(t,e,n){return n?`${_[e]}${t}${_.reset}`:t}function o(t,e,n){let a=t.padEnd(9," ");return` ${r(a,"muted",n)} ${e.join(r(" . ","muted",n))}`}function p(t){let e=t.color??!0,n=t.apiKeyConfigured?"$MCP_SCRAPER_API_KEY":"sk_live_your_key",a=String.raw`
1
+ var s={message:"SERP page-two capture, idempotent replay, provider identity, and Maps retry evidence are now explicit, while the inactive Personal Assistant is removed from live product surfaces."};var _={reset:"\x1B[0m",cyan:"\x1B[36m",lime:"\x1B[32m",amber:"\x1B[33m",red:"\x1B[31m",muted:"\x1B[90m",bold:"\x1B[1m"};function r(t,e,n){return n?`${_[e]}${t}${_.reset}`:t}function o(t,e,n){let a=t.padEnd(9," ");return` ${r(a,"muted",n)} ${e.join(r(" . ","muted",n))}`}function p(t){let e=t.color??!0,n=t.apiKeyConfigured?"$MCP_SCRAPER_API_KEY":"sk_live_your_key",a=String.raw`
2
2
  __ __ ____ ____
3
3
  | \/ |/ ___| _ \
4
4
  | |\/| | | | |_) |
@@ -12,5 +12,5 @@ var s={message:"Scheduled analytics retries now use valid timestamp arithmetic,
12
12
  |____/ \____|_| \_\/_/ \_\_| |_____|_| \_\
13
13
  `,c=[`MCP_SCRAPER_API_KEY=${n} npx -y -p mcp-scraper@latest \\`," mcp-scraper-cli agent install claude --apply"].join(`
14
14
  `),i=["[mcp_servers.mcp-scraper]",'command = "npx"','args = ["-y", "-p", "mcp-scraper@latest", "mcp-scraper"]',`env = { MCP_SCRAPER_API_KEY = "${n}" }`].join(`
15
- `);return[r(`mcp-scraper v${t.version}`,"bold",e),r("> mcp-scraper-install","muted",e),r(a,"amber",e),`${r("MCP Scraper Agent","cyan",e)} . v${t.version} . mcpscraper.dev`,"1/1 install surfaces ready",r(`Newest in v${t.version}: ${s.message}`,"lime",e),"",`${r("Tools","cyan",e)} ${r("(378 MCP tools)","muted",e)}`,o("search",["harvest_paa","search_serp","maps_search","maps_place_intel"],e),o("extract",["extract_url","map_site_urls","extract_site","audit_site","directory_workflow"],e),o("build",["create_editorial_reading_room","rank_tracker_workflow","portable HTML"],e),o("media",["youtube_harvest","youtube_transcribe","facebook_reels_inventory","facebook_ad_search","facebook_page_intel","facebook_ad_transcribe","facebook_video_transcribe","instagram_profile_content","instagram_media_download","reddit_thread"],e),o("browser",["serp_identity_create","serp_identity_list","browser_open","browser_profile_connect","browser_profile_list","browser_close","browser_screenshot","browser_read","browser_locate","browser_replay_mark","browser_replay_annotate"],e),o("connect",["list_service_connections","describe_service_connection_tool","import_service_connection_to_memory","export_connected_service_data","renew_connected_data_download","read_service_connection","call_service_connection_action"],e),o("commons",["commons_search_entities","commons_get_entity_linkset","commons_prepare_entity","commons_submit_entity","commons_prepare_publication","commons_claim_publication","commons_publish_editorial","commons_get_publication"],e),o("account",["credits_info","reports","MCP resources"],e),o("memory",["memory-put","memory-get","memory-search","list-vaults","record-fact","list-scheduled-actions"],e),`${r("Workflows","cyan",e)} ${r("(MCP + CLI + API)","muted",e)}`,o("route",["workflow_list","workflow_suggest","workflow_run","workflow_step","workflow_status","workflow_artifact_read"],e),o("seo",["directory","agent-packet","competitive audit","map/serp comparison","PAA/AIO briefs","scheduled runs"],e),"",r("Usage tips:","amber",e),"Run mcp-scraper-install for this visible card. Run mcp-scraper-cli for setup utilities and subcommands.","Run mcp-scraper in a human terminal to print this card; MCP clients get the same command as a silent stdio server.","Explicit card command: npx -y -p mcp-scraper@latest mcp-scraper-install","Hosted browser sessions use direct/no-proxy egress by default.","Customer auth setup: run browser_profile_connect, send the watch_url, let the user sign in, then call browser_profile_list until AUTHENTICATED.","Connected account ranges: call export_connected_service_data once. It handles Gmail, Calendar, Zoom, and Resend pagination; do not loop read_service_connection over individual records.","Connected account RAG: call import_service_connection_to_memory for one bounded approved read. It writes a redacted, untrusted snapshot to a stable Memory path and embeds it for search.","Stack logins / reconnect: run browser_profile_connect again with the same profile name and another domain to add accounts or refresh a login.","Start with workflow_suggest for broad jobs like market analysis, ICP research, CRO audits, brand briefs, content gaps, and AI visibility.","For MCP clients, use mcp-scraper so one install can mix SERP, Maps, browser, reports, and saved MCP resources.","If you hit the concurrency limit, add 2 browsers for $5/month with mcp-scraper-cli billing concurrency checkout.","",`${r("Ready.","lime",e)} Install the combined MCP server with one command:`,"",r("Setup doctor","amber",e),"npx -y -p mcp-scraper@latest mcp-scraper-cli doctor","",r("Hosted profile setup","amber",e),'In your MCP client, call browser_profile_connect with email="seo@example.com" and domain="chatgpt.com".',"Give the returned watch_url to the user. After they sign in, call browser_profile_list, then browser_open with the returned profile. Add more logins by calling browser_profile_connect again with the same profile and a new domain.","",r("Claude Code one-command setup","amber",e),c,"Then fully exit Claude Code and open a new Claude terminal. Check with: claude mcp list","",r("Codex config","amber",e),i,"",r("Claude Desktop Extension","amber",e),"Download: https://mcpscraper.dev/downloads/mcp-scraper.mcpb","",r("Safety note:","muted",e),"mcp-scraper prints this card only when stdin/stdout are an interactive TTY. In MCP clients it writes only JSON-RPC to stdout.","Use --stdio or MCP_SCRAPER_FORCE_STDIO=1 to force server mode from a terminal.",""].join(`
15
+ `);return[r(`mcp-scraper v${t.version}`,"bold",e),r("> mcp-scraper-install","muted",e),r(a,"amber",e),`${r("MCP Scraper Agent","cyan",e)} . v${t.version} . mcpscraper.dev`,"1/1 install surfaces ready",r(`Newest in v${t.version}: ${s.message}`,"lime",e),"",`${r("Tools","cyan",e)} ${r("(361 MCP tools)","muted",e)}`,o("search",["harvest_paa","search_serp","maps_search","maps_place_intel"],e),o("extract",["extract_url","map_site_urls","extract_site","audit_site","directory_workflow"],e),o("build",["create_editorial_reading_room","rank_tracker_workflow","portable HTML"],e),o("media",["youtube_harvest","youtube_transcribe","facebook_reels_inventory","facebook_ad_search","facebook_page_intel","facebook_ad_transcribe","facebook_video_transcribe","instagram_profile_content","instagram_media_download","reddit_thread"],e),o("browser",["serp_identity_create","serp_identity_list","browser_open","browser_profile_connect","browser_profile_list","browser_close","browser_screenshot","browser_read","browser_locate","browser_replay_mark","browser_replay_annotate"],e),o("connect",["list_service_connections","describe_service_connection_tool","import_service_connection_to_memory","export_connected_service_data","renew_connected_data_download","read_service_connection","call_service_connection_action"],e),o("commons",["commons_search_entities","commons_get_entity_linkset","commons_prepare_entity","commons_submit_entity","commons_prepare_publication","commons_claim_publication","commons_publish_editorial","commons_get_publication"],e),o("account",["credits_info","reports","MCP resources"],e),o("memory",["memory-put","memory-get","memory-search","list-vaults","record-fact","list-scheduled-actions"],e),`${r("Workflows","cyan",e)} ${r("(MCP + CLI + API)","muted",e)}`,o("route",["workflow_list","workflow_suggest","workflow_run","workflow_step","workflow_status","workflow_artifact_read"],e),o("seo",["directory","agent-packet","competitive audit","map/serp comparison","PAA/AIO briefs","scheduled runs"],e),"",r("Usage tips:","amber",e),"Run mcp-scraper-install for this visible card. Run mcp-scraper-cli for setup utilities and subcommands.","Run mcp-scraper in a human terminal to print this card; MCP clients get the same command as a silent stdio server.","Explicit card command: npx -y -p mcp-scraper@latest mcp-scraper-install","Hosted browser sessions use direct/no-proxy egress by default.","Customer auth setup: run browser_profile_connect, send the watch_url, let the user sign in, then call browser_profile_list until AUTHENTICATED.","Connected account ranges: call export_connected_service_data once. It handles Gmail, Calendar, Zoom, and Resend pagination; do not loop read_service_connection over individual records.","Connected account RAG: call import_service_connection_to_memory for one bounded approved read. It writes a redacted, untrusted snapshot to a stable Memory path and embeds it for search.","Stack logins / reconnect: run browser_profile_connect again with the same profile name and another domain to add accounts or refresh a login.","Start with workflow_suggest for broad jobs like market analysis, ICP research, CRO audits, brand briefs, content gaps, and AI visibility.","For MCP clients, use mcp-scraper so one install can mix SERP, Maps, browser, reports, and saved MCP resources.","If you hit the concurrency limit, add 2 browsers for $5/month with mcp-scraper-cli billing concurrency checkout.","",`${r("Ready.","lime",e)} Install the combined MCP server with one command:`,"",r("Setup doctor","amber",e),"npx -y -p mcp-scraper@latest mcp-scraper-cli doctor","",r("Hosted profile setup","amber",e),'In your MCP client, call browser_profile_connect with email="seo@example.com" and domain="chatgpt.com".',"Give the returned watch_url to the user. After they sign in, call browser_profile_list, then browser_open with the returned profile. Add more logins by calling browser_profile_connect again with the same profile and a new domain.","",r("Claude Code one-command setup","amber",e),c,"Then fully exit Claude Code and open a new Claude terminal. Check with: claude mcp list","",r("Codex config","amber",e),i,"",r("Claude Desktop Extension","amber",e),"Download: https://mcpscraper.dev/downloads/mcp-scraper.mcpb","",r("Safety note:","muted",e),"mcp-scraper prints this card only when stdin/stdout are an interactive TTY. In MCP clients it writes only JSON-RPC to stdout.","Use --stdio or MCP_SCRAPER_FORCE_STDIO=1 to force server mode from a terminal.",""].join(`
16
16
  `)}export{p as a};
@@ -1 +1 @@
1
- import{g as _,i as c}from"./chunk-7BEWBRMT.js";var g={\u006b\u0065\u0072\u006e\u0065\u006c:"browserRuntime"},a=/error|message/i,w=(new RegExp("(?:spending|billing|organization|account).{0,80}(?:cap|limit|blocked|disabled)|(?:quota|capacity).{0,40}(?:reached|exceeded)|https?:\\/\\/\\S*(?:dashboard|on\u006b\u0065\u0072\u006e\u0065\u006c)", "i")),E=/\b(?:ENOENT|ENOTDIR|EACCES|EPERM|EISDIR|EMFILE|ENFILE)\b|\b(?:mkdir|open|stat|lstat|readFile|writeFile)\s+['"]?(?:\/|[A-Za-z]:\\)|(?:^|[\s'"])(?:\/Users|\/home|\/tmp|\/var|\/private|\/opt|\/srv|\/root)\//i,k=new Set(["\u006b\u0065\u0072\u006e\u0065\u006c_session_id","browser_session_id","\u006b\u0065\u0072\u006e\u0065\u006cSessionId","browserSessionId","sessionId","\u006b\u0065\u0072\u006e\u0065\u006c_delete_started","session_cleanup_started","\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted","sessionCleanupStarted","\u006b\u0065\u0072\u006e\u0065\u006c_delete_succeeded","session_cleanup_succeeded","\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded","sessionCleanupSucceeded","\u006b\u0065\u0072\u006e\u0065\u006c_delete_error","session_cleanup_error","\u006b\u0065\u0072\u006e\u0065\u006cDeleteError","sessionCleanupError","\u006b\u0065\u0072\u006e\u0065\u006cProxyId","proxyId","requestedProxyIdSuffix","retrievedProxyIdSuffix","provider","providerName","service","serviceName","vendor","vendorName","organization","organizationId","accountId","browser_provider","provider_session_id","provider_session_observed_at","provider_lookup_status","provider_status","provider_error_code","provider_error_message","provider_reason_source","provider_duration_ms","provider_bandwidth_bytes","provider_captcha","provider_checked_at","provider_detail","provider_detail_json","provider_disconnect_observed","provider_disconnect_message","browserProvider","providerSessionId","providerLookupStatus","providerStatus","providerErrorCode","providerErrorMessage","providerReasonSource","providerDurationMs","providerBandwidthBytes","providerCaptcha","providerCheckedAt","providerDetail","providerDisconnectObserved","providerDisconnectMessage"]),S=new Set(["hosted_url","hostedUrl","live_view_url","liveViewUrl","cdp_ws_url","cdpWsUrl","browser_live_view_url"]),f=(new RegExp("\\b(?:wss?|https?):\\/\\/[^\\s\"'<>]*\\bon\u006b\u0065\u0072\u006e\u0065\u006c\\.com[^\\s\"'<>]*", "gi"));function b(e){return e.replace(f,"[browser-service]")}var R=new Set(["\u0062\u0072\u0069\u0067\u0068\u0074_\u0064\u0061\u0074\u0061_browser_api","\u006b\u0065\u0072\u006e\u0065\u006c","local"]),m=new Set(["pending","complete","not_found","unavailable_credentials","temporary_error","invalid_payload","not_applicable"]),h=new Set(["active","running","complete","completed","failed","closed","stopped","terminated","timed_out"]),I=new Set(["provider_session_api","client_runtime","extractor","unknown"]),y=new Set(["browser_disconnected","worker_disconnect","job_killed","cdp_cmd_timeout","network_inactivity_timeout","session_timeout","client_timeout","navigate_domains_limit","cdp_error","browser_session_interrupted","provider_detail_pending","provider_lookup_unavailable","provider_reported_no_error","provider_session_not_found","provider_invalid_json","provider_invalid_payload","provider_lookup_timeout","provider_lookup_network_error","unknown"]),T=new Set(["browser_provider","provider_session_id","provider_lookup_status","provider_status","provider_error_code","provider_error_message","provider_reason_source","provider_duration_ms","provider_bandwidth_bytes","provider_captcha","provider_checked_at","provider_detail","provider_detail_json","provider_disconnect_observed","provider_disconnect_message"]),P=512,A=320;function t(e,r){return typeof e=="string"&&r.has(e)?e:null}function O(e){return typeof e!="string"?null:y.has(e)||/^provider_http_(?:429|5\d\d)$/.test(e)?e:null}function D(e){return typeof e!="string"||e.length<1||e.length>P||/^(?:authorization|bearer|password|secret|token|api[_-]?key|account)/i.test(e)?null:/^[A-Za-z0-9._:-]+$/.test(e)&&!e.includes("://")?e:null}function p(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0?e:null}function l(e){if(typeof e!="string"||e.length>40)return null;let r=Date.parse(e);return Number.isFinite(r)&&new Date(r).toISOString()===e?e:null}function u(e){if(typeof e!="string")return null;let r=e.replace(/[\u0000-\u001f\u007f]+/g," ").replace(/\s+/g," ").trim();if(!r||r.startsWith("{")||r.startsWith("["))return null;let o=r.replace(/\b(?:wss?|https?):\/\/\S+/gi,"[redacted endpoint]").replace(/\b(?:authorization|proxy-authorization)\s*:\s*(?:Bearer\s+)?\S+/gi,"[redacted credential]").replace(/\bBearer\s+\S+/gi,"[redacted credential]").replace(/\b(?:api[_-]?key|password|secret|token|account[_-]?id)\s*[=:]\s*[^\s,;]+/gi,"[redacted credential]").replace(/\b(?:account|organization)\s+(?:id\s+)?[A-Za-z0-9_-]{4,}/gi,"[redacted account]");return b(o).slice(0,A)}function v(e){return typeof e=="boolean"?e:null}function N(e){return{browser_provider:t(e.browser_provider,R),provider_session_id:D(e.provider_session_id),provider_session_observed_at:l(e.provider_session_observed_at),provider_lookup_status:t(e.provider_lookup_status,m),provider_status:t(e.provider_status,h),provider_error_code:O(e.provider_error_code),provider_error_message:u(e.provider_error_message),provider_reason_source:t(e.provider_reason_source,I),provider_duration_ms:p(e.provider_duration_ms),provider_bandwidth_bytes:p(e.provider_bandwidth_bytes),provider_captcha:v(e.provider_captcha),provider_checked_at:l(e.provider_checked_at),provider_disconnect_observed:v(e.provider_disconnect_observed),provider_disconnect_message:u(e.provider_disconnect_message)}}function i(e,r=""){if(typeof e=="string"){let o=b(e);return a.test(r)&&(w.test(e)||E.test(e))?o=_("service_unavailable"):a.test(r)&&(o=c(o)),o}if(Array.isArray(e))return e.map(o=>i(o,r));if(e!==null&&typeof e=="object"){let o={};for(let[n,d]of Object.entries(e)){if(k.has(n))continue;let s=g[n]??n;if(S.has(n)){o[s]=null;continue}o[s]=i(d,n)}return o}return e}function L(e){return e.map(r=>{if(r===null||typeof r!="object"||Array.isArray(r))return i(r);let o=r,n=i(o);return Object.keys(o).some(s=>T.has(s))?{...n,...N(o)}:n})}function C(e){let r=e?.diagnostics;return r?.debug?{...e,diagnostics:{...r,debug:i(r.debug)}}:e}export{i as a,L as b,C as c};
1
+ import{g as _,i as c}from"./chunk-KKHTMYCD.js";var g={\u006b\u0065\u0072\u006e\u0065\u006c:"browserRuntime"},a=/error|message/i,w=(new RegExp("(?:spending|billing|organization|account).{0,80}(?:cap|limit|blocked|disabled)|(?:quota|capacity).{0,40}(?:reached|exceeded)|https?:\\/\\/\\S*(?:dashboard|on\u006b\u0065\u0072\u006e\u0065\u006c)", "i")),E=/\b(?:ENOENT|ENOTDIR|EACCES|EPERM|EISDIR|EMFILE|ENFILE)\b|\b(?:mkdir|open|stat|lstat|readFile|writeFile)\s+['"]?(?:\/|[A-Za-z]:\\)|(?:^|[\s'"])(?:\/Users|\/home|\/tmp|\/var|\/private|\/opt|\/srv|\/root)\//i,k=new Set(["\u006b\u0065\u0072\u006e\u0065\u006c_session_id","browser_session_id","\u006b\u0065\u0072\u006e\u0065\u006cSessionId","browserSessionId","sessionId","\u006b\u0065\u0072\u006e\u0065\u006c_delete_started","session_cleanup_started","\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted","sessionCleanupStarted","\u006b\u0065\u0072\u006e\u0065\u006c_delete_succeeded","session_cleanup_succeeded","\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded","sessionCleanupSucceeded","\u006b\u0065\u0072\u006e\u0065\u006c_delete_error","session_cleanup_error","\u006b\u0065\u0072\u006e\u0065\u006cDeleteError","sessionCleanupError","\u006b\u0065\u0072\u006e\u0065\u006cProxyId","proxyId","requestedProxyIdSuffix","retrievedProxyIdSuffix","provider","providerName","service","serviceName","vendor","vendorName","organization","organizationId","accountId","browser_provider","provider_session_id","provider_session_observed_at","provider_lookup_status","provider_status","provider_error_code","provider_error_message","provider_reason_source","provider_duration_ms","provider_bandwidth_bytes","provider_captcha","provider_checked_at","provider_detail","provider_detail_json","provider_disconnect_observed","provider_disconnect_message","browserProvider","providerSessionId","providerLookupStatus","providerStatus","providerErrorCode","providerErrorMessage","providerReasonSource","providerDurationMs","providerBandwidthBytes","providerCaptcha","providerCheckedAt","providerDetail","providerDisconnectObserved","providerDisconnectMessage"]),S=new Set(["hosted_url","hostedUrl","live_view_url","liveViewUrl","cdp_ws_url","cdpWsUrl","browser_live_view_url"]),f=(new RegExp("\\b(?:wss?|https?):\\/\\/[^\\s\"'<>]*\\bon\u006b\u0065\u0072\u006e\u0065\u006c\\.com[^\\s\"'<>]*", "gi"));function b(e){return e.replace(f,"[browser-service]")}var R=new Set(["\u0062\u0072\u0069\u0067\u0068\u0074_\u0064\u0061\u0074\u0061_browser_api","\u006b\u0065\u0072\u006e\u0065\u006c","local"]),m=new Set(["pending","complete","not_found","unavailable_credentials","temporary_error","invalid_payload","not_applicable"]),h=new Set(["active","running","complete","completed","failed","closed","stopped","terminated","timed_out"]),I=new Set(["provider_session_api","client_runtime","extractor","unknown"]),y=new Set(["browser_disconnected","worker_disconnect","job_killed","cdp_cmd_timeout","network_inactivity_timeout","session_timeout","client_timeout","navigate_domains_limit","cdp_error","browser_session_interrupted","provider_detail_pending","provider_lookup_unavailable","provider_reported_no_error","provider_session_not_found","provider_invalid_json","provider_invalid_payload","provider_lookup_timeout","provider_lookup_network_error","unknown"]),T=new Set(["browser_provider","provider_session_id","provider_lookup_status","provider_status","provider_error_code","provider_error_message","provider_reason_source","provider_duration_ms","provider_bandwidth_bytes","provider_captcha","provider_checked_at","provider_detail","provider_detail_json","provider_disconnect_observed","provider_disconnect_message"]),P=512,A=320;function t(e,r){return typeof e=="string"&&r.has(e)?e:null}function O(e){return typeof e!="string"?null:y.has(e)||/^provider_http_(?:429|5\d\d)$/.test(e)?e:null}function D(e){return typeof e!="string"||e.length<1||e.length>P||/^(?:authorization|bearer|password|secret|token|api[_-]?key|account)/i.test(e)?null:/^[A-Za-z0-9._:-]+$/.test(e)&&!e.includes("://")?e:null}function p(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0?e:null}function l(e){if(typeof e!="string"||e.length>40)return null;let r=Date.parse(e);return Number.isFinite(r)&&new Date(r).toISOString()===e?e:null}function u(e){if(typeof e!="string")return null;let r=e.replace(/[\u0000-\u001f\u007f]+/g," ").replace(/\s+/g," ").trim();if(!r||r.startsWith("{")||r.startsWith("["))return null;let o=r.replace(/\b(?:wss?|https?):\/\/\S+/gi,"[redacted endpoint]").replace(/\b(?:authorization|proxy-authorization)\s*:\s*(?:Bearer\s+)?\S+/gi,"[redacted credential]").replace(/\bBearer\s+\S+/gi,"[redacted credential]").replace(/\b(?:api[_-]?key|password|secret|token|account[_-]?id)\s*[=:]\s*[^\s,;]+/gi,"[redacted credential]").replace(/\b(?:account|organization)\s+(?:id\s+)?[A-Za-z0-9_-]{4,}/gi,"[redacted account]");return b(o).slice(0,A)}function v(e){return typeof e=="boolean"?e:null}function N(e){return{browser_provider:t(e.browser_provider,R),provider_session_id:D(e.provider_session_id),provider_session_observed_at:l(e.provider_session_observed_at),provider_lookup_status:t(e.provider_lookup_status,m),provider_status:t(e.provider_status,h),provider_error_code:O(e.provider_error_code),provider_error_message:u(e.provider_error_message),provider_reason_source:t(e.provider_reason_source,I),provider_duration_ms:p(e.provider_duration_ms),provider_bandwidth_bytes:p(e.provider_bandwidth_bytes),provider_captcha:v(e.provider_captcha),provider_checked_at:l(e.provider_checked_at),provider_disconnect_observed:v(e.provider_disconnect_observed),provider_disconnect_message:u(e.provider_disconnect_message)}}function i(e,r=""){if(typeof e=="string"){let o=b(e);return a.test(r)&&(w.test(e)||E.test(e))?o=_("service_unavailable"):a.test(r)&&(o=c(o)),o}if(Array.isArray(e))return e.map(o=>i(o,r));if(e!==null&&typeof e=="object"){let o={};for(let[n,d]of Object.entries(e)){if(k.has(n))continue;let s=g[n]??n;if(S.has(n)){o[s]=null;continue}o[s]=i(d,n)}return o}return e}function L(e){return e.map(r=>{if(r===null||typeof r!="object"||Array.isArray(r))return i(r);let o=r,n=i(o);return Object.keys(o).some(s=>T.has(s))?{...n,...N(o)}:n})}function C(e){let r=e?.diagnostics;return r?.debug?{...e,diagnostics:{...r,debug:i(r.debug)}}:e}export{i as a,L as b,C as c};
@@ -1,4 +1,4 @@
1
- import{A as f,Ab as _,Bb as y,Cb as C,Ya as g,_a as S,lb as R,mb as E,ob as v,wb as T,yb as h,z as u,zb as w}from"./chunk-LTT2B7NY.js";import{a as P}from"./chunk-7QHYBK6U.js";import{a as m}from"./chunk-KJA62B7P.js";import{readFileSync as N}from"fs";import{homedir as I}from"os";import{join as A}from"path";import{serveStdio as b}from"@modelcontextprotocol/server/stdio";import{McpServer as k}from"@modelcontextprotocol/server";var x=new Map(w.map(r=>[r.upstreamName,r.id]));function O(r){let s=r.split(`
1
+ import{Ca as R,Da as E,Fa as v,G as u,H as f,Na as T,Pa as h,Qa as w,Ra as _,Sa as y,Ta as C,na as g,pa as S}from"./chunk-XARSC34L.js";import{a as P}from"./chunk-5MMN27Q6.js";import{a as m}from"./chunk-UM4WSLKQ.js";import{readFileSync as N}from"fs";import{homedir as I}from"os";import{join as A}from"path";import{serveStdio as b}from"@modelcontextprotocol/server/stdio";import{McpServer as k}from"@modelcontextprotocol/server";var x=new Map(w.map(r=>[r.upstreamName,r.id]));function O(r){let s=r.split(`
2
2
  `).filter(o=>o.startsWith("data:")).map(o=>o.slice(5).trim()).filter(Boolean);if(!s.length)return JSON.parse(r);for(let o of s){let e=JSON.parse(o);if(e.result||e.error)return e}throw new Error("hosted MCP returned no JSON-RPC result")}function a(r){return{content:[{type:"text",text:JSON.stringify({ok:!1,error:r})}],isError:!0}}var c=class{baseUrl;apiKey;constructor(s,o){this.baseUrl=s.replace(/\/$/,""),this.apiKey=o}async callMemoryTool(s,o){let e=x.get(s);if(!e)return a(`unknown memory tool: ${s}`);try{let n=await fetch(`${this.baseUrl}/mcp`,{method:"POST",headers:{"content-type":"application/json",accept:"application/json, text/event-stream","x-api-key":this.apiKey},body:JSON.stringify({jsonrpc:"2.0",id:`memory:${e}`,method:"tools/call",params:{name:e,arguments:o}})}),l=await n.text();if(!n.ok)return a(`hosted memory ${e} failed (HTTP ${n.status})`);let t=O(l);return t.error?a(t.error.message??`hosted memory ${e} failed`):t.result??a(`hosted memory ${e} returned no result`)}catch(n){return a(n instanceof Error?n.message:`hosted memory ${e} call failed`)}}};function M(r,s){if(s.length===0)throw new Error("Restricted MCP tool allowlist must contain at least one tool name");let o=new Set;for(let t of s){if(typeof t!="string"||t.trim()!==t||t.length===0)throw new Error("Restricted MCP tool allowlist contains a malformed tool name");if(o.has(t))throw new Error(`Restricted MCP tool allowlist contains duplicate tool name: ${t}`);o.add(t)}let e=new Set,n=r,l=n.registerTool.bind(r);return n.registerTool=(t,i,p)=>{if(o.has(t))return e.add(t),l(t,i,p)},{assertComplete(){let t=[...o].filter(i=>!e.has(i));if(t.length>0)throw new Error(`Restricted MCP tool allowlist contains unknown or unavailable tool names: ${t.join(", ")}`)},registeredToolNames(){return[...e]}}}var L=new Set(["paa","serp","browser-agent","scheduled-results","memory"]);function $(){let s=[process.env.MCP_SCRAPER_KEY_PATH?.trim(),A(I(),".mcp-scraper-key")].filter(Boolean);for(let o of s)try{let e=N(o,"utf8").trim();if(e)return e}catch{}}function Y(r,s={}){let o=s.toolsets??L,e=process.env.MCP_SCRAPER_BASE_URL?.trim()||process.env.MCP_BASE_URL?.trim()||"https://mcpscraper.dev",n=g(),l=S({deploymentProfile:n,transportProfile:"stdio",baseUrl:e,explicitlyEnabled:process.env.MCP_SCRAPER_ALLOW_PRIVATE_NETWORK==="1"}),t=process.env.BROWSER_AGENT_CONSOLE_URL?.trim()||e,i=new k({name:"mcp-scraper",version:m},{instructions:u,cacheHints:{"server/discover":{ttlMs:3e5,cacheScope:"private"},"tools/list":{ttlMs:3e5,cacheScope:"private"},"prompts/list":{ttlMs:3e5,cacheScope:"private"},"resources/list":{ttlMs:3e5,cacheScope:"private"},"resources/templates/list":{ttlMs:3e5,cacheScope:"private"},"resources/read":{ttlMs:6e4,cacheScope:"private"}}});f(i);let p=s.allowedToolNames?M(i,s.allowedToolNames):void 0,d=s.httpExecutor??new T(e,r,{localNetworkAccess:l});return o.has("paa")&&v(i,d,{ownerId:R(r),deploymentProfile:n,transportProfile:"stdio",baseUrl:e,localNetworkAccess:l,taskHandleSecret:r}),o.has("serp")&&E(i,d,{exposeDevelopmentDiagnostics:n==="development"||n==="test"}),o.has("browser-agent")&&h(i,{baseUrl:e,apiKey:r,consoleBaseUrl:t}),o.has("scheduled-results")&&C(i,new y(e,r)),o.has("memory")&&_(i,new c(e,r)),p?.assertComplete(),i}function se(r={}){let s=process.argv.includes("--stdio")||process.env.MCP_SCRAPER_FORCE_STDIO==="1",o=!!(process.stdin.isTTY&&process.stdout.isTTY),e=process.argv.includes("--help")||process.argv.includes("-h");if(!s&&(o||e)){let l=process.argv.includes("--no-color")||process.env.NO_COLOR!==void 0||process.env.FORCE_COLOR==="0"||!process.stdout.isTTY;process.stdout.write(P({version:m,color:!l,apiKeyConfigured:!!process.env.MCP_SCRAPER_API_KEY?.trim()})),process.exit(0)}let n=(process.env.MCP_SCRAPER_API_KEY??process.env.MCP_SCRAPER_KEY??process.env.MCP_API_KEY??$())?.trim();n||(process.stderr.write(`MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required
3
3
  `),process.exit(1)),b(()=>Y(n,r),{legacy:"serve",onerror(l){process.stderr.write(`${l.message}
4
4
  `)}})}export{se as a};