Skip to main content

Billing SDK for MCP servers

Project description

metrify

Billing SDK for MCP servers. Add pay-per-call monetization to any MCP tool in under 5 minutes — no payment infrastructure required.


Quickstart

1. Register as a provider

Sign up at the Metrify dashboard and get your pk_live_... provider key.

2. Install the SDK

pip install metrify

3. Configure your provider key

export METRIFY_PROVIDER_KEY="pk_live_your_key_here"

Or pass it directly in code (see step 4).

4. Decorate your tools

from metrify import Metrify

m = Metrify()  # reads METRIFY_PROVIDER_KEY from env

@m.tool(price=0.01, unit="per_call")
async def summarize(consumer_api_key: str, text: str) -> str:
    # Balance is pre-checked before this runs; charge happens only on success
    return f"Summary of: {text[:50]}..."

5. Deploy

Your tool now charges consumers on every call. The consumer_api_key is extracted automatically by the decorator — consumers pass it as the first argument or as a keyword argument.


Full example with FastMCP

from metrify import Metrify
from mcp.server.fastmcp import FastMCP

m = Metrify(provider_key="pk_live_your_key_here")
server = FastMCP("my-mcp-server")

@server.tool()
@m.tool(price=0.05, unit="per_call")
async def analyze_document(consumer_api_key: str, content: str) -> str:
    """Analyze a document and return insights."""
    # billing.charge() runs before this line
    analysis = await run_analysis(content)
    return analysis

@server.tool()
@m.tool(price=0.001, unit="per_token")
async def generate_text(consumer_api_key: str, prompt: str) -> str:
    """Generate text from a prompt."""
    result = await llm.complete(prompt)
    return result

Billing flow

The decorator runs a two-phase billing flow on every call:

  1. Pre-check — verify the consumer has enough balance (no charge yet).
  2. Execute — run your tool function.
  3. Charge — deduct only if the function completed without error.

If the function raises any exception the consumer is never charged.

Exception reference

Exception Raised by Behavior
InsufficientBalanceError Pre-check Propagated — consumer has no funds
UpstreamError Your tool Caught — returns message to consumer, no charge
ProviderSuspendedError Pre-check / charge Propagated — your account is suspended
ConsumerSuspendedError Pre-check / charge Propagated — consumer account is suspended
ProviderNotFoundError Pre-check / charge Propagated — your provider key is invalid
GatewayError Pre-check / charge Propagated — network error or backend 5xx
Any other Exception Your tool Caught — returns "Tool error: ...", no charge

Signalling upstream failures with UpstreamError

Use UpstreamError when an external API your tool depends on fails. The decorator catches it, skips billing, and returns your message to the consumer:

from metrify import Metrify, UpstreamError

m = Metrify()

@m.tool(price=0.05, unit="per_call")
async def summarize(consumer_api_key: str, text: str) -> str:
    try:
        result = await anthropic_client.messages.create(...)
    except anthropic.APIError as e:
        raise UpstreamError(f"Anthropic API error: {e.message}")
    return result.content[0].text

The consumer receives "Anthropic API error: ..." and is not charged.

from metrify.exceptions import InsufficientBalanceError, GatewayError

# In your MCP server error handler:
try:
    result = await my_tool(consumer_api_key=ck, query=q)
except InsufficientBalanceError:
    return "Insufficient balance. Please top up at the Metrify dashboard."
except GatewayError:
    return "Billing service temporarily unavailable. Please retry."

Environment variables

Variable Default Description
METRIFY_PROVIDER_KEY Your provider key (pk_live_...)
METRIFY_GATEWAY_URL https://airy-wholeness-production-fcc4.up.railway.app Override backend URL

Supported billing units (V1)

All units charge a flat price per call. The unit field is displayed in your dashboard for reporting purposes.

Unit Use case
per_call Fixed price per tool invocation
per_token LLM completions (flat in V1)
per_minute Audio/video processing
per_image Image generation or analysis
per_page Document processing

License

MIT

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

metrify_sdk-0.1.0.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

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

metrify_sdk-0.1.0-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

File details

Details for the file metrify_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: metrify_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.4

File hashes

Hashes for metrify_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ac7205dda15b0dc6ff91b7dd6f06b60aa8546ca7ab05381fe7e01177c73383e3
MD5 58343701443afb226671638bb016ab91
BLAKE2b-256 435ff845f3c8c83bd133a6c3f66810858dd00b6239e25b36bddb875f646f9088

See more details on using hashes here.

File details

Details for the file metrify_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: metrify_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.4

File hashes

Hashes for metrify_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7ead36337d53c1d76b97b2956a6e29444afbbdf9d35b4842b18f94ec1b22bb25
MD5 ede0889443c877ae4c2bff4045a2f44a
BLAKE2b-256 69c0b57a927732197d1c773261a98b1e9be0af1bf0e667f2d9de2de8249101d0

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