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

@suavesav/stripe-connect-mcp

v0.1.1

Published

Read-only MCP server for the Stripe API with full Connect (stripe_account) support

Readme

stripe-connect-mcp

Read-only MCP server for the Stripe API. Unlike the hosted Stripe MCP, this one:

  • Exposes list_connected_accounts and retrieve_account (Connect platform endpoints).
  • Passes Stripe-Account on every list/retrieve call via an optional connected_account_id argument, so you can inspect any connected account.
  • Redacts learner PII from every response by default, so names, emails, card last4, free-form metadata, and similar fields never reach the LLM. See PII protection.

Setup

npm install
npm run build

Set STRIPE_SECRET_KEY (secret or restricted key with read scopes + Connect read):

cp .env.example .env
# edit .env

Register with Claude Code

Add to ~/.claude.json under mcpServers:

"stripe-connect": {
  "type": "stdio",
  "command": "node",
  "args": ["/absolute/path/to/stripe-connect-mcp/dist/index.js"],
  "env": {
    "STRIPE_SECRET_KEY": "rk_live_..."
  }
}

Restart Claude Code.

Tools

All list/retrieve tools accept optional connected_account_id (forwarded as Stripe-Account).

Connect

  • list_connected_accounts, retrieve_account

Transactions

  • list_charges, retrieve_charge
  • list_payment_intents, retrieve_payment_intent
  • list_checkout_sessions (line items + products expanded by default)
  • list_refunds, list_disputes

Customers & billing

  • list_customers, retrieve_customer
  • list_invoices, retrieve_invoice (line items + products expanded by default)
  • list_subscriptions, retrieve_subscription

Catalog

  • list_products, list_prices

Money movement

  • retrieve_balance, list_balance_transactions
  • list_payouts
  • list_transfers (platform-only)
  • list_application_fees (platform-only)

Other

  • list_events

PII protection

Every tool response is passed through a redaction layer before it reaches the LLM. The goal is to keep learner PII (names, emails, phones, addresses, card last4, bank account fields, free-form metadata, etc.) out of chat transcripts entirely. When you legitimately need the underlying value, use the Stripe dashboard — IDs (cus_…, ch_…, pi_…) are preserved in responses so they're directly pasteable into dashboard URLs.

What gets redacted (replaced with "[REDACTED]"):

  • email, phone, address, shipping, billing_details, customer_details
  • receipt_email (Charge, PaymentIntent)
  • customer_email, customer_name, customer_phone, customer_address, customer_shipping, customer_tax_ids (Invoice, CheckoutSession)
  • tax_id / tax_ids
  • statement_descriptor / statement_descriptor_suffix
  • support_email / support_phone
  • Card fields: last4, fingerprint, exp_month, exp_year, network_token
  • Bank account fields: routing_number, account_holder_name, account_holder_type
  • client_secret (PaymentIntent, SetupIntent) — sensitive token, never returned to the LLM
  • name and description on customer/charge/account/etc. objects (kept on catalog objects: product, price, plan, coupon, tax_rate, shipping_rate)

Metadata is handled by an allowlist at config/pii-allowlist.json. Keys on the list pass through; everything else is silently dropped. Add keys via PR with a rationale in the description (e.g. "add course_id — internal course identifier, not learner-identifying"). The default list is empty.

Bypass (not recommended). Set STRIPE_MCP_ALLOW_PII=true in the server's env to disable the redactor for the session. A loud stderr warning is emitted at startup. Intended for internal debugging only — the LLM will receive and persist raw PII in the transcript.

Removed tools. search_stripe and stripe_get were removed because neither the request (queries, paths, params) nor the response could be safely scoped — both carried arbitrary PII into LLM context. Use the curated list/retrieve tools; if you need an endpoint they don't cover, go to the Stripe dashboard or add a curated tool.

Local testing

STRIPE_SECRET_KEY=rk_... npx @modelcontextprotocol/inspector node dist/index.js

Tests

Unit tests are pure and offline:

npm test

The snapshot suite hits Stripe test mode and compares response shapes (keys + types, no values) against committed JSON snapshots in test/snapshot/snapshots/. It detects Stripe API drift:

STRIPE_SECRET_KEY=sk_test_... npm run test:snapshot         # check for drift
STRIPE_SECRET_KEY=sk_test_... UPDATE=1 npm run test:snapshot  # regenerate snapshots

Requires a test-mode key with write scopes on customers, products, prices, subscriptions, payment_intents, invoices, checkout_sessions — the suite seeds these once (idempotent, tagged with metadata.drift_seed="1") so lists are never empty. The seeded PaymentIntent is confirmed with pm_card_visa so a charge and balance transaction exist to snapshot.

Drift-check workflow

.github/workflows/drift-check.yml runs the snapshot suite on a schedule (Mondays 09:00 UTC) and on manual workflow_dispatch. When it detects shape drift, it regenerates snapshots, re-verifies, and opens a PR (drift/stripe-shapes) containing the new JSON files. The PR body includes the failing-run diff summary; the Files Changed tab is the structural diff itself.

Reviewing a drift PR: inspect the test/snapshot/snapshots/*.json diff. Added fields → Stripe added something (usually safe to merge as-is). Removed fields → if any tool code depends on that field, update the tool alongside accepting the snapshot. Type changes → almost always need a code change.

Secrets the workflow expects:

  • STRIPE_TEST_SECRET_KEY — required. Test-mode key with the scopes above.
  • DRIFT_PR_TOKEN — optional but recommended. A PAT with contents:write + pull_requests:write on this repo. Without it the workflow falls back to GITHUB_TOKEN, which opens the PR but does not re-trigger CI (a GitHub platform rule — prevents workflow loops). Fine-grained PATs expire; rotate before the date stored in the token.

Forcing a run: Actions tab → Stripe drift checkRun workflow. A clean run exits 0 and opens no PR.

Notes

  • All amounts are in Stripe minor units (cents for USD, yen for JPY, etc.).
  • list_* returns Stripe's native shape: { data, has_more, next_page? }. Use starting_after with the last record's id to paginate.
  • list_transfers and list_application_fees only make sense on the platform account. If you pass connected_account_id to them, Stripe will likely error — that's expected.