Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

SparkPay

REMOTE · SPARKPAY.DEV

Stripe billing for indie apps: plans, coupons, subscriptions, customers and revenue reporting.

Available components

+4 this week 80 Trust /100

Last scanned (20 hours ago)

Scores higher than 85% of remote servers

Reachable. Last reached 16 Oct 2026.

Category Finance and Payments

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security89
Transport & Reachability100
Schema Quality & AI Usability69
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 4502 tokens (~180/item across 25 items; 25 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management60
  • Stability observed for 18 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage67
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 0% of tool parameters carry a description.Fail
Tool Safety75
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • 0 of 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "delete_coupon" implies "delete" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
  • An AI judge read all 25 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 15 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 53 to 57. That category is still filling its 30-day observation window: 16 days of observed history at the previous scan, 17 at this one. The score rises as the window fills, whether or not the server changes.

  • 13 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 47 to 50. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 15 at this one. The score rises as the window fills, whether or not the server changes.

  • 12 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 40 to 47. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.

  • 10 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 30 to 40. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 12 at this one. The score rises as the window fills, whether or not the server changes.

  • 7 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 23 to 30. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

  • 4 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

  • 2 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 10 to 13. That category is still filling its 30-day observation window: 3 days of observed history at the previous scan, 4 at this one. The score rises as the window fills, whether or not the server changes.

  • 30 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 16 Oct 2026 · Probed https://sparkpay.dev/api/mcp/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=sparkpay.dev CN=YR1,O=Let's Encrypt,C=US 10 Oct 2026 8 Jan 2027 RSA 2048 SHA256-RSA 6d3c97e094041405ab66ee4e2468285731d
SANs: sparkpay.dev
CN=YR1,O=Let's Encrypt,C=US (CA) CN=Root YR,O=ISRG,C=US 3 Sept 2025 2 Sept 2028 RSA 2048 SHA256-RSA a20253f15f2691c05dc1ce13b9bcca4e
CN=Root YR,O=ISRG,C=US (CA) CN=ISRG Root X1,O=Internet Security Research Group,C=US 13 May 2026 2 Sept 2032 RSA 4096 SHA256-RSA f24b6d17f9d9ad7cb1c9fea78782699f

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of sparkpay.dev. — Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
dev. present 60074 8 Verified
sparkpay.dev. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication Challenged, unverified

The endpoint asked for a token, but we could not retrieve and validate the RFC 9728 metadata that tells a client how to obtain one.

Result Challenged, unverified
Enforced On tool calls
HTTP status 200

WWW-Authenticate challenge Bearer error="invalid_token", error_description="No authorization provided", resource_metadata="https://sparkpay.dev/.well-known/oauth-protected-resource"

Bearer error="invalid_token", error_description="No authorization provided", resource_metadata="https://sparkpay.dev/.well-known/oauth-protected-resource"
Header Value
strict-transport-security max-age=63072000; includeSubDomains; preload
x-content-type-options nosniff
x-frame-options SAMEORIGIN
referrer-policy strict-origin-when-cross-origin
permissions-policy camera=(), microphone=(), geolocation=()

Protected resource metadata

Document https://sparkpay.dev/.well-known/oauth-protected-resource
Retrieved No
Problem metadata_http_error

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://sparkpay.dev/api/mcp/mcp Verified 200
http (plaintext) http://sparkpay.dev/api/mcp/mcp HTTPS enforced 308 https://sparkpay.dev/api/mcp/mcp
MCP tools · 25 exposed · ~4,502 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
archive_plan ~202

Remove a tier from an app's plan catalog. WRITE, human-gated: a real write needs an elicitation-capable client and the human must approve; dry_run previews anywhere. Every other plan tool edits tiers that already exist, so a catalog could grow but never shrink, and collapsing a multi-tier page down to a single offer was a dashboard-only job. Stripe products and prices are deliberately left intact, exactly as update_plan_pricing leaves the old price behind: removing the row stops the plan being offered and never reaches into anyone's existing subscription. Refuses while the tier still has non-cancelled subscribers (matched on its Stripe price ids, since subscriptions carry a price rather than a tier slug), and refuses to remove an app's last remaining tier. Run `bun run plans:sync` in the app repo afterwards to regenerate plans.json.

NameTypeReqDescription
app_idstringyes–
dry_runboolean––
tierstringyes–

No output schema declared.

No examples provided.

bulk_create_coupon ~283

Create the SAME discount code across many apps in one call: the portfolio-promo shortcut (e.g. a summer sale on every owned app). WRITE, human-gated: a real create requires an elicitation-capable client; the human enters the coupon terms ONCE in a form (overriding the arguments here) and that one approval covers the whole batch. Clients without elicitation are refused (dry_run still works anywhere). Runs each app through the same fully-guarded create as create_coupon. Unlike a single call it does NOT fail the batch when an app already has the code: that app is reported `skipped` and the rest are still created. Returns a per-app outcome matrix plus created/skipped/failed counts. Use dry_run:true first to see which apps would create vs skip. Pass explicit app_ids (from list_apps). There is deliberately no 'all apps' shortcut, so a discount can't hit an app you didn't name.

NameTypeReqDescription
app_idsarrayyes–
applies_to_tiersarray––
codestringyes–
confirm_high_discountboolean––
descriptionstring––
discount_percentnumberyes–
dry_runboolean––
expires_atstring––
listedboolean––
max_usesnumber––

No output schema declared.

No examples provided.

bulk_delete_coupon ~207

Delete the SAME coupon code across many apps in one call: the inverse of bulk_create_coupon, for retiring a portfolio-wide promo. WRITE, human-gated: a real delete requires an elicitation-capable client; the human sees every app the code would be removed from (with per-app redemption counts) and must click approve, and confirm_used is only consulted for dry_run previews. Clients without elicitation are refused (dry_run still works anywhere). An app that never had the code is reported `skipped` rather than failing the batch, since the desired end state already holds there. Returns a per-app outcome matrix plus deleted/skipped/failed counts. Use dry_run:true first to see exactly which apps would lose the code. Pass explicit app_ids (from list_apps) so a delete can't hit an app you didn't name.

NameTypeReqDescription
app_idsarrayyes–
codestringyes–
confirm_usedboolean––
dry_runboolean––

No output schema declared.

No examples provided.

create_app_kit ~150

Step 2 of onboarding a new app onto SparkPay. Applies answers.plan_catalog by minting real Stripe prices (same helper /api/apps/sync-plans uses) and registers/updates the app, then returns a downloadable integration kit (lib/spark-pay client + plans.json + sync script + INTEGRATION.md, modeled on still-applying's golden pattern) plus exact post_steps for env vars and secrets. Refuses to overwrite an existing app's plans unless answers.confirm_overwrite is true. Real secrets (a push-mode webhook secret) are only ever returned in post_steps, never written into a kit file.

NameTypeReqDescription
answersobjectyes–
app_namestringyes–

No output schema declared.

No examples provided.

create_coupon ~366

Create a percentage discount coupon for an app. WRITE, human-gated: a real create requires an elicitation-capable client (e.g. Claude Desktop). The human enters the final code, percent, expiry, visibility, and tier scope in a form; those values OVERRIDE the arguments here, which only pre-fill the form message as a proposal. Clients without elicitation are refused (dry_run still works anywhere). Inserts a `coupons` row and best-effort-mints the matching Stripe coupon (checkout backfills it on first use if Stripe is unreachable). The code is uppercased and must be unique per app. By default the coupon applies to every paid tier. Set dry_run:true first to preview the exact row without writing. Cannot discount a free-only app. Three house rules are enforced and cannot be argued out of: every coupon expires within 6 months (omitting expires_at means the 6-month term, not a code that never expires); a coupon at 90%+ is created invite_only, so it is redeemable only by addresses added with invite_to_coupon; and a 90%+ coupon is pinned to the second-highest paid recurring tier and may never cover the top tier or a one-time (lifetime) plan. Use list_coupons afterwards to confirm, and list_plans to see an app's tier slugs.

NameTypeReqDescription
app_idstringyes–
applies_to_tiersarray––
codestringyes–
confirm_high_discountboolean––
descriptionstring––
discount_percentnumberyes–
dry_runboolean––
expires_atstring––
listedboolean––
max_usesnumber––

No output schema declared.

No examples provided.

delete_coupon ~188

Delete one coupon from an app. WRITE, human-gated: a real delete requires an elicitation-capable client; the human sees the exact coupon (code, percent, redemption count) and must click approve. The model cannot confirm on its own, and confirm_used is only consulted for dry_run previews. Clients without elicitation are refused (dry_run still works anywhere). Removes the Stripe coupon object and then the `coupons` row, exactly like the dashboard's delete, so no orphaned Stripe object is left behind. Deleting is permanent and the code becomes reusable afterwards. Set dry_run:true to see exactly which coupon would go (and its redemption count) without touching anything. Use list_coupons first to confirm the code.

NameTypeReqDescription
app_idstringyes–
codestringyes–
confirm_usedboolean––
dry_runboolean––

No output schema declared.

No examples provided.

get_customer ~73

Look up a customer by email. Returns every subscription/registration for that email across apps (or within one app if app_id is given), with full detail: verification, plan, billing period, usage, refunds. Empty when the email is unknown.

NameTypeReqDescription
app_idstring––
emailstringyes–

No output schema declared.

No examples provided.

invite_to_coupon ~238

Add email addresses to a coupon's invite list and, by default, switch the coupon to invite-only so the list is actually enforced. WRITE, human-gated: a real write requires an elicitation-capable client and the human sees every address plus whether the coupon is about to be closed to everyone else; clients without elicitation are refused (dry_run works anywhere). Addresses are lowercased and de-duplicated, malformed ones are reported rather than dropped, and an address already on the list is left exactly as it is -- so re-inviting someone who already redeemed does NOT hand them a second free account, and re-inviting someone who was revoked does NOT un-block them. Set enforce_invite_only:false only to stage a list before gating the code; the result then carries a warning that the coupon is still open. Use dry_run:true first to see exactly who would be added.

NameTypeReqDescription
app_idstringyes–
codestringyes–
dry_runboolean––
emailsarrayyes–
enforce_invite_onlyboolean––
sourcestring––

No output schema declared.

No examples provided.

list_apps ~43

List the registered apps (app_id + name). Use this first to discover valid app_id values, then pass one to the other tools to scope results to a single product.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

list_coupon_invites ~128

List who a coupon was offered to and what they did with it: per-address status (invited / redeemed / revoked), where the invite came from, and the timestamps. Also returns the coupon's own `invite_only` flag -- read that FIRST: when it is false the invite rows are recorded but NOT enforced, and anyone holding the code can still redeem it. Read-only. Use list_coupons for the coupon's terms, invite_to_coupon to add addresses, revoke_coupon_invite to withdraw one.

NameTypeReqDescription
app_idstringyes–
codestringyes–

No output schema declared.

No examples provided.

list_coupons ~91

List discount coupons (code, percent off, expiry, max uses, use count, which paid tiers they apply to). Optionally scope by app_id and/or restrict to currently-active ones (not expired, not maxed out). Read-only: cannot create, edit, or delete coupons.

NameTypeReqDescription
active_onlyboolean––
app_idstring––
limitnumber––

No output schema declared.

No examples provided.

list_plans ~110

Download an app's live plan catalog: tiers, names, prices, trial, and the machine-readable `limits` that gate features inside the app. This is the source of truth each app repo's `bun run plans:sync` regenerates lib/spark-pay/plans.json from, so diff against this rather than trusting the committed file. Stripe price/product IDs are omitted unless include_stripe_ids is set.

NameTypeReqDescription
app_idstringyes–
include_stripe_idsboolean––

No output schema declared.

No examples provided.

list_recent_cancellations ~70

Recently canceled paid subscriptions (excludes free rows), most recent cancellation first, with what each customer was paying. Use for churn review; list_subscriptions orders by signup date instead.

NameTypeReqDescription
app_idstring––
include_samplesboolean––
limitnumber––

No output schema declared.

No examples provided.

list_recent_payments ~77

List recent paid transactions (excludes free-tier rows), newest first, ordered by payment date. Optionally scope by app_id. Use to review recent sales activity. Amounts are in the transaction currency (cents).

NameTypeReqDescription
app_idstring––
include_samplesboolean––
limitnumber––

No output schema declared.

No examples provided.

list_referrals ~70

List referral records (who referred whom, reward coupon code, pending/rewarded status), newest first. Optionally scope by app_id and/or status.

NameTypeReqDescription
app_idstring––
include_samplesboolean––
limitnumber––
statusstring––

No output schema declared.

No examples provided.

list_subscriptions ~94

List subscriptions/registrations, newest first. Optionally filter by app_id, status, or payment_type. Returns metadata (email, status, plan, amounts). Use get_customer for a single user, or revenue_summary for totals.

NameTypeReqDescription
app_idstring––
include_samplesboolean––
limitnumber––
payment_typestring––
statusstring––

No output schema declared.

No examples provided.

plan_app_kit ~92

Step 1 of onboarding a new app onto SparkPay. Recons app_name against existing apps and the rest of the portfolio's plan catalogs, then returns automated findings plus the minimum set of questions that genuinely need a human answer (plan prices, billing model, redirect URLs, trial length, push-webhook opt-in). Pass the answers to create_app_kit next.

NameTypeReqDescription
app_namestringyes–

No output schema declared.

No examples provided.

revenue_by_app ~100

Per-app rollup in USD cents (latest_payments/refunded/MRR + paid customer count), largest refund-adjusted latest payments first. latest_payments sums the most recent payment per customer, so it is a run-rate and NOT lifetime turnover. No lifetime figure is available per app (accrual is recorded per owner). Use to compare products at a glance; use revenue_summary for one app in depth.

NameTypeReqDescription
include_samplesboolean––

No output schema declared.

No examples provided.

revenue_summary ~189

Revenue and subscriber summary in USD cents (normalized from each transaction currency). Returns latest_payments (the MOST RECENT payment summed per customer: a run-rate, NOT lifetime turnover, because amount_paid is overwritten on renewal), refunds, approximate MRR, active/trialing/paid counts, and lifetime_net (the only cumulative total held, accrued per OWNER across all their apps and net of refunds; null when no accrual record exists). lifetime_net counts only charges whose Stripe webhook reached this app, so a missing renewal event under-counts it silently. A 0 or a low figure means "not recorded here", never "no sales". For turnover, accounts or tax, read Stripe directly: it is authoritative, and this database cannot reconstruct lifetime gross. Optionally scope by app_id; omit for platform-wide totals.

NameTypeReqDescription
app_idstring––
include_samplesboolean––

No output schema declared.

No examples provided.

revoke_coupon_invite ~211

Withdraw one address's right to spend a coupon: the targeted block. WRITE, human-gated: a real write requires an elicitation-capable client and the human sees the address and its current status; clients without elicitation are refused (dry_run works anywhere). Works on an address that was never invited too, writing a revoked tombstone, so blocking someone does not depend on whether they were on the list and survives a later bulk re-invite. This only blocks FUTURE redemptions: if the status was already `redeemed` the discount has been granted, and undoing that means cancelling or refunding the subscription in the dashboard. Prefer this over delete_coupon when one recipient misbehaves -- deleting the code punishes every other invitee. Use list_coupon_invites first to see the current status.

NameTypeReqDescription
app_idstringyes–
codestringyes–
dry_runboolean––
emailstringyes–
reasonstring––

No output schema declared.

No examples provided.

set_coupon_listed ~357

Show, hide or SCHEDULE an EXISTING coupon on the public pricing pages by setting its `listed` flag and optional `listed_from` start date. WRITE, human-gated: a real write requires an elicitation-capable client and the human sees the code, the discount, which way it is moving and any start date; clients without elicitation are refused (dry_run works anywhere). These are deliberately the ONLY fields an agent can change on a live coupon: the percent, expiry and tier scope are terms somebody may already have been quoted, while `listed`/`listed_from` are purely a display decision. Together they decide whether the public coupons API returns the code today, which is what every app's promo bar draws from; the discount itself does not move and no Stripe object is touched. `listed_from` in the future STAGES a seasonal coupon so it appears on its own date with no cron: it never blocks anyone holding the code from redeeming it, it only holds the code back from the promo bar. Listing with no `listed_from` clears any existing schedule (lists now). Listing an INVITE-ONLY coupon is refused outright, since that would advertise a near-free code to people who cannot redeem it. A `listed_from` with listed:false is refused as a contradiction. Listing an expired/maxed coupon, or scheduling a start at or after expiry, is allowed but warns. A coupon already in the requested state reports `noop`. Use list_coupons first to see codes and their current visibility.

NameTypeReqDescription
app_idstringyes–
codestringyes–
dry_runboolean––
listedbooleanyes–
listed_fromstring––

No output schema declared.

No examples provided.

setup_pricing_page ~368

Guided, stage-chained wizard that configures an app's hosted pricing page end to end: plan billing model + price (with clickable recommendations), plan name and badge (elite/recommended), optional free tier, a seasonal coupon (SUMMER26-style code suggested from the current season), favicon-derived theme color + card style, and FAQ content. WRITE, human-gated per stage: each call runs AT MOST ONE elicitation form and commits only that stage, then returns next_call for the model to continue (stages: overview -> plans -> coupon -> branding -> content -> finish). The values the HUMAN types in each form OVERRIDE the arguments here - args only pre-fill form defaults (pass price_suggestions from market research and faq_drafts to seed them). Testimonials are NOT configurable here: they are collected from real customers on Sellular and rendered from there. Form stages are refused on clients without elicitation; overview/finish are read-only recon and work anywhere, as does dry_run (echoes the form + would-be writes, writes nothing). A declined stage leaves earlier committed stages applied - each stage is individually approved, and each effect is reversible via the standalone tools. Stripe prices are minted only by the plans stage with human-typed amounts (existing paid tiers only; free tiers never touch Stripe). After plan changes, run `bun run plans:sync` in consumer app repos. Use list_apps first for app_id.

NameTypeReqDescription
app_idstringyes–
coupon_codestring––
discount_percentnumber––
domainstring––
dry_runboolean––
faq_draftsarray––
price_suggestionsarray––
stagestring––
tierstring––

No output schema declared.

No examples provided.

update_plan_limits ~231

Change the usage limits on an app's existing tiers (e.g. set ai_generations_daily to 200 on pro). WRITE, human-gated: a real write requires an elicitation-capable client; the human sees the per-tier before -> after diff and must click approve. Clients without elicitation are refused (dry_run still works anywhere). Tier-keyed, so one call can set a new limit key across every tier in a single atomic write. Use -1 for unlimited, matching the catalog convention. This writes ONLY the limits object: it never touches Stripe, prices, or plan names, so it cannot mint a price by accident. Changing prices or adding a tier is a different job: use create_app_kit or the dashboard. Set dry_run to preview the before/after without writing. After this succeeds, run `bun run plans:sync` in the app repo and commit the regenerated plans.json so the code and the catalog agree.

NameTypeReqDescription
app_idstringyes–
dry_runboolean––
modestring––
updatesobjectyes–

No output schema declared.

No examples provided.

update_plan_meta ~300

Set an existing tier's display metadata: its name and the two badge flags the public pricing page styles cards from: is_elite (gold/carbon BEST VALUE card with the rainbow title and app icon) and recommended (MOST POPULAR). A tier called "Elite" is NOT styled as elite unless is_elite is actually true on the stored plan; the page reads the flag, never the tier slug, so a catalog whose top tier lacks the flag renders as a plain grey card. Use this to repair that. WRITE, human-gated: the human sees the before -> after diff and approves (clients without elicitation pass through, since this touches no money: it never reaches Stripe, never changes an amount, limits or billing model, and is reversible by calling it again). Setting a flag false REMOVES the key rather than storing false, keeping exported plans.json minimal. Convention is at most ONE is_elite and ONE recommended tier per app: this tool does not clear the flag from its siblings, so unset the old holder in a second call. Use list_plans first for tier slugs and current flags, and run `bun run plans:sync` in the app repo afterwards to regenerate plans.json.

NameTypeReqDescription
app_idstringyes–
dry_runboolean––
is_eliteboolean––
namestring––
recommendedboolean––
tierstringyes–

No output schema declared.

No examples provided.

update_plan_pricing ~264

Change what an app's EXISTING tiers charge: the amount, the billing model (one_time vs subscription), or both. WRITE, human-gated at the highest tier: a real write requires an elicitation-capable client, and the human types the tier, billing model and price into a form. Those typed values OVERRIDE the arguments here, which only pre-fill the proposal, so the model cannot move a price on its own. Clients without elicitation are refused (dry_run still works anywhere). Stripe prices are immutable, so this mints a NEW price and repoints the plan; the old price object is left intact and existing subscribers keep the price they signed up on, so this changes what NEW buyers pay. Switching a tier to one_time also clears its monthly/yearly price ids, so checkout cannot fall back to a recurring price the pricing page no longer advertises. Free, contact and payg tiers are refused: converting those is a catalog change, not a reprice. Use list_plans first for tier slugs and current amounts, and run `bun run plans:sync` in the app repo afterwards to regenerate plans.json.

NameTypeReqDescription
app_idstringyes–
dry_runboolean––
updatesarrayyes–

No output schema declared.

No examples provided.

Install

How do I install the SparkPay MCP server?

SparkPay is a hosted endpoint at https://sparkpay.dev/api/mcp/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · sparkpay.dev

# add to Claude Code
claude mcp add --transport http dev-sparkpay-sparkpay 'https://sparkpay.dev/api/mcp/mcp'
Common questions

What is the SparkPay MCP server?

SparkPay is an MCP server listed in the public MCP registry as dev.sparkpay/sparkpay. Stripe billing for indie apps: plans, coupons, subscriptions, customers and revenue reporting. This page covers its hosted endpoint (https://sparkpay.dev/api/mcp/mcp).

Is the SparkPay MCP server safe to use?

SparkPay scores 80 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the SparkPay MCP server expose?

SparkPay exposes 25 tools: list_apps, list_subscriptions, get_customer, list_recent_payments, revenue_summary, and 20 more. Their descriptions and schemas cost roughly 4,502 tokens of context every time the server is loaded.

Does the SparkPay MCP server require authentication?

Yes. SparkPay asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

Is the SparkPay MCP server still maintained?

SparkPay is still listed as active in the MCP registry. We last reached this channel on 16 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.