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(orpayTo),amount(atomic units) and optionalnetwork(CAIP-2, defaulteip155: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. Withon_block="raise"the run ends withBotsRatedPaymentBlocked(aMiddlewareFailure). - The
botsrated.Decisionis stored incontext.metadata["botsrated_decision"];guard.on_decisionis 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.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| agent_framework_botsrated-0.1.1.tar.gz | 9.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agent_framework_botsrated-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.9 kB
Release files / agent_framework_botsrated-0.1.1.tar.gz
| Download URL | agent_framework_botsrated-0.1.1.tar.gz |
|---|---|
| Size | 9.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f0116d09cf78afaad828cd1a8c4c5436316683df0c31839f86c92e36fe178673
|
|
BLAKE2b-256 checksum How to use checksums |
ca893424b187b101473b0c039ab8cd1e694817f238632dad95299682ab538a6c
|
| 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.1-py3-none-any.whl
| Download URL | agent_framework_botsrated-0.1.1-py3-none-any.whl |
|---|---|
| Size | 8.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
32d97782dc24f0c7857b077d1a7c68cc176a711296b0f5eb897049b6e8f35da4
|
|
BLAKE2b-256 checksum How to use checksums |
f0a86fe28ac0d1a7a457ba93ec061d348c4a47891ed92cfdc0efcb5e17f61b57
|
| 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.1
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.