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

@costpad/mcp

v0.2.1

Published

MCP server for CostPad pricing simulator — lets AI assistants model SaaS unit economics

Downloads

395

Readme

@costpad/mcp

MCP server for the CostPad pricing simulator. Lets AI assistants (Claude, Cursor, Windsurf, etc.) read your margins, run pricing reviews and cost audits, compare scenarios, and move models in and out of the CostPad web app — without leaving their flow.

23 tools. In-memory state. Zero config.

Quick Start

npx @costpad/mcp

Or add to your Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "costpad": {
      "command": "npx",
      "args": ["-y", "@costpad/mcp"]
    }
  }
}

Tools

The server exposes 23 tools — 12 read-only and 11 mutations.

Read-only

| Tool | Purpose | |------|---------| | get_simulation | Return the current simulation inputs (COGS, tiers, mix, add-ons, scalars) | | get_economics | Run the calc engine — revenue, margins, COGS, fees, scale, growth | | get_growth | Month-by-month growth projection with optional overrides | | insights | Structured findings on pricing health — margin, free-tier, fees, COGS, growth | | run_scenario | What-if over any parameters without changing state; optional baseline diff | | run_pricing_review | "What should I charge for <tier>?" — price sweep + ranked recommendation | | run_cost_audit | Where margin leaks: COGS by category, infra-at-scale, fee drag, free-tier coverage | | compare_pricing | Diff named/inline scenarios side-by-side against baseline | | list_scenarios | List the named what-if scenarios saved this session | | export_report | Generate a Markdown or JSON pricing report | | export_product | Serialize the session into a costpad.dev-importable ProductSnapshot | | bridge_status | Report whether a local CostPad Desktop is attached over the bridge |

Mutations

| Tool | Purpose | |------|---------| | update_cogs | Add, update, replace, or remove COGS items | | update_tiers | Add, update, replace, or remove pricing tiers (mix auto-syncs) | | update_mix | Set user counts per tier | | update_addons | Add, update, replace, or remove add-on packs (top-up / upsell) | | update_one_time_purchases | Add, update, replace, or remove one-time purchases (attachRate 0–100) | | save_scenario | Store a named what-if (overrides bundle) in session state | | load_scenario | Apply a saved scenario's overrides to the current state | | import_product | Load a costpad.dev ProductSnapshot into the session | | reset_state | Reinitialize the session to built-in defaults | | load_preset | Load a named sample dataset (b2b-saas, usage-based-api) | | pull_from_desktop | Pull the connected Desktop's current product into the session |

Annotations & structured output

  • Annotations — every tool carries MCP tool annotations so hosts can decide auto-approve vs. confirm: read tools are readOnlyHint: true; mutations are readOnlyHint: false, with destructiveHint: true on replace-style tools. openWorldHint: false everywhere (all state is local and in-memory).
  • Structured output — the data tools (get_simulation, get_economics, insights, run_pricing_review, run_cost_audit, compare_pricing, get_growth, export_product) return structuredContent matching a declared outputSchema, so hosts can validate and render results.
  • Instructions — the server advertises an instructions string describing the read → mutate → re-read loop and which tool to reach for; hosts inject it as system context.

Resources

Read-only context a client can pull without spending a tool call. The server advertises resources with subscribe + listChanged.

| URI | Contents | |-----|----------| | costpad://simulation/current | Live session inputs (COGS, tiers, mix, add-ons, scalars) | | costpad://economics/current | Computed economics for the current simulation | | costpad://product/current | costpad.dev-importable ProductSnapshot of the session | | costpad://scenarios/{id} | Resource template — each saved scenario by name (list + id completion) | | costpad://reference/methodology | How COGS, blended ARPU, margins, fees, and free-tier burn are computed | | costpad://reference/cogs-categories | The infra/api/tooling/support/other taxonomy + scalar definitions |

Mutations emit notifications/resources/updated for the live resources, so a subscribed host re-reads automatically; saving, loading, or resetting scenarios emits listChanged.

Prompts

Workflow "skills" a client surfaces as slash commands. Each guides the model through an existing tool sequence; arguments autocomplete from live state.

| Prompt | Orchestrates | Arguments (autocompleted) | |--------|--------------|---------------------------| | pricing_review | get_economicsrun_pricing_reviewinsights | tier (tier names), objective (grossProfit…), rangePct | | cost_audit | run_cost_auditinsights | minSeverity (info/warn/critical) | | compare_pricing | list_scenarioscompare_pricing | scenarioA, scenarioB (saved scenario names) |

Ecosystem recipe prompts

Recipe prompts chain a third-party MCP's data into CostPad. They are provider-aware in their instructions but call only CostPad tools — the model reads from the provider's own MCP, then translates the result into CostPad mutations.

| Prompt | Reads (via that MCP) | Writes (CostPad) | |--------|----------------------|------------------| | import-from-stripe | stripe.list_subscriptions | update_tiers / update_mix | | setup-from-infra | supabase.get_project, vercel.get_project, resend.get_usage | update_cogs |

Each ends by offering pricing_review / cost_audit.

The ecosystem: CostPad consumes, it doesn't integrate

CostPad does not build connectors to Stripe, Supabase, Vercel, or Resend. Those are their own MCP servers. CostPad only consumes the numbers they surface, through its own update_* tools. Connect the provider MCPs alongside @costpad/mcp and let the assistant move the data across.

Stripe / Supabase / Vercel / Resend MCP   ──data──▶   @costpad/mcp   ──▶   analysis tools

Recipes

Pull real numbers from provider MCPs into the model, then analyse:

| From (provider MCP) | Into CostPad | Models | |---------------------|--------------|--------| | stripe.list_subscriptions | update_mix | Real subscriber mix per tier | | supabase.get_project + vercel.get_project | update_cogs | Fixed infra cost | | resend.get_usage | update_cogs | Per-user email cost |

These recipes are runnable as the import-from-stripe and setup-from-infra prompts.

Then run run_pricing_review, run_cost_audit, or compare_pricing for a recommendation.

"What should I charge for Pro?" — end to end

1. stripe.list_subscriptions          → real counts per plan
2. update_mix({ mix: [...] })          → load them as the user mix
3. supabase.get_project / vercel...    → current infra spend
4. update_cogs({ action: "update", … })→ set fixed infra COGS
5. run_pricing_review({ targetTierId: "pro" })
                                       → ranked price with deltas + caveats
6. compare_pricing({ scenarios: [
     { label: "Pro $49", overrides: { tiers: [{ id: "pro", price: 49 }] } },
     { label: "Pro $59", overrides: { tiers: [{ id: "pro", price: 59 }] } } ] })
                                       → side-by-side before you commit

(Step 6 uses inline overrides so it runs as-written; or save_scenario those names first and pass them by name.)

Save, revisit, and compare what-ifs

save_scenario({ name: "Pro $59", overrides: { tiers: [{ id: "pro", price: 59 }] } })
save_scenario({ name: "lean infra", overrides: { infraCost: 40 } })
compare_pricing({ scenarios: ["Pro $59", "lean infra", { label: "both", overrides: { tiers: [{ id: "pro", price: 59 }], infraCost: 40 } }] })
load_scenario({ name: "Pro $59" })     // make one of them the live state

Move a model between the assistant and the web app

export_product({ name: "My SaaS" })    // → paste the JSON into costpad.dev
import_product({ snapshot: { … } })    // ← load a web-app export into the session

Presets

Boot from a realistic sample dataset instead of the built-in defaults:

| Preset | Description | |--------|-------------| | b2b-saas | Seat-based B2B SaaS: free + Team + Business, per-seat support, paid onboarding | | usage-based-api | Metered API priced by included request volume, variable compute/bandwidth |

npx @costpad/mcp --preset b2b-saas

With no --preset, the server starts from defaults (unchanged behavior). Mid-session, the load_preset tool loads any preset by name, and reset_state returns to defaults.

Configuration

Settings resolve in this precedence order (high → low):

  1. CLI flag--preset <name>, --read-only, --config <path>
  2. EnvironmentCOSTPAD_PRESET, COSTPAD_READ_ONLY (1/true/yes), COSTPAD_CONFIG
  3. Config file — JSON at --config/COSTPAD_CONFIG, e.g. { "preset": "b2b-saas", "readOnly": true }
  4. Built-in defaults — full mode, default dataset

--preset and --read-only are independent: a server can boot a preset and run read-only — the preset seeds the data, then read-only blocks further mutations.

Read-Only Mode

Run with --read-only to disable the 11 mutation tools (update_cogs, update_tiers, update_mix, update_addons, update_one_time_purchases, save_scenario, load_scenario, import_product, reset_state, load_preset, pull_from_desktop). Only the 12 read-only tools are exposed.

npx @costpad/mcp --read-only

Claude Desktop config:

{
  "mcpServers": {
    "costpad": {
      "command": "npx",
      "args": ["-y", "@costpad/mcp", "--read-only"]
    }
  }
}

Desktop bridge

When the CostPad Desktop app is running, the server connects to it over a local, auth-free bridge (loopback WebSocket, discovered via ~/.costpad/desktop.json) — use case 2: desktop-attached. With no Desktop running it's a normal offline engine — use case 1: standalone — and never surfaces a connection error.

  • bridge_status — reports connected | offline, the Desktop version, and last sync time.
  • Mutations are mirrored to the Desktop as section/payload events so the matching panel updates live (best-effort; never blocks a tool result).
  • pull_from_desktop — load the Desktop's current product into the session, so an analysis starts from the user's real numbers.

See docs/bridge-protocol.md for the full contract.

How It Works

The server starts pre-loaded with sensible defaults (4 COGS items, 4 pricing tiers, realistic user mix). State lives in-memory for the session — no files, no database, no data leaves your machine.

The same computeEconomics() calc engine that powers the CostPad web app runs inside the MCP server, so the numbers match exactly. The analysis tools (insights, run_pricing_review, run_cost_audit, compare_pricing) are pure functions over that engine's output, in src/analysis/.

Security: All inputs are validated with bounded Zod schemas (max lengths, number ranges). State size is capped at 1MB. No network calls — stdio transport only. Tool errors return graceful error responses instead of crashing.

Design notes

  • MCP Apps spike — evaluation of interactive ui:// widgets (_meta.ui.resourceUri): host-support matrix, esbuild bundling, and a ship-vs-defer recommendation.
  • Bridge protocol — the local MCP ↔ Desktop bridge contract (discovery lockfile, WebSocket transport, message schemas, security) the bridge client is built against.

Local Development

cd packages/mcp-server
npm install
node bin/costpad-mcp.js

To point Claude Desktop at your local build:

{
  "mcpServers": {
    "costpad": {
      "command": "node",
      "args": ["/absolute/path/to/packages/mcp-server/bin/costpad-mcp.js"]
    }
  }
}

Building

npm run build

Bundles the server and calc engine into dist/costpad-mcp.js with source maps using esbuild.

Releasing

Releases are triggered by git tags. CI runs tests, then publishes to npm with provenance.

# 1. Bump version
npm version patch  # or minor/major

# 2. Tag and push
git tag mcp-v$(node -p "require('./package.json').version")
git push origin --tags

The mcp-v* tag triggers the publish job in GitHub Actions. Requires NPM_TOKEN secret in the repo settings.

npm org setup (one-time)

npm org create costpad
npm token create --read-only=false
# Add token as NPM_TOKEN in GitHub → Settings → Secrets