CEP-8 Capability Pricing and Payment Flow
Capability Pricing and Payment Flow
Section titled “Capability Pricing and Payment Flow”Status: Draft Author: @contextvm-org Type: Standards Track
Abstract
Section titled “Abstract”This CEP proposes a standardized pricing mechanism and payment flow for MCP capabilities over ContextVM. The mechanism allows servers to advertise pricing for their capabilities, enables clients to discover and pay for these capabilities through various payment methods, and defines a notification system for payment requests. This creates a sustainable ecosystem for capability servers while maintaining the decentralized nature of the protocol.
Specification
Section titled “Specification”Overview
Section titled “Overview”ContextVM pricing for capabilities is implemented through a standardized mechanism with three main components:
- Pricing Tags: Servers advertise pricing information using the
captag - Payment Method Identifiers (PMI): Both parties advertise supported payment methods using the
pmitag - Payment Notifications: Servers notify clients of payment requirements through the
notifications/payment_requirednotification, and MAY acknowledge outcomes withnotifications/payment_accepted/notifications/payment_rejected
When a capability requires payment, the server acts as the payment processor (generating and validating payment requests) while the client acts as the payment handler (executing payments for supported payment methods). Clients can discover supported payment methods beforehand through PMI discovery, enabling informed decisions before initiating requests.
Scope and Non-goals
Section titled “Scope and Non-goals”This CEP defines:
- How servers advertise reference pricing for capabilities.
- How clients and servers advertise supported payment methods.
- A minimal notification-based flow for requesting and acknowledging payments.
This CEP does not define:
- Privacy guarantees for payment messages (use encryption mechanisms in CEP-4 where required).
- Rate limiting / abuse prevention mechanisms.
- Currency conversion rules or exchange rate discovery.
New Tags Introduced
Section titled “New Tags Introduced”This CEP introduces the following new tags to the ContextVM protocol:
cap Tag
Section titled “cap Tag”The cap tag is used to convey pricing information for capabilities. It follows this format:
["cap", "<capability-identifier>", "<price>", "<currency-unit>"]Where:
<capability-identifier>identifies the priced capability using a typed prefix:tool:<tool_name>prompt:<prompt_name>resource:<resource_uri>
<price>is a string representing the numerical amount:- Fixed price: an integer string (e.g.,
"100"). - Variable price: an inclusive range string
"<min>-<max>"(e.g.,"100-1000").
- Fixed price: an integer string (e.g.,
<currency-unit>is a currency unit label (e.g.,"sats","usd"). Currency conversion, if any, is implementation-defined.
- The
captag is a reference price signal for discovery and UX. The actualamountrequested for payment is provided innotifications/payment_required. - If
<price>is a range, servers MAY request anyamountwithin the advertised inclusive range. Clients MAY accept or ignore the payment request based on their own policy. - If multiple
captags are present for the same capability, clients SHOULD prefer the most specific and most recent context (for example, a livetools/listresponse over a public announcement).
pmi Tag
Section titled “pmi Tag”The pmi tag is used to advertise supported Payment Method Identifiers. It follows this format:
["pmi", "<payment-method-identifier>"]Where <payment-method-identifier> is a standardized PMI string following the W3C Payment Method Identifiers specification (e.g., “bitcoin-lightning-bolt11”, “bitcoin-cashu”).
direct_payment Tag (optional)
Section titled “direct_payment Tag (optional)”The direct_payment tag is an optional optimization for bearer-asset payment methods. It allows a client to include a PMI-scoped settlement payload directly on the request event (see Optional direct payment).
["direct_payment", "<pmi>", "<payload>"]change Tag (optional)
Section titled “change Tag (optional)”The change tag is an optional settlement artifact for bearer-asset payment methods.
It allows a server to return overpayment remainder on the notifications/payment_accepted event.
["change", "<pmi>", "<payload>"]Where:
<pmi>identifies how to interpret<payload>.<payload>is an opaque string whose format is PMI-defined.
Pricing Mechanism
Section titled “Pricing Mechanism”Pricing information is advertised using the cap tag in server announcements and capability list responses:
Server Announcements
Section titled “Server Announcements”{ "kind": 11317, "content": { "tools": [ { "name": "get_weather", "description": "Get current weather information" // ... other tool properties } ] }, "tags": [["cap", "tool:get_weather", "100", "sats"]]}Capability List Responses
Section titled “Capability List Responses”{ "kind": 25910, "pubkey": "<provider-pubkey>", "content": { "result": { "tools": [ { "name": "get_weather", "description": "Get current weather information" // ... other tool properties } ], "nextCursor": "next-page-cursor" } }, "tags": [ ["e", "<request-event-id>"], ["cap", "tool:get_weather", "100", "sats"] ]}The cap tag indicates that using the get_weather tool costs 100 satoshis, allowing clients to display pricing to users.
Payment Method Identifiers (PMI)
Section titled “Payment Method Identifiers (PMI)”The protocol supports multiple payment methods through Payment Method Identifiers (PMI) that follow the W3C Payment Method Identifiers specification.
PMI boundaries (what PMI defines)
Section titled “PMI boundaries (what PMI defines)”PMIs are not only a discovery label; they define the settlement protocol surface for CEP-8 payments.
- The
pmivalue innotifications/payment_requireddefines how a payment handler MUST interpret the associated opaquepay_reqstring. - The format and semantics of
pay_reqare PMI-defined. - The optional
_metaobjects innotifications/payment_requiredandnotifications/payment_acceptedMAY contain PMI-specific fields. Unknown_metafields MUST be ignored.
In other words, pmi is the type tag for pay_req (analogous to a content-type).
PMI Format and Registry
Section titled “PMI Format and Registry”PMIs MUST follow the format defined by the W3C Payment Method Identifiers specification, matching the pattern: [a-z0-9-]+.
Recommended PMIs (ContextVM ecosystem)
Section titled “Recommended PMIs (ContextVM ecosystem)”This CEP maintains no in-document registry of recommended PMIs.
Recommended PMIs and naming conventions are documented in the informational companion CEP, CEP-21: Payment Method Identifier (PMI) Recommendations.
PMI Benefits and Roles
Section titled “PMI Benefits and Roles”Using standardized PMIs provides:
- Interoperability: Clear communication about supported payment methods
- Extensibility: Easy addition of new payment methods
- Multi-currency support: Different PMIs handle different currencies and networks
- Clear separation of concerns: Servers focus on payment processing, clients on payment handling
PMI Discovery
Section titled “PMI Discovery”PMI discovery allows clients and servers to determine compatibility with payment methods, similar to encryption support discovery in CEP-4.
PMI Advertisement
Section titled “PMI Advertisement”Servers advertise supported PMIs using the pmi tag in initialization responses or public announcements:
{ "pubkey": "<server-pubkey>", "content": { /* server details */ }, "tags": [ ["pmi", "bitcoin-lightning-bolt11"], ["pmi", "another-payment-method"] ]}Clients advertise their supported PMIs in initialization requests:
{ "kind": 25910, "content": { "jsonrpc": "2.0", "id": 0, "method": "initialize", "params": { // Initialization parameters } }, "tags": [ ["p", "<server-pubkey>"], ["pmi", "bitcoin-lightning-bolt11"], ["pmi", "another-payment-method"] ]}Discovery Methods
Section titled “Discovery Methods”Clients can discover PMI support through:
- Public Announcements: Check
pmitags in server announcements - Initialization Responses: Check
pmitags in server initialization responses - Stateless Operations: Handle compatibility at request time when no prior discovery is possible
Servers can discover PMI support through:
- Client Initialization Request: Check
pmitags in client initialization request
Stateless operation
Section titled “Stateless operation”In stateless operation (no prior initialization), clients that want to use paid capabilities SHOULD include one or more pmi tags in the request event so the server can select a compatible payment method.
Payment Flow
Section titled “Payment Flow”The complete payment flow for a capability with pricing information follows these steps:
1. Capability Request
Section titled “1. Capability Request”The client sends a capability request to the server:
{ "kind": 25910, "id": "<request-event-id>", "pubkey": "<client-pubkey>", "content": { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "get_weather", "arguments": { "location": "New York" } } }, "tags": [["p", "<provider-pubkey>"]]}2. Payment Required Notification
Section titled “2. Payment Required Notification”If the capability requires payment, the server responds with a notifications/payment_required notification containing payment details:
{ "kind": 25910, "pubkey": "<provider-pubkey>", "content": { "method": "notifications/payment_required", "params": { "amount": 100, "pay_req": "lnbc...", "description": "Payment for tool execution", "pmi": "bitcoin-lightning-bolt11", "ttl": 600, "_meta": { "note": "Optional PMI-specific metadata" } } }, "tags": [ ["p", "<client-pubkey>"], ["e", "<request-event-id>"] ]}3. Payment Processing
Section titled “3. Payment Processing”The client processes the payment and the server verifies it. When the client receives a payment request notification, it matches the PMI to determine if it supports the specified payment method. If compatible, the client processes the payment using the appropriate method for that PMI. The server verifies the payment according to the PMI implementation.
If the client included one or more pmi tags in the original request, the server SHOULD send at most one notifications/payment_required notification using a PMI from the intersection of client- and server-supported PMIs.
If the client did not advertise any PMIs (for example, in a purely stateless request), the server MAY send multiple notifications/payment_required notifications (for example, one per supported PMI). Clients MAY ignore any or all payment requests.
4. Payment Accepted Notification
Section titled “4. Payment Accepted Notification”Once payment is verified, the server SHOULD notify the client that payment has been accepted.
{ "kind": 25910, "pubkey": "<provider-pubkey>", "content": { "method": "notifications/payment_accepted", "params": { "amount": 100, "pmi": "bitcoin-lightning-bolt11", "_meta": { "note": "Optional acceptance metadata" } } }, "tags": [ ["p", "<client-pubkey>"], ["e", "<request-event-id>"] ]}The optional _meta field is the extension point for payment acceptance details.
For bearer-asset direct payments, the server MAY include a change tag on this event to return any overpayment remainder.
4b. Payment Rejected Notification
Section titled “4b. Payment Rejected Notification”If the server cannot accept payment for a request (for example, an invalid or insufficient direct_payment payload), it MAY notify the client that payment was rejected.
{ "kind": 25910, "pubkey": "<provider-pubkey>", "content": { "method": "notifications/payment_rejected", "params": { "pmi": "bitcoin-cashu-v4-direct", "message": "Insufficient direct payment" } }, "tags": [ ["p", "<client-pubkey>"], ["e", "<request-event-id>"] ]}5. Capability Access
Section titled “5. Capability Access”Once payment is verified, the server processes the capability request and responds with the result:
{ "kind": 25910, "pubkey": "<provider-pubkey>", "content": { "jsonrpc": "2.0", "id": 2, "result": { "content": [ { "type": "text", "text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy" } ], "isError": false } }, "tags": [["e", "<request-event-id>"]]}Payment Request Notification Fields
Section titled “Payment Request Notification Fields”The notifications/payment_required notification params object contains:
amount(required): Numeric payment amountpay_req(required): Payment request data stringdescription(optional): Human-readable payment descriptionpmi(required): Payment Method Identifier stringttl(optional): Time-to-live in seconds for this payment request. If omitted, TTL is PMI-defined and/or implementation-defined._meta(optional): Additional payment metadata object. Use for PMI-specific or implementation-specific fields not standardized by this CEP.
Payment request payload
Section titled “Payment request payload”pay_req is an opaque string.
- It MUST be sufficient for a payment handler that supports the specified
pmito attempt payment. - Its format and interpretation are PMI-defined (see PMI boundaries).
TTL and metadata
Section titled “TTL and metadata”- Some PMIs embed an expiry/TTL in the payment request itself (for example, a Lightning BOLT11 invoice). The optional
ttlfield provides a uniform expiry signal for clients, especially when the PMI payload does not embed one or when clients want a quick hint without parsingpay_req. _metais a general-purpose container for extra fields. Implementations SHOULD ignore unknown_metafields. This CEP does not standardize_metacontents.
Payment Accepted Notification Fields
Section titled “Payment Accepted Notification Fields”The notifications/payment_accepted notification params object contains:
amount(required): Numeric payment amount accepted by the serverpmi(required): Payment Method Identifier string_meta(optional): Additional acceptance metadata object. Use for PMI-specific or implementation-specific fields.
If the server returns change for a bearer-asset direct payment, it SHOULD include a change tag on the event. In that case, amount is the final amount charged for the request.
Payment Rejected Notification Fields
Section titled “Payment Rejected Notification Fields”The notifications/payment_rejected notification params object contains:
pmi(required): Payment Method Identifier string associated with the attempted payment.amount(optional): Numeric amount hint. For example, if a bearer-assetdirect_paymentwas insufficient, servers MAY set this to the required amount.message(optional): Human-readable rejection reason.
notifications/payment_rejectedis a generic negative acknowledgment for CEP-8 payment attempts.- For non-bearer PMIs (for example, invoice-based rails), servers will typically use
notifications/payment_requiredto request the exact amount, andpayment_rejectedMAY be used when an attempted payment cannot be accepted or verified. - Only bearer-asset direct payments can return remainder value via the
changetag.
Optional direct payment (bearer-asset optimization)
Section titled “Optional direct payment (bearer-asset optimization)”Some payment methods are based on bearer assets and can be sent directly with the capability request, avoiding a notifications/payment_required roundtrip.
This CEP defines an optional request tag for such cases:
["direct_payment", "<pmi>", "<payload>"]Where:
<pmi>identifies how to interpret<payload>.<payload>is an opaque string whose format is PMI-defined.
-direct PMI suffix
Section titled “-direct PMI suffix”PMIs that support direct bearer payments SHOULD use the -direct suffix to signal that a client MAY include direct_payment on the request.
Example (conceptual): bitcoin-cashu-v4-direct.
If a server receives a request with a direct_payment tag:
- If the server supports the specified PMI and validates the provided payload, it MAY proceed directly to fulfill the request.
- If the provided payload is valid and its value exceeds the final price, the server MAY return the remainder as change by including a
changetag onnotifications/payment_accepted. - If the server cannot accept the provided payload (for example, invalid or insufficient), it MAY emit
notifications/payment_rejectedand/or fall back to the normal CEP-8 flow (emitnotifications/payment_required), implementation-defined.
Multiple direct_payment tags
Section titled “Multiple direct_payment tags”Clients SHOULD include at most one direct_payment tag. If multiple direct_payment tags are present, servers SHOULD evaluate them in request order and select the first one whose <pmi> the server supports.
Rejection and bearer-asset consumption
Section titled “Rejection and bearer-asset consumption”For bearer-asset PMIs, servers SHOULD treat notifications/payment_rejected as meaning the bearer asset was not consumed/redeemed.
Correlation and Idempotency
Section titled “Correlation and Idempotency”Payment-related notifications MUST include an e tag referencing the original request event id.
Clients MAY retry publishing the same request event (same event id) to achieve idempotent semantics. Servers SHOULD treat duplicate request events with the same id as retries and MUST NOT charge more than once for the same request.
Backward Compatibility
Section titled “Backward Compatibility”This CEP introduces no breaking changes to the existing protocol:
- Existing servers can continue to operate without pricing
- Existing clients continue to work with existing servers
- New pricing is additive - capabilities can be free or paid
- Optional participation: Both providers and clients can choose to participate in pricing
Reference Implementation
Section titled “Reference Implementation”// TODO