scrapeloop-mcp 0.11.2 → 0.13.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.11.2",
3
+ "version": "0.13.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
  },
@@ -563,6 +564,24 @@ const TOOLS = {
563
564
  def: { description: 'Read one scrape plan, its saved scope, limits, progress and spending.', inputSchema: obj({ plan_id: { ...S, format: 'uuid' } }, ['plan_id']) },
564
565
  run: (a) => api('GET', `/plans/${enc(a.plan_id)}`),
565
566
  },
567
+ get_scrape_plan_ready_goal: {
568
+ def: { description: 'Read a scrape plan verified-email goal and its dated ready count. Newly ready, unused stock, consumption and corrections are separate. Stale or incomplete checks never imply usable stock. This read does not run paid checks or start anything.', inputSchema: obj({ plan_id: { ...S, format: 'uuid' } }, ['plan_id']) },
569
+ run: (a) => api('GET', `/plans/${enc(a.plan_id)}/ready`),
570
+ },
571
+ set_scrape_plan_ready_goal: {
572
+ def: { description: 'Save a verified-email goal on a native Maps draft without repeat searches. Choose the ready Table and its email campaign, monthly goal/minimum, unused-stock ceiling and evidence rules. Pass the reviewed expected_updated_at from get_scrape_plan. Counts require current input-bound verification, qualification, campaign fields and sender-history checks. This does not start scraping, verification or campaigns. Complete-search pacing must be available before Start.', inputSchema: obj({
573
+ plan_id: { ...S, format: 'uuid' }, expected_updated_at: { ...S, format: 'date-time' },
574
+ goal: obj({ kind: { ...S, enum: ['verified_email'] }, ready_list_id: { ...S, format: 'uuid' },
575
+ campaign_id: { ...S, format: 'uuid' }, monthly_goal: { type: 'integer', minimum: 1, maximum: 1000000 },
576
+ monthly_minimum: { type: 'integer', minimum: 0, maximum: 1000000 },
577
+ stock_ceiling: { type: 'integer', minimum: 1, maximum: 1000000 }, timezone: S,
578
+ evidence_max_age_days: { type: 'integer', minimum: 1, maximum: 90 }, allow_resolved_catchall: B,
579
+ required_fields: ARR({ ...S, enum: ['name', 'organization_name', 'first_name', 'last_name', 'industry', 'city', 'state', 'postal_code', 'domain', 'language'] }),
580
+ languages: ARR({ ...S, pattern: '^[a-z]{2}$' }),
581
+ }, ['ready_list_id', 'campaign_id', 'monthly_goal', 'monthly_minimum', 'stock_ceiling', 'timezone']),
582
+ }, ['plan_id', 'expected_updated_at', 'goal']) },
583
+ run: ({ plan_id, ...body }) => api('PUT', `/plans/${enc(plan_id)}/ready`, body),
584
+ },
566
585
  pause_scrape_plan: {
567
586
  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']) },
568
587
  run: (a) => api('POST', `/plans/${enc(a.plan_id)}/pause`),
@@ -45,6 +45,7 @@ export const MUTATION_POLICIES = Object.freeze({
45
45
  create_scrape_plan: keyed('POST', ['list_scrape_plans'], ['name', 'target_list_id', 'kind']),
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
+ set_scrape_plan_ready_goal: reconcile('PUT', ['get_scrape_plan_ready_goal'], ['plan_id', 'goal']),
48
49
  estimate_scrape: read(),
49
50
  submit_scrape: keyed('POST', ['list_jobs'], ['kind', 'integration_id', 'credential_id', 'table_id']),
50
51
  cancel_job: never('POST', ['get_job'], ['job_id', 'status']),