Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Subscribe

FreeNot checked

Exposes subscription insights to AI clients, including platform statistics and subscription plan information.

GitHubEmbed

About

Exposes subscription insights to AI clients, including platform statistics and subscription plan information.

README

A TypeScript/Express backend for a SaaS subscription workflow with Razorpay test payments, PostgreSQL persistence, Redis-backed background jobs, invoice emails, cached platform statistics, and an MCP server that exposes subscription insights to AI clients.

What This Project Includes

  • Plan catalog seeded with Basic, Pro, and Premium subscription plans.
  • Checkout API that creates Razorpay test orders.
  • Verified Razorpay webhook endpoint for successful payment events.
  • Subscription lifecycle handling with trial, active, failed, refunded, and expired states.
  • PDF invoice generation and Mailtrap email delivery.
  • Daily renewal scanner plus a BullMQ worker for renewal reminder emails.
  • Redis-cached platform statistics.
  • MCP tools for AI clients:
    • get_platform_stats
    • get_plans

Tech Stack

Area Technology
Runtime Node.js, TypeScript
API Express
Database PostgreSQL, Prisma
Cache and jobs Redis, BullMQ
Payments Razorpay test mode
Email testing Mailtrap SMTP
Background scheduling node-cron
AI integration Model Context Protocol over stdio

Prerequisites

Install these before running the project:

Local Setup

  1. Install dependencies:
npm install
  1. Start PostgreSQL and Redis:
docker compose up -d

The Compose file starts:

Service Host URL
PostgreSQL localhost:5433
Redis localhost:6379
  1. Create your local environment file:
cp .env.example .env

On Windows PowerShell:

Copy-Item .env.example .env
  1. Fill in .env using the credential guide below.

  2. Apply database migrations:

npx prisma migrate deploy
  1. Seed the subscription plans:
npx prisma db seed
  1. Start the API server:
npm run dev

The server runs at:

http://localhost:3000

Environment Configuration

Use .env.example as the safe template. Never commit your real .env file.

Database and Redis

These values work with the included Docker Compose setup:

DATABASE_URL="postgresql://saas_user:saas_password@localhost:5433/saas_db?schema=public"
REDIS_URL="redis://localhost:6379"

Razorpay Test Credentials

  1. Create or log in to a Razorpay account.
  2. Switch to test mode in the Razorpay dashboard.
  3. Go to Account & Settings > API Keys.
  4. Generate a test key pair.
  5. Copy the values into .env:
RAZORPAY_KEY_ID="rzp_test_xxxxxxxxxxxxx"
RAZORPAY_KEY_SECRET="your_test_secret"

For webhook testing, first run the API and ngrok tunnel. For the complete payment test, see Webhook Flow. ngrok prints a public Forwarding URL in the terminal, for example:

Forwarding  https://abc123.ngrok-free.app -> http://localhost:3000

Copy that HTTPS URL and add /api/webhooks/payment at the end. Then add the full URL in the Razorpay dashboard:

Webhook URL: https://abc123.ngrok-free.app/api/webhooks/payment
Events: payment.captured, payment.failed

You can also see the full step-by-step Razorpay webhook instructions in .env.example.

Then copy the webhook signing secret into:

RAZORPAY_WEBHOOK_SECRET="your_webhook_secret"

Mailtrap SMTP Credentials

  1. Create or log in to Mailtrap.
  2. Open an Email Testing inbox.
  3. Copy the SMTP host, port, username, and password.
  4. Add them to .env:
MAILTRAP_HOST="sandbox.smtp.mailtrap.io"
MAILTRAP_PORT="2525"
MAILTRAP_USER="your_mailtrap_username"
MAILTRAP_PASS="your_mailtrap_password"
MAILTRAP_FROM="[email protected]"

Running the Application

Always open Docker Desktop first. PostgreSQL and Redis must be running before the app starts:

docker compose up -d

For the complete local demo, run everything together with one command:

npm run dev:all

This starts:

  • API server on http://localhost:3000
  • ngrok tunnel for Razorpay webhooks
  • renewal reminder worker

If you want to run each process separately, use the commands below.

Run the API only:

npm run dev

Run the renewal reminder worker in a separate terminal:

npm run worker

Run the ngrok tunnel in another terminal:

npm run tunnel

Open Prisma Studio to view database tables in the browser:

npx prisma studio

Build and run production output:

npm run build
npm start

Verify Everything Works

1. Check infrastructure

docker compose ps

You should see saas_postgres and saas_redis running.

2. Check the API

curl http://localhost:3000/health

Expected response:

{
  "status": "ok",
  "timestamp": "..."
}

You can also open the application in your browser:

http://localhost:3000

From there, select a plan and complete a Razorpay test payment. After payment succeeds, Razorpay sends the webhook to the ngrok URL, and the backend activates the subscription, generates the invoice, and sends the confirmation email.

3. Confirm plans were seeded

curl http://localhost:3000/api/plans

You should see the Basic, Pro, and Premium plans.

4. Create a checkout order

curl -X POST http://localhost:3000/api/checkout \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"Demo User\",\"email\":\"[email protected]\",\"planName\":\"Pro\"}"

Expected result:

  • A new pending subscription is stored in PostgreSQL.
  • A Razorpay test order is returned.
  • The response includes the public Razorpay key id.

5. Verify platform stats

curl http://localhost:3000/api/stats

The first request computes stats from PostgreSQL. Repeated requests within 30 seconds should return cached stats from Redis.

6. Verify background processes

Start the worker:

npm run worker

In another terminal, manually trigger the renewal scanner:

curl -X POST http://localhost:3000/api/dev/trigger-renewal-scan

Expected behavior:

  • The API activates any expired trials.
  • Subscriptions expiring within 3 days are queued in Redis.
  • The worker processes queued renewal reminders.
  • Renewal emails appear in Mailtrap.

Webhook Flow

For a full payment test:

  1. Start the API:
npm run dev
  1. Start ngrok:
npm run tunnel
  1. Copy the HTTPS Forwarding URL printed by ngrok:
Forwarding  https://abc123.ngrok-free.app -> http://localhost:3000
  1. Add /api/webhooks/payment to that URL and paste it into the Razorpay webhook settings:
https://abc123.ngrok-free.app/api/webhooks/payment
  1. Select these webhook events:
payment.captured
payment.failed
  1. Save the webhook and copy the webhook signing secret into RAZORPAY_WEBHOOK_SECRET in .env.
  2. Restart the API after changing .env.
  3. Create a checkout order through POST /api/checkout.
  4. Complete the payment in Razorpay test mode.
  5. Razorpay sends the webhook to the public ngrok URL, and ngrok forwards it to http://localhost:3000/api/webhooks/payment.
  6. The API verifies the signature, activates the subscription, generates an invoice, and sends a confirmation email through Mailtrap.

API Reference

Method Endpoint Purpose
GET /health Health check
GET /api/plans List available plans
POST /api/checkout Create a subscription and Razorpay order
POST /api/webhooks/payment Receive Razorpay webhook events
GET /api/stats Get cached platform statistics
POST /api/dev/trigger-renewal-scan Manually run the renewal scanner

Checkout request body:

{
  "name": "Demo User",
  "email": "[email protected]",
  "planName": "Pro"
}

Expose the MCP Tool to an AI Client

The MCP server runs over stdio and uses the same .env values as the API.

Run it directly:

npm run mcp

You do not need to run this every time. Run npm run mcp only when you want to test the MCP server directly or connect it to an AI client.

Supported AI Desktop Clients

The easiest desktop app for this setup is Claude Desktop, because it supports local stdio MCP servers with an mcpServers JSON config.

Other MCP-compatible tools may also work, such as Claude Code, Cursor, Windsurf, VS Code MCP extensions, or any AI client that supports local stdio MCP servers. Their setup screens may be different, but the same command, args, and cwd values are used.

Add This MCP Server in Claude Desktop

  1. Make sure the backend setup is complete:
docker compose up -d
npx prisma migrate deploy
npx prisma db seed
  1. Make sure .env exists and has the required database, Redis, Razorpay, and Mailtrap values.

  2. Open Claude Desktop.

  3. Open Settings > Developer > Edit Config.

On Windows, Claude Desktop opens this file:

%APPDATA%\Claude\claude_desktop_config.json
  1. Add this MCP server config:
{
  "mcpServers": {
    "saas-platform-stats": {
      "command": "npm",
      "args": ["run", "mcp"],
      "cwd": "/absolute/path/to/saas-backend" // your project path
    }
  }
}

On this machine, the project path is:

D:\Bitcot-Task\saas-backend

For Windows-based clients, use escaped backslashes:

{
  "mcpServers": {
    "saas-platform-stats": {
      "command": "npm",
      "args": ["run", "mcp"],
      "cwd": "D:\\Bitcot-Task\\saas-backend" // your project path
    }
  }
}
  1. Save the config file.

  2. Fully quit and reopen Claude Desktop.

  3. Start a new Claude chat and ask:

Use the saas-platform-stats MCP server and show me the available subscription plans.

You should see Claude use the get_plans tool.

Example AI prompts you can ask:

How many active subscribers do we have right now?
What subscription plans do we offer?
What's the price of the Pro plan?
How much total revenue have we generated so far?

You do not need to run npm run mcp manually when Claude Desktop is configured. Claude Desktop starts the MCP server automatically from the config. Run npm run mcp manually only when you want to test the MCP server directly from the terminal.

Available MCP tools:

Tool Description
get_platform_stats Returns active subscribers, trialing subscribers, total revenue, and revenue by plan
get_plans Returns the available subscription plans with pricing, trials, and features

Before using MCP, make sure PostgreSQL and Redis are running and the database has been migrated and seeded.

Autmated Tests

Run npm run test to run unit tests and integration tests.

Test file layout


tests/
├── setup-env.ts                      # fake env vars for test runs
├── helpers/
│   └── prismaMock.ts                  # shared mocked Prisma client
├── unit/
│   ├── subscription.service.test.ts
│   ├── stats.service.test.ts
│   ├── invoice.service.test.ts
│   └── cron.test.ts
└── integration/
    ├── checkout.test.ts
    ├── webhook.test.ts
    └── plansAndStats.test.ts

Project Structure

saas-backend/
├── docker-compose.yml       # Postgres + Redis
├── .env.example
├── README.md
├── public/
│   └── index.html           # Pricing page (served at localhost:3000)
├── prisma/
│   ├── schema.prisma        # User, Plan, Subscription, Invoice models
│   └── seed.ts               # Seeds the 3 subscription plans
├── src/
│   ├── index.ts               # Express app entrypoint
│   ├── config/
│   │   ├── env.ts              # Centralized, validated env vars
│   │   └── redis.ts            # Shared Redis connection (BullMQ + cache)
│   ├── db/
│   │   └── prisma.ts           # Prisma client singleton
│   ├── routes/                 # checkout, webhook, plan, stats, dev
│   ├── controllers/            # HTTP request/response handling
│   ├── services/                # Business logic (payment, subscription,
│   │                             invoice, email, plan, stats, cache)
│   ├── jobs/
│   │   ├── queue.ts             # BullMQ queue definition
│   │   ├── cron.ts              # Daily renewal scan
│   │   └── renewal.worker.ts    # Standalone worker process
│   └── mcp/
│       └── server.ts            # MCP server (get_platform_stats, get_plans)
└── storage/
    └── invoices/                # Generated PDF invoices

Troubleshooting

Problem Fix
Missing required environment variable Confirm .env exists and all required keys from .env.example are filled in
Cannot connect to PostgreSQL Run docker compose up -d and confirm the database is on port 5433
Cannot connect to Redis Confirm saas_redis is running and REDIS_URL is redis://localhost:6379
No plans returned Run npx prisma migrate deploy and npx prisma db seed
Razorpay webhook rejected Confirm RAZORPAY_WEBHOOK_SECRET matches the webhook secret in Razorpay
Emails not appearing Confirm Mailtrap SMTP credentials and keep npm run worker running for renewal reminders
MCP client cannot start server Use an absolute cwd, confirm .env is present, and test npm run mcp manually

Author

For any queries, contact [email protected].

LinkedIn: sharifa-sheriff

from github.com/Sharifa26/subscribe-mcp

Installing Subscribe

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/Sharifa26/subscribe-mcp

FAQ

Is Subscribe MCP free?

Yes, Subscribe MCP is free — one-click install via Unyly at no cost.

Does Subscribe need an API key?

No, Subscribe runs without API keys or environment variables.

Is Subscribe hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install Subscribe in Claude Desktop, Claude Code or Cursor?

Open Subscribe on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Subscribe with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All ai MCPs