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

@bhorizon/sparky-desc

v0.1.0

Published

Pay-as-you-go CLI and MCP server for SparkCommerce — generate AI product descriptions, manage Shopify integrations, and run batch jobs from your terminal or any MCP-compatible client (Claude Desktop, Cursor, etc.).

Readme

@bhorizon/sparky-desc

Pay-as-you-go CLI and Model Context Protocol (MCP) server for SparkCommerce — generate AI product descriptions, manage Shopify integrations, and run batch jobs from your terminal or any MCP-compatible client (Claude Desktop, Cursor, Continue, etc.).

npm version license node

  • Sync + async generation — single descriptions in one call, or batch up to 1,000 rows per job
  • 🛒 Shopify integration — connect a store, pull products, push descriptions back, all from the CLI / MCP
  • 🎨 Brand identity aware — every generation is flavored by your saved brand voice, audience, and word lists
  • 📚 Version history — list and restore previous descriptions for any row
  • 🔍 Spot-check — pull a random sample of completed rows for QA review
  • 📤 Multi-format export — CSV, Shopify JSON, WooCommerce JSON, plain text
  • 🧠 MCP server built-in — drop into Claude Desktop / Cursor and let an LLM use 18 tools on your behalf
  • 💸 Metered billing — $0.01 per successful description; you only pay for what gets generated

Table of contents


Requirements

  • Node.js ≥ 18.17 (the binary uses native fetch, ESM, and modern abort signals)
  • A Pay As You Go SparkCommerce account with a payment method on file (create one at catalogspark.com)
  • An API key generated from the Developer page in the dashboard (starts with sk_payg_…)

Why Pay As You Go? The CLI and MCP server are exclusive to the metered PAYG plan. The starter and growth subscription tiers don't include API access.

Install

Globally (recommended for the CLI)

npm install -g @bhorizon/sparky-desc

Per-project

npm install @bhorizon/sparky-desc
npx sparky-desc --help

Without installing (one-shot)

npx -y @bhorizon/sparky-desc whoami

npx -y is also the recommended way to launch the MCP server from Claude Desktop and Cursor — see MCP server.

Quick start

# 1. Authenticate (paste your sk_payg_... API key when prompted)
sparky-desc login

# 2. Sanity check
sparky-desc whoami

# 3. Generate a single description
sparky-desc generate "Italian Hand-Stitched Leather Wallet" \
  --category Accessories --brand "Atelier Verona" \
  --tone luxury --length medium

# 4. Submit a CSV batch and wait for results
sparky-desc batch products.csv \
  --name-column title --category-column cat --brand-column vendor \
  --tone professional --length short --platform shopify \
  --wait --out descriptions.csv

Configuration

Configuration is read in this order (first match wins):

  1. CLI flags (--api-url, --key on login)
  2. Environment variables
    • CATALOGSPARK_API_KEY — your sk_payg_… key
    • CATALOGSPARK_API_URL — overrides the default backend (default: https://api.catalogspark.com)
  3. Config file written by sparky-desc login, in the platform-standard location:
    • Linux: ~/.config/sparky-desc/config.json
    • macOS: ~/Library/Preferences/sparky-desc/config.json
    • Windows: %APPDATA%\sparky-desc\config.json

Run sparky-desc whoami to see the resolved values.

CLI commands

Run sparky-desc help <command> for full flag reference on any command.

Account

| Command | What it does | |---|---| | sparky-desc login [--key sk_payg_...] [--api-url URL] | Save an API key for this device | | sparky-desc logout | Forget the saved API key | | sparky-desc whoami | Show account, plan, payment status, and current period usage | | sparky-desc usage | Show metered usage and the estimated invoice |

Generation

Single description

sparky-desc generate <name> [options]

Options:

--category <category>       --tone <tone>          professional|casual|luxury|playful|technical
--brand <brand>             --length <length>      short|medium|long
--sku <sku>                 --platform <platform>  shopify|amazon|woocommerce|generic
--material <material>       --copy-style <style>   descriptive|persuasive
--price <price>             --seo <kw1,kw2,...>    comma-separated SEO keywords
--attributes <attrs>        --image-url <url>      image URL for vision-capable models
--json                      Output the full JSON response (default: just the description)

The description is printed to stdout (so you can pipe it). Usage and cost are written to stderr when run in a TTY.

Batch from CSV

sparky-desc batch <csv> [options]

Options:

--name-column <col>      column with the product name (default: name)
--category-column <col>
--brand-column <col>
--sku-column <col>
--image-column <col>
--tone <tone>            professional|casual|luxury|playful|technical
--length <length>        short|medium|long
--platform <platform>    shopify|amazon|woocommerce|generic
--copy-style <style>     descriptive|persuasive
--seo <keywords>         comma-separated
--wait                   poll until complete and stream results
--out <file>             write results CSV here (with --wait)

Jobs

sparky-desc jobs list [--limit 20]
sparky-desc jobs get <id>
sparky-desc jobs results <id> [--format json|csv|text] [--out file]

Brand identity

Brand identity is woven into every generation prompt — voice, audience, words to use/avoid.

# View current settings
sparky-desc brand get [--json]

# Update from a file
sparky-desc brand set --file brand.json

# Update individual fields
sparky-desc brand set --field "tagline=Built for the bold" \
                      --field "brandValues=Quality,Trust,Speed"

# Pipe JSON via stdin
cat brand.json | sparky-desc brand set

Note: brand set is a full replacement (matches the dashboard's behavior). Always send the complete object you want stored. Use --field for one-shot tweaks of common fields, or pull → modify → push the JSON.

Stores

# List connected store integrations
sparky-desc stores list

# Get a Shopify install URL (open in browser to authorize)
sparky-desc stores connect myshop.myshopify.com

# Disconnect a store
sparky-desc stores disconnect <integration-id>

# Pull all products as a CSV (max 5,000 — Shopify pagination)
sparky-desc stores pull <integration-id> --out products.csv

# Push descriptions / SEO back to Shopify
sparky-desc stores push <integration-id> --updates updates.json

updates.json is an array of:

[
  {
    "shopifyProductId": 1234567890,
    "bodyHtml": "<p>...</p>",
    "seoTitle": "Premium Leather Wallet | Atelier Verona",
    "metaDescription": "Hand-stitched in Italy. Lifetime guarantee."
  }
]

Export & QA

# Export a completed job in any of four formats
sparky-desc export <jobId> --format csv         --out out.csv
sparky-desc export <jobId> --format shopify     --out shopify.json
sparky-desc export <jobId> --format woocommerce --out woo.json
sparky-desc export <jobId> --format plaintext   --out out.txt

# List failed rows for a job
sparky-desc errors <jobId> [--json]

# Random sample of completed rows for human review
sparky-desc spot-check <jobId> [--size 20] [--json]

Version history

Every regenerate / restore creates a stored revision.

sparky-desc revisions list <rowId> [--json]
sparky-desc revisions restore <rowId> <revisionId>

MCP server

sparky-desc mcp exposes the same surface area to any Model Context Protocol host — most commonly Claude Desktop and Cursor — so an LLM can read your usage, generate descriptions, push to Shopify, etc., on your behalf.

Claude Desktop

Open ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows) and add:

{
  "mcpServers": {
    "sparky-desc": {
      "command": "npx",
      "args": ["-y", "@bhorizon/sparky-desc", "mcp"],
      "env": {
        "CATALOGSPARK_API_KEY": "sk_payg_REPLACE_ME",
        "CATALOGSPARK_API_URL": "https://api.catalogspark.com"
      }
    }
  }
}

Restart Claude Desktop. Open a chat, click the 🔧 tools icon and you should see all 18 sparky-desc tools.

Cursor

Open Settings → Cursor Settings → MCP and add a server with the same JSON above (or edit ~/.cursor/mcp.json directly).

Linux / nvm caveat: MCP hosts launch commands without a login shell, so they don't see nvm/fnm/volta shims. If npx isn't on the host's PATH (you'll get spawn npx ENOENT), use absolute paths:

{
  "command": "/home/you/.nvm/versions/node/v20.x.x/bin/node",
  "args": [
    "/home/you/.nvm/versions/node/v20.x.x/lib/node_modules/@bhorizon/sparky-desc/dist/index.js",
    "mcp"
  ]
}

Find them with which node and npm root -g.

Tool reference

The MCP server advertises 18 tools. Argument names match the JSON schemas the server publishes — your client will surface those automatically.

| Tool | Purpose | |---|---| | generate_description | Synchronous single description (~5–15 s, $0.01) | | batch_generate | Async batch of up to 1,000 rows, returns a jobId | | get_job_status | Poll a job's status and row counts | | get_job_results | Paginated results for a job (cursor-based) | | list_jobs | Recent jobs for the account | | get_usage | Current period descriptions + estimated invoice | | get_brand_identity | Read brand identity | | update_brand_identity | Replace brand identity | | list_stores | List connected store integrations | | connect_shopify_store | Get a Shopify install URL for {shop} | | disconnect_store | Remove an integration by ID | | pull_store_products | Fetch all products from a connected store | | push_to_store | Push bodyHtml / seoTitle / metaDescription per product | | export_job | Export a job in csv / shopify / woocommerce / plaintext | | get_job_errors | List failed rows with error messages | | spot_check_job | Random sample of completed rows (max 50) | | list_revisions | Version history for a row | | restore_revision | Restore a previous revision (current state is auto-archived) |

Programmatic API

The package's CLI is just a thin wrapper around the public REST endpoints, all of which accept either a JWT or your sk_payg_… API key as a Bearer token. Useful endpoints:

GET    /v1/account
GET    /v1/usage
POST   /v1/descriptions
POST   /v1/descriptions/batch
GET    /v1/jobs
GET    /v1/jobs/:id
GET    /v1/jobs/:id/results
GET    /v1/jobs/:id/export
GET    /v1/jobs/:id/errors
GET    /v1/jobs/:id/spot-check
GET    /v1/me/brand
PUT    /v1/me/brand
GET    /v1/integrations
POST   /v1/integrations/shopify/install
DELETE /v1/integrations/:id
POST   /v1/integrations/:id/pull-products
POST   /v1/integrations/:id/push-products
GET    /v1/rows/:rowId/revisions
POST   /v1/rows/:rowId/restore/:revisionId

Send Authorization: Bearer sk_payg_… and Content-Type: application/json.

Pricing

| Plan | Price | API + CLI + MCP | Monthly minimum | |---|---|---|---| | Pay As You Go | $0.01 / successful description | ✅ | None | | Starter / Growth | Subscription tiers | ❌ | — |

You only pay for descriptions that complete successfully. Failed rows are not billed.

A successful description currently runs on Anthropic Claude 3 Haiku for the right balance of speed, cost, and quality. The exact model is an implementation detail and may change without notice.

Troubleshooting

Add a payment method to start using the API.

You're on the PAYG plan but haven't completed Stripe checkout. Visit the dashboard → PricingPay As You Go and add a card. The CLI will work as soon as Stripe confirms the setup.

This action requires the Pay As You Go plan.

Your account is on Free / Starter / Growth. Upgrade to PAYG from the pricing page; the API + CLI + MCP unlock immediately.

spawn npx ENOENT from Claude / Cursor

Your MCP host can't find npx on its PATH. Either:

  1. Install Node.js via the system package manager (apt, brew) so the binary lives in a standard path, or
  2. Use the absolute-path config shown in Cursor above.

Authentication failed. in the CLI

Your API key was revoked, expired, or never saved. Run sparky-desc login again with a fresh key from the Developer page.

Stale config on a shared machine

Run sparky-desc logout and then sparky-desc login --key sk_payg_…. The config file is keyed per-OS-user.

License

MIT © BHorizon