Perly Pay

io.perly由 perly.io 发布v0.3.0更新于 Nov 3, 2026

在编辑器中用加密货币销售:产品、支付链接、发票和测试付款。

AI 翻译由 AI 模型根据下方的原文描述翻译,可能有误。

原文描述

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

已验证STDIO仅桌面金融商业与电商

概览

Perly Pay 的本地 MCP 服务,由 perly.io 发布;无需登录;STDIO;38 个工具。

暂无 AI 概览:以下信息来自注册中心条目和服务本身。

发布者
perly.io

安装

在 SourceWeft 中

  1. 打开 控制台中的 Perly Pay,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

perly-pay-mcp

Sell your work for crypto from your AI coding assistant. perly-pay-mcp is a local MCP server for Perly Pay: your assistant can create products, prices, payment links and invoices, pay them in test mode, read payments and receipts, and check a buyer's access. Bitcoin, USDC and USDT land straight in your own wallet; Perly Pay never holds them. It costs 2.5¢ a payment, never more than 0.5% of it, and a month of up to 21 payments is free.

It runs on your machine over stdio and talks only to Perly Pay's public API with your key. There is no server of ours in between.

Set up

Get a test key in Perly Pay: Dashboard → Developers → API keys (sk_test_…).

Claude Code

bash
claude mcp add perly-pay --env PERLY_PAY_SECRET_KEY=sk_test_… -- npx -y perly-pay-mcp

Cursor: ~/.cursor/mcp.json, or .cursor/mcp.json in a project

json
{  "mcpServers": {    "perly-pay": {      "command": "npx",      "args": ["-y", "perly-pay-mcp"],      "env": { "PERLY_PAY_SECRET_KEY": "sk_test_…" }    }  }}

Codex: ~/.codex/config.toml

toml
[mcp_servers.perly-pay]command = "npx"args = ["-y", "perly-pay-mcp"]env = { PERLY_PAY_SECRET_KEY = "sk_test_…" }

Keep the key out of git: a config file in a project is often committed. Node 20 or newer.

Variable
PERLY_PAY_SECRET_KEYsk_test_… while you build. sk_live_… reads only (see below).
PERLY_PAY_APIDefault https://pay.perly.io. A perly.io host or this machine; plain http only for localhost.
PERLY_PAY_ALLOW_ANY_API1 sends your key to any other https host in PERLY_PAY_API, for a copy you run yourself.
PERLY_PAY_WEBHOOK_SECRETOptional whsec_…, the default for verify_webhook_signature.

Try it

Sell a one-hour consultation for $49 with a payment link, then pay it in test mode and show me the payment.

The assistant calls create_product, create_price, create_payment_link, simulate_payment and list_payments.

Tools

AreaTools
Products and pricescreate_product, list_products, update_product, create_price, list_prices, update_price
Payment linkscreate_payment_link, list_payment_links, update_payment_link
Invoices and checkoutcreate_invoice, list_invoices, retrieve_invoice, cancel_invoice, create_checkout_session, retrieve_checkout_session
Customerscreate_customer, list_customers, retrieve_customer
Subscriptions (renewed by invoice)create_subscription, list_subscriptions, retrieve_subscription
Access and creditscheck_entitlement, list_entitlements, consume_entitlement_credits, list_credit_usage
Money in, read onlylist_payments, retrieve_payment, list_receipts, retrieve_receipt, list_events
Refundscreate_refund, list_refunds
Webhookscreate_webhook_endpoint, list_webhook_endpoints, delete_webhook_endpoint
Test modesimulate_payment: pays an invoice, or buys from a payment link and pays that
On your machineverify_webhook_signature checks a Perly-Signature; pay_links gives the dashboard pages only you can use: plan, wallet, go live, two-factor, keys

The tools are generated from Perly Pay's OpenAPI document, so their arguments are the API's own.

What it will not do

  • With a live key, it only reads. Every tool that writes is refused: creating invoices, checkout sessions, products, prices, customers, payment links and subscriptions, cancelling, editing, refunds, credit spending, simulated payments and webhook endpoints. It says why, and you do it in the dashboard or in your app's own code. Lists and lookups work as in test. Why: text a buyer typed can reach the assistant, and nothing the server receives proves that you, not the model, approved a live change (confirm: true is written by the model; a client's approval prompt and an MCP elicitation answer both come back through the client). So the server never writes with a live key.
  • Wallets, API keys, billing, live mode and two-factor have no tool at all. You set them in the dashboard; pay_links gives the pages.
  • What cannot be undone (cancelling an invoice, opening a refund, deleting a webhook endpoint) waits for confirm: true, which the assistant should only send after asking you.
  • Your secret key is never repeated in an answer or a log.
  • Buyers' license keys never reach the assistant: an event that carries one comes back without its key; they stay in the dashboard.
  • Text others wrote is marked as data. Customer names, emails, descriptions and metadata can come from buyers, or from anyone who opens a payment link; every API answer ends with a note telling the assistant not to follow them. Still read what a tool is about to change before you approve it.

Docs: https://pay.perly.io/docs/mcp. API reference: https://pay.perly.io/docs/api. MIT licence.

来源:README.md,提交 966d0f2

工具

38

list_invoices

List invoices

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

输入参数limitcursorstatuscustomersubscription

create_invoice

Create an invoice

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.

输入参数amountcouponlocalecurrencycustomerdiscountmetadataline_itemsreturn_urldescriptionsubscriptioncustomer_email另有 1 个

retrieve_invoice

Retrieve an invoice

Retrieve an invoice.

输入参数id必填

cancel_invoice

Cancel an invoice

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`.

输入参数id必填confirm必填

simulate_payment

Simulate a payment (test mode only)

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.

输入参数idassetchainoutcomepayment_link

create_checkout_session

Create a checkout session

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.

输入参数couponcustomermetadatacancel_urlline_items必填return_urlcustomer_emailexpires_in_minutes

retrieve_checkout_session

Retrieve a checkout session

Retrieve a checkout session.

输入参数id必填

list_products

List products

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

输入参数limitactivecursor

create_product

Create a product

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

输入参数name必填activemetadataimage_urldescriptionissues_licenselicense_activation_limit

update_product

Update a product

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.

输入参数id必填nameactivemetadataimage_urldescriptionissues_licenselicense_activation_limit

list_prices

List prices

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

输入参数limitmodelactivecursorproduct

create_price

Create a price

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.

输入参数model必填creditsproduct必填refundscurrencylifetimemetadatanicknamerecurringterm_daysunit_amountcustom_amount

update_price

Update a price

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.

输入参数id必填activerefundsmetadatanickname

list_customers

List customers

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

输入参数emaillimitcursorexternal_id

create_customer

Create a customer

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

输入参数nameemaillocalecountrymetadataexternal_id

retrieve_customer

Retrieve a customer

Retrieve a customer.

输入参数id必填

list_subscriptions

List subscriptions

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

输入参数limitpricecursorstatuscustomer

create_subscription

Create a subscription

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.

输入参数price必填couponcustomer必填metadataquantitytrial_days

retrieve_subscription

Retrieve a subscription

Retrieve a subscription.

输入参数id必填

check_entitlement

Check access

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`).

输入参数priceproductcustomercustomer_emailcustomer_external_id

list_entitlements

List entitlements

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

输入参数limitcursorproductcustomersubscription

consume_entitlement_credits

Spend credits

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.

输入参数id必填actioncredits必填

list_credit_usage

List credit spends

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

输入参数limitactioncursorproductcustomer

list_payments

List payments

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.

输入参数assetlimitcursorinvoice

retrieve_payment

Retrieve a payment

Retrieve a payment.

输入参数id必填

list_refunds

List refunds

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

输入参数limitcursorstatusinvoice

create_refund

Open a refund

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`.

输入参数amountreasonconfirm必填invoice必填

list_receipts

List receipts

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.

输入参数kindlimitcursorinvoice

retrieve_receipt

Retrieve a receipt

Retrieve a receipt.

输入参数id必填

list_events

List events

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.

输入参数typelimitcursorobject

list_webhook_endpoints

List webhook endpoints

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

输入参数limitcursor

create_webhook_endpoint

Create a webhook endpoint

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.

输入参数url必填descriptionenabled_events

delete_webhook_endpoint

Delete a webhook endpoint

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`.

输入参数id必填confirm必填

verify_webhook_signature

Verify a webhook signature

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.

输入参数secretpayload必填signature必填tolerance_seconds

版本历史

1
  1. v0.3.0最新Nov 3, 2026

评分

已满足适用检查项的 90%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分
  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分