Skip to main content

FastAPI for safe AI tools.

Project description

ToolRampart

ToolRampart is a small Python framework for exposing normal Python functions as safe AI-agent tools and MCP-compatible tools.

Positioning:

  • FastAPI for safe AI tools.
  • Give agents tools without giving them unrestricted production access.

It is not an agent framework, chatbot framework, or LangChain replacement. It is a developer-first safety layer around tool execution.

Alpha Status

ToolRampart is currently alpha software. The public API is usable for evaluation, examples, and controlled internal pilots, but production deployments should follow the security notes, threat model, and production checklist in the docs.

Quick Start

Install:

pip install toolrampart

Documentation site:

pip install ".[docs]"
mkdocs serve

AI agents can start from llms.txt and AGENTS.md.

from toolrampart import tool, require_approval, redact, scope, rate_limit, side_effects

@tool
@scope("billing.refund")
@require_approval(over_amount=500)
@redact(["email", "phone", "api_key"])
@rate_limit("10/hour/user")
@side_effects(money_movement=True, writes_data=True)
def refund_user(user_id: str, amount: float, reason: str) -> dict:
    return {
        "status": "refund_started",
        "user_id": user_id,
        "amount": amount,
        "reason": reason,
    }

Run a tool module as an API:

toolrampart serve my_tools

Invoke a tool from Python:

from toolrampart import ToolContext, default_rampart

result = default_rampart.invoke(
    "refund_user",
    {"user_id": "u_123", "amount": 100, "reason": "duplicate charge"},
    ToolContext(actor="support-agent", scopes=["billing.refund"]),
)

What It Does

ToolRampart runs every tool through the same safety pipeline:

  1. Validate inputs from the Python function signature with Pydantic v2.
  2. Check trusted actor scopes.
  3. Run custom policy functions.
  4. Create or verify approval requests for risky calls.
  5. Enforce local or Redis-backed rate limits.
  6. Deduplicate retries with idempotency keys.
  7. Execute with timeout, retry, and optional subprocess isolation controls.
  8. Validate structured return values when annotated.
  9. Emit optional OpenTelemetry spans and metrics.
  10. Write redacted audit logs.

REST API

from toolrampart.app import create_app

app = create_app()

Endpoints:

  • GET /health
  • GET /tools
  • GET /mcp/tools
  • POST /tools/{tool_name}/invoke
  • GET /approvals
  • POST /approvals/{approval_id}/approve
  • POST /approvals/{approval_id}/reject
  • GET /audit
  • GET /metrics
  • GET /dashboard

CLI

toolrampart init
toolrampart list tools
toolrampart call refund_user --target tools --args '{"user_id":"u_1","amount":100,"reason":"duplicate"}' --scope billing.refund
toolrampart approvals list --target tools
toolrampart approvals approve APPROVAL_ID --target tools --actor alice
toolrampart call refund_user --target tools --idempotency-key refund-u_1-001 --args '{"user_id":"u_1","amount":100,"reason":"duplicate"}'
toolrampart serve tools
toolrampart mcp tools

On shells that make inline JSON awkward, write arguments to a file and use:

toolrampart call refund_user --target tools --args-file args.json --scope billing.refund

Python Client

from toolrampart import ToolRampartClient

client = ToolRampartClient("http://localhost:8000", api_key="dev-secret")

result = client.invoke(
    "refund_user",
    {"user_id": "u_1", "amount": 100, "reason": "duplicate"},
    idempotency_key="refund-u_1-001",
)

if result.approval_required:
    client.approve(result.approval_id, actor="alice")

Auth Boundary

REST auth is optional for local development and should be enabled for shared or production use.

ToolRampart supports:

  • API keys through Authorization: Bearer <key> or X-ToolRampart-Key
  • hashed API keys for production configuration and key rotation
  • HS256 JWTs with signed actor and scopes
  • JWKS-backed JWT verification for RS256/ES256 tokens
  • trusted upstream headers: X-ToolRampart-Actor and X-ToolRampart-Scopes

When auth is enabled, the REST request body cannot grant actor identity or scopes. Those come from the authenticator or trusted middleware.

Generate and hash API keys:

toolrampart auth generate-key
toolrampart auth hash-key trp_example_secret

Scopes support exact matches, *, and prefix wildcards such as billing.*.

Idempotency

Use idempotency keys for write tools so agent retries do not duplicate side effects:

from toolrampart import ToolContext, default_rampart

result = default_rampart.invoke(
    "refund_user",
    {"user_id": "u_1", "amount": 100, "reason": "duplicate"},
    ToolContext(actor="agent", scopes=["billing.refund"], idempotency_key="refund-u_1-001"),
)

For REST, send Idempotency-Key or X-Idempotency-Key. ToolRampart replays the completed ToolResult when the same actor/tool/key/arguments are seen again, and returns idempotency_conflict if the key is reused with different arguments.

Subprocess Isolation

Use subprocess isolation for risky or long-running tools that need killable timeouts:

from toolrampart import isolated_process, timeout, tool

@tool
@isolated_process
@timeout(5)
def rebuild_index(index_name: str) -> dict:
    return {"status": "rebuilt", "index_name": index_name}

The function and return value must be pickleable, and the function should be importable at module top level. Closures, local functions, live database clients, and open sockets do not cross a process boundary safely.

OpenTelemetry

Install:

pip install toolrampart[otel]

ToolRampart uses the OpenTelemetry API only. Host applications remain responsible for configuring SDK providers and exporters. When available, ToolRampart emits:

  • toolrampart.tool.invoke spans
  • toolrampart.tool.invocations counter
  • toolrampart.tool.duration histogram

MCP

Install MCP support:

pip install toolrampart[mcp]

Run a stdio MCP server:

TOOLRAMPART_MCP_SCOPES=billing.refund toolrampart mcp tools

ToolRampart uses the official MCP Python SDK as an optional dependency and keeps its own execution pipeline for validation, approvals, rate limits, and audit logging.

Storage

SQLite is the default storage backend and is intended for local development and single-node deployments.

Optional adapters:

  • toolrampart[postgres] for PostgreSQL audit and approval storage
  • toolrampart[redis] for Redis-backed rate limiting
  • toolrampart[otel] for OpenTelemetry API instrumentation
  • toolrampart[all] for MCP, OpenTelemetry, Postgres, and Redis extras

SQLite uses an explicit migration runner. Check local schema state with:

toolrampart migrations status

The CI workflow includes service-container integration tests for Postgres and Redis.

Docker Compose

Run ToolRampart with Postgres and Redis:

docker compose up --build

Then open http://localhost:8000/dashboard.

Current Boundaries

ToolRampart controls whether a tool function is called. It does not magically sandbox all side effects inside the function. For dangerous tools, combine ToolRampart with least-privilege service credentials, network controls, execution timeouts, and approval workflows.

Release Readiness

Before publishing an alpha, run the release checklist in docs/RELEASE.md. The short version is:

python -m pip install -e ".[dev,docs]"
python -m pytest
python -m mkdocs build --strict
python -m build
python -m twine check dist/*

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

toolrampart-0.2.0.tar.gz (64.2 kB view details)

Uploaded Source

Built Distribution

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

toolrampart-0.2.0-py3-none-any.whl (39.6 kB view details)

Uploaded Python 3

File details

Details for the file toolrampart-0.2.0.tar.gz.

File metadata

  • Download URL: toolrampart-0.2.0.tar.gz
  • Upload date:
  • Size: 64.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for toolrampart-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b82ddc650bb92dd53b46128b856cafbed9710fd80b64b2929407a8a0c9e5f00d
MD5 076d476d6ca9378b2fea519f1f986d9f
BLAKE2b-256 f4fb5f33967fb6bdc924108290be0fa4211b859a7e282fcd37fff8e029419eca

See more details on using hashes here.

Provenance

The following attestation bundles were made for toolrampart-0.2.0.tar.gz:

Publisher: release.yml on yuvrajraina/toolrampart

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file toolrampart-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: toolrampart-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 39.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for toolrampart-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8f932f0fb78f5918666b48d28c5f9c987c01602a5d62644d66eca30ae636e759
MD5 d3600e43fd47d3dd600691ad7f00e799
BLAKE2b-256 018c84516b2cc11cf262457a76eeb1a9cb0797efc49cbe093eec8d09f72c4042

See more details on using hashes here.

Provenance

The following attestation bundles were made for toolrampart-0.2.0-py3-none-any.whl:

Publisher: release.yml on yuvrajraina/toolrampart

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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