MCP Hub
Back to servers

@onesub/mcp-server

MCP server for onesub — AI tools for setting up in-app subscriptions in React Native / Expo apps

npm526/wk
Updated
Apr 6, 2026

Quick Install

npx -y @onesub/mcp-server

@onesub/server @onesub/sdk @onesub/mcp-server
MIT License Node >= 20 Platform

onesub

Server-side receipt validation for react-native-iap. One line.

react-native-iap handles the purchase.
onesub handles everything after — validation, webhooks, subscription state.
Open source. Self-hosted. Zero revenue share.


The Problem

You use react-native-iap to handle purchases. But then you need a server to:

  • Verify Apple StoreKit 2 receipts (JWS signature validation)
  • Verify Google Play receipts (Play Developer API v3)
  • Handle webhooks (renewals, cancellations, refunds)
  • Track subscription state in a database
  • Track one-time purchases (consumables + non-consumables)
  • Expose "is this user subscribed?" and "what did this user buy?" endpoints

That's 2-3 weeks of work. Or one line:

app.use(createOneSubMiddleware(config));

How It Works

react-native-iap (client)            @onesub/server (your backend)
                                      ┌─────────────────────────────────┐
Subscriptions:                        │                                 │
  requestSubscription() ──receipt───▶ │ POST /onesub/validate           │
  fetch('/onesub/status') ──────────▶ │ GET  /onesub/status             │
                                      │                                 │
One-time purchases:                   │                                 │
  requestPurchase() ────receipt───▶   │ POST /onesub/purchase/validate  │
  fetch('/onesub/purchase/status') ──▶│ GET  /onesub/purchase/status    │
                                      │                                 │
Webhooks (auto):                      │ POST /onesub/webhook/apple      │
                                      │ POST /onesub/webhook/google     │
                                      └─────────────────────────────────┘

Quick Start

1. Install

npm install @onesub/server

2. Add to your Express app

import { createOneSubMiddleware, PostgresSubscriptionStore } from '@onesub/server';

app.use(createOneSubMiddleware({
  apple: {
    bundleId: 'com.yourapp.id',
    sharedSecret: process.env.APPLE_SHARED_SECRET,
  },
  google: {
    packageName: 'com.yourapp.id',
    serviceAccountKey: process.env.GOOGLE_SERVICE_ACCOUNT_KEY,
  },
  database: { url: process.env.DATABASE_URL },
  store: new PostgresSubscriptionStore(process.env.DATABASE_URL),
}));

3. Check subscription from your app

const res = await fetch('https://api.yourapp.com/onesub/status?userId=user123');
const { active } = await res.json();
// active: true → subscribed, false → not subscribed

Done. Apple/Google receipt validation, webhooks, and subscription tracking — all handled.


What You Get

Subscriptions (auto-renewable)

EndpointWhat it does
POST /onesub/validateVerify receipt, save subscription
GET /onesub/status?userId=Check if user has active subscription
POST /onesub/webhook/appleHandle App Store Server Notifications V2
POST /onesub/webhook/googleHandle Google Real-Time Developer Notifications

One-time Purchases (consumable + non-consumable)

EndpointWhat it does
POST /onesub/purchase/validateVerify receipt, save purchase
GET /onesub/purchase/status?userId=List user's purchases

Consumables (coins, credits): Can be purchased multiple times. Each purchase is tracked.

Non-consumables (unlock premium, remove ads): Purchased once. Duplicate purchases are rejected with 409 NON_CONSUMABLE_ALREADY_OWNED.

// Validate a consumable purchase
const res = await fetch('https://api.yourapp.com/onesub/purchase/validate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    platform: 'apple',
    receipt: transactionReceipt,
    userId: 'user123',
    productId: 'credits_100',
    type: 'consumable',    // or 'non_consumable'
  }),
});
const { valid, purchase } = await res.json();

What's Under the Hood

  • Apple: JWS signature verified against Apple JWKS (not just decoded)
  • Google: OAuth2 service account → Play Developer API v3, token cached
  • Webhooks: Auto-handle renewals, cancellations, expirations, refunds
  • Storage: Pluggable SubscriptionStore — built-in PostgreSQL + in-memory
  • Validation: zod input validation, 50KB body limit, userId length checks
  • Security: Full details →

Optional: React Native SDK

If you want a drop-in React hook + paywall component (built on react-native-iap):

npm install @onesub/sdk react-native-iap
import { OneSubProvider, useOneSub } from '@onesub/sdk';

// Wrap your app
<OneSubProvider config={{ serverUrl, productId }} userId={userId}>
  <App />
</OneSubProvider>

// Subscriptions
const { isActive, subscribe, restore } = useOneSub();

// One-time products (consumable / non-consumable)
const { purchaseProduct } = useOneSub();

// Purchase a consumable (e.g. coins)
const purchase = await purchaseProduct('credits_100', 'consumable');
// purchase is null if user cancelled, PurchaseInfo on success

// Purchase a non-consumable (e.g. premium unlock)
const purchase = await purchaseProduct('premium_unlock', 'non_consumable');

The SDK is optional. You can use @onesub/server with any client — React Native, Flutter, or plain HTTP calls.


Optional: MCP Server (AI Integration)

For Claude Code / Cursor users — AI helps set up your subscription:

{ "mcpServers": { "onesub": { "command": "npx", "args": ["@onesub/mcp-server"] } } }

"Add a monthly subscription to my Expo app"


Packages

PackageVersionWhatInstall
@onesub/servernpmExpress middleware — receipt validation + webhooksnpm i @onesub/server
@onesub/sdknpmReact Native SDK — useOneSub() + <Paywall />npm i @onesub/sdk
@onesub/mcp-servernpmMCP tools — AI creates products + paywallsnpx @onesub/mcp-server
@onesub/sharednpmShared TypeScript typesAuto-installed

vs RevenueCat

RevenueCatonesub
Receipt validationTheir serversYour server
Revenue share1% after $2.5K0% forever
Data ownershipTheir databaseYour database
Vendor lock-inYesNo (MIT open source)
DashboardYesNot yet
Setup time2-3 hours10 minutes

onesub is not a RevenueCat replacement. RevenueCat offers analytics, experiments, and a dashboard. onesub is for developers who want to own their subscription infrastructure.


Examples

Working examples to get you started in minutes:

ExampleWhatRun
examples/serverExpress server with receipt validationnpm start
examples/expo-appExpo Router app with paywallnpx expo start
# 1. Start the server
cd examples/server
cp .env.example .env   # add your Apple/Google credentials
npm install && npm start

# 2. Start the app (in another terminal)
cd examples/expo-app
npm install && npx expo start

Custom Store

Built-in PostgreSQL store, or bring your own:

import { SubscriptionStore } from '@onesub/server';

class RedisStore implements SubscriptionStore {
  async save(sub) { /* ... */ }
  async getByUserId(userId) { /* ... */ }
  async getByTransactionId(txId) { /* ... */ }
}

app.use(createOneSubMiddleware({ ...config, store: new RedisStore() }));

Roadmap

  • Apple StoreKit 2 receipt validation (JWKS verified)
  • Google Play Billing v3 receipt validation
  • Webhook handlers (Apple V2 + Google RTDN)
  • PostgreSQL subscription store
  • React Native SDK + paywall components
  • MCP server for AI-assisted setup
  • Security hardening (zod validation, body limits, signature verification)
  • CLI scaffolding (npx onesub init)
  • Analytics dashboard
  • Hosted service (no server needed)

Contributing

git clone https://github.com/jeonghwanko/onesub.git
cd onesub && npm install && npm run build && npm test

See CLAUDE.md for architecture and conventions.


License

MIT


react-native-iap handles the purchase.
onesub handles everything after.

Reviews

No reviews yet

Sign in to write a review