mcp-scraper 0.63.1 → 0.63.2

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 (35) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/README.md +1 -1
  3. package/dist/bin/api-server.cjs +49 -15
  4. package/dist/bin/api-server.cjs.map +1 -1
  5. package/dist/bin/api-server.js +2 -2
  6. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  7. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  8. package/dist/bin/mcp-scraper-cli.js +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs +1 -1
  10. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  11. package/dist/bin/mcp-scraper-install.js +1 -1
  12. package/dist/bin/mcp-stdio-server.cjs +2 -2
  13. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  14. package/dist/bin/mcp-stdio-server.js +3 -3
  15. package/dist/chunk-JDNM65MP.js +7 -0
  16. package/dist/chunk-JDNM65MP.js.map +1 -0
  17. package/dist/{chunk-DPE2TOCF.js → chunk-O4WUHQO7.js} +2 -2
  18. package/dist/{chunk-BWSGR75I.js → chunk-PIILOYUV.js} +4 -4
  19. package/dist/chunk-PIILOYUV.js.map +1 -0
  20. package/dist/{chunk-DKKTAT3B.js → chunk-ZTGYALNU.js} +11 -4
  21. package/dist/{chunk-DKKTAT3B.js.map → chunk-ZTGYALNU.js.map} +1 -1
  22. package/dist/{extract-bundle-QXIMQRTF.js → extract-bundle-6CTSKCTB.js} +3 -3
  23. package/dist/{server-KPB4NXGE.js → server-6HVQEEIF.js} +38 -19
  24. package/dist/server-6HVQEEIF.js.map +1 -0
  25. package/dist/{site-extract-repository-TJG6DVSG.js → site-extract-repository-OXKRUOZH.js} +3 -3
  26. package/dist/{worker-PUQTKS6O.js → worker-ZBTU45L2.js} +2 -2
  27. package/package.json +1 -1
  28. package/dist/chunk-2HKLEEQV.js +0 -7
  29. package/dist/chunk-2HKLEEQV.js.map +0 -1
  30. package/dist/chunk-BWSGR75I.js.map +0 -1
  31. package/dist/server-KPB4NXGE.js.map +0 -1
  32. /package/dist/{chunk-DPE2TOCF.js.map → chunk-O4WUHQO7.js.map} +0 -0
  33. /package/dist/{extract-bundle-QXIMQRTF.js.map → extract-bundle-6CTSKCTB.js.map} +0 -0
  34. /package/dist/{site-extract-repository-TJG6DVSG.js.map → site-extract-repository-OXKRUOZH.js.map} +0 -0
  35. /package/dist/{worker-PUQTKS6O.js.map → worker-ZBTU45L2.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@ All notable changes to MCP Scraper are documented here. The format is based on [
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.63.2] - 2026-08-24
8
+
9
+ ### Fixed
10
+
11
+ - Kept base-plan, bundled and standalone Memory, and concurrency-pack entitlements active while Stripe retries a `past_due` renewal, while terminal subscription states still remove access.
12
+ - Reused an existing active, trialing, or past-due base subscription during plan changes instead of risking a duplicate subscription when the local subscription reference is missing.
13
+ - Replaced unavailable credit-top-up guidance with the supported larger-plan path and a terminal upgrade command that lists only publicly purchasable tiers.
14
+
7
15
  ## [0.63.1] - 2026-08-23
8
16
 
9
17
  ### Fixed
@@ -1005,7 +1013,10 @@ All notable changes to MCP Scraper are documented here. The format is based on [
1005
1013
  - Write actions remain unavailable until the account owner explicitly enables them.
1006
1014
  - Provider-specific connection data is normalized into one agent-facing contract.
1007
1015
 
1008
- [Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.55.0...HEAD
1016
+ [Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.63.2...HEAD
1017
+ [0.63.2]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.63.1...v0.63.2
1018
+ [0.63.1]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.63.0...v0.63.1
1019
+ [0.63.0]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.60.0...v0.63.0
1009
1020
  [0.55.0]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.54.4...v0.55.0
1010
1021
  [0.54.4]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.54.3...v0.54.4
1011
1022
  [0.54.3]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.54.2...v0.54.3
package/README.md CHANGED
@@ -90,7 +90,7 @@ Build the branded one-click bundle:
90
90
  npm run build:mcpb
91
91
  ```
92
92
 
93
- 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.63.1`, SHA-256 `10646568735791bcf6235db18fcec2aac9b2e53d0c926140af51ba299e4d3ddd`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
93
+ 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.63.2`, SHA-256 `31a2725eb363da4d38e12559eedf83160916550294795203031dc003a78afb7c`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
94
94
 
95
95
  The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
96
96
 
@@ -12964,24 +12964,30 @@ function concurrencyPackBillingInfo() {
12964
12964
  function mcToCredits(mc) {
12965
12965
  return mc / MC_PER_CREDIT;
12966
12966
  }
12967
+ function purchasablePlanTiers() {
12968
+ return Object.values(SUBSCRIPTION_TIERS).filter((tier) => !tier.private_offer).sort((a, b) => a.credits_mc - b.credits_mc);
12969
+ }
12967
12970
  function insufficientBalanceResponse(balanceMc, requiredMc) {
12968
- const topupUrl = process.env.TOPUP_URL ?? "https://mcpscraper.dev/billing";
12971
+ const billingUrl = process.env.TOPUP_URL ?? "https://mcpscraper.dev/billing";
12969
12972
  const balanceCredits = mcToCredits(balanceMc);
12970
12973
  const requiredCredits = mcToCredits(requiredMc);
12974
+ const planKeys = purchasablePlanTiers().map((tier) => tier.tier).join("|");
12975
+ const upgradeCommand = `${SUBSCRIPTION_TERMINAL_COMMAND} <${planKeys}>`;
12971
12976
  return {
12972
12977
  error: "insufficient_balance",
12973
12978
  error_code: "insufficient_balance",
12974
- message: `Insufficient credits. Balance: ${balanceCredits} credits. This call requires ${requiredCredits} credits. Top up at ${topupUrl}`,
12979
+ message: `Insufficient credits. Balance: ${balanceCredits} credits. This call requires ${requiredCredits} credits. Credits refresh when your plan renews; for more now, move to a larger plan at ${billingUrl} (terminal: ${upgradeCommand})`,
12975
12980
  balance_credits: balanceCredits,
12976
12981
  required_credits: requiredCredits,
12977
- topup_url: topupUrl
12982
+ topup_url: billingUrl,
12983
+ upgrade_command: upgradeCommand
12978
12984
  };
12979
12985
  }
12980
12986
  function mediaTranscribeChargeMc(durationSecs) {
12981
12987
  const mins = Math.max(1, Math.ceil((durationSecs || 60) / 60));
12982
12988
  return MEDIA_TRANSCRIBE_FLAT_MC + MEDIA_TRANSCRIBE_PER_MIN_MC * mins;
12983
12989
  }
12984
- var MC_COSTS, MC_PER_BROWSER_MS, BROWSER_OPEN_MIN_BALANCE_MC, MC_PER_CREDIT, SERP_SEARCH_CREDITS, PAA_BASE_CREDITS, PAA_QUESTION_CREDITS, PAGE_SCRAPE_CREDITS, LISTING_WRITE_RATE_POLICY, BILLING_MC_PER_USD_NUMERATOR, BILLING_MC_PER_USD_DENOMINATOR, BILLING_BASIS_POINTS, USD_NANOS, SCHEDULED_RUN_BASE_CREDITS, SCHEDULED_RUN_BASE_MC, SCHEDULED_AGENT_LLM_MARKUP_BPS, SCHEDULED_AGENT_LLM_MARKUP, SCHEDULED_RUN_DEFAULT_MAX_CREDITS, CONNECTED_USAGE_RATE_POLICY_VERSION, CONNECTED_ACTIVE_CONNECTION_MONTHLY_CREDITS, CONNECTED_ACTIVE_CONNECTION_MONTHLY_MC, CONNECTED_FUNCTION_RUN_CREDITS, CONNECTED_PROXY_REQUEST_CREDITS, CONNECTED_COMPUTE_CREDITS_PER_SECOND, CONNECTED_FUNCTION_RUN_MC, CONNECTED_PROXY_REQUEST_MC, CONNECTED_COMPUTE_MC_PER_SECOND, CONNECTED_USAGE_RATE_POLICY, CREDIT_COST_CATALOG, CONCURRENCY_PRICE_ID, SUBSCRIPTION_TIERS, SUBSCRIPTION_TIER_BY_KEY, PRIVATE_OFFERS, CONCURRENCY_PACK_PRICE_USD, CONCURRENCY_PACK_PRICE_CURRENCY, CONCURRENCY_PACK_PRICE_INTERVAL, CONCURRENCY_SLOTS_PER_PACK, CONCURRENCY_PACK_RATE_POLICY_VERSION, CONCURRENCY_PACK_PRICE_LABEL, CONCURRENCY_PACK_INVOICE_DESCRIPTION, CONCURRENCY_PACK_INVOICE_FOOTER, CONCURRENCY_PACK_TERMINAL_COMMAND, MEMORY_FREE_QUOTA_BYTES, MEMORY_PLANS, MEMORY_PLAN_QUOTA, MEMORY_MARGIN_MULTIPLE, MEMORY_PRO_COST_BUDGET_USD, LedgerOperation, MEMORY_AI_MARGIN_MULTIPLE, SITE_AUDIT_LLM_MARGIN_MULTIPLE, VIDEO_ANALYSIS_LLM_MARGIN_MULTIPLE, MEDIA_TRANSCRIBE_FLAT_MC, MEDIA_TRANSCRIBE_PER_MIN_MC, MEDIA_TRANSCRIBE_HOLD_MC, MC_PER_USD;
12990
+ var MC_COSTS, MC_PER_BROWSER_MS, BROWSER_OPEN_MIN_BALANCE_MC, MC_PER_CREDIT, SERP_SEARCH_CREDITS, PAA_BASE_CREDITS, PAA_QUESTION_CREDITS, PAGE_SCRAPE_CREDITS, LISTING_WRITE_RATE_POLICY, BILLING_MC_PER_USD_NUMERATOR, BILLING_MC_PER_USD_DENOMINATOR, BILLING_BASIS_POINTS, USD_NANOS, SCHEDULED_RUN_BASE_CREDITS, SCHEDULED_RUN_BASE_MC, SCHEDULED_AGENT_LLM_MARKUP_BPS, SCHEDULED_AGENT_LLM_MARKUP, SCHEDULED_RUN_DEFAULT_MAX_CREDITS, CONNECTED_USAGE_RATE_POLICY_VERSION, CONNECTED_ACTIVE_CONNECTION_MONTHLY_CREDITS, CONNECTED_ACTIVE_CONNECTION_MONTHLY_MC, CONNECTED_FUNCTION_RUN_CREDITS, CONNECTED_PROXY_REQUEST_CREDITS, CONNECTED_COMPUTE_CREDITS_PER_SECOND, CONNECTED_FUNCTION_RUN_MC, CONNECTED_PROXY_REQUEST_MC, CONNECTED_COMPUTE_MC_PER_SECOND, CONNECTED_USAGE_RATE_POLICY, CREDIT_COST_CATALOG, CONCURRENCY_PRICE_ID, SUBSCRIPTION_TIERS, SUBSCRIPTION_TIER_BY_KEY, PRIVATE_OFFERS, CONCURRENCY_PACK_PRICE_USD, CONCURRENCY_PACK_PRICE_CURRENCY, CONCURRENCY_PACK_PRICE_INTERVAL, CONCURRENCY_SLOTS_PER_PACK, CONCURRENCY_PACK_RATE_POLICY_VERSION, CONCURRENCY_PACK_PRICE_LABEL, CONCURRENCY_PACK_INVOICE_DESCRIPTION, CONCURRENCY_PACK_INVOICE_FOOTER, CONCURRENCY_PACK_TERMINAL_COMMAND, SUBSCRIPTION_TERMINAL_COMMAND, MEMORY_FREE_QUOTA_BYTES, MEMORY_PLANS, MEMORY_PLAN_QUOTA, MEMORY_MARGIN_MULTIPLE, MEMORY_PRO_COST_BUDGET_USD, LedgerOperation, MEMORY_AI_MARGIN_MULTIPLE, SITE_AUDIT_LLM_MARGIN_MULTIPLE, VIDEO_ANALYSIS_LLM_MARGIN_MULTIPLE, MEDIA_TRANSCRIBE_FLAT_MC, MEDIA_TRANSCRIBE_PER_MIN_MC, MEDIA_TRANSCRIBE_HOLD_MC, MC_PER_USD;
12985
12991
  var init_rates = __esm({
12986
12992
  "src/api/rates.ts"() {
12987
12993
  "use strict";
@@ -13359,6 +13365,7 @@ var init_rates = __esm({
13359
13365
  CONCURRENCY_PACK_INVOICE_DESCRIPTION = "MCP Scraper browser concurrency pack \u2014 each $5 monthly pack adds 2 browsers.";
13360
13366
  CONCURRENCY_PACK_INVOICE_FOOTER = "Billed monthly until canceled. A receipt is emailed after each successful payment.";
13361
13367
  CONCURRENCY_PACK_TERMINAL_COMMAND = "npx -y -p mcp-scraper@latest mcp-scraper-cli billing concurrency checkout";
13368
+ SUBSCRIPTION_TERMINAL_COMMAND = "npx -y -p mcp-scraper@latest mcp-scraper-cli billing subscribe";
13362
13369
  MEMORY_FREE_QUOTA_BYTES = 1e7 * 1;
13363
13370
  MEMORY_PLANS = {
13364
13371
  "price_1TnMSTS8aAcsk3TGBgiwuvqL": { plan: "pro", label: "Pro", price_id: "price_1TnMSTS8aAcsk3TGBgiwuvqL", interval: "month", monthly_usd: 19, quota_bytes: 5e9 },
@@ -18200,7 +18207,7 @@ function publicErrorText(envelope) {
18200
18207
  if (envelope.retry_after_seconds) lines.push(`Retry after: ${envelope.retry_after_seconds} seconds.`);
18201
18208
  if (envelope.charge_status) lines.push(`Charge status: ${envelope.charge_status.replaceAll("_", " ")}.`);
18202
18209
  if (typeof details.upgrade_url === "string") lines.push(`Add capacity: ${details.upgrade_url}`);
18203
- if (typeof details.topup_url === "string") lines.push(`Top up: ${details.topup_url}`);
18210
+ if (typeof details.topup_url === "string") lines.push(`Plans: ${details.topup_url}`);
18204
18211
  if (typeof details.upgrade_command === "string") lines.push(`Terminal: ${details.upgrade_command}`);
18205
18212
  if (envelope.retryable) lines.push("Retryable: yes.");
18206
18213
  return lines.join(" ");
@@ -34262,6 +34269,25 @@ var init_inbox_routes = __esm({
34262
34269
  }
34263
34270
  });
34264
34271
 
34272
+ // src/api/subscription-status-policy.ts
34273
+ function isEntitledSubscriptionStatus(status) {
34274
+ return ENTITLED_SUBSCRIPTION_STATUSES.includes(status);
34275
+ }
34276
+ function findPreferredEntitledSubscription(subscriptions, predicate) {
34277
+ for (const status of ENTITLED_SUBSCRIPTION_STATUSES) {
34278
+ const match = subscriptions.find((subscription) => subscription.status === status && predicate(subscription));
34279
+ if (match) return match;
34280
+ }
34281
+ return void 0;
34282
+ }
34283
+ var ENTITLED_SUBSCRIPTION_STATUSES;
34284
+ var init_subscription_status_policy = __esm({
34285
+ "src/api/subscription-status-policy.ts"() {
34286
+ "use strict";
34287
+ ENTITLED_SUBSCRIPTION_STATUSES = ["active", "trialing", "past_due"];
34288
+ }
34289
+ });
34290
+
34265
34291
  // src/api/connected-account-billing.ts
34266
34292
  function connectedBillingPeriodStart(now = /* @__PURE__ */ new Date()) {
34267
34293
  return `${now.getUTCFullYear()}-${String(now.getUTCMonth() + 1).padStart(2, "0")}`;
@@ -34338,6 +34364,12 @@ function connectedAccountBillingView(actualQuantity, state) {
34338
34364
  function findBasePlanItem(subscription) {
34339
34365
  return subscription.items.data.find((item) => !!item.price?.id && item.price.id in SUBSCRIPTION_TIERS);
34340
34366
  }
34367
+ function findAdoptableBasePlanSubscription(subscriptions) {
34368
+ return findPreferredEntitledSubscription(
34369
+ subscriptions,
34370
+ (subscription) => !!findBasePlanItem(subscription)
34371
+ );
34372
+ }
34341
34373
  function safeErrorCode(error) {
34342
34374
  if (error instanceof ConnectedAccountBillingError) return error.code;
34343
34375
  return "stripe_connection_billing_failed";
@@ -34455,6 +34487,7 @@ var DEFAULT_CONNECTED_ACCOUNT_PRICE_ID, BILLABLE_LIFECYCLE, ConnectedAccountBill
34455
34487
  var init_connected_account_billing = __esm({
34456
34488
  "src/api/connected-account-billing.ts"() {
34457
34489
  "use strict";
34490
+ init_subscription_status_policy();
34458
34491
  init_db();
34459
34492
  init_rates();
34460
34493
  init_connected_cost_telemetry();
@@ -45467,7 +45500,7 @@ var PACKAGE_VERSION;
45467
45500
  var init_version = __esm({
45468
45501
  "src/version.ts"() {
45469
45502
  "use strict";
45470
- PACKAGE_VERSION = "0.63.1";
45503
+ PACKAGE_VERSION = "0.63.2";
45471
45504
  }
45472
45505
  });
45473
45506
 
@@ -61267,7 +61300,7 @@ async function processStripeEvent(event2) {
61267
61300
  if (concurrencyItem) {
61268
61301
  const user2 = await getUserByStripeCustomerId(sub.customer);
61269
61302
  if (!user2) return;
61270
- const live = sub.status === "active" || sub.status === "trialing";
61303
+ const live = isEntitledSubscriptionStatus(sub.status);
61271
61304
  await setConcurrencyPackQuantity(user2.id, live ? subscriptionItemQuantity(concurrencyItem) : 0);
61272
61305
  await setConcurrencySubId(user2.id, live ? sub.id : null);
61273
61306
  return;
@@ -61277,7 +61310,7 @@ async function processStripeEvent(event2) {
61277
61310
  const mem = MEMORY_PLANS[priceId];
61278
61311
  const user2 = await resolveUser3(sub.customer, sub.customer_email);
61279
61312
  if (user2) {
61280
- const live = sub.status === "active" || sub.status === "trialing";
61313
+ const live = isEntitledSubscriptionStatus(sub.status);
61281
61314
  const newMemoryPlan = live ? mem.plan : "free";
61282
61315
  await setMemoryPlan(user2.id, newMemoryPlan, live ? sub.id : null);
61283
61316
  await syncMemoryKeyPlan(user2, resolveEffectiveMemoryPlan({ ...user2, memory_plan: newMemoryPlan }));
@@ -61288,7 +61321,7 @@ async function processStripeEvent(event2) {
61288
61321
  if (!user) return;
61289
61322
  if (priceId && priceId in SUBSCRIPTION_TIERS) {
61290
61323
  const tier = SUBSCRIPTION_TIERS[priceId];
61291
- const live = sub.status === "active" || sub.status === "trialing";
61324
+ const live = isEntitledSubscriptionStatus(sub.status);
61292
61325
  const newTier = live ? tier.tier : null;
61293
61326
  await setSubscriptionTier(user.id, newTier, live ? tier.concurrency : 0, live ? sub.id : null);
61294
61327
  if (tier.includes_memory) {
@@ -61391,6 +61424,7 @@ var init_stripe_routes = __esm({
61391
61424
  init_rates();
61392
61425
  init_memory();
61393
61426
  init_connected_account_billing();
61427
+ init_subscription_status_policy();
61394
61428
  init_stripe_credit_policy();
61395
61429
  stripe = new import_stripe.default(process.env.STRIPE_SECRET_KEY, { apiVersion: "2026-02-25.clover" });
61396
61430
  stripeApp = new import_hono23.Hono();
@@ -80410,6 +80444,10 @@ function desiredConcurrencyPackQuantity(value) {
80410
80444
  function stripeSubscriptionCustomerId(subscription) {
80411
80445
  return typeof subscription.customer === "string" ? subscription.customer : subscription.customer.id;
80412
80446
  }
80447
+ async function findExistingBasePlanSubscriptionId(stripeClient, customerId) {
80448
+ const subs = await stripeClient.subscriptions.list({ customer: customerId, status: "all", limit: 100 });
80449
+ return findAdoptableBasePlanSubscription(subs.data)?.id;
80450
+ }
80413
80451
  function concurrencyAccountView(user, quantityOverride) {
80414
80452
  const packQuantity = quantityOverride ?? concurrencyPackQuantityForUser(user);
80415
80453
  const extraSlots = packQuantity * CONCURRENCY_SLOTS_PER_PACK;
@@ -83465,9 +83503,7 @@ var init_server = __esm({
83465
83503
  let existingSubId = user.subscription_id;
83466
83504
  if (!existingSubId) {
83467
83505
  try {
83468
- const active = await stripeClient.subscriptions.list({ customer: customerId, status: "active", limit: 20 });
83469
- const baseSub = active.data.find((s) => findBasePlanItem(s));
83470
- if (baseSub) existingSubId = baseSub.id;
83506
+ existingSubId = await findExistingBasePlanSubscriptionId(stripeClient, customerId) ?? null;
83471
83507
  } catch (err) {
83472
83508
  console.warn("[billing/subscribe] could not check for existing subscription", err instanceof Error ? err.message : err);
83473
83509
  }
@@ -83622,9 +83658,7 @@ var init_server = __esm({
83622
83658
  let existingSubId = user.subscription_id;
83623
83659
  if (!existingSubId) {
83624
83660
  try {
83625
- const active = await stripeClient.subscriptions.list({ customer: customerId, status: "active", limit: 20 });
83626
- const baseSub = active.data.find((s) => findBasePlanItem(s));
83627
- if (baseSub) existingSubId = baseSub.id;
83661
+ existingSubId = await findExistingBasePlanSubscriptionId(stripeClient, customerId) ?? null;
83628
83662
  } catch (err) {
83629
83663
  console.warn("[billing/subscribe] could not check for existing subscription", err instanceof Error ? err.message : err);
83630
83664
  }