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 +1 -1
- package/src/index.js +22 -3
- package/src/mutation-policies.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scrapeloop-mcp",
|
|
3
|
-
"version": "0.
|
|
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`),
|
package/src/mutation-policies.js
CHANGED
|
@@ -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']),
|