scrapeloop-mcp 0.12.0 → 0.14.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scrapeloop-mcp",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "description": "Scrapeloop MCP server - set up and run Scrapeloop end-to-end (integrations, scraping, lead database, verification, cleaners, enrichment, strategies, Instantly campaigns) from any MCP client (Claude Desktop, Cursor, ChatGPT, …).",
5
5
  "type": "module",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -361,6 +361,7 @@ const PLAN_FIELDS = {
361
361
  granularity: { ...S, enum: ['country', 'state', 'city', 'postal_code'] },
362
362
  locations: ARR(S), location_items: ARR(O), categories: ARR(S),
363
363
  min_population: { type: 'integer', minimum: 0 }, scrape_config: O,
364
+ coverage_mode: { ...S, enum: ['standard', 'complete'] },
364
365
  run_mode: { ...S, enum: ['all_now', 'over_time'] }, spread_evenly: B,
365
366
  monthly_max_leads: { type: 'integer', minimum: 1 },
366
367
  monthly_lead_ceiling: { type: 'integer', minimum: 1 },
@@ -543,15 +544,15 @@ const TOOLS = {
543
544
  },
544
545
  preview_scrape_plan: {
545
546
  def: {
546
- description: 'Preview all-now or over-time scraping with the same limits as the app. No scrape or credential is created. Read the Playbook and scraper capabilities first. Set a lead or credit cap for credit-priced work, or a dollar cap for dollar-priced work. all_now limits apply once; over_time limits reset each month. Show costs and coverage warnings before creating.',
547
+ description: 'Preview all-now or over-time scraping with the same limits as the app. Native coverage_mode complete previews up to 100000 frozen searches as a draft with no raw-row caps; output and cost remain unknown until measured. No scrape or credential is created. Read the Playbook and scraper capabilities first. Set a lead or credit cap for credit-priced work, or a dollar cap for dollar-priced work. all_now limits apply once; over_time limits reset each month. Show costs and coverage warnings before creating.',
547
548
  inputSchema: obj(PLAN_FIELDS, PLAN_REQUIRED),
548
549
  },
549
550
  run: (a) => api('POST', '/plans/preview', a),
550
551
  },
551
552
  create_scrape_plan: {
552
553
  def: {
553
- description: 'Save a scrape plan into an existing writable Table. Set start_mode to draft to save without starting searches or spending. The default active mode starts approved work and can spend credits or vendor money. Preview the exact choices first and stay within the approved limit and time period. Pass explicit territory values and matching billing limits. Reuse the same idempotency_key after a lost reply, inspect list_scrape_plans and never create a second plan to escape an uncertain result. Over-time limits reset monthly; a total one-time approval does not authorize recurring spend.',
554
- inputSchema: obj({ ...PLAN_FIELDS, target_list_id: { ...S, format: 'uuid' }, start_mode: { ...S, enum: ['active', 'draft'] } }, [...PLAN_REQUIRED, 'target_list_id']),
554
+ description: 'Save a scrape plan into an existing writable Table. Native coverage_mode complete requires start_mode draft, a stable scope_operation_id and no monthly raw-row caps or repeats. It saves the whole scope in restartable batches and cannot Start until complete-search pacing and shared budgets are ready. Set start_mode to draft to save without starting searches or spending. The default active mode starts approved work and can spend credits or vendor money. Preview the exact choices first and stay within the approved limit and time period. Pass explicit territory values and matching billing limits. Reuse the same idempotency_key after a lost reply, inspect list_scrape_plans and never create a second plan to escape an uncertain result. Over-time limits reset monthly; a total one-time approval does not authorize recurring spend.',
555
+ inputSchema: obj({ ...PLAN_FIELDS, scope_operation_id: { ...S, format: 'uuid' }, target_list_id: { ...S, format: 'uuid' }, start_mode: { ...S, enum: ['active', 'draft'] } }, [...PLAN_REQUIRED, 'target_list_id']),
555
556
  },
556
557
  run: ({ idempotency_key: _key, ...body }) => api('POST', '/plans', body),
557
558
  },
@@ -581,6 +582,24 @@ const TOOLS = {
581
582
  }, ['plan_id', 'expected_updated_at', 'goal']) },
582
583
  run: ({ plan_id, ...body }) => api('PUT', `/plans/${enc(plan_id)}/ready`, body),
583
584
  },
585
+ get_scrape_plan_budget: {
586
+ def: { description: 'Read shared monthly and lifetime lead/verify credit limits, reserved work and remaining allowance. Open holds stay counted across month changes. This makes no provider calls.', inputSchema: obj({ plan_id: { ...S, format: 'uuid' } }, ['plan_id']) },
587
+ run: (a) => api('GET', `/plans/${enc(a.plan_id)}/budget`),
588
+ },
589
+ set_scrape_plan_budget: {
590
+ def: { description: 'Save reviewed credit limits and Table ownership for a paused complete-search plan with a ready-email goal. Include Raw, Email ready and every check Table. One Table belongs to one budget. Preserve expected_revision from the current budget; omit it only for the first save. A lost reply requires readback before retry. This starts no work and does not enable checks. BYOK paid vendors are not supported by these limits. Launch remains gated until complete-search pacing and reviewed Start are ready.', inputSchema: obj({
591
+ plan_id: { ...S, format: 'uuid' }, expected_revision: { ...S, format: 'uuid' },
592
+ limits: obj({
593
+ monthly_lead_credits: { type: 'integer', minimum: 0, maximum: 1000000000 },
594
+ lifetime_lead_credits: { type: 'integer', minimum: 0, maximum: 1000000000 },
595
+ monthly_verify_credits: { type: 'integer', minimum: 0, maximum: 1000000000 },
596
+ lifetime_verify_credits: { type: 'integer', minimum: 0, maximum: 1000000000 },
597
+ allowed_checks: { type: 'array', items: { ...S, enum: ['verify_email', 'verify_catchall', 'verify_phone'] }, maxItems: 3 },
598
+ }, ['monthly_lead_credits', 'lifetime_lead_credits', 'monthly_verify_credits', 'lifetime_verify_credits', 'allowed_checks']),
599
+ list_ids: { type: 'array', items: { ...S, format: 'uuid' }, minItems: 1, maxItems: 20 },
600
+ }, ['plan_id', 'limits', 'list_ids']) },
601
+ run: ({ plan_id, ...body }) => api('PUT', `/plans/${enc(plan_id)}/budget`, body),
602
+ },
584
603
  pause_scrape_plan: {
585
604
  def: { description: 'Pause new work from a scrape plan. A job already running may still finish. Inspect the plan and its jobs after pausing.', inputSchema: obj({ plan_id: { ...S, format: 'uuid' } }, ['plan_id']) },
586
605
  run: (a) => api('POST', `/plans/${enc(a.plan_id)}/pause`),
@@ -46,6 +46,7 @@ export const MUTATION_POLICIES = Object.freeze({
46
46
  pause_scrape_plan: never('POST', ['get_scrape_plan'], ['plan_id']),
47
47
  start_scrape_plan: never('POST', ['get_scrape_plan'], ['plan_id']),
48
48
  set_scrape_plan_ready_goal: reconcile('PUT', ['get_scrape_plan_ready_goal'], ['plan_id', 'goal']),
49
+ set_scrape_plan_budget: reconcile('PUT', ['get_scrape_plan_budget'], ['plan_id', 'limits', 'list_ids']),
49
50
  estimate_scrape: read(),
50
51
  submit_scrape: keyed('POST', ['list_jobs'], ['kind', 'integration_id', 'credential_id', 'table_id']),
51
52
  cancel_job: never('POST', ['get_job'], ['job_id', 'status']),