npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

scrapeloop-mcp

v0.39.5

Published

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, …).

Readme

scrapeloop-mcp

A Model Context Protocol server for Scrapeloop. Set up and run Scrapeloop end-to-end from Claude Desktop, Cursor, ChatGPT, or any MCP client - connect integrations, scrape or pull from the lead database, verify (incl. catch-all), clean, enrich, tag, and feed Instantly campaigns.

Pair it with the scrapeloop skill for a saved Playbook setup and task flow ("set up Scrapeloop").

Setup

  1. Generate an API key in Scrapeloop: Settings → API access → "MCP / full automation" (mints an sl_live_… key with the full driving scope set).
  2. Add it to your MCP client config.

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "scrapeloop": {
      "command": "npx",
      "args": ["-y", "scrapeloop-mcp"],
      "env": {
        "SCRAPELOOP_API_KEY": "sl_live_your_key_here"
      }
    }
  }
}

(For local/self-hosted, also set SCRAPELOOP_API_URL, e.g. http://localhost:8000.)

ChatGPT / other MCP clients

Add the same command + SCRAPELOOP_API_KEY as a custom connector. For ChatGPT, pair it with the generated instructions pack (skill dist/chatgpt-instructions.md).

Scopes

The key's scopes gate tenant data reads, writes, and spend. Catalog reads remain free, and credit gating lives in the API as 402s. The "MCP / full automation" preset requests the full set so the setup flow works end-to-end:

leads:read  leads:reveal  verify  lists  lists:write  integrations:read
integrations:write  scrape  enrich  cleaners  strategies  campaigns:write  instantly

A 403 with "API key missing scope(s): …" means the key was minted with a narrower set - regenerate it with the full preset.

Tools

Call get_capabilities first (the live manifest: scrapers + schemas, presets, cleaners, strategy tags, vendors, scopes, and the ordered 7 setup steps) and get_setup_status to see what's done. Then walk the steps. Tools cover:

| Area | Tools | |------|-------| | Discovery | get_capabilities, get_setup_status, get_credits, get_meta | | Integrations (BYOK) | list_integrations, create_integration, list_credentials, add_credential, test_credential, list_instantly_connections | | Scrape | list_scrapers, estimate_scrape, submit_scrape, list_jobs, get_job, cancel_job, attach_job_to_table | | Lead database | search_leads, estimate_leads, reveal_lead, save_leads, bulk_verify_leads | | Verify | verify_email, verify_catchall | | Clean | list_cleaners, preview_cleaners, apply_cleaners | | Enrich + strategies | list_presets, create_preset, estimate_enrich, run_enrich, test_recipe, get_ai_settings, update_ai_settings, list_strategies, create_strategy, assign_strategy | | Campaigns + Instantly | list_instantly_campaigns, list_instantly_lead_lists, import_instantly_campaigns, import_instantly_lead_list, list_segments, create_segment, preview_segment, list_campaigns, create_campaign, update_campaign, activate_campaign, pause_campaign, sync_campaign, campaign_stats, get_sender_config, update_sender_config | | B2B saved collections | get_lists, create_list, add_list_members | | Campaign-ready Tables | get_tables, create_table, get_table_columns, create_table_column, create_table_preset_column, set_table_cells, list_table_rows |

import_leads, preview_import, and import_leads_csv take leads that have no email. No placeholder email is needed. Each row needs at least one of: email, LinkedIn URL, external ID or an absolute source URL, so Scrapeloop can tell which lead it is. The default match order is normalized email, canonical LinkedIn, then external ID or source URL, all scoped to the API key's workspace. A later import with a real email fills in the lead that had none. A row that cannot be imported is skipped and comes back in invalid_reasons. Each entry has a reason written for the user: show it as it is written. Records from a public source list can only be previewed. An import is read that way when a record has source, source_state and niche together, when a CSV has those three columns, or when sourcing_contract is set. It is then refused as a whole. The answer says what was seen and what to change, and a preview of such a batch carries a warning that says the same. For your own leads leave source_state out and use state_region. Mutating imports generate one operation_id and reuse it across transient HTTP retries. The API returns the first committed result for the same key and payload, and rejects reuse with different inputs. If every response is lost, retry the original request with the exact key returned in the error.

Manual Table columns and cells are zero-cost, and cell writes are limited to active static Tables. Archived Tables must be unarchived before column or cell writes. Select types require 1-100 declared options. Every cell must include a typed value, with explicit null reserved for clearing. set_table_cells accepts at most 500 cells and 256 KiB of JSON, validates the complete batch, then persists it as one atomic upsert.

create_table_preset_column attaches a shipped system preset or an active workspace preset as a real enrichment column. It requires a stable operation_id, defaults auto_run to false, and accepts only overrides declared by the preset. When auto-run would backfill existing rows, the first call returns the exact row and cost estimate without writing. Repeat with confirm_auto_run and that exact confirmed_estimated_cost_usd only after user confirmation. The Table master switch and workspace budget caps still gate the queued work.

create_table, create_table_column, create_table_preset_column, and create_table_view are idempotent. The MCP generates one operation_id for the logical create and reuses it across transient HTTP retries. The API returns the first resource for the same key and normalized payload, including concurrent calls, and returns 409 if that key is reused with different inputs. If every response is lost, the terminal error includes the exact key and retry call. Retry with that same key, never a replacement UUID.

Credit-spending (reveal_lead, save_leads, submit_scrape, verify_*, run_enrich) and send-starting (activate_campaign) tools should be preceded by the matching estimate_* call and an explicit user confirmation. Out-of-credit (402), missing-scope (403), and confirmation-needed (409) responses are returned verbatim so the assistant can explain or self-correct.

Develop / smoke-test locally

SCRAPELOOP_API_URL=http://localhost:8000 \
SCRAPELOOP_API_KEY=sl_live_… \
  node test/mcp_smoke.mjs       # drives tools against a running API + drift-checks the manifest

node test/mcp_table_tools.mjs    # offline endpoint/schema contract for Table tools

Release readiness

MCP package releases use the publish-mcp GitHub Actions workflow. A release is successful only after all four conditions are true:

  1. The exact mcp-v<version> tag matches package.json.
  2. Tests pass and the packed tarball contains only the declared package files.
  3. npm accepts the exact tarball through Trusted Publishing, or already has that same version with the same integrity.
  4. npx scrapeloop-mcp@<version> reports the expected version and tool count.

The installed-package check removes GitHub Actions' temporary npm authentication settings and replaces them with an empty, temporary public-registry config before it runs npx. That makes the final check use the public registry exactly like a customer install, without reusing publishing access.

The Actions summary reports Build and test separately from Publish and registry. A green package build does not mean the version is published. A missing OIDC identity, a rejected trusted-publisher match, a conflicting duplicate version, or a registry verification timeout fails the workflow.

Trusted npm publishing

The npm package trusts only the publish-mcp.yml GitHub Actions workflow in Hinkam-Lanello/scrapeloop. The workflow uses GitHub OIDC to request a short-lived npm publishing identity. It must run on a GitHub-hosted runner with id-token: write, Node.js 24, and npm 11.5.1 or newer. Do not add NPM_TOKEN or another long-lived publish token.

The source repository is private, so the workflow must not force npm provenance. npm supports Trusted Publishing from a private GitHub repository, but provenance is available only when the source repository is public.

To recover an already tagged but unpublished version, run the workflow manually with its exact existing tag. The workflow archives and publishes that tag's source rather than the current default branch.

Local preflight, which never publishes:

npm ci --no-audit --no-fund
npm test
npm run release:preflight -- --tag mcp-v0.7.1