Paybond's recommended default when you have no agent framework SDK — or when you call Claude/Gemini tool-use, a queue worker, or a custom orchestrator directly. One paybond.instrument() call wraps { name, execute } tools with spend verify before side effects and auto-evidence after success.
Adapter reference: /docs/kit/agent-agnostic.
Any { name, execute } surface
Wrap Claude tool-use, Gemini function calls, queue workers, or custom orchestrators.
spend verify before execute
createPaybondGenericAgentConfig authorizes operation and amount before side effects.
Auto-evidence
Wrapped execute finalizes spend and submits signed evidence after tool success.
TypeScript and Python
Same generic path via paybond.instrument() / paybond.agent() on npm and pip.
Why Paybond (not just custom checks)?
Host or model approvals do not enforce a spend limit, a per-operation permission check (capability token), or a signed completion receipt tied to a spend agreement (intent).
Model / input guardrails
- Custom runtime alone
- Yes — SDK or host checks and approvals
- With Paybond
- Yes — plus Harbor authorize at the tool boundary
Spend boundary
- Custom runtime alone
- No per-tool Harbor budget or capability token
- With Paybond
- Per-call and intent budgets enforced before invoke
Signed evidence
- Custom runtime alone
- SDK traces / logs only
- With Paybond
- Signed completion digests bound to the intent
Intent binding
- Custom runtime alone
- No Harbor intent or settlement receipt
- With Paybond
- Capability token + intentId from authenticated bind
Paid tool deny / HITL
- Custom runtime alone
- Host or SDK approvals only
- With Paybond
- spend verify, deny, or HITL hold before side effects
| Capability | Custom runtime 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 | spend verify, deny, or HITL hold before side effects |
How it works
Adapter flow
Orchestrator tool call
Your runtime invokes a registered { name, execute } tool
Paybond wrap
Harbor authorize before your handler runs
- Verify spend and operation
- Deny or HITL hold
- Issue / check capability
Execute
Your handler performs the paid work
Evidence
Wrapped execute finalizes spend + auto-evidence
Paybond wraps generic { name, execute } tools: Harbor authorize before execute, then auto-evidence after success.
3-minute quickstart
Smoke the generic adapter sandbox contract:
terminal
paybond login
paybond agent demo generic smoke \
--operation paid-tool \
--requested-spend-cents 100 \
--evidence-preset cost_and_completion \
--format tableWhen 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 generic --out paybond-agent.ts
paybond policy init --preset travel --out paybond.policy.yamlValidate before deploy:
terminal
paybond policy validate-tools --file paybond.policy.yaml --local-onlyWire middleware
Recommended wiring
paybond.agent without a framework SDK returns tools with PaybondGenericToolCall envelopes so Harbor runs before execute.
paybond-session.ts
import { Paybond } from "@paybond/kit";
const paybond = await Paybond.open({ apiKey: process.env.PAYBOND_API_KEY! });
const { tools, run } = await paybond.agent({
policy: "travel",
tools: {
"travel.book_hotel": bookHotel,
searchWeb: searchWeb,
},
});
// Your orchestrator calls tools with PaybondGenericToolCall envelopes:
const bookHotelTool = tools.find((t) => t.name === "travel.book_hotel")!;
const result = await bookHotelTool.execute({
toolName: "travel.book_hotel",
toolCallId: "call-1",
arguments: { city: "Lisbon", estimatedPriceCents: 18_700 },
});Claude / Gemini tool-use without a framework SDK
Map model function calls to Paybond-wrapped handlers:
- Parse the model's tool call (name, arguments, and call id).
- Find the matching entry in
instrumented.tools. - Call
executewith the Paybond envelope — authorization and evidence run automatically.
For the Claude Agent SDK specifically, use the Claude Agents adapter guide.
Production: omit sandbox defaults, use deferred bind, then instrumented.bind({ intentId, capabilityToken }) per session. Lazy binding: pass context: () => activeRequest.paybond on instrument().
Production checklist
Production checklist
- Scaffold middleware with paybond init agent-middleware --framework generic
- Init a policy preset (e.g. travel) and validate tools
- Wire paybond.agent({ tools }) without a framework SDK
- Bind intentId and capabilityToken per session in production
- Smoke with paybond agent demo generic smoke before ship
Works with
Works with
- Agent-agnostic
- OpenAI
- Anthropic
- Gemini
Ready to test?
Related guides
- Agent middleware — registry, interceptor, evidence
- Express and Fastify agent routes — HTTP servers wrapping instrument()
- Mastra spend controls — native Mastra adapter
- Protect Stripe payments from agents — payment tool example
Developer reference: /docs/kit/agent-agnostic.