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
Prefer middleware for multi-tool agents
When building agents with several side-effecting tools, start with paybond.instrument() or paybond.wrapTools() / paybond.wrap_tools(). Reserve per-tool guardTool / guard_tool for single-handler integrations or advanced evidence timing.
- 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:
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 + 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)
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 + 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 + Python) | /docs/kit/langgraph | paybond agent demo langgraph smoke |
| Claude Agent SDK (TypeScript + 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 (TypeScript only) | /docs/kit/openai-agents | paybond agent demo openai-agents smoke |
| MCP hosts (TypeScript + Python) | /docs/kit/mcp-server | paybond login → paybond-mcp-server (see coding-agent setup) |
Planned (use agent-agnostic or MCP today; request an adapter):
| Framework | Doc | Recipe guide |
|---|---|---|
| Mastra | /docs/kit/mastra | /guides/mastra-spend-controls |
| CrewAI | /docs/kit/crewai | — |
| Cloudflare Agents | /docs/kit/cloudflare-agents | /guides/cloudflare-agents-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. Enterprise org 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.
Related
- Agent middleware docs
- Agent-agnostic adapter
- Vercel AI adapter
- LangGraph adapter
- Claude Agents adapter
- OpenAI Agents adapter
- MCP server
- Mastra spend controls (planned adapter)
- CrewAI adapter (planned)
- Cloudflare Agents spend controls (planned adapter)
- Agent policy guide
- Agent integrations
- Agent policy validate
- Agent spend controls SDK
- Paybond CLI