Skip to main content

toolbreaker

PyPI version License: MIT CI

Why this exists

AI agents don't fail gracefully. When an upstream tool returns truncated JSON, a 429 Too Many Requests, or a 502 Bad Gateway, the agent doesn't back off — it retries. And retries. And retries. Burning tokens, burning time, and burning your budget on infinite retry loops that never change their arguments.

We call this "tool rot": the silent degradation of agent reliability when external tools fail in realistic ways. Unit tests with 200 OK responses don't catch it. Integration tests against a live MCP server don't catch it either, because they pass until they don't.

toolbreaker is a chaos-engineering harness and circuit breaker for AI agent tools. You wrap your tool functions (sync or async), inject realistic faults, and watch your agent fail — before it fails in production.

What it does

  • Injects faults — truncated JSON, HTTP 429s, latency spikes, stack-trace bombs, empty {"data": null} responses, and server errors
  • Detects retry loops — trips AgentRetryLoopError when an agent calls the same failing tool with the same arguments too many times
  • Preserves signatures — inspect.signature(fn) still works on wrapped functions, so LangChain, MCP, CrewAI, and OpenAI function-calling schemas keep working
  • Deterministic chaos — a seeded random.Random makes CI runs reproducible

Install

pip install toolbreaker

Quickstart

toolbreaker demo

This runs a zero-config simulation comparing a naive retry agent against a resilient one:

┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Tool              ┃ Injected Fault ┃ Calls Made ┃ Loop Status ┃ Verdict     ┃
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ Naive Retry Agent │ server_fault   │ 3          │ Caught      │ LOOP CAUGHT │
│ Resilient Agent   │ server_fault   │ 3          │ Caught      │ LOOP CAUGHT │
└───────────────────┴────────────────┴────────────┴─────────────┴─────────────┘

Pytest plugin

Add --toolbreaker-seed to any test run:

pytest --toolbreaker-seed=42

Use the toolbreaker fixture in your tests:

def test_agent_handles_truncation(toolbreaker):
    harness = toolbreaker  # RotHarness, seeded from --toolbreaker-seed (default 42)
    wrapped_tool = harness.wrap(my_mcp_tool)
    result = wrapped_tool({"query": "users"})
    assert "error" in result or result is not None

If a test fails with AgentRetryLoopError, pytest appends a reproduction line:

Reproduce with: pytest --toolbreaker-seed=42

MCP wrapper example

from toolbreaker import RotHarness, truncate_json, rate_limit

def call_tool(name: str, arguments: dict):
    # your MCP dispatch logic
    ...

harness = RotHarness(
    faults=[truncate_json(ratio=0.5), rate_limit(retry_after=30)],
    seed=42,
)
wrapped = harness.wrap_mcp(call_tool)

wrap_mcp accepts a single call_tool(name, arguments) function or a dict of {tool_name: callable}.

CLI: toolbreaker run

Inspect how your function's output mutates under every built-in fault:

toolbreaker run my_module:my_function

API

from toolbreaker import (
    RotHarness,
    CircuitBreaker,
    AgentRetryLoopError,
    truncate_json,
    rate_limit,
    payload_bomb,
    latency_spike,
    empty_lie,
    server_fault,
)
Fault What it simulates
truncate_json(ratio=0.5) Mid-stream socket drop — output cut in half
rate_limit(retry_after=30) MCP/HTTP 429 — return dict or raise
payload_bomb(size_kb=128) Stack-trace + memory dump — context window overflow
latency_spike(seconds=2.0) Upstream latency — blocking sleep before return
empty_lie() {"status": "success", "data": None} — hallucination bait
server_fault(code=502) Bad Gateway — upstream process crashed

CI

GitHub Actions runs ruff check, ruff format --check, and pytest on Python 3.11, 3.12, and 3.13. Publishing to PyPI happens automatically on GitHub Release via OIDC Trusted Publishing.

License

MIT.# toolbreaker

Metadata

Release files for toolbreaker 0.1.0

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

Source distribution (sdist)

Source distribution for toolbreaker 0.1.0
File Size Uploaded Provenance Actions
toolbreaker-0.1.0.tar.gz 9.1 kB Without provenance Details for toolbreaker-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for toolbreaker 0.1.0
File Interpreter ABI Platform Actions
toolbreaker-0.1.0-py3-none-any.whl Python 3 none any Details for toolbreaker-0.1.0-py3-none-any.whl

Total release size: 19.2 kB

Release files / toolbreaker-0.1.0.tar.gz

Download URL toolbreaker-0.1.0.tar.gz
Size 9.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9507b1769dc5be54ef3a7d489f3c61b8973fb4f98ee6ecded7c34d37041b5bc6
BLAKE2b-256 checksum
How to use checksums
270b88e4b9727ba66b0f6eae41635674394ad367c234aaceef7ac1c135cb3ae3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.1

Release files / toolbreaker-0.1.0-py3-none-any.whl

Download URL toolbreaker-0.1.0-py3-none-any.whl
Size 10.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8ae7baee1e419e2f90faddce1829ba9d7f3747bad0cb753506ad39f06ee7d510
BLAKE2b-256 checksum
How to use checksums
9c74e34d3d4f430953b1619f56c3fabb50f34ff319ea9c36458c67a638075ec2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.1

Security for toolbreaker 0.1.0

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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