Metadata-Version: 2.1
Name: metrify-sdk
Version: 0.2.3
Summary: Billing SDK for MCP servers
License: MIT
Project-URL: Homepage, https://github.com/mangelico/metrify-sdk
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.0
Requires-Dist: python-dotenv>=1.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: pytest-mock>=3.12; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"

# metrify-sdk

> Billing infrastructure for MCP servers.
> Add one decorator. Start charging. Get paid in USDT.

---

## Installation

```bash
pip install metrify-sdk
```

Requires Python 3.8+

---

## Quickstart (Provider)

**Step 1** — Register at [metrify.dev](https://metrify.dev) and get your `pk_live_...` provider key.

**Step 2** — Install the SDK:

```bash
pip install metrify-sdk
```

**Step 3** — Decorate your tools:

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

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

@mcp.tool()
@m.tool(price=0.01, description="Search the web for a query")
def search(query: str) -> str:
    # Your logic here
    return f"Results for: {query}"

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

---

## How billing works

When a consumer calls your tool, Metrify verifies their balance before execution.
If sufficient, the tool runs. On success, the consumer wallet is debited atomically:
95% goes to you, 5% to Metrify. If your tool raises an exception, the consumer is
not charged.

```
Consumer wallet → [Metrify] → Provider wallet
    $0.01000           ↓          $0.00950
                  fee: $0.00050
```

---

## @m.tool() parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `price` | float | ✓ | Cost per call in USDT |
| `description` | str | ✓ | Tool description shown to agents |

---

## Policy: no charge on upstream error

If your tool raises any exception, the consumer is not charged.
Raise `UpstreamError` explicitly when an external API you depend on fails:

```python
from metrify import Metrify, UpstreamError

m = Metrify(provider_key="your_provider_key")

@m.tool(price=0.05, description="Summarize text using an LLM")
async def summarize(text: str) -> str:
    try:
        result = await llm_client.complete(text)
    except Exception as e:
        raise UpstreamError(f"LLM unavailable: {e}")
    return result
```

The consumer receives your error message and is not charged.
Idempotency keys are implemented from day one — duplicate charges are impossible.

---

## Provider registration

[metrify.dev](https://metrify.dev) — currently invite-only waitlist.

---

## Links

- [metrify.dev](https://metrify.dev)
- [metrify-mcp](https://github.com/mangelico/metrify-mcp) — consumer wallet management MCP server
- [Changelog](https://github.com/mangelico/metrify-sdk/releases)

---

## License

MIT
