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.

Perly Pay

NPM · PERLY-PAY-MCP

Sell for crypto from your editor: products, payment links, invoices and test payments.

Available components

66 Trust /100

Last scanned (7 hours ago)

Scores higher than 34% of npm servers

Category Finance and Payments

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security100
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • No install/post-install scripts declared.Pass
  • 0 of 3 dependencies flagged as unhealthy. View diagnostics → Pass
Provenance & Transparency45
Schema Quality & AI Usability60
  • AI-judged instruction clarity (good).Pass
  • Context-footprint check failed: tool/resource definitions use about 4844 tokens (~127/item across 38 items; 38 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 Management0
  • Stability not yet verified: not enough scan history yet (needs a 30-day window).Unverified
Tool Coverage89
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 66% of tool parameters carry a description.Partial
Tool Safety92
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • 2 of 3 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "pay_links" implies "pay" and declares readOnlyHint instead, contradicting what its own name says it does. See how to fix → Partial
  • An AI judge read all 39 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass

Unverified: 1 category

A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

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.

  • 3 Nov 26 +15
    • Malware scan: unverified → pass ▲ security
  • 2 Nov 26 51

    First indexed and scored.

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 5 Nov 2026 · Analysed npm/perly-pay-mcp@0.3.0

Provenance No attestation

The registry publishes no build provenance for this version, so there is nothing to verify.

Result No attestation
Ecosystem npm

Background: How many MCP packages publish verified provenance →

Dependencies 3 packages
Packages resolved 3
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 38 exposed · ~4,548 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
cancel_invoice ~109

Cancel an invoice. Only while nothing has arrived. Money that arrives later is still seen (the address stays watched) and lands in review. Test keys only: refused with a live key. Cannot be undone — Cancels the invoice: its buyer can no longer pay it. Ask the person first, then call with `confirm: true`.

NameTypeReqDescription
confirmbooleanyestrue once the person has agreed to this exact call. Without it nothing is done.
idstringyesThe object's id.

No output schema declared.

No examples provided.

check_entitlement ~115

Check access. One call: may this customer use this product now? Name the customer by `customer`, `customer_email` or `customer_external_id`, and the product by `product` (or `price`).

NameTypeReqDescription
customerstring–A customer id, `cus_…`.
customer_emailstring––
customer_external_idstring––
pricestring–A price id, `price_…`.
productstring–A product id, `prod_…`.

No output schema declared.

No examples provided.

consume_entitlement_credits ~113

Spend credits. Spends credits from one credit pack, atomically. Refused when fewer are left. `action` labels the spend for your reports; with an `Idempotency-Key` a retry never spends twice. To spend from a customer's packs together, use POST /credits/consume. Test keys only: refused with a live key.

NameTypeReqDescription
actionstring–Your label for what the credits paid for.
creditsintegeryes–
idstringyesThe object's id.

No output schema declared.

No examples provided.

create_checkout_session ~233

Create a checkout session. A cart of 1–20 prices in one currency. Send the buyer to `url`, or open it in an overlay with pay.js (`data-session="cs_…"`). The buyer comes back to `return_url` after paying, `cancel_url` if they leave. Live mode: a new session is refused with 403 `bill_overdue` while a Perly Pay bill is unpaid past its 14 days. Test keys only: refused with a live key.

NameTypeReqDescription
cancel_urlstring–An http(s) URL.
couponstring–A coupon code.
customerstring–A customer id, `cus_…`.
customer_emailstring––
expires_in_minutesinteger–Default 1440 (24 hours).
line_itemsarrayyes–
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
return_urlstring–An http(s) URL.

No output schema declared.

No examples provided.

create_customer ~114

Create a customer. Test keys only: refused with a live key.

NameTypeReqDescription
countrystring–ISO 3166-1 alpha-2.
emailstring––
external_idstring–Your own id for this buyer (unique).
localestring––
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
namestring––

No output schema declared.

No examples provided.

create_invoice ~405

Create an invoice. Lines are prices (`{ price, quantity }`) or your own (`{ description, amount, quantity }`), in one currency. For a single amount, `amount` + `description` is short for one line. `customer` is an id or `{ email }`. A price line may carry its own `description` ("Seat #12"), and `discount` takes an amount off this invoice alone. The buyer pays at `url`, choosing bitcoin or a stablecoin there. Live mode: a new invoice is refused with 403 `bill_overdue` while a Perly Pay bill is unpaid past its 14 days, until it is paid in the dashboard's Billing; invoices already made are still paid. Test keys only: refused with a live key.

NameTypeReqDescription
amountinteger–One amount instead of line_items in minor units (cents), an integer.
couponstring––
currencystring–For lines without a price. Default: your account's currency.
customer––A customer id, or `{ email }` to find or make one.
customer_emailstring–Without `customer`: finds or makes the customer by email.
descriptionstring–With `amount`: what it is for.
discountinteger–A one-off amount off this invoice (a credit you owe the buyer; not with `coupon`) in minor units (cents), an integer.
expires_in_minutesinteger–Until when a rail may be chosen.
line_itemsarray––
localestring––
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
return_urlstring–Where the buyer's page sends them back.
subscriptionstring–A subscription id, `sub_…`.

No output schema declared.

No examples provided.

create_payment_link ~159

Create a payment link. A page at /l/<slug> that sells one price. Share it anywhere, or open it with pay.js. Test keys only: refused with a live key.

NameTypeReqDescription
adjustable_quantityboolean––
allow_couponsboolean––
collect_nameboolean––
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
pricestringyesA price id, `price_…`.
quantityinteger––
slugstring–Default: random.
success_urlstring–Where the buyer goes after paying.

No output schema declared.

No examples provided.

create_price ~323

Create a price. Every model: one_time, pay_what_you_want (with a minimum), fixed_term (N days of access), subscription (interval, trial, grace, prepay), lifetime (optional cap and cohort tiers), credit_pack. Amounts are immutable; make a new price to change one. Body is one of: model = one_time: needs product, model, unit_amount; model = pay_what_you_want: needs product, model, custom_amount; model = fixed_term: needs product, model, unit_amount, term_days; model = subscription: needs product, model, unit_amount, recurring; model = lifetime: needs product, model; model = credit_pack: needs product, model, unit_amount, credits. Test keys only: refused with a live key.

NameTypeReqDescription
creditsinteger–Credits one pack holds.
currencystring–USD or EUR. Default: your account's currency.
custom_amountobject––
lifetimeobject––
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
modelstringyes–
nicknamestring––
productstringyesA product id, `prod_…`.
recurringobject––
refundsobject–Refund terms the buyer accepts at checkout.
term_daysinteger–Days of access one purchase gives.
unit_amount–––

No output schema declared.

No examples provided.

create_product ~121

Create a product. Test keys only: refused with a live key.

NameTypeReqDescription
activeboolean––
descriptionstring––
image_urlstring––
issues_licenseboolean–Issue a license key with every purchase.
license_activation_limitinteger–Instances a key may be active on.
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
namestringyes–

No output schema declared.

No examples provided.

create_refund ~236

Open a refund. Starts a refund in the asset that was paid. We email the buyer a link to give an address; the link is never returned, since whoever holds it decides where the money goes. With no email on the invoice, the owner makes one in the dashboard. When the address is checked, the refund is `ready_to_send` with `amount_to_send`. Refused with `sanctioned_sender` when money on the invoice came from an address on a sanctions list, or one the coin's issuer froze: sending it back may itself be prohibited, so nothing refunds it — leave it and talk to a lawyer. Test keys only: refused with a live key. Cannot be undone — Opens a refund to the buyer. Ask the person first, then call with `confirm: true`.

NameTypeReqDescription
amountstring–In the paid asset's smallest unit. Default: everything still refundable.
confirmbooleanyestrue once the person has agreed to this exact call. Without it nothing is done.
invoicestringyesA invoice id, `inv_…`.
reasonstring––

No output schema declared.

No examples provided.

create_subscription ~147

Create a subscription. Renewed by invoice: the customer pays each period themselves. Without a trial the first invoice opens now (`latest_invoice`); the subscription turns active when it is paid. Test keys only: refused with a live key.

NameTypeReqDescription
couponstring––
customerstringyesA customer id, `cus_…`.
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
pricestringyesA subscription price.
quantityinteger––
trial_daysinteger–Default: the price's.

No output schema declared.

No examples provided.

create_webhook_endpoint ~86

Create a webhook endpoint. The response carries `secret` — the only time you see it. Keep it to verify `Perly-Signature`. Test keys only: refused with a live key.

NameTypeReqDescription
descriptionstring––
enabled_eventsarray–Event types to send, or `["*"]` for every one.
urlstringyes–

No output schema declared.

No examples provided.

delete_webhook_endpoint ~84

Delete a webhook endpoint. Test keys only: refused with a live key. Cannot be undone — Deletes the webhook endpoint: its events stop. Ask the person first, then call with `confirm: true`.

NameTypeReqDescription
confirmbooleanyestrue once the person has agreed to this exact call. Without it nothing is done.
idstringyesThe object's id.

No output schema declared.

No examples provided.

list_credit_usage ~130

List credit spends. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
actionstring–Your label for what the credits paid for (`chat`, `image.hd`, `api/search`). Shows in your dashboard by action.
cursorstring–`next_cursor` from the previous page.
customerstring–A customer id, `cus_…`.
limitinteger–How many objects to return, 1–100. Default 10.
productstring–A product id, `prod_…`.

No output schema declared.

No examples provided.

list_customers ~81

List customers. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
cursorstring–`next_cursor` from the previous page.
emailstring––
external_idstring––
limitinteger–How many objects to return, 1–100. Default 10.

No output schema declared.

No examples provided.

list_entitlements ~112

List entitlements. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
cursorstring–`next_cursor` from the previous page.
customerstring–A customer id, `cus_…`.
limitinteger–How many objects to return, 1–100. Default 10.
productstring–A product id, `prod_…`.
subscriptionstring–A subscription id, `sub_…`.

No output schema declared.

No examples provided.

list_events ~121

List events. What happened in the last 30 days, newest first. `type` filters (`invoice.paid`, or `invoice.*`). Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
cursorstring–`next_cursor` from the previous page.
limitinteger–How many objects to return, 1–100. Default 10.
objectstring–Only events about this object (`inv_…`, `sub_…`).
typestring––

No output schema declared.

No examples provided.

list_invoices ~103

List invoices. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
cursorstring–`next_cursor` from the previous page.
customerstring–A customer id, `cus_…`.
limitinteger–How many objects to return, 1–100. Default 10.
statusstring––
subscriptionstring–A subscription id, `sub_…`.

No output schema declared.

No examples provided.

list_payment_links ~89

List payment links. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
activestring––
cursorstring–`next_cursor` from the previous page.
limitinteger–How many objects to return, 1–100. Default 10.
pricestring–A price id, `price_…`.

No output schema declared.

No examples provided.

list_payments ~101

List payments. Transfers seen on chain into addresses we handed out, newest first. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
assetstring––
cursorstring–`next_cursor` from the previous page.
invoicestring–A invoice id, `inv_…`.
limitinteger–How many objects to return, 1–100. Default 10.

No output schema declared.

No examples provided.

list_prices ~94

List prices. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
activestring––
cursorstring–`next_cursor` from the previous page.
limitinteger–How many objects to return, 1–100. Default 10.
modelstring––
productstring–A product id, `prod_…`.

No output schema declared.

No examples provided.

list_products ~72

List products. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
activestring––
cursorstring–`next_cursor` from the previous page.
limitinteger–How many objects to return, 1–100. Default 10.

No output schema declared.

No examples provided.

list_receipts ~101

List receipts. One for every fulfilled payment and every confirmed refund, newest first. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
cursorstring–`next_cursor` from the previous page.
invoicestring–A invoice id, `inv_…`.
kindstring––
limitinteger–How many objects to return, 1–100. Default 10.

No output schema declared.

No examples provided.

list_refunds ~88

List refunds. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
cursorstring–`next_cursor` from the previous page.
invoicestring–A invoice id, `inv_…`.
limitinteger–How many objects to return, 1–100. Default 10.
statusstring––

No output schema declared.

No examples provided.

list_subscriptions ~103

List subscriptions. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
cursorstring–`next_cursor` from the previous page.
customerstring–A customer id, `cus_…`.
limitinteger–How many objects to return, 1–100. Default 10.
pricestring–A price id, `price_…`.
statusstring––

No output schema declared.

No examples provided.

list_webhook_endpoints ~69

List webhook endpoints. Newest first; pass `next_cursor` back as `cursor` for the next page.

NameTypeReqDescription
cursorstring–`next_cursor` from the previous page.
limitinteger–How many objects to return, 1–100. Default 10.

No output schema declared.

No examples provided.

pay_links ~101

The Perly Pay dashboard pages for steps no API key can take: pay a Perly Pay bill, connect a wallet (public key only), go live, set up two-factor sign-in, manage API keys and live webhooks, send live refunds, and the go-live checklist. Give the person the link and say what to do there; do not try these through other tools.

NameTypeReqDescription
topicstring–One page; all of them when left out.

No output schema declared.

No examples provided.

retrieve_checkout_session ~24

Retrieve a checkout session.

NameTypeReqDescription
idstringyesThe object's id.

No output schema declared.

No examples provided.

retrieve_customer ~22

Retrieve a customer.

NameTypeReqDescription
idstringyesThe object's id.

No output schema declared.

No examples provided.

retrieve_invoice ~22

Retrieve an invoice.

NameTypeReqDescription
idstringyesThe object's id.

No output schema declared.

No examples provided.

retrieve_payment ~22

Retrieve a payment.

NameTypeReqDescription
idstringyesThe object's id.

No output schema declared.

No examples provided.

retrieve_receipt ~23

Retrieve a receipt.

NameTypeReqDescription
idstringyesThe object's id.

No output schema declared.

No examples provided.

retrieve_subscription ~22

Retrieve a subscription.

NameTypeReqDescription
idstringyesThe object's id.

No output schema declared.

No examples provided.

simulate_payment ~234

Simulate a payment (test mode only). Test keys only. `full` pays the amount due: the invoice turns paid and is fulfilled — entitlements, license keys, a receipt, and the events your webhooks get. `short` sends half (underpaid), `over` a tenth more (overpaid); those two need the buyer's chain and asset chosen first. For `full`, an invoice with no chain yet gets one: `chain` and `asset` if given, else the first stablecoin offered (refund terms count as accepted). Pass the invoice's `id`, or a `payment_link` id: then a test invoice is made for the link's price (as a buyer opening the link would) and paid. Test keys only: refused with a live key.

NameTypeReqDescription
assetstring––
chainstring––
idstring–The invoice's id, `inv_…`.
outcomestring–Default full.
payment_linkstring–Instead of `id`: a payment link, `plink_…`, to buy from first.

No output schema declared.

No examples provided.

update_payment_link ~119

Update a payment link. Test keys only: refused with a live key.

NameTypeReqDescription
activeboolean––
adjustable_quantityboolean––
allow_couponsboolean––
collect_nameboolean––
idstringyesThe object's id.
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
quantityinteger––
success_url–––

No output schema declared.

No examples provided.

update_price ~130

Update a price. Nickname, active, refund terms (`refunds` replaces them whole; what you leave out takes its default) and metadata. Amounts and the model never change. Test keys only: refused with a live key.

NameTypeReqDescription
activeboolean––
idstringyesThe object's id.
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
nickname–––
refundsobject–Refund terms the buyer accepts at checkout.

No output schema declared.

No examples provided.

update_product ~140

Update a product. Set `active: false` to stop selling it; products are never deleted (invoices point at them). Test keys only: refused with a live key.

NameTypeReqDescription
activeboolean––
description–––
idstringyesThe object's id.
image_url–––
issues_licenseboolean–Issue a license key with every purchase.
license_activation_limit–––
metadataobject–Your own key–value pairs (≤ 50 keys, values ≤ 500 characters). On an update they are merged in; an empty value removes its key.
namestring––

No output schema declared.

No examples provided.

verify_webhook_signature ~180

Checks a Perly Pay webhook on this machine: the HMAC-SHA256 in its Perly-Signature header against the raw body and the endpoint's signing secret, and that it is under five minutes old. Nothing is sent anywhere. Use it to debug a webhook handler that rejects real events. Pass the body exactly as received (the raw text, before JSON parsing). `secret` defaults to PERLY_PAY_WEBHOOK_SECRET.

NameTypeReqDescription
payloadstringyesThe request body, exactly as received.
secretstring–The endpoint's signing secret, `whsec_…`. Default: PERLY_PAY_WEBHOOK_SECRET.
signaturestringyesThe Perly-Signature header: `t=…,v1=…`.
tolerance_secondsinteger–How old a signature may be. Default 300.

No output schema declared.

No examples provided.

Install

How do I install the Perly Pay MCP server?

Perly Pay runs locally as an npm package, launched with npx -y perly-pay-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

npm · perly-pay-mcp

# add to Claude Code
claude mcp add io-perly-pay-mcp -- npx -y perly-pay-mcp
Common questions

What is the Perly Pay MCP server?

Perly Pay is an MCP server listed in the public MCP registry as io.perly/pay-mcp. Sell for crypto from your editor: products, payment links, invoices and test payments. This page covers its npm package (perly-pay-mcp).

Is the Perly Pay MCP server safe to use?

Perly Pay scores 66 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. It declares no install or post-install scripts. 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 Perly Pay MCP server expose?

Perly Pay exposes 38 tools: list_invoices, create_invoice, retrieve_invoice, cancel_invoice, simulate_payment, and 33 more. Their descriptions and schemas cost roughly 4,548 tokens of context every time the server is loaded.

Is the Perly Pay MCP server still maintained?

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

What licence is the Perly Pay MCP server under?

Perly Pay declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.