Devoured - April 30, 2026
Link CLI (GitHub Repo)

Link CLI (GitHub Repo)

Tech Read original

Stripe released Link CLI, a tool that lets AI agents complete purchases using secure, one-time payment credentials without ever accessing users' real card details.

What: Link CLI is a command-line tool and MCP server from Stripe that provisions temporary, single-use payment credentials from a Link wallet, enabling AI agents to make purchases on behalf of users while keeping actual payment information hidden.
Why it matters: As AI agents become more capable of autonomous task completion, they increasingly need to handle payments, but traditional approaches require exposing sensitive card data. This creates a secure middle ground where users can approve transactions via push notification while agents get just enough credential access to complete the purchase.
Takeaway: Install via npm or npx, authenticate with your Link account, and integrate spend request flows into your agent applications to enable secure autonomous purchases.
Deep dive
  • Agents create spend requests specifying merchant details, line items, and amounts, then receive one-time virtual card credentials (number, CVV, expiration) or shared payment tokens
  • The --request-approval flag triggers push notifications or emails requiring explicit user consent before credentials are provisioned
  • Each spend request includes a context field requiring at least 100 characters explaining the purchase rationale to the user
  • Supports two payment flows: traditional virtual cards for standard checkout forms, and Machine Payments Protocol (HTTP 402) for merchants with native support
  • Runs as both a standalone CLI tool and an MCP (Model Context Protocol) server for integration with Claude and other agent platforms
  • Spend requests have transaction limits (max $500/50,000 cents) and credentials expire after use or time limit
  • Test mode allows development and integration testing without real payment methods using Stripe's test card
  • Polling mechanisms let agents wait for user approval with configurable intervals and timeouts, exiting with specific error codes if requests remain pending
  • Authentication flow shows the connecting agent name in the Link app (e.g., "Claude Code on my-macbook") for transparency
  • The tool never stores or logs real card details—credentials are generated on-demand and scoped to specific merchants
Decoder
  • Link: Stripe's digital wallet product that stores payment methods and generates secure credentials
  • MCP (Model Context Protocol): A protocol that allows AI assistants like Claude to connect to external tools and services
  • Spend request: A request for temporary payment credentials specifying merchant, amount, and context for user approval
  • MPP (Machine Payments Protocol): An HTTP 402-based protocol for programmatic payments where merchants can request payment directly
  • Shared payment token (SPT): A one-time-use payment token for MPP-compatible merchants, alternative to virtual card credentials
  • Virtual card: A temporary card number with CVV and expiration generated specifically for one transaction
Original article

Link CLI

Link CLI lets agents get secure, one-time-use payment credentials from a Link wallet — so they can complete purchases on your behalf without ever storing your real card details.

Installation

npm i -g @stripe/link-cli

Or run directly with npx:

npx @stripe/link-cli

You can install the skill via npx skills add stripe/link-cli.

MCP Server

Link CLI can also run as a local MCP server. Add the following to your MCP client config (.mcp.json, etc.)

{
  "mcpServers": {
    "link": {
      "command": "npx",
      "args": ["@stripe/link-cli", "--mcp"]
    }
  }
}

Quickstart

Login

The link-cli requires a Link account. You can log in to your existing one or register online.

link-cli auth login

You'll receive a verification URL and a short phrase. Visit the URL, log in to your Link account, and enter the phrase to approve the connection.

List payment methods

link-cli payment-methods list

Returns the cards and bank accounts saved to your Link account. Use the id field as payment_method_id in the next step. If you have no payment methods, you can add new ones in Link.

Create a spend request

To request a secure, one-time payment credential from your Link wallet, you create a spend request. You specify a payment method in your account, as well as some merchant details, line items, and amounts.

link-cli spend-request create \
  --payment-method-id csmrpd_xxx \
  --merchant-name "Stripe Press" \
  --merchant-url "https://press.stripe.com" \
  --context "Purchasing 'Working in Public' from press.stripe.com. The user initiated this purchase through the shopping assistant." \
  --amount 3500 \
  --line-item "name:Working in Public,unit_amount:3500,quantity:1" \
  --total "type:total,display_text:Total,amount:3500" \
  --request-approval

The --request-approval flag triggers a push notification (or email) to the user for approval, then polls until the request is approved or denied.

Users can easily approve requests with the Link app.

Credential types

By default, a spend request provisions a virtual card. For merchants that support the Machine Payments Protocol (HTTP 402) and the Stripe payment method, you can instead include --credential-type "shared_payment_token".

Execute payment

The approved spend request includes a card object with number, cvc, exp_month, exp_year, billing_address, and valid_until. Enter these into the merchant's checkout form.

link-cli spend-request retrieve lsrq_001 --format json

By default, retrieving a spend request will not include card details. Use the --include=card to see unmasked card details.

For agent polling, pass --interval and optionally --max-attempts:

link-cli spend-request retrieve lsrq_001 --interval 2 --max-attempts 150 --format json

Polling exits successfully only after the request reaches a terminal status such as approved, denied, or expired. If polling reaches --timeout or exhausts --max-attempts while the request is still non-terminal, the command exits non-zero with code: "POLLING_TIMEOUT" so callers do not treat a still-pending request as complete.

If the merchant supports MPP, use link-cli mpp pay instead:

link-cli mpp pay https://climate.stripe.dev/api/contribute \
  --spend-request-id lsrq_001 \
  --method POST \
  --data '{"amount":100}' \
  --format json

Advanced

Authentication

link-cli auth login --client-name "Claude Code" --format json   # identify the connecting agent
link-cli auth status --format json                               # check auth status
link-cli auth logout --format json                               # disconnect

When --client-name is provided, the name is shown in the Link app when the user approves the connection — e.g. Claude Code on my-macbook instead of link-cli on my-macbook.

auth status --format json includes an update field when a newer version is available:

{
  "authenticated": true,
  "update": {
    "current_version": "0.1.2",
    "latest_version": "0.2.0",
    "update_command": "npm install -g @stripe/link-cli"
  }
}

Set NO_UPDATE_NOTIFIER=1 to suppress update checks (e.g. in CI).

Spend request lifecycle

A spend request moves through: createrequest approvalapproved (with credentials).

Required fields for create: payment_method_id, merchant_name, merchant_url, context, amount

Constraints: context must be at least 100 characters; amount must not exceed 50000 (cents); currency must be a 3-letter ISO code. Test mode: Pass --test to create testmode credentials (uses test card 4242424242424242). Useful for development and integration testing without using real payment methods.

# Update before approval
link-cli spend-request update lsrq_001 \
  --merchant-url https://press.stripe.com/working-in-public \
  --format json

# Request approval separately (alternative to create --request-approval)
link-cli spend-request request-approval lsrq_001 --format json

# Retrieve at any time (includes card credentials once approved)
link-cli spend-request retrieve lsrq_001 --format json

Output formats

All commands accept --format json for structured JSON output. Other formats: yaml, md, jsonl, toon (default). Errors are returned as JSON with code and message fields, with exit code 1.

MPP

Use mpp pay to complete purchases on merchants that use the Machine Payments Protocol. The spend request must use credential_type: "shared_payment_token" and be approved. The SPT is one-time-use — if payment fails, create a new spend request.

link-cli mpp pay https://climate.stripe.dev/api/contribute \
  --spend-request-id lsrq_001 \
  --method POST \
  --data '{"amount":100}' \
  --header "X-Custom: value" \
  --format json

Use mpp decode to validate a raw WWW-Authenticate header and extract the network_id needed for shared_payment_token spend requests:

link-cli mpp decode \
  --challenge 'Payment id="ch_001", realm="merchant.example", method="stripe", intent="charge", request="..."' \
  --format json

Environment variables

Variable Effect
LINK_API_BASE_URL Override the API base URL
LINK_AUTH_BASE_URL Override the auth base URL
LINK_HTTP_PROXY Route all requests through an HTTP proxy (requires undici)

Onboard

Run the guided setup flow — authenticates, checks payment methods, shows the app download QR, and walks through both demo flows:

link-cli onboard

Demo

Run an interactive demo of both Link payment flows (always uses test mode — no real charges):

link-cli demo              # shows menu to choose flow
link-cli demo --only-card  # virtual card flow only
link-cli demo --only-spt   # machine payment (SPT) flow only

Development

pnpm install
pnpm run build
pnpm run link-cli --help

Watch mode:

pnpm run dev

Run tests:

pnpm run test

Type-check and lint:

pnpm run typecheck
pnpm biome check .

Releasing

This project uses Changesets to manage versioning and publishing. Only @stripe/link-cli is published to npm — internal packages (@stripe/link-sdk, @stripe/link-typescript-config) are ignored by changesets.

Add a changeset

When you make a user-facing change, add a changeset before merging:

pnpm changeset

Follow the prompts to select the package (@stripe/link-cli) and the semver bump type (patch, minor, or major). This creates a markdown file in .changeset/ describing the change.

Version

Once changesets have accumulated on main, create a version PR:

pnpm changeset version

This consumes all pending changesets, bumps the version in packages/cli/package.json, and updates CHANGELOG.md.

Publish

After the version PR is merged:

pnpm run build
pnpm changeset publish

This publishes @stripe/link-cli to npm. CI also runs pnpm --filter @stripe/link-cli publish --dry-run --no-git-checks on every push to main to verify the package is publishable.