The Vercel AI SDK’s tool() helper lets you give a language model structured actions it can invoke during a conversation. By combining tool() with createAgentClient from @meterlane/x402/client, you can expose any Meterlane gateway route as a model-callable tool that handles x402 payment negotiation without any extra logic in your application code.
All examples on this page target Base Sepolia (eip155:84532) and the public sandbox demo route. Do not use mainnet keys in development or CI environments.
Install dependencies
You need the ai package for the tool primitive and generateText, zod for parameter schemas, and @meterlane/x402 for the payment client.npm add ai zod @meterlane/x402
Import the MIT-licensed client entry point — not the server middleware:import { createAgentClient } from "@meterlane/x402/client";
Set your environment variable
Never hard-code your private key in source files or commit it to version control. Read it from AGENT_PRIVATE_KEY at runtime. Use a dedicated hot wallet funded with only the USDC you need for testing.
AGENT_PRIVATE_KEY=0xYOUR_BASE_SEPOLIA_PRIVATE_KEY
Get test USDC from the Circle faucet — select Base Sepolia before requesting.Define the tool
Save the following as vercel-ai-meterlane-tool.ts. The execute function uses paidFetch as a drop-in replacement for fetch; x402 payment is handled automatically on 402 responses.import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";
import type { Hex } from "viem";
import { createAgentClient } from "@meterlane/x402/client";
const privateKey = process.env.AGENT_PRIVATE_KEY as Hex | undefined;
if (!privateKey?.startsWith("0x")) {
throw new Error("Set AGENT_PRIVATE_KEY to a 0x-prefixed Base Sepolia funded key");
}
// Drop-in fetch replacement — pays 402 automatically
const paidFetch = createAgentClient(privateKey, "eip155:84532");
const gatewayBase =
process.env.GATEWAY_URL ?? "https://gateway.meterlane.app";
const orgSlug = process.env.ORG_SLUG ?? "demo";
export const meterlanePaidGet = tool({
description:
"Fetch a Meterlane gateway route. Pays x402 automatically on HTTP 402 using USDC on Base Sepolia.",
parameters: z.object({
path: z
.string()
.describe("Route path under /gateway/:orgSlug, e.g. /demo"),
}),
execute: async ({ path }) => {
const normalized = path.startsWith("/") ? path : `/${path}`;
const url = `${gatewayBase}/gateway/${orgSlug}${normalized}`;
const res = await paidFetch(url, { method: "GET" });
const text = await res.text();
return {
status: res.status,
paymentReceipt:
res.headers.get("PAYMENT-RESPONSE") ??
res.headers.get("X-PAYMENT-RESPONSE") ??
null,
bodyPreview: text.slice(0, 500),
};
},
});
Call the tool and optionally attach it to a model
You can invoke the tool directly for testing, or pass it to generateText so the model decides when to call it:async function main() {
// Direct invocation — no model required, useful for smoke testing payment
const result = await meterlanePaidGet.execute!({ path: "/demo" }, {
messages: [],
toolCallId: "test",
});
console.log("Direct result:", JSON.stringify(result, null, 2));
// Model-driven invocation — requires OPENAI_API_KEY
if (process.env.OPENAI_API_KEY) {
const { text } = await generateText({
model: openai("gpt-4o-mini"),
tools: { meterlanePaidGet },
maxSteps: 3,
prompt:
"Call meterlanePaidGet with path /demo and summarize the HTTP status and response.",
});
console.log("Model output:", text);
}
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
Run the file:AGENT_PRIVATE_KEY=0xYOUR_KEY npx tsx vercel-ai-meterlane-tool.ts
A successful paid call returns "status": 200 and a bodyPreview with the upstream API response.tool.execute signature requirements vary by ai package version. If your version only supports tools inside generateText, pass tools: { meterlanePaidGet } directly and let the model invoke it rather than calling .execute manually.
How it works
The execute handler calls paidFetch instead of native fetch. When the Meterlane gateway returns 402, @meterlane/x402/client reads the X-Payment-Requirements header, uses ExactEvmScheme to produce an ERC-3009 USDC authorization signed by your private key on Base Sepolia, and retries the request with the authorization header attached. The second request receives 200 and the tool returns the response body to the model.
The tool also forwards the settlement receipt header (PAYMENT-RESPONSE) back to the model so it has an on-chain record of the payment if needed.