Paybond agent middleware is the recommended integration path for multi-tool agents. Call paybond.instrument() to load policy and register tools (deferred by default), then bind() per session, pass a lazy context provider, or use paybond.agent() for sandbox quickstart.
Agent selection rule
- Middleware:
instrument()→ run binding, registry, interceptor, required auto-evidence. - Manual guard: per-tool
guardTool/guard_tool; you callsubmitEvidenceyourself. - Model token caps: use provider-native usage controls — not Paybond.
Public product page: /kit/agent-middleware. Developer reference: /docs/kit/agent-middleware. CLI overview: /kit/cli.
When to use middleware vs manual guard
| Approach | Best for |
|---|---|
| Agent middleware | Multi-tool agents, coding-agent automation, any integration that must not forget evidence on side-effecting tools |
Per-tool guardTool | Single paid handler, legacy code, or advanced cases where you control evidence timing explicitly |
Use middleware when:
- The agent exposes multiple paid or side-effecting tools.
- You want automatic evidence on every successful side-effecting call.
- You need defaultDeny to catch forgotten wraps before production.
- Coding agents or CI should test the full authorize → evidence path without vendor APIs.
Keep per-tool guardTool / guard_tool when:
- You have a single paid tool and full control over evidence timing.
- You are migrating incrementally from an existing guard wrapper.
See Agent integrations for single-handler examples.
Sandbox smoke (no integration code)
Local dev loop (recommended — policy scaffold, validate, smoke, trace URL):
terminal
paybond dev loop --offline # terminal 1
paybond dev trace # terminal 2 — same project directoryWith sandbox credentials:
terminal
paybond login
paybond dev loop
paybond dev traceThe trace dashboard at http://127.0.0.1:9477 renders a vertical timeline (authorize → execute → evidence → settlement). Events persist to .paybond/dev-trace.jsonl so smoke and trace can run in separate terminals. See the middleware trace guide and developer reference for the event model and UI phases.
Manual smoke (explicit flags):
terminal
paybond login
paybond agent sandbox smoke \
--operation paid-tool \
--requested-spend-cents 100 \
--evidence-preset cost_and_completion \
--result-body '{"status":"ok","cost_cents":100}' \
--format jsonFor multi-step runs: paybond agent run bind --sandbox ... then paybond agent tool execute --run-id ..., then paybond agent run trace --run-id ... to inspect authorize → execute → evidence steps from the CLI. See the agent quickstart for paybond dev workflows, middleware trace for the visual dashboard, the agent middleware docs for SDK traceSink, and paybond doctor --agent for the same smoke path in diagnostics.
Trace events (SDK)
The interceptor emits structured events as each side-effecting tool runs: tool_selected → spend_authorized → tool_executed → spend_finalized → evidence_submitted. Pass traceSink on bind to debug denied calls or wire custom telemetry:
paybond-session.ts
const run = await paybond.agentRun.bind({
bootstrap: { kind: "sandbox", operation: "travel.book_hotel", requestedSpendCents: 20_000 },
registry,
traceSink: (event) => console.log(event.type, event),
});paybond dev loop and paybond dev trace collect the same events locally without app code — timeline steps are written to .paybond/dev-trace.jsonl and rendered in the dashboard. For bind → execute workflows, paybond agent run trace --run-id <id> prints the per-run timeline from .paybond/runs/<run_id>.trace.json. Python: trace_sink on agent_run.bind(). Full reference: Trace events and observability.
SDK shape (TypeScript)
paybond-session.ts
import { Paybond } from "@paybond/kit";
const paybond = await Paybond.open({ apiKey: process.env.PAYBOND_API_KEY! });
const instrumented = await paybond.instrument({
policy: "./paybond.policy.yaml", // or preset id "travel"
tools: {
"travel.book_hotel": bookHotel,
searchWeb: searchWeb,
},
});
// Sandbox quickstart: paybond.agent({ policy: "travel", tools }) binds sandbox automatically.
// Production: const runtime = await instrumented.bind({ intentId, capabilityToken });
// Or lazy: instrument({ ..., context: () => activeRequest.paybond })Python: await paybond.instrument(policy=..., tools=...) with the same semantics; await instrumented.bind(...) or context=lambda: ... for lazy binding.
For step-by-step registry and bind control, see Agent middleware docs.
Framework adapters
Shipped adapter packs plug into the same run binding and registry:
| Framework | Doc | Smoke |
|---|---|---|
| Agent-agnostic (default) | /docs/kit/agent-agnostic | paybond agent demo generic smoke |
| LangGraph (TypeScript and Python) | /docs/kit/langgraph | paybond agent demo langgraph smoke |
| Claude Agent SDK (TypeScript and Python) | /docs/kit/claude-agents | paybond agent demo claude-agents smoke |
| Vercel AI SDK (TypeScript only) | /docs/kit/vercel-ai | paybond agent demo vercel-ai smoke |
| OpenAI Agents SDK | /docs/kit/openai-agents | paybond agent demo openai-agents smoke |
| MCP hosts (TypeScript and Python) | /docs/kit/mcp-server | paybond login → paybond-mcp-server (see coding-agent setup) |
| CrewAI (Python only) | /docs/kit/crewai | paybond agent demo crewai smoke |
| Pydantic AI (Python only) | /docs/kit/pydantic-ai | paybond agent demo pydantic-ai smoke |
| Google ADK (TypeScript and Python) | /docs/kit/google-adk | paybond agent demo google-adk smoke |
| Microsoft Agent Framework (Python only) | /docs/kit/microsoft-agent-framework | paybond agent demo microsoft-agent-framework smoke |
| Mastra (TypeScript only) | /docs/kit/mastra | paybond agent demo mastra smoke |
| Cloudflare Agents (TypeScript only) | /docs/kit/cloudflare-agents | paybond agent demo cloudflare-agents smoke |
Planned (use agent-agnostic or MCP today; request an adapter):
| Framework | Doc | Recipe guide |
|---|---|---|
| LlamaIndex Workflows | — | Agent-agnostic spend controls |
Use paybond init agent-middleware --framework <name> to scaffold integration files.
Policy-as-code
For GitOps-friendly configuration, version a paybond.policy.yaml and validate before deploy:
terminal
paybond policy validate-tools --file paybond.policy.yaml --local-only --format jsonBuyer guide: /guides/agent-policy. Remote validation: /docs/kit/agent-policy-validate. Org policy inheritance: /docs/kit/enterprise-policy-inheritance. Long-lived processes: /docs/kit/policy-hot-reload.
Going to production
Sandbox smoke and paybond.agent() never require payee identities or signing seeds. When you attach to a funded production intent, see Production attach for CLI flags, SDK productionEvidence, and env fallbacks.
Performance and latency
Guarded tool calls add serial Gateway and Harbor round trips that usually dominate latency versus local handler time. For an overhead model, authorization-cache behavior, and what dev trace does not measure, see Middleware performance and latency.
Related
- Agent middleware docs
- Agent-agnostic adapter
- Vercel AI adapter
- LangGraph adapter
- Claude Agents adapter
- OpenAI Agents adapter
- MCP server
- CrewAI adapter
- CrewAI spend controls
- Pydantic AI adapter
- Pydantic AI spend controls
- Google ADK adapter
- Google ADK spend controls
- Microsoft Agent Framework adapter
- Microsoft Agent Framework spend controls
- Mastra spend controls
- Cloudflare Agents spend controls
- Agent policy guide
- Agent integrations
- Agent policy validate
- Agent spend controls SDK
- Paybond CLI