+ Mercado Pago Agent Toolkit +
++ Agent that drives Mercado Pago billing flows via{" "} + + @ar-agents/mercadopago + {" "} + tools, Vercel AI SDK 6, and AI Gateway. +
++ Pick a prompt above or write your own. +
+ ) : ( + messages.map((m) => ( +diff --git a/solutions/mercadopago-agent-toolkit/.env.example b/solutions/mercadopago-agent-toolkit/.env.example new file mode 100644 index 0000000000..fe0e398785 --- /dev/null +++ b/solutions/mercadopago-agent-toolkit/.env.example @@ -0,0 +1,11 @@ +# Mercado Pago access token from https://www.mercadopago.com.ar/developers/panel/app +# Use TEST- prefix for sandbox, APP_USR- for production. +MP_ACCESS_TOKEN=TEST-... + +# Vercel AI Gateway API key from https://vercel.com/dashboard/ai-gateway +# The Gateway routes the LLM call without exposing your Anthropic key to the client. +AI_GATEWAY_API_KEY= + +# HTTPS URL where MP redirects buyers after the first payment. +# In dev, use a stable tunnel (e.g. https://your-tunnel.ngrok-free.app/done). +NEXT_PUBLIC_BACK_URL=https://example.com/done diff --git a/solutions/mercadopago-agent-toolkit/.gitignore b/solutions/mercadopago-agent-toolkit/.gitignore new file mode 100644 index 0000000000..c21489df93 --- /dev/null +++ b/solutions/mercadopago-agent-toolkit/.gitignore @@ -0,0 +1,42 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files +.env*.local +.env + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/solutions/mercadopago-agent-toolkit/README.md b/solutions/mercadopago-agent-toolkit/README.md new file mode 100644 index 0000000000..8fc3d6d58f --- /dev/null +++ b/solutions/mercadopago-agent-toolkit/README.md @@ -0,0 +1,87 @@ +--- +name: Mercado Pago Agent Toolkit +slug: mercadopago-agent-toolkit +description: A Next.js app where an agent drives Mercado Pago billing flows (Subscriptions, Payments, Refunds, Cuotas) via @ar-agents/mercadopago tools, Vercel AI SDK 6, and AI Gateway. +framework: Next.js +useCase: + - AI + - Edge Functions + - Agents +css: CSS Modules +deployUrl: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fsolutions%2Fmercadopago-agent-toolkit&project-name=mercadopago-agent-toolkit&repository-name=mercadopago-agent-toolkit&env=MP_ACCESS_TOKEN,AI_GATEWAY_API_KEY,NEXT_PUBLIC_BACK_URL&envDescription=API%20keys%20needed%20to%20run%20the%20agent&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fsolutions%2Fmercadopago-agent-toolkit%23environment-variables +demoUrl: https://ar-agents.vercel.app +--- + +# Mercado Pago Agent Toolkit + +A Next.js app where an agent drives [Mercado Pago](https://www.mercadopago.com.ar/developers) billing flows via [`@ar-agents/mercadopago`](https://www.npmjs.com/package/@ar-agents/mercadopago) tools, [Vercel AI SDK 6](https://ai-sdk.dev/), and [AI Gateway](https://vercel.com/docs/ai-gateway). + +The agent picks the right tool from a natural-language prompt: + +- "Cobrale $25.000 mensual a juan@example.com con razón Plan Pro." → `create_subscription` returns an `init_point_url` you send to the customer. +- "Buscá pagos de los últimos 30 días por más de $5.000." → `search_payments` with date + amount filters. +- "Reembolsame el último pago de juan@example.com." → confirms then calls `refund_payment`. + +## Demo + +[ar-agents.vercel.app](https://ar-agents.vercel.app) + +## How it works + +`@ar-agents/mercadopago` ships 89 typed tools across the agent-relevant Mercado Pago API surface (Subscriptions, Payments, Checkout Pro, Marketplace OAuth, Order Management, Customers, Cards, Cuotas, QR, 3DS, Point devices, Stores+POS, Account/Balance/Settlements, Webhooks, Disputes, Lookups, Bank Accounts). + +The example wires those tools into `streamText` from `ai`, picks `anthropic/claude-sonnet-4-6` via the AI Gateway (so the Anthropic key never reaches the client), and renders the result with `useChat` from `@ai-sdk/react`. + +```ts +// app/api/agent/route.ts +const client = new MercadoPagoClient({ + accessToken: process.env.MP_ACCESS_TOKEN!, +}); + +const tools = mercadoPagoTools(client, { + state: new InMemoryStateAdapter(), + backUrl: process.env.NEXT_PUBLIC_BACK_URL!, +}); + +const result = streamText({ + model: "anthropic/claude-sonnet-4-6", + messages: await convertToModelMessages(messages), + tools, + stopWhen: stepCountIs(8), +}); +``` + +Every `POST` against the Mercado Pago API gets an auto-generated idempotency key, so retries do not double-charge. Webhook signature verification (HMAC plus 5-minute replay window), circuit breaker, deadline propagation, and OpenTelemetry instrumentation are available in the same package via subpath imports. + +## Environment variables + +Copy `.env.example` to `.env.local` and fill in: + +| Variable | Required | Where to get it | +| --- | --- | --- | +| `MP_ACCESS_TOKEN` | yes | [Mercado Pago dev panel](https://www.mercadopago.com.ar/developers/panel/app). Use a `TEST-` token for sandbox. | +| `AI_GATEWAY_API_KEY` | yes | [Vercel AI Gateway](https://vercel.com/dashboard/ai-gateway). Required so the LLM call routes through the Gateway and the Anthropic key is never bundled. | +| `NEXT_PUBLIC_BACK_URL` | yes | An HTTPS URL where MP redirects buyers after the first payment. In dev, use a stable tunnel (ngrok, cloudflared, etc.). | + +## Run locally + +```bash +pnpm install +cp .env.example .env.local +# fill in the env vars above +pnpm dev +``` + +Open [http://localhost:3000](http://localhost:3000), pick a suggested prompt, and watch the agent drive the flow. + +## Deploy + +[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fsolutions%2Fmercadopago-agent-toolkit&project-name=mercadopago-agent-toolkit&repository-name=mercadopago-agent-toolkit&env=MP_ACCESS_TOKEN,AI_GATEWAY_API_KEY,NEXT_PUBLIC_BACK_URL) + +## Learn more + +- [`@ar-agents/mercadopago` README](https://github.com/ar-agents/ar-agents/blob/main/packages/mercadopago/README.md) +- [`@ar-agents/mercadopago` AGENTS.md](https://github.com/ar-agents/ar-agents/blob/main/packages/mercadopago/AGENTS.md): tool decision tree, result schemas, error patterns +- [Cookbook](https://github.com/ar-agents/ar-agents/tree/main/packages/mercadopago/cookbook): 9 production recipes (Checkout Pro, SaaS subscription, webhook handler, marketplace OAuth, QR in-store, 3DS challenge, manual capture, recovery patterns, OpenTelemetry) +- [Vercel AI SDK](https://ai-sdk.dev) +- [Vercel AI Gateway](https://vercel.com/docs/ai-gateway) diff --git a/solutions/mercadopago-agent-toolkit/app/api/agent/route.ts b/solutions/mercadopago-agent-toolkit/app/api/agent/route.ts new file mode 100644 index 0000000000..43a675ed7a --- /dev/null +++ b/solutions/mercadopago-agent-toolkit/app/api/agent/route.ts @@ -0,0 +1,41 @@ +import { + MercadoPagoClient, + mercadoPagoTools, + InMemoryStateAdapter, +} from "@ar-agents/mercadopago"; +import { + convertToModelMessages, + stepCountIs, + streamText, + type UIMessage, +} from "ai"; + +export const runtime = "edge"; + +const client = new MercadoPagoClient({ + accessToken: process.env.MP_ACCESS_TOKEN!, +}); + +const tools = mercadoPagoTools(client, { + state: new InMemoryStateAdapter(), + backUrl: process.env.NEXT_PUBLIC_BACK_URL ?? "https://example.com/done", +}); + +export async function POST(req: Request) { + const { messages }: { messages: UIMessage[] } = await req.json(); + + const result = streamText({ + // Vercel AI Gateway routes by string model name; no provider package needed. + model: "anthropic/claude-sonnet-4-6", + system: + "Sos un asistente de billing para una SaaS argentina. " + + "Usás los tools de @ar-agents/mercadopago para crear suscripciones, " + + "cobrar pagos, y consultar estado. Respondé en español rioplatense, " + + "sin emojis, breve.", + messages: await convertToModelMessages(messages), + tools, + stopWhen: stepCountIs(8), + }); + + return result.toUIMessageStreamResponse(); +} diff --git a/solutions/mercadopago-agent-toolkit/app/layout.tsx b/solutions/mercadopago-agent-toolkit/app/layout.tsx new file mode 100644 index 0000000000..cba740e294 --- /dev/null +++ b/solutions/mercadopago-agent-toolkit/app/layout.tsx @@ -0,0 +1,26 @@ +import type { Metadata } from "next"; +import type { ReactNode } from "react"; + +export const metadata: Metadata = { + title: "Mercado Pago Agent Toolkit", + description: + "Agent that drives Mercado Pago billing flows via @ar-agents/mercadopago tools and Vercel AI SDK 6.", +}; + +export default function RootLayout({ children }: { children: ReactNode }) { + return ( + +
+ {children} + + + ); +} diff --git a/solutions/mercadopago-agent-toolkit/app/page.tsx b/solutions/mercadopago-agent-toolkit/app/page.tsx new file mode 100644 index 0000000000..39e574bc9d --- /dev/null +++ b/solutions/mercadopago-agent-toolkit/app/page.tsx @@ -0,0 +1,163 @@ +"use client"; + +import { useChat } from "@ai-sdk/react"; +import { DefaultChatTransport } from "ai"; +import { useState } from "react"; + +export default function Home() { + const [transport] = useState( + () => new DefaultChatTransport({ api: "/api/agent" }), + ); + const { messages, sendMessage, status } = useChat({ transport }); + const [input, setInput] = useState(""); + + const send = (text: string) => { + if (!text.trim() || status === "submitted" || status === "streaming") return; + sendMessage({ text }); + setInput(""); + }; + + return ( ++ Agent that drives Mercado Pago billing flows via{" "} + + @ar-agents/mercadopago + {" "} + tools, Vercel AI SDK 6, and AI Gateway. +
++ Pick a prompt above or write your own. +
+ ) : ( + messages.map((m) => ( +