You build an AI shopping agent that takes "find me a 24,000 mAh power bank under $40", searches Amazon, picks one, and asks for a card that only works once for that amount after the customer approves on their phone.
Link agent payments work for customers in the United States and Canada while the developer and the merchant can be anywhere. A single spend request is capped at $500 and the virtual card is valid for 12 hours from creation. The whole thing is roughly 200 lines of TypeScript and a template repo is linked below.
Get the template repo Stripe Link CLI
What you need
- Use Node.js 20 or newer.
- Use a SerpApi account. The free plan gives 250 searches a month and the Starter plan is $25 a month for 1,000 searches. See SerpApi pricing.
- Use a Link account in the United States or Canada with a card saved, because that account approves and pays.
- Install the Stripe Link CLI as @stripe/link-cli. See stripe/link-cli on GitHub.
- Use a coding agent such as Claude Code, Cursor or Codex to do the typing.
- Host the small Node service somewhere public, because custom connectors are called from Anthropic's cloud and cannot reach localhost.
Step 1: Clone the template and brief your coding agent
git clone https://github.com/dansinger93/shopping-agent-mcp.git
cd shopping-agent-mcp
npm install
cp .env.example .env # SERPAPI_KEY, MCP_BEARER_TOKENThe template is at the template repo and holds three files that matter. src/serpapi.ts handles search and src/link.ts wraps the Link CLI while src/server.ts exposes both as MCP tools. Paste CLAUDE.md into your coding agent as the brief. It lists the tools and the two environment variables SERPAPI_KEY and MCP_BEARER_TOKEN, and it states the one rule that matters: card details never enter the model context.
Step 2: Search Amazon with SerpApi
// src/serpapi.ts
export async function searchAmazon(query: string, domain = 'amazon.com') {
const url = new URL('https://serpapi.com/search');
url.search = new URLSearchParams({
engine: 'amazon',
k: query,
amazon_domain: domain,
s: 'review-rank',
api_key: process.env.SERPAPI_KEY!,
}).toString();
const { organic_results = [] } = await (await fetch(url)).json();
return organic_results
.filter((r: any) => !r.sponsored)
.slice(0, 8)
.map((r: any) => ({
title: r.title,
asin: r.asin,
url: r.link_clean, // https://www.amazon.com/dp/{ASIN}/
price: r.extracted_price, // number; r.price is the display string
rating: r.rating,
reviews: r.reviews,
}));
}The SerpApi Amazon Search API is a GET request with engine=amazon and k as the query. The amazon_domain parameter selects the store and defaults to amazon.com, and s=review-rank sorts by reviews. The code uses title, asin, link_clean, extracted_price, rating and reviews. link_clean is the plain https://www.amazon.com/dp/{ASIN}/ URL and the link field can be a sponsored redirect. extracted_price is a number and price is the display string. The code drops sponsored results and keeps eight, which is enough for the model to choose from without burning context. One search is one SerpApi credit.
