Skip to main content

agent-framework-botsrated: BotsRated pre-payment check for Microsoft Agent Framework (Python)

Function middleware for Microsoft Agent Framework that checks an x402 payment with BotsRated before a payment tool runs. BotsRated probes x402 sellers on Base and records which payTo wallet each one actually quoted. The middleware asks BotsRated's free preflight (no API key, no wallet) whether the payTo your agent is about to pay was observed for that seller, and stops the call if it wasn't.

Maintained by BotsRated, not by Microsoft. Issues: https://github.com/botsrated/botsrated/issues/new

Install

pip install agent-framework-botsrated
# with the hosted MCP server example:
pip install "agent-framework-botsrated[mcp]"

Requires Python 3.10+, agent-framework-core>=1.22,<2 and botsrated 0.1.5+ (below 0.2). Tested with agent-framework-core 1.22.0 (with mcp 1.30) and 1.23.0 (with mcp 2.3). agent-framework-core 1.22 can't initialize MCP sessions with mcp 2.x, so pin mcp<2 there if you use the hosted MCP server.

Middleware: check payments before they run

from agent_framework import Agent
from agent_framework_botsrated import BotsRatedPaymentMiddleware


def pay_x402(url: str, pay_to: str, amount: str, network: str = "eip155:8453") -> str:
    """Pay an x402 seller."""
    ...  # your payment code


agent = Agent(
    client=chat_client,
    tools=[pay_x402],
    middleware=[BotsRatedPaymentMiddleware(["pay_x402"])],
)
  • Only the functions you name are checked. Every other function call passes through untouched.
  • The quote is read from the call's arguments: url, pay_to (or payTo), amount (atomic units) and optional network (CAIP-2, default eip155:8453). For other argument names pass an extractor: BotsRatedPaymentMiddleware({"buy": lambda a: PaymentQuote(url=a["endpoint"], pay_to=a["recipient"], amount=str(a["atomic"]))}).
  • A blocked call never reaches call_next. The reason (with a link to the BotsRated probe receipt) becomes the call's result, so the model reads it. With on_block="raise" the run ends with BotsRatedPaymentBlocked (a MiddlewareFailure).
  • The botsrated.Decision is stored in context.metadata["botsrated_decision"]; guard.on_decision is also called.

Default policy (from botsrated.GuardPolicy, configurable through guard=PrePaymentGuard(policy=...)):

Situation Result
payTo never observed by BotsRated for that host (same network) blocked (payto_mismatch)
Quote can't be read from the arguments blocked (quote_unreadable)
Price above the last observed price on the same route allowed with a warning
Host not covered, or data older than 24 h allowed (info)
BotsRated unreachable allowed (fail_open=True); set PrePaymentGuard(fail_open=False) to block

The middleware checks what the payment tool was asked to pay. If your tool fetches the 402 itself and signs it, also register botsrated.PrePaymentGuard().x402_hook on your x402Client's on_before_payment_creation so the check runs on the exact quote being signed, and make the request through guard.wrap_get(...) (or inside with botsrated.paying_request(url):) so the guard checks the host actually being paid rather than the seller-supplied 402 resource.url (botsrated 0.1.5+).

Tool: let the model check a payment option

from agent_framework_botsrated import botsrated_check_payment_tool

agent = Agent(client=chat_client, tools=[botsrated_check_payment_tool(), pay_x402])

botsrated_check_payment(url, pay_to, amount, network) returns JSON with action (allow/block), reasons and receipt_url. It uses the free preflight only.

Hosted MCP server (no package needed)

BotsRated also runs a remote MCP server (streamable HTTP, no auth). Its free tools are preflight, coverage, sample and history:

from agent_framework import MCPStreamableHTTPTool

botsrated_mcp = MCPStreamableHTTPTool(
    name="botsrated",
    url="https://botsrated.com/mcp",
    allowed_tools=["preflight", "coverage", "sample", "history"],
)
async with botsrated_mcp:
    result = await Agent(client=chat_client, tools=[botsrated_mcp]).run("Is blockrun.ai a known x402 seller?")

The paid lookups (check $0.001, report $0.002, best $0.01 USDC on Base; the first 100 checks and 10 reports per client per day are free) are not used by this package unless you pass a paid-enabled BotsRatedClient to the guard.

Run the example and tests

pip install -e ".[mcp]" pytest pytest-asyncio
python examples/quickstart.py   # scripted model, real free preflight, stub payment
pytest -m "not live"            # offline
pytest -m live                  # real free BotsRated preflight + hosted MCP server; nothing is paid

examples/quickstart.py uses a scripted chat client instead of a model, so it runs without an API key. One payment call uses an unknown payTo and is blocked; the other uses the payTo BotsRated observed for blockrun.ai and runs.

BotsRated results are measurements, not endorsements. MIT licensed.

Metadata

Release files for agent-framework-botsrated 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agent-framework-botsrated 0.1.2
File Size Uploaded Provenance
agent_framework_botsrated-0.1.2.tar.gz 10.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for agent-framework-botsrated 0.1.2
File Interpreter ABI Platform
agent_framework_botsrated-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 18.1 kB

Release files / agent_framework_botsrated-0.1.2.tar.gz

Download URL agent_framework_botsrated-0.1.2.tar.gz
Size 10.0 kB
Tags Source
SHA-256 checksum
How to use checksums
d9555a7904cef93388d34cbcfd31a9c60c3c371c222ea1ddd4cc2edc3dc85ce2
BLAKE2b-256 checksum
How to use checksums
f5933248cac84e53662384ebe83c2a5e3758aba9fa96531506d5d815b7896177
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / agent_framework_botsrated-0.1.2-py3-none-any.whl

Download URL agent_framework_botsrated-0.1.2-py3-none-any.whl
Size 8.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c5654c608cd020378785cc1053f5b2ab6491c58ee69c947caa883b1657e7ad40
BLAKE2b-256 checksum
How to use checksums
a106dac705ea2113707000f32d26aa6c8233a273051377c2dac693c3d6828c28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for agent-framework-botsrated 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page