Pydantic AI agents call tools through Tool instances and plain callables. Paybond hooks that execution boundary — Harbor verify before side-effecting tools execute, then auto-evidence after success. Model inference stays on your provider client.
Python only — install paybond-kit[pydantic-ai] for the native adapter.
Adapter reference: /docs/kit/pydantic-ai.
Harbor verify before Tool
Wrapped Tool / callable handlers authorize operation and amount before paid work.
Auto-evidence
Guarded tools finalize spend and submit signed evidence after success.
Policy budgets
Versioned YAML caps per-call and intent spend for type-safe Python agents.
Python native
Install paybond-kit[pydantic-ai] — TypeScript stacks use agent-agnostic or another adapter.
Why Paybond (not just Pydantic AI checks)?
Pydantic AI prepare hooks and host approvals do not enforce Harbor spend budgets, capability tokens, or signed completion evidence bound to an intent.
Model / input guardrails
- Pydantic AI alone
- Yes — SDK or host checks and approvals
- With Paybond
- Yes — plus Harbor authorize at the tool boundary
Spend boundary
- Pydantic AI alone
- No per-tool Harbor budget or capability token
- With Paybond
- Per-call and intent budgets enforced before invoke
Signed evidence
- Pydantic AI alone
- SDK traces / logs only
- With Paybond
- Signed completion digests bound to the intent
Intent binding
- Pydantic AI alone
- No Harbor intent or settlement receipt
- With Paybond
- Capability token + intentId from authenticated bind
Paid tool deny / HITL
- Pydantic AI alone
- Host or SDK approvals only
- With Paybond
- Harbor verify, deny, or HITL hold before side effects
| Capability | Pydantic AI alone | With Paybond |
|---|---|---|
| Model / input guardrails | Yes — SDK or host checks and approvals | Yes — plus Harbor authorize at the tool boundary |
| Spend boundary | No per-tool Harbor budget or capability token | Per-call and intent budgets enforced before invoke |
| Signed evidence | SDK traces / logs only | Signed completion digests bound to the intent |
| Intent binding | No Harbor intent or settlement receipt | Capability token + intentId from authenticated bind |
| Paid tool deny / HITL | Host or SDK approvals only | Harbor verify, deny, or HITL hold before side effects |
How it works
Adapter flow
Tool / callable
Pydantic AI agent invokes a side-effecting tool
Paybond wrap
Harbor authorize before your handler runs
- Verify spend and operation
- Deny or HITL hold
- Issue / check capability
Tool runs
Your tool body performs the paid work
Evidence
Wrapped tool finalizes spend + auto-evidence
Paybond wraps Pydantic AI Tool / callable handlers: Harbor authorize before the tool runs, then auto-evidence after success.
Python native adapter
Install pip install "paybond-kit[pydantic-ai]". TypeScript stacks should use agent-agnostic spend controls or another framework adapter.
3-minute quickstart
Smoke the pydantic-ai adapter Harbor contract:
terminal
paybond login
paybond agent demo pydantic-ai smoke \
--operation paid-tool \
--requested-spend-cents 100 \
--evidence-preset cost_and_completion \
--format tableInstall the extra first:
terminal
pip install "paybond-kit[pydantic-ai]"When the smoke succeeds you should see:
- ✓ Spend approved
- ✓ Tool completed
- ✓ Evidence verified (
cost_and_completion)
What success looks like
What success looks like
Authorized tool call · illustrative
- Operation
- paid-tool
- Status
- Approved
- Requested
- $1.00
- Evidence
- Verified
- Preset
- cost_and_completion
Scaffold
terminal
paybond init agent-middleware --framework pydantic-ai --out paybond_pydantic_ai.py
paybond policy init --preset saas --out paybond.policy.yamlWire middleware
Recommended wiring
paybond.agent with framework pydantic-ai returns guarded agent_tools for your Pydantic AI Agent.
paybond_session.py
from pydantic_ai import Agent, Tool
from paybond_kit import Paybond
paybond = await Paybond.open(api_key=os.environ["PAYBOND_API_KEY"])
def book_flight(amount_cents: int) -> dict:
"""Book a flight."""
...
result = await paybond.agent(
policy="./paybond.policy.yaml",
framework="pydantic-ai",
tools=[book_flight, search_catalog],
)
agent = Agent("openai:gpt-4o", tools=result.tools)Manual hook wiring
When you already bound a PaybondAgentRun:
paybond_session.py
from paybond_kit.pydantic_ai import create_paybond_pydantic_ai_config
config = create_paybond_pydantic_ai_config(run, tools)
guarded_tools = config.tools
# Or wrap incrementally: config.wrap_tool(new_tool)Approval holds: when Harbor returns an approval hold, guarded tools raise pydantic_ai.ModelRetry with a Paybond message. Approve in the tenant console, then retry with the same operation, amount, metadata, and approvalToken. Hard denials must not execute the tool.
Bypass classes: provider native tools, unwrapped MCP/toolsets, and tools registered with @agent.tool without going through Paybond wrap are not governed.
Production checklist
Production checklist
- Scaffold middleware with paybond init agent-middleware --framework pydantic-ai
- Init a policy preset (e.g. saas) and validate tools
- Wire paybond.agent(framework="pydantic-ai", tools=...)
- Bind intentId and capabilityToken per session in production
- Smoke with paybond agent demo pydantic-ai smoke before ship
Works with
Works with
- Pydantic AI
- OpenAI
- Anthropic
- MCP
Ready to test?
Related guides
- Agent middleware — run binding and policy hot-reload
- Agent policy-as-code — long-lived agents with GitOps YAML
- Agent-agnostic spend controls — fallback for mixed runtimes
Developer reference: /docs/kit/pydantic-ai.