Full multi-account Stripe API access for Claude Code. Every endpoint the pinned stripe-node SDK exposes, a binary-enforced safety tier with live-mode arming, and the bundled Stripe CLI. Replaces the single-account MCP connector.
  • JavaScript 99.1%
  • Shell 0.9%
Find a file
juliandickie 734c0cd157 chore(release): 0.2.0
The registry format change is breaking, so this is a minor bump rather than a
patch. Four breaking changes ship in it, all listed in the CHANGELOG entry:
the reference-only registry, env: refused for live keys, `stripe-x vet`
requiring a named operation, and the cli bridge carrying the engine's gates.

Also removes a version copy that had already gone stale. The MCP shim
reported a hardcoded serverInfo version of 0.1.0; it now reads
.claude-plugin/plugin.json, and test/manifest.test.js fails if a quoted
version literal reappears, if the two manifests diverge, or if a released
version has no CHANGELOG section. Verified by mutation: reintroducing the
literal fails the suite, restoring it passes. A live initialize handshake
now reports 0.2.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 16:51:36 +10:00
.claude-plugin chore(release): 0.2.0 2026-08-02 16:51:36 +10:00
agents feat: stripe-bulk-runner agent for verbose and bulk jobs 2026-05-18 14:29:15 +10:00
assets fix: api-map generator now walks namespace tier (issuing/treasury/etc); lock with tests (spec review) 2026-05-18 13:57:15 +10:00
bin feat: stripe-x entrypoint with gating, confirmation, arming, bulk, fan-out refusal 2026-05-18 13:32:07 +10:00
hooks feat(vetting): bind the token to the call, gate arming and the CLI bridge 2026-08-02 09:24:18 +10:00
scripts fix: fail-loud curl, validate pinned version, post-verify mkdir (security review) 2026-05-18 14:11:53 +10:00
skills docs: state the bound guarantee, the new vet syntax, and the residuals 2026-08-02 09:24:26 +10:00
src chore(release): 0.2.0 2026-08-02 16:51:36 +10:00
test chore(release): 0.2.0 2026-08-02 16:51:36 +10:00
.gitignore chore: ignore .superpowers/ SDD scratch 2026-08-01 16:51:44 +10:00
.mcp.json feat: opt-in MCP shim exposing stripe_call and stripe_accounts 2026-05-18 14:32:23 +10:00
CHANGELOG.md chore(release): 0.2.0 2026-08-02 16:51:36 +10:00
CLAUDE.md chore(release): 0.2.0 2026-08-02 16:51:36 +10:00
LICENSE docs: README, CHANGELOG, LICENSE, plugin CLAUDE.md 2026-05-18 14:38:17 +10:00
package-lock.json feat: repo skeleton, pinned stripe-node 22.1.1, node:test harness 2026-05-18 12:18:41 +10:00
package.json chore(release): 0.2.0 2026-08-02 16:51:36 +10:00
README.md docs: state the bound guarantee, the new vet syntax, and the residuals 2026-08-02 09:24:26 +10:00

stripe

Full programmatic access to every Stripe API endpoint the pinned stripe-node SDK exposes, across many accounts, for Claude Code. Replaces the single-account Stripe MCP connector with a multi-account engine (standalone keys and Stripe Connect), a binary-enforced safety tier with live-mode arming, and the bundled official Stripe CLI for webhooks.

Install

/plugin marketplace add juliandickie/stripe-plugin
/plugin install stripe@stripe-plugin

Then run /stripe:stripe-setup to create the accounts registry and provision the Stripe CLI.

Accounts

Accounts live in a JSON registry (default ${CLAUDE_PLUGIN_DATA}/stripe-x/accounts.json, chmod 600, gitignored). Each entry is standalone (its own test and live keys) or connect (a platform profile plus a connected account id). Keys are references, never plaintext: test keys may use env:VAR_NAME indirection; live keys must be a 1Password reference (op://Vault/Item/field).

Credentials

Secret-bearing fields hold a reference, never a value. op://Vault/Item/field resolves through the 1Password CLI and is accepted for both test_secret_key and live_secret_key; env:NAME reads a process environment variable and is accepted for test_secret_key only. Anything else, including a raw sk_live_... or sk_test_... key, is refused at registry load. A Connect account carries no keys of its own; both fields, plus op_account, are read from the platform account it names.

1Password resolution needs the op CLI installed and the app unlocked. When more than one 1Password account is signed in, set op_account on the registry entry to the sign-in address op should use, or op read fails with "multiple accounts found". /stripe:stripe-setup walks through this and scaffolds a starter registry.

Safety

Three classes enforced inside the engine binary: reads run immediately; mutating and destructive operations print a confirmation preview and do not call Stripe without --confirm; destructive ones state irreversibility. Test mode is default; live writes need --live. --arm-live (live-mode arming) is its own call: it arms the session for one account and exits without executing (exit code 14), so execution always needs a separate, later --live --confirm call. Bulk writes over the threshold return a scope review. Multi-account fan-out is read-only.

The engine enforces all of the above, but it cannot defend against a caller that writes its own flags. A PreToolUse hook is a required second layer that reads the harness permission mode and denies or escalates stripe-x calls Claude Code would otherwise run unattended (see Security below).

Live mutating and destructive operations, live arming, and live calls through the stripe-x cli bridge all require a vetting token, proof that a permission gate saw that specific call, on top of arming. Inside Claude Code the PreToolUse guard issues one automatically, so this needs no separate step. Working directly in a terminal, run stripe-x vet <resource> <action> --live first, naming the same account, target id and registry as the call it authorises; it requires a real terminal (a TTY) and refuses otherwise. A live call carrying no token for that operation is refused, exit code 15.

The token is bound to the call, not to the session. It is filed under a canonical key covering the account, resource, action, live flag, arm flag, target id and registry path, which the guard and the engine compute independently, so a token for customers list cannot authorise refunds create --live, an arming token cannot authorise the execution it armed for, and a token approved for one customer id cannot delete another. An invocation assembled at runtime that no text classifier can recognise produces no token at all, and is therefore refused rather than allowed.

Two limits worth stating plainly. The target is bound through --id and --bulk-ids but not through --data, so for an operation whose target lives in --data (refunds create --data charge=ch_1) a warm token still authorises the same operation against a different charge until it expires. The TTY requirement on stripe-x vet is a presence heuristic, not proof of a human, and tools such as script and expect defeat it.

What you get

Skills: stripe-setup (user-only), stripe-api, stripe-accounts, stripe-multi-account, stripe-webhooks, stripe-reports, stripe-money-ops (user-only). Agent: stripe-bulk-runner. Optional MCP shim (off by default; set enable_mcp_shim).

Pinned versions

stripe-node 22.1.1, Stripe API 2026-04-22.dahlia, Stripe CLI pinned in scripts/stripe-cli-version.txt.

Testing

node --test test/*.test.js runs the full suite with no network and no keys. The plugin never needs live keys to test.

Security

No secrets in the repo. Two hooks: SessionStart installs the npm dependency and provisions the Stripe CLI; PreToolUse gates stripe-x Bash calls (see Safety above) whenever Claude Code is in a permission mode that would not otherwise prompt - auto, dontAsk, bypassPermissions, or any unrecognised mode. Review before installing.