Skip to main content

Provider-agnostic payment layer for MCP (Model Context Protocol) tools and agents.

Project description

PayMCP

Provider-agnostic payment layer for MCP (Model Context Protocol) tools and agents.

paymcp is a lightweight SDK that helps you add monetization to your MCP‑based tools, servers, or agents. It supports multiple payment providers and integrates seamlessly with MCP's tool/resource interface.

See the full documentation.


🔧 Features

  • ✅ Add @price(...) decorators to your MCP tools to enable payments
  • 🔁 Choose between different payment flows (elicit, progress, dynamic_tools, etc.)
  • 🔌 Built-in support for major providers (see list) — plus a pluggable interface for custom providers.
  • ⚙️ Easy integration with FastMCP or other MCP servers

🚀 Quickstart

Install the SDK from PyPI:

pip install mcp paymcp

Initialize PayMCP:

import os
from mcp.server.fastmcp import FastMCP, Context
from paymcp import PaymentFlow, price
from paymcp.providers import StripeProvider

mcp = FastMCP("AI agent name")

PayMCP(
    mcp,
    providers=[
        StripeProvider(api_key=os.getenv("STRIPE_API_KEY")),
    ],
    payment_flow=PaymentFlow.TWO_STEP # optional, TWO_STEP (default) / ELICITATION / PROGRESS / DYNAMIC_TOOLS
)

Use the @price decorator on any tool:

@mcp.tool()
@price(amount=0.99, currency="USD")
def add(a: int, b: int, ctx: Context) -> int: # `ctx` is required by the PayMCP tool signature — include it even if unused
    """Adds two numbers and returns the result."""
    return a + b

Demo server: For a complete setup, see the example repo: python-paymcp-server-demo.

🧭 Payment Flows

The payment_flow parameter controls how the user is guided through the payment process. Choose the strategy that fits your use case:

  • PaymentFlow.TWO_STEP (default)
    Splits the tool into two separate MCP methods.
    The first step returns a payment_url and a next_step method for confirmation.
    The second method (e.g. confirm_add_payment) verifies payment and runs the original logic.
    Supported in most clients.

  • PaymentFlow.ELICITATION Sends the user a payment link when the tool is invoked. If the client supports it, a payment UI is displayed immediately. Once the user completes payment, the tool proceeds.

  • PaymentFlow.PROGRESS
    Shows payment link and a progress indicator while the system waits for payment confirmation in the background. The result is returned automatically once payment is completed.

  • PaymentFlow.DYNAMIC_TOOLS Steer the client and the LLM by changing the visible tool set at specific points in the flow (e.g., temporarily expose confirm_payment_*), thereby guiding the next valid action.

All flows require the MCP client to support the corresponding interaction pattern. When in doubt, start with TWO_STEP.


🗄️ State Storage

By default, when using the TWO_STEP payment flow, PayMCP stores pending tool arguments (for confirming payment) in memory using a process-local Map. This is not durable and will not work across server restarts or multiple server instances (no horizontal scaling).

To enable durable and scalable state storage, you can provide a custom StateStore implementation. PayMCP includes a built-in RedisStateStore, which works with any Redis-compatible client.

from redis.asyncio import from_url
from paymcp import PayMCP, RedisStateStore

redis = await from_url("redis://localhost:6379")
PayMCP(
    mcp,
    providers=[
        StripeProvider(api_key=os.getenv("STRIPE_API_KEY")),
    ],
    state_store=RedisStateStore(redis)
)

🧩 Supported Providers

Built-in support is available for the following providers. You can also write a custom provider.

🔌 Writing a Custom Provider

Any provider must subclass BasePaymentProvider and implement create_payment(...) and get_payment_status(...).

from paymcp.providers import BasePaymentProvider

class MyProvider(BasePaymentProvider):

    def create_payment(self, amount: float, currency: str, description: str):
        # Return (payment_id, payment_url)
        return "unique-payment-id", "https://example.com/pay"

    def get_payment_status(self, payment_id: str) -> str:
        return "paid"

PayMCP(mcp, providers=[MyProvider(api_key="...")])

📄 License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

paymcp-0.3.1.tar.gz (58.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

paymcp-0.3.1-py3-none-any.whl (32.2 kB view details)

Uploaded Python 3

File details

Details for the file paymcp-0.3.1.tar.gz.

File metadata

  • Download URL: paymcp-0.3.1.tar.gz
  • Upload date:
  • Size: 58.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.26.0 CPython/3.10.14 Darwin/24.3.0

File hashes

Hashes for paymcp-0.3.1.tar.gz
Algorithm Hash digest
SHA256 67b799e3345e3ec4b64316ab3115bbf6232ed7dafbc551dc0099d529b802472d
MD5 0c85e6c80fdeb81fefb5a269d52232ca
BLAKE2b-256 600bca88610040fe87d96a81e0dbe2298c81b820641d879e979535500965e981

See more details on using hashes here.

File details

Details for the file paymcp-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: paymcp-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 32.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.26.0 CPython/3.10.14 Darwin/24.3.0

File hashes

Hashes for paymcp-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dc89149f9929c2c9f5dd0dd68ac16e7a2fb0b074550066206786baf1858633a7
MD5 f0e9e9a09aa68f007aa964707763e19d
BLAKE2b-256 5322a406558be378bc9ae6db9f2b6b451e86ae1ed725fa152c2d0b141dbbf1b7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page