MCPInstall

stripe-link-cli

Enable AI agents to request payment credentials from Link wallets for secure purchases without exposing real card details

Installs
220
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/reason-machines/devtools-skills --skill stripe-link-cli
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads stripe-link-cli automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Stripe Link CLI

Skill by ara.so — Devtools Skills collection.

Link CLI lets AI agents get secure, one-time-use payment credentials from a Link wallet to complete purchases on your behalf. Your real card details are never exposed — you approve every purchase through the Link mobile app. The CLI can produce virtual cards (PAN) for standard web checkouts or Shared Payment Tokens (SPT) for Machine Payment Protocol (MPP) merchants.

Installation

npm i -g @stripe/link-cli

Or run directly with npx:

npx @stripe/link-cli

Agent Integration

Install as a skill:

npx skills add stripe/link-cli

By default, commands use toon output (compact, LLM-friendly text) when called from agents (non-TTY). All commands accept --format [json|yaml|md|jsonl] for structured output.

MCP Server

Add to your MCP client config (.mcp.json):

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

Authentication

Before using Link CLI, authenticate with a Link account:

# Login with custom client name for identification
link-cli auth login --client-name "Claude Code"

# Check authentication status
link-cli auth status

# Logout
link-cli auth logout

The login flow provides a verification URL and short phrase. The user visits the URL, logs in to Link, and enters the phrase to approve the connection.

Using custom auth file:

# Store credentials in specific file
link-cli auth login --auth /path/to/auth.json

# Use credentials from specific file (all commands)
link-cli payment-methods list --auth /path/to/auth.json

Or set LINK_AUTH_FILE environment variable:

export LINK_AUTH_FILE=/path/to/auth.json
link-cli payment-methods list

Payment Methods & Addresses

List Payment Methods

# List all saved payment methods
link-cli payment-methods list

# JSON output
link-cli payment-methods list --format json

Returns cards and bank accounts saved to the Link account. Use the id field as payment_method_id when creating spend requests.

List Shipping Addresses

# List saved shipping addresses
link-cli shipping-address list

# JSON output
link-cli shipping-address list --format json

Spend Requests

A spend request is a request for payment credentials tied to a specific purchase. The lifecycle: create → request approval → approved (with credentials).

Create Spend Request

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 to learn about open source sustainability." \
  --amount 3500 \
  --line-item "name:Working in Public,unit_amount:3500,quantity:1" \
  --total "type:total,display_text:Total,amount:3500" \
  --request-approval

Required fields:

  • --payment-method-id: ID from payment-methods list
  • --merchant-name: Merchant display name
  • --merchant-url: Merchant website URL
  • --context: Detailed description (minimum 100 characters)
  • --amount: Total amount in cents (max 50000)

Optional fields:

  • --currency: 3-letter ISO code (default: usd)
  • --credential-type: virtual_card (default) or shared_payment_token
  • --shipping-address-id: ID from shipping-address list
  • --request-approval: Request approval immediately after creation

Constraints:

  • context must be at least 100 characters
  • amount must not exceed 50000 cents
  • currency must be valid 3-letter ISO code

Line Items Format

Use repeatable --line-item flags with key:value pairs:

--line-item "name:Running Shoes,unit_amount:12000,quantity:1,description:Trail runners,sku:SKU-123" \
--line-item "name:Socks,unit_amount:1500,quantity:2"

Available keys:

  • name (required)
  • quantity
  • unit_amount
  • description
  • sku
  • url
  • image_url
  • product_url

Totals Format

Use repeatable --total flags:

--total "type:subtotal,display_text:Subtotal,amount:12000" \
--total "type:shipping,display_text:Shipping,amount:500" \
--total "type:tax,display_text:Tax,amount:950" \
--total "type:total,display_text:Total,amount:13450"

Required keys:

  • type: One of subtotal, tax, total, items_base_amount, items_discount, discount, fulfillment, shipping, fee, gift_wrap, tip, store_credit
  • display_text
  • amount

Test Mode

Create test credentials without real payment methods:

link-cli spend-request create \
  --test \
  --payment-method-id pm_test_card \
  --merchant-name "Test Merchant" \
  --merchant-url "https://example.com" \
  --context "Testing payment flow with test credentials. This is a development test to verify the integration before using real payment methods." \
  --amount 1000 \
  --line-item "name:Test Item,unit_amount:1000,quantity:1" \
  --total "type:total,display_text:Total,amount:1000"

Retrieve Spend Request

# Basic retrieval (card masked)
link-cli spend-request retrieve lsrq_001

# Include unmasked card details
link-cli spend-request retrieve lsrq_001 --include card

# Write card to secure file (stdout shows redacted data only)
link-cli spend-request retrieve lsrq_001 \
  --include card \
  --output-file /tmp/link-card.json \
  --format json

When using --output-file:

  • File is created with 0600 permissions
  • Command fails if file exists unless --force is passed
  • Stdout shows redacted card data (brand, last4, expiry)
  • Full card details written to file
  • JSON output includes card_output_file path instead of full card object

Polling for Approval

// Poll until terminal status (approved, denied, expired, canceled)
link-cli spend-request retrieve lsrq_001 \
  --interval 2 \
  --max-attempts 300

Polling exits successfully only when the request reaches a terminal status. If polling times out or exhausts attempts while the request is still pending, the command exits with non-zero status and code: "POLLING_TIMEOUT".

Update Spend Request

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

Request Approval

# Request approval separately (alternative to --request-approval flag)
link-cli spend-request request-approval lsrq_001

Cancel Spend Request

# Cancel from any non-terminal state
link-cli spend-request cancel lsrq_001

Using Credentials

Virtual Card Checkout

After approval, retrieve the spend request with card details:

link-cli spend-request retrieve lsrq_001 --include card --output-file /tmp/card.json --format json

The card object includes:

  • number: Full card number
  • cvc: CVV/CVC code
  • exp_month: Expiration month
  • exp_year: Expiration year
  • billing_address: Address object
  • valid_until: Timestamp when credentials expire

Enter these details into the merchant's checkout form.

TypeScript example:

import { readFileSync } from 'fs';

// Read card from secure file
const cardData = JSON.parse(readFileSync('/tmp/card.json', 'utf8'));
const card = cardData.card;

// Use card details in checkout automation
await fillCheckoutForm({
  cardNumber: card.number,
  cvc: card.cvc,
  expMonth: card.exp_month,
  expYear: card.exp_year,
  billingAddress: card.billing_address
});

Machine Payment Protocol (MPP)

For merchants supporting MPP, create a spend request with credential_type: shared_payment_token:

# Create SPT spend request
link-cli spend-request create \
  --payment-method-id csmrpd_xxx \
  --merchant-name "Climate Stripe" \
  --merchant-url "https://climate.stripe.dev" \
  --context "Contributing to climate initiatives through climate.stripe.dev. The user wants to offset carbon emissions from their recent travel." \
  --amount 100 \
  --credential-type "shared_payment_token" \
  --line-item "name:Carbon Offset,unit_amount:100,quantity:1" \
  --total "type:total,display_text:Total,amount:100" \
  --request-approval

# After approval, pay using MPP
link-cli mpp pay https://climate.stripe.dev/api/contribute \
  --spend-request-id lsrq_001 \
  --method POST \
  --data '{"amount":100}' \
  --header "Content-Type: application/json"

The SPT is one-time-use. If payment fails, create a new spend request.

Decode MPP Challenge

Extract payment information from a WWW-Authenticate header:

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

Returns the network_id needed for SPT spend requests and decoded challenge parameters.

Command Schema

Get full JSON schema for any command:

# Get schema for create command
link-cli spend-request create --schema

# List all commands in LLM-friendly format
link-cli --llms-full

Common Patterns

Agent Purchase Flow (Virtual Card)

import { execSync } from 'child_process';

// 1. Get payment methods
const pmResult = execSync('link-cli payment-methods list --format json', { encoding: 'utf8' });
const paymentMethods = JSON.parse(pmResult);
const pmId = paymentMethods[0].id;

// 2. Create spend request
const createCmd = `link-cli spend-request create \
  --payment-method-id ${pmId} \
  --merchant-name "Acme Store" \
  --merchant-url "https://acme.example" \
  --context "Purchasing office supplies from acme.example. The user requested pens and notebooks for the team meeting next week." \
  --amount 2500 \
  --line-item "name:Blue Pens,unit_amount:1000,quantity:1" \
  --line-item "name:Notebook,unit_amount:1500,quantity:1" \
  --total "type:total,display_text:Total,amount:2500" \
  --request-approval \
  --format json`;

const createResult = JSON.parse(execSync(createCmd, { encoding: 'utf8' }));
const spendRequestId = createResult.id;

// 3. Poll for approval
const pollCmd = `link-cli spend-request retrieve ${spendRequestId} \
  --interval 2 \
  --max-attempts 300 \
  --include card \
  --output-file /tmp/card-${spendRequestId}.json \
  --format json`;

const approvedResult = JSON.parse(execSync(pollCmd, { encoding: 'utf8' }));

// 4. Read card from secure file
const cardFile = `/tmp/card-${spendRequestId}.json`;
const cardData = JSON.parse(readFileSync(cardFile, 'utf8'));

// 5. Use card in checkout
await completeCheckout(cardData.card);

Agent Purchase Flow (MPP)

import { execSync } from 'child_process';

// 1. Decode MPP challenge to get network_id
const challenge = response.headers['www-authenticate'];
const decodeResult = execSync(
  `link-cli mpp decode --challenge '${challenge}' --format json`,
  { encoding: 'utf8' }
);
const { network_id } = JSON.parse(decodeResult);

// 2. Create SPT spend request
const createCmd = `link-cli spend-request create \
  --payment-method-id ${pmId} \
  --merchant-name "Climate Stripe" \
  --merchant-url "https://climate.stripe.dev" \
  --context "Contributing to climate offset program through climate.stripe.dev. The user wants to neutralize carbon emissions from their last flight." \
  --amount 100 \
  --credential-type "shared_payment_token" \
  --line-item "name:Carbon Offset,unit_amount:100,quantity:1" \
  --total "type:total,display_text:Total,amount:100" \
  --request-approval \
  --format json`;

const createResult = JSON.parse(execSync(createCmd, { encoding: 'utf8' }));
const spendRequestId = createResult.id;

// 3. Poll for approval
execSync(`link-cli spend-request retrieve ${spendRequestId} --interval 2 --max-attempts 300`);

// 4. Pay using MPP
const payCmd = `link-cli mpp pay https://climate.stripe.dev/api/contribute \
  --spend-request-id ${spendRequestId} \
  --method POST \
  --data '{"amount":100}' \
  --header "Content-Type: application/json" \
  --format json`;

const payResult = JSON.parse(execSync(payCmd, { encoding: 'utf8' }));

Multiple Auth Sessions

// User 1 session
process.env.LINK_AUTH_FILE = '/secure/user1-auth.json';
execSync('link-cli auth login --client-name "User1 Agent"');

// User 2 session
process.env.LINK_AUTH_FILE = '/secure/user2-auth.json';
execSync('link-cli auth login --client-name "User2 Agent"');

// Use different sessions
function getPaymentMethodsForUser(userId: string) {
  const authFile = `/secure/${userId}-auth.json`;
  return execSync(`link-cli payment-methods list --auth ${authFile} --format json`, {
    encoding: 'utf8'
  });
}

Environment Variables

VariableDescription
LINK_AUTH_FILEOverride auth credential file path (flag --auth takes precedence)
LINK_API_BASE_URLOverride API base URL
LINK_AUTH_BASE_URLOverride auth base URL
LINK_HTTP_PROXYRoute requests through HTTP proxy (requires undici)
NO_UPDATE_NOTIFIERSet to 1 to suppress update checks (useful in CI)

Troubleshooting

Authentication Issues

Problem: link-cli auth status shows authenticated: false

Solution:

# Logout and login again
link-cli auth logout
link-cli auth login --client-name "My Agent"

Spend Request Denied

Problem: User denies spend request in Link app

Solution: The polling command exits with status reflecting denial. Create a new spend request with updated context or amounts:

link-cli spend-request create \
  --payment-method-id csmrpd_xxx \
  --merchant-name "Updated Merchant" \
  --merchant-url "https://merchant.example" \
  --context "Revised purchase with updated details per user feedback. The user now wants the blue model instead of red, which has a different price point." \
  --amount 4000 \
  --line-item "name:Blue Model,unit_amount:4000,quantity:1" \
  --total "type:total,display_text:Total,amount:4000" \
  --request-approval

Context Too Short

Problem: context must be at least 100 characters

Solution: Provide detailed purchase context:

--context "Purchasing premium subscription to ExampleService for the team. This will give us access to advanced features including API access, priority support, and increased usage limits that we need for the upcoming project launch."

Amount Exceeds Limit

Problem: amount must not exceed 50000

Solution: Link CLI enforces a 50000 cent ($500) limit per request. For larger purchases, split into multiple spend requests or handle outside Link CLI.

Polling Timeout

Problem: Polling exits with code: "POLLING_TIMEOUT"

Solution: Increase --max-attempts or check if user has Link app installed:

# Poll for up to 15 minutes (2s interval × 450 attempts)
link-cli spend-request retrieve lsrq_001 \
  --interval 2 \
  --max-attempts 450

MPP Payment Fails

Problem: SPT payment returns error

Solution: SPTs are one-time-use. Create a new spend request and try again:

# Cancel old request
link-cli spend-request cancel lsrq_001

# Create new request
link-cli spend-request create \
  --payment-method-id csmrpd_xxx \
  --credential-type "shared_payment_token" \
  # ... rest of flags

File Already Exists

Problem: --output-file fails because file exists

Solution: Use --force to overwrite or choose different path:

link-cli spend-request retrieve lsrq_001 \
  --include card \
  --output-file /tmp/card.json \
  --force

Demo & Onboarding

Interactive Demo

# Run interactive demo (test mode)
link-cli demo

# Only virtual card flow
link-cli demo --only-card

# Only MPP/SPT flow
link-cli demo --only-spt

Guided Onboarding

# Complete setup flow
link-cli onboard

Walks through authentication, payment method checks, app download, and both demo flows.

FAQ

What does the stripe-link-cli skill do?

Enable AI agents to request payment credentials from Link wallets for secure purchases without exposing real card details

How do I install stripe-link-cli?

Run npx skills add https://github.com/reason-machines/devtools-skills --skill stripe-link-cli in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/stripe-link-cli/ (personal) or .claude/skills/stripe-link-cli/ (project).

Which AI agents can use stripe-link-cli?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is stripe-link-cli safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains stripe-link-cli?

It is published by reason-machines in reason-machines/devtools-skills. It has 220 recorded installs.

More from reason-machines/devtools-skills

View all →

cc-switch-cli

reason-machines/devtools-skills

Cross-platform CLI tool for managing Claude Code, Codex, Gemini, OpenCode & OpenClaw providers, MCP servers, prompts, skills, and proxies.

AI & Agents316 installs

wx-cli-wechat-local-data

reason-machines/devtools-skills

Open the skill to read its SKILL.md instructions.

284 installs

chrome-devtools-mcp-automation

reason-machines/devtools-skills

Open the skill to read its SKILL.md instructions.

AI & Agents263 installs

officecli-office-automation

reason-machines/devtools-skills

Open the skill to read its SKILL.md instructions.

cli-anything-agent-native-software

reason-machines/devtools-skills

Generate and use command-line interfaces that make any software controllable by AI agents with structured JSON output

AI & Agents258 installs

autocli-web-scraping

reason-machines/devtools-skills

Open the skill to read its SKILL.md instructions.

Popular backend & apis skills

View category →

find-skills

vercel-labs/skills

Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.

OfficialBackend & APIs4.1M installs

entra-app-registration

microsoft/azure-skills

Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.

OfficialBackend & APIs566.7K installs

This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).

Backend & APIs514.8K installs

embedded-captions

heygen-com/hyperframes

Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.

Backend & APIs453.3K installs

entra-agent-id

microsoft/azure-skills

Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).

OfficialBackend & APIs336.6K installs

neon

neondatabase/agent-skills

Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.

Backend & APIs237.1K installs