Skip to main content

Quickstart

Get PayMCP up and running in your MCP server in just a few minutes.

Installation

Install PayMCP:

pip install paymcp

Requirements

  • Python 3.8+ or Node.js 16+
  • An MCP server framework (Official MCP SDK recommended)
  • Hosted server environment (not STDIO mode)
  • API keys from your chosen payment provider

AI Coding Agents (Skills)

If you use an AI coding agent with Skills support, we recommend installing the monetization skill. Skills are folders of instructions and resources that your agent loads when relevant. They teach the agent how to perform specialized tasks like adding pricing, subscriptions, and provider configuration to MCP servers.

Install the monetization skill

If you are using Claude Code, you can install the skill directly with:

/plugin marketplace add PayMCP/skills
/plugin install paymcp@paymcp-skills

You can also use the Vercel Skills CLI to install skills across different AI coding agents:

npx skills add https://github.com/PayMCP/skills --skill monetization

Or copy the skill folder into your agent's skills directory (varies by agent):

AgentSkills directory (macOS/Linux)Skills directory (Windows)
Claude Code~/.claude/skills/%USERPROFILE%\\.claude\\skills\\
VS Code and GitHub Copilot~/.copilot/skills/%USERPROFILE%\\.copilot\\skills\\
Gemini CLI~/.gemini/skills/%USERPROFILE%\\.gemini\\skills\\
Cline~/.cline/skills/%USERPROFILE%\\.cline\\skills\\
Goose~/.config/goose/skills/%USERPROFILE%\\.config\\goose\\skills\\
Codex~/.codex/skills/%USERPROFILE%\\.codex\\skills\\

After installation, you can simply ask your agent to add PayMCP monetization and follow its guided instructions.

Basic Setup

1. Initialize Your MCP Server

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

mcp = FastMCP("My AI Assistant")

2. Configure PayMCP

PayMCP(mcp, providers=[StripeProvider(apiKey="sk_test_...")])

Adding Pricing

@mcp.tool()
@price(amount=0.50, currency="USD")
def generate_ai_image(prompt: str, ctx: Context) -> str:
"""Generate an AI image from a text prompt"""
return f"Generated image for: {prompt}"

Different Price Points

@mcp.tool()
@price(amount=0.05, currency="USD")
def check_text_grammar(text: str, ctx: Context) -> str:
"""Check and correct grammar in text"""
return corrected_text

@mcp.tool()
@price(amount=2.99, currency="USD")
def analyze_document(document: str, ctx: Context) -> dict:
"""Perform detailed document analysis"""
return analysis_results

Subscriptions

Gate tools behind an active subscription instead of pay-by-request.

from paymcp import subscription

@mcp.tool()
@subscription(plan="price_pro_monthly") # or a list of accepted plan IDs
async def generate_report(ctx: Context) -> str:
return "Your report"

Coordination Modes

Choose the mode (AUTO, RESUBMIT, ELICITATION, TWO_STEP, X402, PROGRESS, or DYNAMIC_TOOLS) that works best for your use case:

AUTO (Default)

Automatically detects client capabilities. If X402 is configured and supported by the client, it uses X402; otherwise it uses ELICITATION when supported and falls back to RESUBMIT.

PayMCP(mcp, providers=[StripeProvider(apiKey="sk_test_...")], mode=Mode.AUTO)

RESUBMIT (Retry-after-error)

Adds an optional payment_id to the original tool signature.

PayMCP(mcp, providers=[StripeProvider(apiKey="sk_test_...")], mode=Mode.RESUBMIT)

Call sequence

  1. First call: PayMCP invokes the tool without a payment_id, responds with Payment Required Error containing a payment_url plus payment_id, and instructs the client to retry.
  2. Second call: The client calls the same tool again with the returned payment_id; PayMCP validates payment server-side and runs your original tool logic if paid.

ELICITATION (Interactive)

For real-time interactions.

PayMCP(mcp, providers=[StripeProvider(apiKey="sk_test_...")], mode=Mode.ELICITATION)

Shows payment link immediately when tool is called (if supported by client) Waits for payment confirmation before proceeding

TWO_STEP

Splits tool execution into two steps.

PayMCP(mcp, providers=[StripeProvider(apiKey="sk_test_...")], mode=Mode.TWO_STEP)

Confirmation tool will be added automatically.

X402 (On-chain)

Use this mode only with an x402-capable client and the X402 provider. See the X402 Provider guide for setup details.

PayMCP(mcp, providers=[X402Provider(pay_to=[{"address": "0xAddress"}])], mode=Mode.X402)

By default PayMCP uses the public facilitator at https://facilitator.paymcp.info and no API keys are required. To change facilitators, set facilitator.url. The Coinbase CDP facilitator (https://api.cdp.coinbase.com/platform/v2/x402) requires apiKeyId and apiKeySecret.

PROGRESS (Experimental)

For experimental auto-checking of payment status.

PayMCP(mcp, providers=[StripeProvider(apiKey="sk_test_...")], mode=Mode.PROGRESS)

Shows payment link and progress indicator (if supported by client) Automatically proceeds when payment is received

DYNAMIC_TOOLS (Guided Tool Lists)

For clients that support dynamic tool lists and listChanged notifications:

PayMCP(
mcp,
providers=[StripeProvider(apiKey="sk_test_...")],
mode=Mode.DYNAMIC_TOOLS
)

# Temporarily hides/shows tools to steer the next valid action

See the list of MCP clients and their capabilities here: https://modelcontextprotocol.io/clients

Configuring StateStore

By default, PayMCP uses an in-memory StateStore, which does not persist across server restarts. It's highly recommended to use RedisStateStore in production environments.

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

redis = await from_url("redis://localhost:6379")
PayMCP(
mcp,
providers=[''' ... ''' ],
state_store=RedisStateStore(redis)
)

Testing Your Integration

1. Start Your Server

# server.py
from mcp.server.fastmcp import FastMCP, Context
from paymcp import PayMCP, price
from paymcp.providers import StripeProvider

mcp = FastMCP("Test Server")
PayMCP(mcp, providers=[StripeProvider(apiKey="sk_test_...")])

@mcp.tool()
@price(amount=1.00, currency="USD")
def test_payment_integration(name: str, ctx: Context) -> str:
"""Test payment integration with greeting"""
return f"Hello, {name}! Payment successful."

if __name__ == "__main__":
mcp.run(transport="streamable-http")

2. Connect Your MCP Client

For testing, we recommend using the MCP Inspector.

  1. Run your MCP server code.
  2. Check the console for the /mcp URL (e.g. http://127.0.0.1:8000/mcp).
  3. Start the inspector with:
    npx @modelcontextprotocol/inspector@latest
  4. In MCP Inspector, select streamable HTTP as the transport type and enter your /mcp URL.

3. Use Test Credentials

Always use test/sandbox credentials during development:

  • Stripe: Use sk_test_... keys and test card 4242424242424242
  • PayPal: Set sandbox=True
  • Square: Use sandbox environment
  • Walleot: Use test API keys
  • Coinbase Commerce: No sandbox is available, so test with very small amounts.
  • USDC (Base): Use Base-sepolia network (eip155:84532)
  • USDC (Solana): Use devnet network (solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1)

Next Steps

Basic setup complete! Your MCP tools will now ask for payment before running.

Explore More:

Need help? Check our troubleshooting guide or open an issue.