mcp-scraper 0.96.3 → 0.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -1
- package/README.md +12 -18
- package/dist/{actions-FKAX2PYT.js → actions-NCZNPYEY.js} +1 -1
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/mcp-scraper-cli.js +26 -27
- package/dist/bin/mcp-scraper-core.js +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.js +1 -1
- package/dist/{bundle-7JMACIIR.js → bundle-XR6XKYJM.js} +1 -1
- package/dist/chunk-4P3LZNVA.js +954 -0
- package/dist/chunk-6FAMBNHY.js +1 -0
- package/dist/{chunk-3HXMW2UJ.js → chunk-A4UASMEQ.js} +1 -1
- package/dist/chunk-AMYPXA2F.js +930 -0
- package/dist/chunk-B5Y26E3A.js +1 -0
- package/dist/{chunk-WP3QS4CJ.js → chunk-EYGA6LOU.js} +1 -1
- package/dist/{chunk-P55O4IDC.js → chunk-JNPM3U3L.js} +1 -1
- package/dist/chunk-ND4WIBXT.js +16 -0
- package/dist/{chunk-PANT6VEM.js → chunk-NULRGHJ4.js} +1 -1
- package/dist/{chunk-42SLBGDI.js → chunk-OOB3RKWD.js} +2 -2
- package/dist/{chunk-DJT2547J.js → chunk-OSKCHEVM.js} +1 -1
- package/dist/{chunk-U7BZ5KTE.js → chunk-PD7BI7TR.js} +1 -1
- package/dist/{chunk-WBJ6Y7WP.js → chunk-PQRT4T2G.js} +2 -2
- package/dist/chunk-U3NV72AL.js +8 -0
- package/dist/{chunk-4KHDV5E7.js → chunk-WHVK6FUB.js} +1 -1
- package/dist/{chunk-E7I3OQHQ.js → chunk-XYUJTIPE.js} +1 -1
- package/dist/{chunk-JREMJRSS.js → chunk-YJPFEL2E.js} +1 -1
- package/dist/{chunk-CFZXZKFT.js → chunk-Z4EHBBL4.js} +1 -1
- package/dist/{core-schema-423BSTE6.js → core-schema-Y47YFKH2.js} +7 -44
- package/dist/{dispatch-E6VTNHHS.js → dispatch-ILBBKOSW.js} +1 -1
- package/dist/{queue-4XHYUV7J.js → queue-VOGXQDPR.js} +1 -1
- package/dist/{reconciliation-43CSC3XD.js → reconciliation-OXBG7JA2.js} +1 -1
- package/dist/{server-74VGVXA4.js → server-6HUBN3OR.js} +700 -1016
- package/dist/settlement-3PS32LQO.js +1 -0
- package/dist/{worker-L5NISZQV.js → worker-NXRU3TT3.js} +1 -1
- package/package.json +2 -2
- package/dist/chunk-2IATUJO6.js +0 -1
- package/dist/chunk-7ZR5IO3B.js +0 -16
- package/dist/chunk-JGGQ3UX5.js +0 -1
- package/dist/chunk-MJOXIDKF.js +0 -935
- package/dist/chunk-OY24ERPV.js +0 -8
- package/dist/chunk-QYPSFZK3.js +0 -955
- package/dist/settlement-I5IBIK6U.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to MCP Scraper are documented here. The format is based on [
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.97.0] - 2026-10-13
|
|
8
|
+
|
|
9
|
+
### Removed
|
|
10
|
+
|
|
11
|
+
- **Breaking:** Remove recurring actions, workflow schedules, assistant reminders, automatic vault cleanup and their MCP/API/CLI controls. Use the retained tools and manual workflows for requested work; historical notes, results, billing records and credentials remain stored.
|
|
12
|
+
- Remove scheduling dashboards, run viewers, add-on pricing and current product guidance. Artifact templates move to their independent workspace and remain available through their existing tools.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Host Memory and admitted background work through the existing native runtime. Preserve scoped search, full-file delivery, operation recovery, subscriptions and credit expiry; internal maintenance continues.
|
|
17
|
+
- Publish updated SDKs with scheduling methods removed and template methods in the artifacts namespace. Ordinary connected-service routes use `/connections`; existing connection transport aliases remain compatible.
|
|
18
|
+
- Align technical and business reports with the native worker while preserving customer costs, retries, refunds and client attribution.
|
|
19
|
+
|
|
7
20
|
## [0.96.3] - 2026-10-13
|
|
8
21
|
|
|
9
22
|
### Changed
|
|
@@ -2240,7 +2253,7 @@ All notable changes to MCP Scraper are documented here. The format is based on [
|
|
|
2240
2253
|
- Write actions remain unavailable until the account owner explicitly enables them.
|
|
2241
2254
|
- Provider-specific connection data is normalized into one agent-facing contract.
|
|
2242
2255
|
|
|
2243
|
-
[Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.
|
|
2256
|
+
[Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.97.0...HEAD
|
|
2244
2257
|
[0.95.2]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.95.1...v0.95.2
|
|
2245
2258
|
[0.95.1]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.95.0...v0.95.1
|
|
2246
2259
|
[0.95.0]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.94.4...v0.95.0
|
|
@@ -2414,3 +2427,5 @@ All notable changes to MCP Scraper are documented here. The format is based on [
|
|
|
2414
2427
|
[0.96.2]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.96.1...v0.96.2
|
|
2415
2428
|
|
|
2416
2429
|
[0.96.3]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.96.2...v0.96.3
|
|
2430
|
+
|
|
2431
|
+
[0.97.0]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.96.3...v0.97.0
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ This repository owns the complete private product runtime while preserving indep
|
|
|
10
10
|
deployment boundaries:
|
|
11
11
|
|
|
12
12
|
- `/` — primary MCP/API server and public `mcp-scraper` package;
|
|
13
|
-
- `apps/
|
|
13
|
+
- `apps/worker` — private native execution of admitted video and explicit Memory jobs;
|
|
14
14
|
- `apps/web` — private Next.js product and marketing application;
|
|
15
15
|
- `apps/memory` — hosted Memory service plus its independently publishable DB, Tools, and stdio packages.
|
|
16
16
|
|
|
@@ -85,20 +85,15 @@ npx -y -p mcp-scraper@latest mcp-scraper-cli report open last
|
|
|
85
85
|
|
|
86
86
|
Workflow runs save `manifest.json`, `report.html`, CSVs, Markdown, and evidence JSON under `MCP_SCRAPER_OUTPUT_DIR/workflows` or `~/Downloads/mcp-scraper/workflows`. High-level workflow IDs are `directory`, `agent-packet`, `local-competitive-audit`, `map-comparison`, `serp-comparison`, `paa-expansion-brief`, and `ai-overview-language`.
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
Inspect hosted run history:
|
|
89
89
|
|
|
90
90
|
```bash
|
|
91
|
-
npx -y -p mcp-scraper@latest mcp-scraper-cli schedule create local-competitive-audit --weekly --query roofers --state TN --min-pop 100000 --per-city 20 --webhook https://example.com/mcp-scraper-hook
|
|
92
|
-
npx -y -p mcp-scraper@latest mcp-scraper-cli schedule list
|
|
93
|
-
npx -y -p mcp-scraper@latest mcp-scraper-cli schedule run <schedule-id>
|
|
94
|
-
npx -y -p mcp-scraper@latest mcp-scraper-cli schedule pause <schedule-id>
|
|
95
|
-
npx -y -p mcp-scraper@latest mcp-scraper-cli schedule resume <schedule-id>
|
|
96
91
|
npx -y -p mcp-scraper@latest mcp-scraper-cli runs list
|
|
97
92
|
npx -y -p mcp-scraper@latest mcp-scraper-cli runs status <run-id>
|
|
98
93
|
npx -y -p mcp-scraper@latest mcp-scraper-cli runs download <run-id>
|
|
99
94
|
```
|
|
100
95
|
|
|
101
|
-
The hosted workflow API is mounted under `/workflows`: `GET /definitions`, `POST /run`, `GET /runs`, `GET /runs/:id`, `GET /runs/:id/artifacts/:artifactId
|
|
96
|
+
The hosted workflow API is mounted under `/workflows`: `GET /definitions`, `POST /run`, `GET /runs`, `GET /runs/:id`, and `GET /runs/:id/artifacts/:artifactId`. Workflows run on explicit request. Internal maintenance resumes already-admitted jobs; it does not create user schedules.
|
|
102
97
|
|
|
103
98
|
## Build or enrich lead lists
|
|
104
99
|
|
|
@@ -177,7 +172,7 @@ Build the branded one-click bundle:
|
|
|
177
172
|
npm run build:mcpb
|
|
178
173
|
```
|
|
179
174
|
|
|
180
|
-
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.
|
|
175
|
+
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.97.0`, SHA-256 `96b701920f66a0ee1a19dc52c6f39bf017e41c33983368d1dc09bbdc999bd110`). 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.
|
|
181
176
|
|
|
182
177
|
The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
|
|
183
178
|
|
|
@@ -296,20 +291,19 @@ Check `pagination.requestedPages`, `pagination.capturedPages`, and `pagination.p
|
|
|
296
291
|
- `list_service_connections` — list this caller's tenant-owned Nango OAuth and official remote MCP connections, including verified provider-side account email/name when exposed, exact live reads, gated actions, permanently blocked administrative tools, credential transport, and schema-discovery metadata. Provider identity is distinct from the MCP Scraper login, and connections are never shared between customers.
|
|
297
292
|
- `describe_service_connection_tool` — fetch the sanitized live MCP Tool definition for one tool listed on one tenant-owned connection, including its current callability, input schema, optional output schema, safe annotations, and schema hash. Use this before constructing provider-native arguments; provider functions stay behind the generic bridges instead of becoming dozens of permanent top-level tools.
|
|
298
293
|
- `export_connected_service_data` — fetch a fresh Gmail, Google Calendar, Google Search Console, Zoom, Slack, Resend, or Meta dataset in one MCP call. Slack's `slack_channel_messages` dataset accepts a `channelId`, paginates top-level history, fetches threaded replies in bounded parallel batches, preserves file metadata, honors retry delays, and supports `allTime:true`; it never joins or changes the channel. Zoom's `zoom_transcripts` dataset resolves VTT files from recording metadata and downloads them through the authenticated connection without looping the separately rate-limited `get-meeting-transcript` function. Search Console's `search_console_performance` dataset walks accessible properties and bounded live Search Analytics pages with continuation. Small exports return inline; larger exports become private JSONL retained for seven days with exact `report_artifact_read` arguments plus an optional 15-minute human download URL. For relationship work, gather source evidence first: inspect existing People records, resolve the exact provider account, preserve provider provenance when writing a linked Communication, and never treat an export as permission to mutate the source account.
|
|
299
|
-
- `export_search_console_table_data` — filter up to 50,000 Search Console
|
|
294
|
+
- `export_search_console_table_data` — filter up to 50,000 Search Console historically stored Search Console rows and create a private renewable JSONL artifact without calling Google again. Get the typed `gsc_performance_*` table name from `list_service_connections`, inspect it with `table-describe`, and use the same filters with `table-query` for interactive analysis.
|
|
300
295
|
- `renew_connected_data_download` — issue a fresh 15-minute signed URL for an unexpired private export artifact without pulling the provider again.
|
|
301
296
|
- `read_service_connection` — run one small live read by exact allowlisted name across Nango OAuth or official remote MCP connections, including bounded Google Drive inventory, change, Doc, Sheet, and text-file tools. Do not loop it over a time range when `export_connected_service_data` supports that provider's collection.
|
|
302
297
|
- `import_service_connection_to_memory` — run one exact approved read and upsert the bounded, redacted result into an existing ordinary Memory vault at a stable server-generated path. The snapshot is embedded for semantic search and explicitly marked as untrusted provider data. This is not account-wide pagination or continuous sync.
|
|
303
298
|
- `call_service_connection_action` — run one exact mutation only after the account action switch is enabled. Google Drive, Search Console, Resend, GitHub, Gmail, Calendar, Slack, Zoom, Facebook, Google Analytics, X, and YouTube actions remain live-inventory, provider-policy, tenant, and audit gated; credential, OAuth-grant, and raw editor-session administration is never exposed.
|
|
304
|
-
- `set_scheduled_action_connections` — bind exact tenant connections and exact tool grants to one scheduled action. Deterministic connection syncs are model-free and one schedule occurrence counts as one metered event even when provider pagination spans many pages.
|
|
305
299
|
|
|
306
|
-
|
|
300
|
+
Connected-account charges come from the canonical rate card and actual usage receipts. OAuth connect and reconnect do not consume Credits. Separately metered scraper, browser, and media operations keep their normal rates; inspect `get_credit_costs` before paid work.
|
|
307
301
|
|
|
308
|
-
GitHub uses the same provider-neutral read/action bridges: 27 live reads cover repository discovery, issues, pull requests, commits, releases, and workflows; 20 live mutations remain account- and
|
|
302
|
+
GitHub uses the same provider-neutral read/action bridges: 27 live reads cover repository discovery, issues, pull requests, commits, releases, and workflows; 20 live mutations remain account- and action-gated. The 47 Nango functions and expanded reconnect scopes are deployed. The current test token remains `public_repo` until owners approve its two pending organization requests, so private-repository and workflow parity is not yet claimed.
|
|
309
303
|
|
|
310
|
-
Google Drive Phase 1 exposes ten bounded reads plus the separately gated `create-drive-folder` and `copy-drive-file` actions through those same bridges
|
|
304
|
+
Google Drive Phase 1 exposes ten bounded reads plus the separately gated `create-drive-folder` and `copy-drive-file` actions through those same bridges with explicit account and action permissions. It is interactive tool support, not a bulk-export feature; large binary delivery and broader Drive mutations remain unreleased.
|
|
311
305
|
|
|
312
|
-
Google Search Console exposes eight bounded reads and eight gated property and sitemap mutations, including API-only batches for URL inspection, Search Analytics comparison, property management, and sitemap management. Batch calls return per-item receipts, run quota-consciously, and do not require database persistence; destructive batches default to dry-run previews and require explicit confirmation.
|
|
306
|
+
Google Search Console exposes eight bounded reads and eight gated property and sitemap mutations, including API-only batches for URL inspection, Search Analytics comparison, property management, and sitemap management. Batch calls return per-item receipts, run quota-consciously, and do not require database persistence; destructive batches default to dry-run previews and require explicit confirmation. Supported direct exports and Memory imports preserve returned records and checkpoints. Query tenant-owned tables with `table-describe` and `table-query`; the server does not create recurring syncs.
|
|
313
307
|
|
|
314
308
|
### Memory discovery and safe editing
|
|
315
309
|
|
|
@@ -353,9 +347,9 @@ The `mcp-scraper` server (and the MCPB bundle, which runs it) exposes both secti
|
|
|
353
347
|
|
|
354
348
|
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.
|
|
355
349
|
|
|
356
|
-
The canonical tool inventory is generated at `docs/mcp-tool-manifest.generated.json`. The
|
|
350
|
+
The canonical tool inventory is generated at `docs/mcp-tool-manifest.generated.json`. The generated manifest is the authoritative current inventory across scraper, browser, manual workflow, billing, connected-service and 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 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.
|
|
357
351
|
|
|
358
|
-
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,
|
|
352
|
+
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, 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`.
|
|
359
353
|
|
|
360
354
|
The public REST registry in `src/api/public-rest-contract.ts` owns Maps search and directory run/status request and response schemas, headers, descriptions, and paths. Run `npm run contracts:rest` after changing one of those operations; `npm run contracts:rest:check` fails when the versioned artifact or the web docs projection is stale. The SDK imports `contracts/public-rest.v1.json`, projects it over its curated OpenAPI base, and regenerates Node and Python models together. Other public REST operations remain in that curated base until migrated.
|
|
361
355
|
|
|
@@ -412,7 +406,7 @@ The bundle runs `mcp-scraper` internally, so the user installs `MCP Scraper` onc
|
|
|
412
406
|
|
|
413
407
|
## Development
|
|
414
408
|
|
|
415
|
-
Production deployments track `codex/mcp-ownership-tree` for the server, web app, Memory and
|
|
409
|
+
Production deployments track `codex/mcp-ownership-tree` for the server, web app, Memory and native worker. Their Vercel configurations admit this branch and disable automatic deployments from `main`. Before deploying server schema changes, run `npm run release:server:predeploy` against the production database. Customer request capture additionally requires `MCP_ANALYTICS_CAPTURE=1`; missing historical attribution stays unknown.
|
|
416
410
|
|
|
417
411
|
See the [codebase layout and edit guide](docs/architecture/codebase-file-tree.md) for the populated tree, feature homes and compatibility entrypoints.
|
|
418
412
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{e as a,f as b,g as c,h as d,i as e,j as f,k as g,l as h}from"./chunk-
|
|
1
|
+
import{e as a,f as b,g as c,h as d,i as e,j as f,k as g,l as h}from"./chunk-Z4EHBBL4.js";import"./chunk-PQRT4T2G.js";import"./chunk-NALXKTUU.js";import"./chunk-OSKCHEVM.js";import"./chunk-RDHGQ2WZ.js";import"./chunk-U3NV72AL.js";import"./chunk-SEZETSB3.js";import"./chunk-SDQW7IJN.js";import"./chunk-VVSHZV5S.js";import"./chunk-4ZVO6GX4.js";import"./chunk-WNUXMPVX.js";import"./chunk-EYGA6LOU.js";import"./chunk-OILOHQNL.js";export{d as GMAIL_ATTACHMENT_REF_TTL_MS,c as GMAIL_INLINE_BODY_BYTES,b as GMAIL_MAIN_CONTRACT_HASH,a as GMAIL_MAIN_CONTRACT_VERSION,h as GmailService,e as GmailServiceError,g as normalizeGmailMessage,f as parseGmailAddresses};
|
package/dist/bin/api-server.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
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-
|
|
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-6HUBN3OR.js"),import("../worker-NXRU3TT3.js"),import("../core-schema-Y47YFKH2.js")]),n=parseInt(process.env.PORT??"3001");try{if(await i(),process.env.ANALYTICS_DATABASE_URL){let{migrateAnalytics:t}=await import("../migrations-3AKEC5QE.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,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{k as
|
|
3
|
-
`)){let
|
|
4
|
-
`):
|
|
5
|
-
`):
|
|
2
|
+
import{k as E,l as j,m as N,n as D,r as L}from"../chunk-4HZXATHB.js";import"../chunk-KJQXUZ4Y.js";import"../chunk-6N5EC7ZO.js";import{g as v,j as b,k as U,l as T,m as K}from"../chunk-24YDQ3EO.js";import"../chunk-OLYPLX5C.js";import"../chunk-B3JRL45T.js";import{c as S}from"../chunk-OILOHQNL.js";import{a as h}from"../chunk-6FAMBNHY.js";import{Command as we}from"commander";import{spawn as Z}from"child_process";import{mkdir as ye,writeFile as he}from"fs/promises";import{basename as ke,join as X}from"path";function ne(e){return e.apiKey?.trim()||"sk_live_your_key"}function oe(e){return e.packageSpec?.trim()||"mcp-scraper@latest"}function P(e={}){return["-y","--package",oe(e),"mcp-scraper"]}function ie(e){let t={MCP_SCRAPER_API_KEY:ne(e)},s=e.browserProfileName?.trim();return s&&(t.BROWSER_AGENT_PROFILE_NAME=s),e.browserProfileSaveChanges===!0&&(t.BROWSER_AGENT_PROFILE_SAVE_CHANGES="true"),t}function H(){return["mcp","remove","mcp-scraper","-s","user"]}function B(){return["mcp","get","mcp-scraper"]}function q(e){let t=e.match(/^\s*Command:\s*(.+?)\s*$/m)?.[1];if(!t)return null;let s=e.match(/^\s*Args:\s*(.*?)\s*$/m)?.[1]??"",i=s.length?s.split(/\s+/):[],p={},u=e.split(/^\s*Environment:\s*$/m)[1];if(u)for(let a of u.split(`
|
|
3
|
+
`)){let o=a.match(/^\s{2,}([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);if(!o){if(a.trim().length&&!/^\s{2,}/.test(a))break;continue}p[o[1]]=o[2]}return{command:t,args:i,env:p}}function O(e){let t=["mcp","add","mcp-scraper","--scope","user"];for(let[s,i]of Object.entries(e.env))t.push("--env",`${s}=${i}`);return t.push("--",e.command,...e.args),t}function G(e={}){let t=["mcp","add","mcp-scraper","--scope","user"];for(let[s,i]of Object.entries(ie(e)))t.push("--env",`${s}=${i}`);return t.push("--","npx",...P(e)),t}function M(e){if(e==="claude-code")return"claude";if(e==="claude"||U.hosts.some(t=>t.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 ae(e){return T(e==="claude"?"claude-code":e)}function J(e,t={}){let s=M(e),i=ae(s),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 s==="codex"?["# Codex MCP config",a,i.exactConfig,"",`Continuation: ${i.continuation}`,`Rollback: ${i.rollback}`,"",p].join(`
|
|
4
|
+
`):s==="claude"?["# Claude Code command",a,i.exactConfig,"","# One-command Claude Code setup",u,"",`Continuation: ${i.continuation}`,`Rollback: ${i.rollback}`,"",p].join(`
|
|
5
|
+
`):s==="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(`
|
|
6
6
|
`):[`# ${i.label} MCP config`,a,i.exactConfig,"",`Continuation: ${i.continuation}`,`Rollback: ${i.rollback}`,...i.restartRequired?["",p]:[]].join(`
|
|
7
|
-
`)}import{access as
|
|
8
|
-
Fix: ${i.fix}`:"";return`[${
|
|
9
|
-
`)}var
|
|
7
|
+
`)}import{access as se,mkdir as ce,readFile as pe}from"fs/promises";import{homedir as ue}from"os";import{join as le}from"path";function de(e,t=!1){return e?"pass":t?"warn":"fail"}function me(e){return Number(e.replace(/^v/,"").split(".")[0]??0)}async function fe(){let e=process.env.MCP_SCRAPER_KEY_PATH?.trim()||le(ue(),".mcp-scraper-key");try{return(await pe(e,"utf8")).trim()||null}catch{return null}}async function ge(e){try{let t=await e("https://registry.npmjs.org/mcp-scraper/latest",{signal:AbortSignal.timeout(5e3)});return t.ok?(await t.json()).version??null:null}catch{return null}}async function Y(e={}){let t=e.fetchImpl??fetch,s=(e.apiUrl??process.env.MCP_SCRAPER_API_URL??"https://mcpscraper.dev").replace(/\/$/,""),i=S(e.outputDir),p=e.apiKey?.trim()||process.env.MCP_SCRAPER_API_KEY?.trim()||await fe(),u=await ge(t),a=[],o=me(process.version);a.push({id:"node",label:"Node.js",status:de(o>=20),detail:process.version,fix:o>=20?void 0:"Install Node.js 20 or newer."}),a.push({id:"package_version",label:"Local package",status:u&&u!==h?"warn":"pass",detail:u?`local ${h}, npm latest ${u}`:`local ${h}, npm latest unavailable`,fix:u&&u!==h?"Use mcp-scraper@latest and restart the MCP client.":void 0}),a.push({id:"api_key",label:"API key",status:p?"pass":"warn",detail:p?"configured":"not configured",fix:p?void 0:"Set MCP_SCRAPER_API_KEY or pass --api-key."});try{await ce(i,{recursive:!0}),await se(i),a.push({id:"output_dir",label:"Output directory",status:"pass",detail:i})}catch(r){a.push({id:"output_dir",label:"Output directory",status:"fail",detail:i,fix:r instanceof Error?r.message:"Create a writable output directory."})}if(p)try{let r=await t(`${s}/me`,{headers:{"x-api-key":p},signal:AbortSignal.timeout(8e3)});a.push({id:"api_reachability",label:"Hosted API",status:r.ok?"pass":"fail",detail:`${s}/me returned ${r.status}`,fix:r.ok?void 0:"Verify the API key and account status."})}catch(r){a.push({id:"api_reachability",label:"Hosted API",status:"fail",detail:r instanceof Error?r.message:String(r),fix:"Check network access and MCP_SCRAPER_API_URL."})}else a.push({id:"api_reachability",label:"Hosted API",status:"skip",detail:"skipped because no API key is configured"});return a.push({id:"mcp_config",label:"MCP command",status:"pass",detail:`npx ${P().join(" ")}`,fix:"Restart the MCP client after package updates."}),{ok:a.every(r=>r.status==="pass"||r.status==="skip"),version:h,npmLatest:u,checks:a,recommendedConfig:{command:"npx",args:P(),env:{MCP_SCRAPER_API_KEY:p?"$MCP_SCRAPER_API_KEY":"sk_live_your_key"}}}}function W(e){let t={pass:"PASS",warn:"WARN",fail:"FAIL",skip:"SKIP"};return[`mcp-scraper doctor v${e.version}`,"",...e.checks.map(i=>{let p=i.fix?`
|
|
8
|
+
Fix: ${i.fix}`:"";return`[${t[i.status]}] ${i.label}: ${i.detail}${p}`}),"",`Recommended MCP command: npx ${e.recommendedConfig.args.join(" ")}`].join(`
|
|
9
|
+
`)}var F={"xray-setup":K(),"agent-packet":["# MCP Scraper Agent Packet Prompt","","Use MCP Scraper as the evidence layer. Run the agent-packet workflow for the target keyword/domain, then treat `evidence.json`, `sources.csv`, and `competitors.csv` as source of truth.","","Do not invent citations. If a recommendation is not supported by the packet, mark it as an assumption. Turn the evidence into a concise SEO brief, an implementation task list, and content recommendations tied to source rows."].join(`
|
|
10
10
|
`),"local-competitive-audit":["# MCP Scraper Local Competitive Audit Prompt","","Run the local-competitive-audit workflow for the niche and markets. Use the city summary, competitor CSV, and review-insight CSV to identify market difficulty, review themes, GBP category patterns, and weak competitors.","","Ground recommendations in Maps rank position, review count, star rating, categories, profile details, and review topics. Do not overstate heuristic opportunity scores."].join(`
|
|
11
11
|
`),"directory-workflow":["# MCP Scraper Directory Workflow Prompt","","Use directory_workflow when the user wants cities selected by population and Google Maps candidates per city. Keep query and location separate. Preserve result_position, source_location, review stars/count, categories, and profile URLs for downstream CSV or directory use."].join(`
|
|
12
12
|
`),"map-comparison":["# MCP Scraper Maps Comparison Prompt","","Run the map-comparison workflow when the user wants to compare local Maps competitors in a city or across selected markets. Use `maps-results.csv`, `map-comparison.csv`, and `profile-insights.csv` as source of truth.","","Ground recommendations in result_position, review_stars, review_count, category, website presence, review topics, and profile attributes. Treat review gaps and missing websites as opportunity signals, not guaranteed ranking factors."].join(`
|
|
@@ -15,26 +15,25 @@ import{k as N,l as j,m as L,n as T,r as U}from"../chunk-4HZXATHB.js";import"../c
|
|
|
15
15
|
`),"ai-overview-language":["# MCP Scraper AI Overview Language Prompt","","Run the ai-overview-language workflow when the user wants to know how to phrase content for AI Overview inclusion. Use `claim-patterns.csv`, `language-guidance.csv`, `ai-overview-citations.csv`, and PAA follow-ups as evidence.","","Recommend concise answer blocks, criteria/step language, citation hooks, and follow-up sections. Do not claim the target will be cited; frame the output as evidence-based language guidance."].join(`
|
|
16
16
|
`),"ai-citation-monitor":["# MCP Scraper AI Citation Monitor Prompt","","Use search_serp and harvest_paa to check whether the target brand/domain appears in AI Overview citations, organic results, People Also Ask sources, local pack, forums, and videos. Save evidence before summarizing trends or gaps."].join(`
|
|
17
17
|
`),"serp-brief":["# MCP Scraper SERP Brief Prompt","","Use live SERP, PAA, AI Overview, forum, video, and source evidence to create a writer brief. Tie each recommended section to evidence rows and identify missing proof, entities, comparisons, and customer questions."].join(`
|
|
18
|
-
`)};function
|
|
18
|
+
`)};function R(){return Object.keys(F).sort()}function V(e){let t=F[e];if(!t)throw new Error(`Unknown prompt "${e}". Available: ${R().join(", ")}`);return t}function d(e){if(e==null||e==="")return;let t=Number(e);return Number.isFinite(t)?t:void 0}function Pe(e){if(e!==void 0){if(typeof e=="boolean")return e;if(e==="true")return!0;if(e==="false")return!1}}function x(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}function Ce(e,t){return x(e==="agent-packet"||e==="serp-comparison"||e==="ai-overview-language"?{keyword:t.keyword,domain:t.domain,url:t.url,location:t.location,maxResults:d(t.maxResults),maxQuestions:d(t.maxQuestions),extractTop:d(t.extractTop),includeSerp:t.serp===!1?!1:void 0,includePaa:t.paa===!1?!1:void 0,includeAiOverview:Pe(t.includeAiOverview),returnPartial:t.returnPartial===!1?!1:void 0}:e==="paa-expansion-brief"?{keyword:t.keyword,location:t.location,maxQuestions:d(t.maxQuestions),depth:d(t.depth),returnPartial:t.returnPartial===!1?!1:void 0}:e==="directory"||e==="local-competitive-audit"||e==="map-comparison"?{query:t.query,location:t.location,state:t.state,minPopulation:d(t.minPop??t.minPopulation),maxCities:d(t.maxCities),maxResultsPerCity:d(t.perCity??t.maxResultsPerCity??t.maxResults),concurrency:d(t.concurrency),proxyMode:t.proxyMode,hydrateTop:e==="local-competitive-audit"||e==="map-comparison"?d(t.hydrateTop):void 0,maxReviews:e==="local-competitive-audit"||e==="map-comparison"?d(t.reviews??t.maxReviews):void 0,returnPartial:t.returnPartial===!1?!1:void 0}:t)}function c(e,t){t?process.stdout.write(`${JSON.stringify(e,null,2)}
|
|
19
19
|
`):typeof e=="string"?process.stdout.write(`${e}
|
|
20
20
|
`):process.stdout.write(`${JSON.stringify(e,null,2)}
|
|
21
|
-
`)}function
|
|
22
|
-
`),!1)}}),
|
|
23
|
-
`),!1)}),
|
|
24
|
-
`),!1)});let i=e.command("agent").description("Generate AI-agent install configs and workflow prompts.");i.command("install <host>").description("Print or apply install/config instructions for Codex, Claude, Cursor, Windsurf, Cline, or a handoff-only MCP host.").option("--api-key <key>","API key to place in generated config").option("--package <spec>","npm package spec","mcp-scraper@latest").option("--browser-profile <name>","Default saved browser profile for browser_open sessions.").option("--save-browser-profile-changes","Persist cookies and browser storage back to the named browser profile when sessions close").option("--apply","Apply the config to this client when supported. For Claude Code, this upserts the user-scope mcp-scraper server.").option("--json","Print machine-readable JSON").action(async(r
|
|
25
|
-
`).trim()),
|
|
26
|
-
claude `+O(
|
|
27
|
-
`))}let
|
|
28
|
-
`).trim())};if(
|
|
29
|
-
${
|
|
30
|
-
`),!1);return}let
|
|
31
|
-
`),
|
|
32
|
-
${
|
|
33
|
-
`),!1)}),p.command("run <id>").description("Run a workflow and save local artifacts.").option("--api-key <key>","MCP Scraper API key").option("--api-url <url>","MCP Scraper API URL","https://mcpscraper.dev").option("--output-dir <path>","Workflow output directory").option("--json","Print machine-readable JSON").option("--keyword <keyword>","Agent packet keyword").option("--domain <domain>","Target domain").option("--url <url>","Target page URL").option("--location <location>","Target location").option("--max-results <n>","Maximum SERP or Maps results").option("--max-questions <n>","Maximum PAA questions").option("--extract-top <n>","Top result pages or citation pages to extract").option("--depth <n>","PAA expansion depth").option("--no-serp","Skip SERP evidence for agent packet").option("--no-paa","Skip PAA evidence for agent packet").option("--query <query>","Business category or workflow query").option("--state <state>","US state").option("--min-pop <n>","Minimum city population").option("--max-cities <n>","Maximum selected cities").option("--per-city <n>","Maps results per city").option("--concurrency <n>","City search concurrency").option("--proxy-mode <mode>","Proxy mode: location, configured, or none").option("--hydrate-top <n>","Profiles to hydrate per city for competitive audits").option("--reviews <n>","Review cards to collect per hydrated profile").option("--no-return-partial","Fail instead of writing partial artifacts").action(async(r
|
|
34
|
-
${
|
|
21
|
+
`)}function z(e){return e.replace(/sk_[A-Za-z0-9_-]+/g,"sk_***")}function A(e,t){return new Promise(s=>{let i=Z(e,t,{stdio:["ignore","pipe","pipe"]}),p=[],u=[],a=!1,o=r=>{a||(a=!0,s(r))};i.stdout.on("data",r=>p.push(Buffer.from(r))),i.stderr.on("data",r=>u.push(Buffer.from(r))),i.on("error",r=>{o({code:127,stdout:"",stderr:r.message})}),i.on("close",r=>{o({code:typeof r=="number"?r:1,stdout:Buffer.concat(p).toString("utf8"),stderr:Buffer.concat(u).toString("utf8")})})})}function ee(e){let t=String(e.apiKey??process.env.MCP_SCRAPER_API_KEY??"").trim();if(!t)throw new Error("MCP_SCRAPER_API_KEY is required. Pass --api-key or set the environment variable.");return{apiUrl:String(e.apiUrl??process.env.MCP_SCRAPER_API_URL??"https://mcpscraper.dev").replace(/\/$/,""),apiKey:t}}function Q(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",s=process.platform==="win32"?["/c","start","",e]:[e];try{return Z(t,s,{detached:!0,stdio:"ignore"}).unref(),!0}catch{return!1}}async function C(e,t,s,i){let{apiUrl:p,apiKey:u}=ee(s),a=await fetch(`${p}${e}`,{method:t,headers:{"Content-Type":"application/json","x-api-key":u},body:i==null?void 0:JSON.stringify(i)}),o=await a.json().catch(()=>({}));if(!a.ok){let r=typeof o.error=="string"?o.error:`API request failed with ${a.status}`;throw new Error(r)}return o}function ve(){let e=new we;e.name("mcp-scraper-cli").description("Human CLI for MCP Scraper setup, workflows, reports, and agent-ready SEO artifacts.").version(h),e.command("doctor").description("Check setup, API key, output directory, package version, and recommended MCP config.").option("--api-key <key>","MCP Scraper API key").option("--api-url <url>","MCP Scraper API URL","https://mcpscraper.dev").option("--output-dir <path>","Output directory to test").option("--json","Print machine-readable JSON").action(async o=>{let r=await Y({apiKey:o.apiKey,apiUrl:o.apiUrl,outputDir:o.outputDir});c(o.json?r:W(r),o.json),r.ok||(process.exitCode=1)});let t=e.command("billing").description("Inspect billing and start checkout flows."),s=t.command("concurrency").description("Manage MCP Scraper concurrency packs.");s.command("info").description("Show current concurrency limit and concurrency-pack price.").option("--api-key <key>","MCP Scraper API key").option("--api-url <url>","MCP Scraper API URL","https://mcpscraper.dev").option("--json","Print machine-readable JSON").action(async o=>{let r=await C("/billing/credits","POST",o,{});if(o.json)c(r.concurrency,!0);else{let n=r.concurrency?.upgrade;c([`Current limit: ${r.concurrency?.current_limit??"unknown"} concurrent operations`,`Extra slots: ${r.concurrency?.current_extra_slots??"unknown"}`,`Concurrency pack: ${n?.price_label??"$5/month for 2 extra browsers"}`,`Upgrade command: ${n?.terminal_command??"mcp-scraper-cli billing concurrency checkout"}`].join(`
|
|
22
|
+
`),!1)}}),s.command("checkout").description("Create or update a hosted Stripe checkout for concurrency packs (two browsers per pack).").argument("[quantity]","Desired pack quantity","1").option("--api-key <key>","MCP Scraper API key").option("--api-url <url>","MCP Scraper API URL","https://mcpscraper.dev").option("--json","Print machine-readable JSON").option("--no-open","Print the checkout URL without opening a browser").action(async(o,r)=>{let n=await C("/billing/concurrency/terminal-checkout","POST",r,{quantity:Number(o)});if(r.json){c(n,!0);return}let l=!!n.checkout_url&&r.open!==!1&&Q(n.checkout_url);c([`Concurrency pack: ${n.price?.price_label??"$5/month for 2 extra browsers"}`,n.updated?"Concurrency pack quantity updated.":l?`Opened checkout: ${n.checkout_url}`:`Checkout URL: ${n.checkout_url}`,n.next_step??"Complete checkout, then retry the MCP request."].join(`
|
|
23
|
+
`),!1)}),t.command("subscribe <tier>").description("Subscribe to a plan (starter | growth | scale) via a hosted Stripe checkout link.").option("--api-key <key>","MCP Scraper API key").option("--api-url <url>","MCP Scraper API URL","https://mcpscraper.dev").option("--json","Print machine-readable JSON").option("--no-open","Print the checkout URL without opening a browser").action(async(o,r)=>{let n=await C("/billing/subscribe/terminal-checkout","POST",r,{tier:String(o).toLowerCase()});if(r.json){c(n,!0);return}if(n.updated){c(n.message??`Switched to ${n.tier}.`,!1);return}let l=r.open!==!1&&!!n.checkout_url&&Q(n.checkout_url),k=n.billing_interval==="year"?"year":"month",w=n.amount_usd??n.monthly_usd,y=n.credits_per_interval??n.credits_per_month,m=k==="year"?"/yr":"/mo",f=k==="year"?"credits/yr":"credits/mo",g=[n.credits_never_expire?"credits never expire":null,n.includes_memory?"includes Memory Pro":null,n.intro].filter(Boolean).join(" \xB7 ");c([`Plan: ${n.label??o} \u2014 $${w}${m} \xB7 ${y?.toLocaleString()} ${f} \xB7 ${n.concurrency} concurrency${g?` \xB7 ${g}`:""}`,l?`Opened checkout: ${n.checkout_url}`:`Checkout URL: ${n.checkout_url}`,n.next_step??"Complete payment in the browser."].join(`
|
|
24
|
+
`),!1)});let i=e.command("agent").description("Generate AI-agent install configs and workflow prompts.");i.command("install <host>").description("Print or apply install/config instructions for Codex, Claude, Cursor, Windsurf, Cline, or a handoff-only MCP host.").option("--api-key <key>","API key to place in generated config").option("--package <spec>","npm package spec","mcp-scraper@latest").option("--browser-profile <name>","Default saved browser profile for browser_open sessions.").option("--save-browser-profile-changes","Persist cookies and browser storage back to the named browser profile when sessions close").option("--apply","Apply the config to this client when supported. For Claude Code, this upserts the user-scope mcp-scraper server.").option("--json","Print machine-readable JSON").action(async(o,r)=>{let n=M(o),l=r.apiKey??process.env.MCP_SCRAPER_API_KEY;if(r.apply){if(n!=="claude")throw new Error('--apply is currently supported for Claude Code only. Use host "claude" or "claude-code".');if(!l?.trim())throw new Error("MCP_SCRAPER_API_KEY is required for --apply. Set it in the environment or pass --api-key.");let w={apiKey:l,packageSpec:r.package,browserProfileName:r.browserProfile,browserProfileSaveChanges:r.saveBrowserProfileChanges},y=await A("claude",B()),m=y.code===0?q(y.stdout):null,f=await A("claude",H()),g=await A("claude",G(w));if(g.code!==0){let te=z([g.stderr,g.stdout].filter(Boolean).join(`
|
|
25
|
+
`).trim()),_;throw f.code!==0?_="No existing entry was removed, so your configuration is unchanged.":m?_=(await A("claude",O(m))).code===0?"Your previous mcp-scraper entry was restored; nothing was lost.":`WARNING: the previous mcp-scraper entry was removed and could NOT be restored. Re-add it with:
|
|
26
|
+
claude `+O(m).join(" "):_="WARNING: the previous mcp-scraper entry was removed and could not be captured for rollback. Re-add it manually.",new Error(["Claude Code MCP registration failed.",te||"No error output returned.",_,"Make sure Claude Code is installed and the `claude` command is on PATH."].join(`
|
|
27
|
+
`))}let I=await A("claude",["mcp","list"]),$={host:"claude",applied:!0,replacedExisting:f.code===0,command:"npx",args:P(w),nextStep:"Fully exit Claude Code, start a new Claude terminal, then run: claude mcp list",list:z([I.stdout,I.stderr].filter(Boolean).join(`
|
|
28
|
+
`).trim())};if(r.json){c($,!0);return}c(["Applied Claude Code MCP config: mcp-scraper",f.code===0?"Replaced existing mcp-scraper entry.":"No existing mcp-scraper entry found; added a new one.","Command: npx "+P(w).join(" "),r.browserProfile?`Browser profile: ${r.browserProfile}`:"","","Next step: fully exit Claude Code, start a new Claude terminal, then run:"," claude mcp list","",$.list?`Current Claude MCP list:
|
|
29
|
+
${$.list}`:""].filter(Boolean).join(`
|
|
30
|
+
`),!1);return}let k=J(n,{apiKey:r.apiKey,packageSpec:r.package,browserProfileName:r.browserProfile,browserProfileSaveChanges:r.saveBrowserProfileChanges});c(r.json?{host:n,protocolVersion:v,protocolDigest:b,text:k}:k,r.json)}),i.command("prompt [name]").description("Print an agent prompt template.").option("--json","Print machine-readable JSON").action((o,r)=>{if(!o){c(r.json?{prompts:R()}:R().join(`
|
|
31
|
+
`),r.json);return}let n=V(o);c(r.json?{name:o,...o==="xray-setup"?{protocolVersion:v,protocolDigest:b}:{},text:n}:n,r.json)});let p=e.command("workflow").description("Run named SEO workflows.");p.command("list").description("List available workflows.").option("--json","Print machine-readable JSON").action(o=>{let r=D();o.json?c({workflows:r},!0):c(r.map(n=>`${n.id} ${n.title}
|
|
32
|
+
${n.description}`).join(`
|
|
33
|
+
`),!1)}),p.command("run <id>").description("Run a workflow and save local artifacts.").option("--api-key <key>","MCP Scraper API key").option("--api-url <url>","MCP Scraper API URL","https://mcpscraper.dev").option("--output-dir <path>","Workflow output directory").option("--json","Print machine-readable JSON").option("--keyword <keyword>","Agent packet keyword").option("--domain <domain>","Target domain").option("--url <url>","Target page URL").option("--location <location>","Target location").option("--max-results <n>","Maximum SERP or Maps results").option("--max-questions <n>","Maximum PAA questions").option("--extract-top <n>","Top result pages or citation pages to extract").option("--depth <n>","PAA expansion depth").option("--no-serp","Skip SERP evidence for agent packet").option("--no-paa","Skip PAA evidence for agent packet").option("--query <query>","Business category or workflow query").option("--state <state>","US state").option("--min-pop <n>","Minimum city population").option("--max-cities <n>","Maximum selected cities").option("--per-city <n>","Maps results per city").option("--concurrency <n>","City search concurrency").option("--proxy-mode <mode>","Proxy mode: location, configured, or none").option("--hydrate-top <n>","Profiles to hydrate per city for competitive audits").option("--reviews <n>","Review cards to collect per hydrated profile").option("--no-return-partial","Fail instead of writing partial artifacts").action(async(o,r)=>{let n=await L(o,Ce(o,r),{apiKey:r.apiKey,apiUrl:r.apiUrl,outputDir:r.outputDir});r.json?c(n,!0):c([`${n.title}: ${n.status}`,n.summary,n.reportPath?`Report: ${n.reportPath}`:"",n.warnings.length?`Warnings:
|
|
34
|
+
${n.warnings.map(l=>`- ${l}`).join(`
|
|
35
35
|
`)}`:""].filter(Boolean).join(`
|
|
36
|
-
`),!1)});let u=e.command("report").description("List and open local workflow reports.");u.command("list").description("List recent workflow reports.").option("--output-dir <path>","Workflow output directory").option("--json","Print machine-readable JSON").action(async
|
|
37
|
-
`),
|
|
38
|
-
`),!1)}),a.command("
|
|
39
|
-
`)
|
|
40
|
-
`),t.json)}),e}async function ne(e=process.argv){await Se().parseAsync(e)}ne().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});
|
|
36
|
+
`),!1)});let u=e.command("report").description("List and open local workflow reports.");u.command("list").description("List recent workflow reports.").option("--output-dir <path>","Workflow output directory").option("--json","Print machine-readable JSON").action(async o=>{let r=await E(o.outputDir);c(o.json?{reports:r}:r.map(n=>`${n.startedAt} ${n.workflow} ${n.status} ${n.reportPath??n.manifestPath}`).join(`
|
|
37
|
+
`),o.json)}),u.command("path [id]").description("Print a report path. Defaults to last.").option("--output-dir <path>","Workflow output directory").option("--json","Print machine-readable JSON").action(async(o="last",r)=>{let n=await j(o,r.outputDir);if(!n?.reportPath)throw new Error(`No report found for "${o}"`);c(r.json?{path:n.reportPath,run:n}:n.reportPath,r.json)}),u.command("open [id]").description("Open a report. Defaults to last.").option("--output-dir <path>","Workflow output directory").option("--json","Print machine-readable JSON instead of opening").action(async(o="last",r)=>{if(r.json){let l=await j(o,r.outputDir);if(!l?.reportPath)throw new Error(`No report found for "${o}"`);c({path:l.reportPath,run:l},!0);return}let n=await N(o,r.outputDir);c(`Opened: ${n}`,!1)});let a=e.command("runs").description("Inspect and download hosted workflow runs.");return a.command("list").description("List hosted workflow runs.").option("--api-key <key>","MCP Scraper API key").option("--api-url <url>","MCP Scraper API URL","https://mcpscraper.dev").option("--json","Print machine-readable JSON").action(async o=>{let r=await C("/workflows/runs","GET",o);o.json?c(r,!0):c(r.runs.map(n=>`${n.id} ${n.status} ${n.workflow_id} ${n.queued_at}`).join(`
|
|
38
|
+
`),!1)}),a.command("status <id>").description("Show a hosted workflow run.").option("--api-key <key>","MCP Scraper API key").option("--api-url <url>","MCP Scraper API URL","https://mcpscraper.dev").option("--json","Print machine-readable JSON").action(async(o,r)=>c(await C(`/workflows/runs/${o}`,"GET",r),r.json)),a.command("download <id>").description("Download hosted workflow run artifacts.").option("--api-key <key>","MCP Scraper API key").option("--api-url <url>","MCP Scraper API URL","https://mcpscraper.dev").option("--output-dir <path>","Download directory").option("--json","Print machine-readable JSON").action(async(o,r)=>{let n=await C(`/workflows/runs/${o}`,"GET",r),{apiUrl:l,apiKey:k}=ee(r),w=X(r.outputDir??S(),"workflow-downloads",o);await ye(w,{recursive:!0});let y=[];for(let m of n.run.artifacts??[]){let f=await fetch(`${l}/workflows/runs/${o}/artifacts/${m.id}`,{headers:{"x-api-key":k}});if(!f.ok)throw new Error(`Failed to download ${m.label}: HTTP ${f.status}`);let g=X(w,ke(m.path));await he(g,Buffer.from(await f.arrayBuffer())),y.push(g)}c(r.json?{runId:o,files:y}:y.join(`
|
|
39
|
+
`),r.json)}),e}async function re(e=process.argv){await ve().parseAsync(e)}re().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as e}from"../chunk-
|
|
2
|
+
import{a as e}from"../chunk-OOB3RKWD.js";import"../chunk-4P3LZNVA.js";import"../chunk-QER2ELZP.js";import"../chunk-WHVK6FUB.js";import"../chunk-7POHNTVW.js";import"../chunk-MVMWPKRC.js";import"../chunk-63VWBMYR.js";import"../chunk-3F7AFM53.js";import"../chunk-RDHGQ2WZ.js";import"../chunk-B5Y26E3A.js";import"../chunk-U3NV72AL.js";import"../chunk-CNSVZTTT.js";import"../chunk-K3VDGJNK.js";import"../chunk-7SR7MEU5.js";import"../chunk-ANQ4JJVI.js";import"../chunk-SEZETSB3.js";import"../chunk-SDQW7IJN.js";import"../chunk-B4ZKPLSP.js";import"../chunk-VVSHZV5S.js";import"../chunk-C7MGJUTU.js";import"../chunk-PKQHHCO4.js";import"../chunk-4ZVO6GX4.js";import"../chunk-WNUXMPVX.js";import"../chunk-ND4WIBXT.js";import"../chunk-EYGA6LOU.js";import"../chunk-24YDQ3EO.js";import"../chunk-OLYPLX5C.js";import"../chunk-B3JRL45T.js";import"../chunk-OILOHQNL.js";import"../chunk-6FAMBNHY.js";import"../chunk-HNNYXMSI.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-
|
|
2
|
+
import{a as s}from"../chunk-ND4WIBXT.js";import"../chunk-EYGA6LOU.js";import{a as e}from"../chunk-6FAMBNHY.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-
|
|
2
|
+
import{a as r}from"../chunk-OOB3RKWD.js";import"../chunk-4P3LZNVA.js";import"../chunk-QER2ELZP.js";import"../chunk-WHVK6FUB.js";import"../chunk-7POHNTVW.js";import"../chunk-MVMWPKRC.js";import"../chunk-63VWBMYR.js";import"../chunk-3F7AFM53.js";import"../chunk-RDHGQ2WZ.js";import"../chunk-B5Y26E3A.js";import"../chunk-U3NV72AL.js";import"../chunk-CNSVZTTT.js";import"../chunk-K3VDGJNK.js";import"../chunk-7SR7MEU5.js";import"../chunk-ANQ4JJVI.js";import"../chunk-SEZETSB3.js";import"../chunk-SDQW7IJN.js";import"../chunk-B4ZKPLSP.js";import"../chunk-VVSHZV5S.js";import"../chunk-C7MGJUTU.js";import"../chunk-PKQHHCO4.js";import"../chunk-4ZVO6GX4.js";import"../chunk-WNUXMPVX.js";import"../chunk-ND4WIBXT.js";import"../chunk-EYGA6LOU.js";import"../chunk-24YDQ3EO.js";import"../chunk-OLYPLX5C.js";import"../chunk-B3JRL45T.js";import"../chunk-OILOHQNL.js";import"../chunk-6FAMBNHY.js";import"../chunk-HNNYXMSI.js";r();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as b,k as c}from"./chunk-
|
|
1
|
+
import{j as b,k as c}from"./chunk-NULRGHJ4.js";import"./chunk-U4WIJZCX.js";import{F as a}from"./chunk-JNPM3U3L.js";import"./chunk-KXJCGV3H.js";import"./chunk-JMZIDHYQ.js";import"./chunk-M5QHXNFZ.js";import"./chunk-CNSVZTTT.js";import"./chunk-K3VDGJNK.js";import"./chunk-7SR7MEU5.js";import"./chunk-ANQ4JJVI.js";import"./chunk-SEZETSB3.js";import"./chunk-SDQW7IJN.js";import"./chunk-C7MGJUTU.js";import"./chunk-PKQHHCO4.js";import"./chunk-4ZVO6GX4.js";import"./chunk-WNUXMPVX.js";import"./chunk-OLYPLX5C.js";import"./chunk-B3JRL45T.js";import"./chunk-OILOHQNL.js";import"./chunk-HNNYXMSI.js";export{b as MAX_ANALYZED_LINK_EDGES,a as SITE_EXTRACT_PAGE_CHUNK,c as assembleExtractArtifacts};
|