The Vercel AI SDK runs tools through generateText / streamText with optional toolApproval. Paybond supplies that approval hook and wraps execute on side-effecting tools — spend verify before side effects, auto-evidence after success. Keep your provider client for inference; Paybond guards paid tool calls only.
TypeScript only.
paybond-kitPython rejectsframework: "vercel-ai"(native adapter is@paybond/kit/vercel-ai). Use agent-agnostic spend controls for Python hosts.
Adapter reference: /docs/kit/vercel-ai.
toolApproval with wrapped execute
Harbor authorize runs before side-effecting tools; generateText/streamText stay on your provider.
Auto-evidence
Wrapped execute finalizes spend and submits signed evidence after tool success.
Policy budgets
Versioned YAML caps per-call and intent spend — default-deny for paid tools.
TypeScript only
Native @paybond/kit/vercel-ai adapter; Python hosts use agent-agnostic or another dual-language adapter.
Why Paybond (not just AI SDK guardrails)?
Vercel AI SDK tool 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
- AI SDK alone
- Yes — SDK or host checks and approvals
- With Paybond
- Yes — plus Harbor authorize at the tool boundary
Spend boundary
- AI SDK alone
- No per-tool Harbor budget or capability token
- With Paybond
- Per-call and intent budgets enforced before invoke
Signed evidence
- AI SDK alone
- SDK traces / logs only
- With Paybond
- Signed completion digests bound to the intent
Intent binding
- AI SDK alone
- No Harbor intent or settlement receipt
- With Paybond
- Capability token + intentId from authenticated bind
Paid tool deny / HITL
- AI SDK alone
- Host or SDK approvals only
- With Paybond
- spend verify, deny, or HITL hold before side effects
| Capability | AI SDK 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
generateText / streamText
Vercel AI SDK invokes a side-effecting tool
Paybond toolApproval
Harbor authorize before execute
- Verify spend and operation
- Deny or HITL hold
- Issue / check capability
execute
Your tool handler performs the paid work
Evidence
Wrapped execute finalizes spend + auto-evidence
Paybond supplies toolApproval and wraps execute: Harbor authorize before the tool runs, then auto-evidence after success.
3-minute quickstart
Smoke the vercel-ai adapter sandbox contract — no Vercel credentials required for this check:
terminal
paybond login
paybond agent demo vercel-ai 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 vercel-ai --out paybond-vercel-ai.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 with framework vercel-ai returns agentTools plus toolApproval for generateText/streamText.
paybond-session.ts
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";
import { Paybond } from "@paybond/kit";
const paybond = await Paybond.open({ apiKey: process.env.PAYBOND_API_KEY! });
const { agentTools: tools, toolApproval } = await paybond.agent({
policy: "travel",
framework: "vercel-ai",
tools: {
bookHotel: tool({
description: "Book a hotel room",
inputSchema: z.object({
city: z.string(),
estimatedPriceCents: z.number().int().nonnegative(),
}),
execute: async (args) => bookHotel(args),
}),
searchWeb: tool({
description: "Search the web",
inputSchema: z.object({ query: z.string() }),
execute: async (args) => searchWeb(args),
}),
},
});
const result = await generateText({
model: openai("gpt-4.1"),
tools,
toolApproval,
prompt: "Find hotels in Lisbon and book one under budget.",
});Already bound a run? paybond.wrapTools(run, tools, { framework: "vercel-ai" }) returns { tools, toolApproval } without reloading policy.
For a full App Router example with request-scoped bind, see Next.js agent checkout.
Production: omit sandbox defaults, use deferred bind, then instrumented.bind({ intentId, capabilityToken }) per session.
Production checklist
Production checklist
- Scaffold middleware with paybond init agent-middleware --framework vercel-ai
- Init a policy preset (e.g. travel) and validate tools
- Wire paybond.agent({ framework: "vercel-ai", tools })
- Bind intentId and capabilityToken per session in production
- Smoke with paybond agent demo vercel-ai smoke before ship
Works with
Works with
- Vercel
- OpenAI
- Anthropic
- MCP
Ready to test?
Related guides
- Next.js agent checkout — App Router and Vercel AI
- Agent middleware — lazy context and tenant isolation
- Let agents buy groceries — shopping preset example
Developer reference: /docs/kit/vercel-ai.