npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@recurrente/cli

v0.1.0

Published

The Recurrente API from your shell, and an MCP server that serves the same surface to any agent. Checkouts, subscriptions, customers, reports and money movement, with a sandbox where money cannot move.

Downloads

57

Readme

@recurrente/cli

The Recurrente API from your shell — and the same surface served over MCP to any agent.

npx @recurrente/cli login --profile sandbox
npx @recurrente/cli whoami --sandbox

Nothing to install and no runtime dependencies: one package.json, plain ESM, Node's built-in fetch. If you run it more than once a day, npm i -g @recurrente/cli gives you recurrente on your PATH and saves npx the round trip — the rest of this file writes it that way.

Requires Node 20 or newer.

Why a CLI and not only an MCP server

An MCP server sends every tool definition to the model on every turn. One tool per endpoint over 122 operations costs tens of thousands of tokens before the user has said anything. A CLI costs nothing until it is invoked, --help is progressive disclosure for free, and it works in any harness that can run a shell — no per-client plugin, no protocol negotiation.

So the CLI is the surface, and recurrente mcp is a second rendering of it for clients that prefer tools. Both read the same catalog and enforce the same rules.

Using it

recurrente help                       # topics
recurrente help withdrawals           # commands in one topic, with their risk tier
recurrente search reembolso           # find a command, in Spanish or English
recurrente show checkouts create      # parameters and body fields

recurrente checkouts list --items 5
recurrente checkouts create --data '{"items":[{"product_id":"prod_abc"}]}'
recurrente products update --id prod_abc --name "Camisa"

Flags the CLI does not claim for itself become request fields: path parameters go in the path, the rest become query parameters on a read and body fields on a write. Use --data for payloads too nested to express as flags.

Output and exit codes

Every invocation prints one JSON object and exits with a typed code, so a script can branch on $? without parsing prose.

| Code | Meaning | | --- | --- | | 0 | success | | 1 | failed | | 2 | usage — unknown command or bad arguments | | 3 | unauthorized — no key, or the key was rejected | | 4 | not found | | 5 | forbidden — the key lacks a permission | | 6 | invalid — the API rejected the payload | | 7 | needs confirmation — the operation moves money and --yes was absent | | 8 | unreachable — the network, not the API |

Money never moves on a guess

Operations that move funds, repoint a payout destination or charge a card are refused with exit 7 unless --yes is present:

$ recurrente withdrawals create --amount-in-cents 50000
{
  "ok": false,
  "error": { "message": "withdrawals create moves money and needs a human to confirm it." },
  "hint": "Re-run with --yes once a person has approved it."
}

Profiles

Keys live in ~/.recurrente/credentials.json, written at 0600. --sandbox and --live pick a profile; --key sk_... uses one without storing it; RECURRENTE_SECRET_KEY overrides everything.

Develop against --sandbox. A Sandbox is a real tenant that simulates money: it has its own objects, activity and webhooks, and every path that would reach a bank, a processor or a tax certifier is refused server-side. It is the only place to let an agent try something for the first time.

As an MCP server

claude mcp add recurrente -- recurrente mcp --sandbox

Install it globally first (npm i -g @recurrente/cli) and point the client at the binary. npx re-resolves the package on every launch, which is fine for a one-off and wasteful for a server an editor starts all day.

Four tools, not 122: recurrente_api_search, recurrente_api_details, recurrente_api_read and recurrente_api_write. The agent searches for what it needs and calls it, instead of carrying the whole API in context.

Money-moving operations are refused unless the server was started with --allow-money. The agent cannot grant itself that flag.

Merchants who do not want to install anything can connect the hosted server at https://app.recurrente.com/mcp from claude.ai instead, which asks for consent in a browser and scopes access to read, write or money. That one needs no Node at all, which matters: our integrators are not all on it.

Skills

npx skills add https://app.recurrente.com

Installs our integration guides — payments, subscriptions, webhooks, sandbox — into Claude Code, Codex, Cursor and anything else that reads the agent-skills standard.

Developing

The command surface is generated, not hand-written: it comes from data/agent_surface.json, which bin/rails agent_surface:sync builds from config/agent_surface.yml and the OpenAPI spec in the main repo. Adding an endpoint to the API adds a command here without a line of code. The generated file is JSON rather than YAML because parsing it must not cost a dependency.

Renaming or removing a command breaks whoever scripted it, so the set of command names is pinned in a committed list and CI fails when it changes without that list changing too.

Tests live with the app's, in test/javascript/cli/, and run with the rest of the suite:

npx vitest run test/javascript/cli