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

@bazantic/cli

v0.10.1

Published

Bazantic CLI · pay for and manage agent gateways (x402 · MPP).

Downloads

680

Readme

@bazantic/cli

CLI for the Bazantic substrate. The command is baz — what the examples below spell and what the CLI's own --help prints. The longer bazantic and bazantic-cli still work as aliases:

  • baz curl … — call any x402 endpoint and auto-settle the payment (USDC · Base).
  • baz login / whoami / logout — sign in this device to manage gateways and Recipes. This session cannot spend.
  • baz gateway … — register and list your gateways over the login session (requires login).
  • baz wallet … — your self-custody wallet: the payer you hold and fund.
  • baz grant … — authorize a device to pay from your Bazantic-hosted balance (capped, revocable).

Pay for API calls (x402)

baz curl calls any paid endpoint and settles the 402 for you. Every price, cap and ceiling is USDC, never ETH and never a gas estimate. Payment settles on Base (the default, over x402) or Tempo (over MPP). On Tempo the token is USDC.e, and the tempo-moderato testnet uses AlphaUSD. You never handle a token unless you want to. Pay from a self-custody wallet you hold and fund (needs no Bazantic account), or from your Bazantic-hosted balance via a capped, revocable grant.

# 1. Create a self-custody wallet (stored 0600; passphrase optional — press
#    Enter to skip for unattended agent use, or set one to encrypt at rest)
baz wallet new
#    → 0xYourAddress…

# 2. Fund it with USDC on Base, then check it landed.
baz wallet balance

# 3. Make a paid call — the 402 is signed and retried automatically
baz curl https://<provider>.bazgateway.com/<path> --account wallet --json

Prefer to spend your Bazantic-hosted balance instead of a local wallet? Create a capped, revocable grant (approved once in the browser) and select it by name:

baz grant create --name agent-1 --cap 5    # authorize this device, 5 USDC cap
baz curl https://<provider>.bazgateway.com/<path> --account agent-1 --json

A wallet holds funds you custody; a grant is a capped permission to spend your hosted balance — they are different things. Because --account wallet always means the wallet, wallet and local are reserved: grant create refuses them as a --name rather than mint a grant that could never be selected.

curl flags

| Flag | Meaning | | --- | --- | | --account | who pays: a grant name, or wallet for the self-custody wallet (default: the sole grant, else the configured account) | | -X, --method | HTTP method (default GET) | | -d, --data | request body | | -H, --header | extra request header (repeatable) | | --max-amount | per-call spend ceiling in USDC (default 0.01) | | --network | advanced: base | tempo (default: matches the gateway — base on production, base-sepolia on a preview; testnets: base-sepolia, tempo-moderato) | | --x402-version | pin the accepted x402 version, 1 | 2 (default: the 402 body, then its PAYMENT-REQUIRED header) | | --passphrase-stdin | read the local wallet passphrase from stdin | | --yes | skip the pay confirmation (the ceiling still applies) | | --json | structured result / errors | | --verbose | print the settlement receipt to stderr |

Defaults in the config file

Set any of these once in the gateway block of ~/.bazantic/config.json. An everyday call then needs no flags at all:

{"gateway": {"account": "my-grant", "maxAmountUsd": "0.05", "network": "base"}}

account takes a grant name, or wallet for the self-custody wallet. A flag always wins over the file. A stale account that names no credential on this device is ignored, and the error lists the credentials you do have.

An --account you pass explicitly is checked against this device's credentials: a name that matches none is an error listing the real ones, never a quiet fallback to the wallet. A mistyped grant name would otherwise have moved the spend from capped, revocable money to uncapped money without saying so. To pay from the wallet, ask for it: --account wallet.

Environment (headless / CI / agents)

| Var | Purpose | | --- | --- | | BAZANTIC_GATEWAY_PRIVATE_KEY | use this key instead of the keystore | | BAZANTIC_GATEWAY_PASSPHRASE | unlock the keystore without a prompt | | BAZANTIC_GATEWAY_DEVICE_KEY | PEM key for a hosted-balance credential (headless single-credential use) | | BAZANTIC_GATEWAY_RPC_URL | override the network RPC used by wallet balance |

For agent use (e.g. Claude Code), curl never prompts when stdin is not a TTY — the --max-amount ceiling is the guard. Errors return one JSON object, e.g. {"ok":false,"error":"amount_exceeds_ceiling","detail":…}, and the process exits non-zero.

baz login --json and baz grant create --json both need a human to approve in a browser. In --json mode they print the approval URL to stderr as one JSON line ({"status":"pending_approval","verification_url":…}), and stdout keeps only the final object. Neither opens a browser by itself in that mode. Pass --browser when a script drives the command and a human is still at the keyboard. --no-browser always wins over --browser.

Networks

USDC on Base is the default rail — with no --network, the CLI picks the network from the gateway you're calling: a *.bazgateway.com gateway settles on Base mainnet, a *.bazgateway.dev preview on Base Sepolia. A gateway in sandbox mode answers with a 402 that offers Base Sepolia only, whatever its hostname is. With no --network, baz curl then pays on Base Sepolia. A testnet holds no real money, so the CLI asks for no confirmation. With an explicit --network that the 402 does not offer, baz curl stops and names the network the 402 offered. Payments move real dollars, settled over x402. --network tempo settles on Tempo instead, over MPP (Machine Payments Protocol): the CLI signs a Tempo transaction for the exact charge and the gateway broadcasts it only after your call succeeds. On Tempo the token is USDC.e and fees come out of it — no gas balance to manage. Both are production networks; you should never need to think about which chain you're on unless you pass --network yourself.

For testing without real funds: --network base-sepolia (fund from the Circle faucet, https://faucet.circle.com, selecting Base Sepolia) or --network tempo-moderato (AlphaUSD on Tempo's Moderato testnet).

Spending your Bazantic-hosted balance uses a grant (baz grant create / baz grant revoke) instead of a local wallet — see the pay examples above. Grants settle on Base today, so Tempo payments need the self-custody wallet (--account wallet).

Manage Recipes (login)

baz login creates a management session for the account that you select in the browser. New sessions include these scopes:

gateway:read
gateway:write
recipe:read
recipe:write

Old sessions can omit Recipe scopes. Run baz login again if a Recipe command reports a missing scope.

| Command | Purpose | | --- | --- | | baz recipe list [--json] | List Recipes that the selected account owns. | | baz recipe get <handle> [--json] | Get one Recipe that the selected account owns. | | baz recipe create <file> [--json] | Create a draft from a strict JSON file. | | baz recipe update <handle> <file> [--json] | Update a draft from a strict partial JSON file. | | baz recipe publish <handle> [--json] | Publish the current draft revision. | | baz recipe unpublish <handle> [--json] | Return a published Recipe to draft state. | | baz recipe delete <handle> [--yes] [--json] | Delete a draft after confirmation. |

List and get require recipe:read. All other commands in the table require recipe:write.

Recipe files

The create file contains exactly eight fields:

  • name
  • description
  • input_schema
  • input_example
  • output_example
  • prompt_template
  • model
  • tool_bindings

The update file contains a nonempty subset of the same fields. Unknown fields cause an error before a network request.

The compact UTF-8 JSON for a control definition cannot exceed 24 KiB. Update applies this limit after it merges the patch.

Neither file accepts a handle, owner, account, status, timestamp, or generation field. The API derives an immutable handle from name.

Each tool binding contains only gateway_slug and tool_name. A Recipe must have from 1 through 64 unique tool bindings.

prompt_template contains exactly one {{inputs}} placeholder. input_schema uses JSON Schema Draft 2020-12 and local references.

Supported model values are:

anthropic/claude-haiku-4.5
anthropic/claude-sonnet-4.6
anthropic/claude-opus-5
meta/llama-3.1-8b
deepseek/deepseek-v4-flash-0731
openai/gpt-5-nano

This file is a valid create document:

{
  "name": "Account Brief",
  "description": "Summarize one account.",
  "input_schema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": { "account": { "type": "string" } },
    "required": ["account"]
  },
  "input_example": { "account": "acme" },
  "output_example": { "summary": "Example" },
  "prompt_template": "Summarize {{inputs}}",
  "model": "anthropic/claude-haiku-4.5",
  "tool_bindings": [
    {
      "gateway_slug": "abcdefghijklmnopqrstuvwxyz",
      "tool_name": "lookup_account"
    }
  ]
}

Create produces a draft. Update works only on a draft.

Publish reads bounded Recipe metadata for updated_at and validates the live tool bindings. A concurrent update causes a conflict.

Unpublish returns the Recipe to draft state. Delete works on a draft, so a published Recipe takes an unpublish first.

Interactive delete asks for confirmation. Noninteractive delete and --json delete require --yes.

The CLI has no Recipe transfer, compose, generate, test, or draft-run command. JSON success output uses an { "ok": true, ... } envelope.

Use hosted Recipes in MCP clients

First, configure a wallet or grant with the steps above. Set gateway.maxAmountUsd to the maximum USDC amount for one Recipe call.

Register one dynamic Recipe MCP server in a supported client:

baz recipe install --client claude-code
baz recipe install --client codex
baz recipe install --client cursor

Run only the command for your selected client. The installer does not install Claude Code, Codex, or Cursor.

The installer previews the bazantic-recipes entry before it changes the file. The installer saves a 0600 backup of an existing config. The installer then uses an atomic write for the selected file.

| Client | User config | | --- | --- | | Claude Code | ~/.claude.json | | Codex | ~/.codex/config.toml | | Cursor | ~/.cursor/mcp.json |

The entry runs the current baz executable with the recipe mcp arguments. It does not save individual Recipe tools. Each tools/list request gets the current published catalog.

The adapter sends initialize and public tools/list requests to the API /mcp endpoint. This endpoint needs no authentication for those methods.

If a valid CLI session exists, the adapter also connects to API /control-mcp. It adds authorized bazantic_ tools to each tools/list result.

The current Control MCP server exposes these tools:

bazantic_recipe_list
bazantic_recipe_get
bazantic_recipe_create
bazantic_recipe_update
bazantic_recipe_delete
bazantic_recipe_publish
bazantic_recipe_unpublish
bazantic_marketplace_search
bazantic_gateway_list_owned
bazantic_gateway_list_tools

The three gateway discovery tools require gateway:read. Recipe read tools require recipe:read, and Recipe mutation tools require recipe:write.

bazantic_marketplace_search returns active, owner-published, Bazantic-verified services. bazantic_gateway_list_owned returns safe data for non-retired account gateways.

Both tools return at most four rows. Pass each next_offset value as offset until it is null.

Discovery rows omit descriptions, tags, URLs, timestamps, secrets, and raw specifications.

bazantic_gateway_list_tools makes a live request to one gateway. The account must own that gateway, or the verified marketplace must expose it.

The live result includes tool names, descriptions, input schemas, and annotations. Failure results use an explicit availability state instead of an empty tool list.

The adapter sends each bazantic_ call to API /control-mcp with the CLI session bearer. These calls do not load a wallet or use x402.

The adapter sends each published Recipe call to the paid Recipe gateway. The adapter pays through x402 with the configured payment source.

Without a valid CLI session, the adapter lists and calls public Recipes only. Public Recipe calls still use the paid gateway path.

The adapter does not use the generated gateway MCP endpoint. The direct route preserves the Recipe MCP request for the API.

Recipe calls use the account, network, and maxAmountUsd values from the gateway config block. The stdio adapter does not request payment approval. It rejects a charge above maxAmountUsd.

In Production, Baz CLI uses https://api.bazantic.com/mcp. Production needs no Recipe endpoint environment variables.

During initialize, the canonical API advertises the direct Recipe execution URL. Baz CLI uses this URL for tools/call.

| Variable | Requirement | Purpose | | --- | --- | --- | | BAZANTIC_RECIPE_MCP_URL | Optional | Override the canonical API /mcp URL for local or Preview checks. The override API must advertise its direct execution route. |

Remove the Recipe MCP server

Remove only the bazantic-recipes entry from the selected client config:

  • In Claude Code, remove mcpServers.bazantic-recipes from ~/.claude.json.
  • In Cursor, remove mcpServers.bazantic-recipes from ~/.cursor/mcp.json.
  • In Codex, remove [mcp_servers.bazantic-recipes] from ~/.codex/config.toml.

Also remove any Codex child table whose name starts with [mcp_servers.bazantic-recipes.. Keep all unrelated fields and MCP server entries. The install output gives the backup path for manual restore.

Manage gateways (login)

baz login signs this device in to manage your Bazantic account — create and edit gateways. It is a control-plane session, completely separate from paying: the token it stores can never spend or move funds (that is what wallet/grant are for). Sign-in is a device-code flow — the CLI prints a URL, you approve it in the browser, and the token lands in ~/.bazantic/config.json under a session block (0600).

# 1. Sign in (opens an approval link; approve it in your browser)
baz login
#    → signed in as <account> · scopes gateway:read, gateway:write · until <date>

# 2. Register an API as a gateway. Bazantic fetches + parses the spec,
#    generates the listing, and auto-generates its MCP endpoint.
baz gateway add \
  --spec-url https://api.example.com/openapi.json \
  --endpoint https://api.example.com \
  --name "Example API"
#    → gateway example-api
#        mcp https://<gateway-host>/example-api/mcp

# 3. List your gateways, or sign out
baz gateway list
baz whoami          # show the signed-in account + scopes + expiry
baz logout          # end this device's session (also revocable from the dashboard)

| Command | What it does | | --- | --- | | login | Device-code sign-in; stores a management session token (365-day, revocable). | | whoami | Show the signed-in account, scopes, and expiry (--json for the block, never the token). | | logout | Self-revoke the session server-side and clear the local token. | | gateway add --spec-url <url> --endpoint <url> [--name <s>] [--auth-type <t>] [--status draft\|active] | Register a gateway under the session's account (default auth type: none); prints the slug + mcp_url. | | gateway list | List the session account's gateways. | | gateway resync <slug> [--yes] [--json] | Match the gateway's paid routes to the spec it stores. Prints which routes would be added, removed and kept, then applies the lot on one confirmation. A route in both keeps the price you set. --json prints the change and writes nothing. | | gateway domains … | Manage a gateway's custom domain — see below. |

The account is chosen in the browser at approval (default: your personal account) — the CLI never holds a platform key, and a gateway is only ever created under an account you own.

Custom domains

Serve a gateway from your own hostname, such as api.your-domain.com, instead of its *.bazgateway.com address. Bazantic verifies that you control the domain, issues a TLS certificate for it, and then advertises that hostname as the gateway's URL. The original URL keeps working.

Four steps take a hostname from nothing to live:

# 1. Claim the hostname. Bazantic mints a token and prints two DNS records.
baz gateway domains add my-gateway api.your-domain.com
#    → hostname  api.your-domain.com
#      status    pending_ownership
#
#      Type   Host                                 Value
#      TXT    _baz-challenge.api.your-domain.com   baz-verify=api.your-domain.com,<token>
#      CNAME  api.your-domain.com                  bazgateway.com
#
#      then run: baz gateway domains verify my-gateway

# 2. Create both records at your DNS provider.
#    TXT   proves that you own the domain.
#    CNAME sends the traffic to Bazantic.

# 3. Run the checks. DNS needs time to propagate, so a first failure is normal.
baz gateway domains verify my-gateway
#    → hostname  api.your-domain.com
#      status    pending_cert

# 4. Wait for the certificate. Bazantic re-checks on its own every few minutes.
baz gateway domains status my-gateway
#    → hostname       api.your-domain.com
#      status         active

| Command | What it does | | --- | --- | | gateway domains add <slug> <hostname> | Claims a custom hostname for the gateway. It prints the TXT and CNAME records to create, and a hint to run verify next. API errors, such as hostname_in_use, print verbatim. | | gateway domains status <slug> | Prints the hostname, the status, the state of each record, the failureReason when set, and lastCheckedAt. | | gateway domains verify <slug> | Runs the DNS and certificate checks now, and prints the new status. A 429 prints the retry time. | | gateway domains rm <slug> [--yes] | Releases the domain. It prompts first unless you pass --yes. It always warns that your own CNAME record stays in place. A dangling record is a subdomain-takeover risk. |

Every command takes --json.

Status values. pending_ownership waits for the TXT record. pending_dns waits for the CNAME record, or for a CAA or AAAA problem to clear. pending_cert means the records pass and the certificate is on order. active means the hostname serves traffic and Bazantic advertises it. temporary_failure means a DNS lookup failed. degraded means the hostname still serves but its DNS drifted. failed means the setup did not complete.

Failure reasons. A failed check reports one code. The CLI prints the code verbatim, and the dashboard shows the same state in words. The common codes are txt_missing, txt_mismatch, cname_missing, cname_wrong_target, cname_proxied, caa_blocks_issuance, aaaa_conflict, registrar_autoappend_suspected, dns_error_temporary, cert_pending, cert_failed, expired_pending, and dns_drift.

Limits. One custom domain for each gateway. Five for each account. Six verifications an hour for each hostname. Ten domain changes an hour for each account. A setup that does not reach active in 7 days expires.

Custom domains need a signed-in session (baz login) with gateway:write. They work only where the webapp has the feature configured, which is production today. The full walkthrough, including the certificate steps, is at https://bazantic.com/docs/custom-domains.

Install

Published on npm as @bazantic/cli:

# Run without installing
npx -p @bazantic/cli baz --help

# Or install globally
npm i -g @bazantic/cli      # or: pnpm add -g @bazantic/cli

The command is baz, with bazantic and bazantic-cli as aliases.

Update

baz update updates the CLI to the latest version. baz update --check reports the latest version without an install. baz update --to <version> moves to an exact version. Use --to to return from a bad release.

The CLI checks npm once per 24 hours, in a background process. The process detaches from the command. No command waits on the network. When a newer version exists, baz prints one line on stderr at exit.

| Opt-out | Effect | | --- | --- | | BAZANTIC_NO_UPDATE_CHECK | skip the check | | NO_UPDATE_NOTIFIER | skip the check (shared convention) | | GH_NO_UPDATE_NOTIFIER | skip the check (shared convention) | | --no-update-notifier | skip the check for one command | | CI | skip automatically | | a pipe (stderr not a TTY) | skip automatically | | --json | skip automatically |

baz update refuses to install under npx or inside a source checkout. A global install there would shadow the checkout. Run npm i -g @bazantic/cli for a global install. Run git pull inside a source checkout instead. baz update --check still reports the latest version in both cases.