Multi-tenant AI agent platform. Businesses sign up, embed a chat widget on their site, plug in a knowledge base, and get a Claude-powered support / commerce assistant β with built-in product catalog, shopping cart, orders, Stripe billing, and Socket.IO realtime.
- Multi-tenant β every signup gets its own isolated tenant; data, conversations, and billing are scoped per-tenant.
- Embeddable chat widget β drop one
<script>on any site and get a Claude-powered chat that knows your business. - RAG-powered knowledge base β upload docs / FAQs; OpenAI embeddings index them into Qdrant; Claude grounds every reply on relevant chunks.
- Realtime conversations β Socket.IO streams agent + customer messages, supports typing indicators and presence.
- Built-in commerce β products, cart, orders. The agent can recommend products, walk customers through checkout, and confirm orders mid-conversation.
- Stripe-billed SaaS β tenants subscribe via Stripe; webhook updates plan + entitlements.
- Email + SMS notifications β SendGrid for transactional email (login, receipts), Twilio for SMS confirmations.
- JWT auth β bcrypt-hashed passwords, signed access tokens, rate limiting on every endpoint.
- Operator dashboard β React 19 + Tailwind 4 + TanStack Query for tenants to inspect conversations, manage knowledge base, configure the agent, and view metrics.
βββββββββββββββββββββββββββ
β Customer's website β
β <embeds chat widget/> β
ββββββββββββββ¬ββββββββββββββ
β Socket.IO
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Backend (Express + TS) β
β β
β /auth /tenants /widget /conversations β
β /dashboard /chat /products /cart /orders β
β β
β ββ chat service βββββββββββββββββββββββββββ β
β β Claude (Anthropic) for responses β β
β β OpenAI embeddings for retrieval β β
β ββββββββββββββ¬ββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββΌββββββββββββββββ ββββββββββββββββββββββ β
β β knowledge service β β commerce service β β
β β (RAG over Qdrant vectors) β β (catalog, cart, β β
β βββββββββββββββββββββββββββββββ β orders, Stripe) β β
β ββββββββββββββββββββββ β
βββββββ¬ββββββββββββββββ¬ββββββββββββββββ¬βββββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββ βββββββββββββ ββββββββββββββ
β Postgres β β Redis β β Qdrant β
β (data) β β (cache, β β (vector DB β
β β β rate-lim,β β for RAG) β
β β β pubsub) β β β
βββββββββββββ βββββββββββββ ββββββββββββββ
β²
β
Stripe / SendGrid / Twilio (3rd-party SaaS)
| Concern | Choice |
|---|---|
| Language | TypeScript 5.5 |
| Runtime | Node.js 20+ (tsx for dev) |
| Framework | Express 4 |
| Auth | JWT + bcrypt |
| DB | PostgreSQL via pg (raw SQL + migrations script) |
| Cache / pub-sub | Redis via ioredis |
| Realtime | Socket.IO 4 |
| LLM (responses) | Anthropic Claude (@anthropic-ai/sdk) |
| LLM (embeddings) | OpenAI (openai) |
| Vector DB | Qdrant |
| Payments | Stripe |
| SendGrid | |
| SMS | Twilio |
| Validation | Zod |
| Rate limiting | express-rate-limit |
| Concern | Choice |
|---|---|
| Framework | React 19 |
| Build tool | Vite 8 |
| Styling | Tailwind CSS 4 |
| Data fetching | TanStack Query 5 |
| Routing | React Router 7 |
| Forms | React Hook Form + Zod resolver |
| State | Zustand 5 |
| HTTP | Axios |
| Charts | Recharts |
| Icons | Lucide |
| Notifications | react-hot-toast |
| Linting | ESLint 9 + typescript-eslint 8 |
.
βββ package.json # backend deps + scripts
βββ tsconfig.json
βββ .env.example # all env vars documented
βββ public/ # static assets served by the API
βββ src/ # backend source
β βββ index.ts # entry point
β βββ config/ # env + service clients
β βββ db/ # migrations, query helpers
β βββ middleware/ # auth, tenant, rate-limit, error
β βββ routes/
β β βββ auth.ts # login / signup / refresh
β β βββ tenants.ts # tenant CRUD + invitations
β β βββ chat.ts # send/receive messages
β β βββ conversations.ts # list / archive / search
β β βββ dashboard.ts # metrics + analytics
β β βββ widget.ts # embeddable widget bootstrap
β β βββ products.ts # catalog
β β βββ cart.ts # shopping cart
β β βββ orders.ts # checkout + order history
β βββ services/
β β βββ chat/ # Claude orchestration, streaming
β β βββ commerce/ # cart, pricing, Stripe, orders
β β βββ knowledge/ # ingest, embed, retrieve (Qdrant)
β βββ types/ # shared TS types
βββ frontend/ # React + Vite dashboard
βββ package.json
βββ vite.config.ts
βββ tsconfig.json
βββ public/
βββ src/
- Node.js 20+
- PostgreSQL 14+
- Redis 7+
- Qdrant (
docker run -p 6333:6333 qdrant/qdrant) - API keys for: Anthropic, OpenAI, Stripe, SendGrid, Twilio
git clone https://github.com/Muhammad-Adil-code/Automation.git ai-agent-saas
cd ai-agent-saas
npm install
cd frontend && npm install && cd ..cp .env.example .env
# fill in DATABASE_URL, REDIS_URL, all the API keys, etc.The .env.example documents every variable with placeholder values.
npm run migrateIn two terminals:
# Terminal 1 β backend (Express on :3000 by default)
npm run dev
# Terminal 2 β frontend (Vite on :5173)
cd frontend
npm run devThe dashboard is at http://localhost:5173. Sign up, create a tenant, get your widget script, and embed it on a test page.
- Every request is scoped by a
tenantIdresolved from the auth token (dashboard) or widget API key (embed). - Postgres rows carry
tenant_id; every query indb/filters on it. - Stripe customers are namespaced per tenant; webhook handler verifies signature before mutating tenant state.
- Rate limiting is per-tenant + per-IP via Redis-backed
express-rate-limit. - Knowledge base vectors in Qdrant are partitioned by tenant collection.
- Customer message hits
/chat(or arrives via Socket.IO). services/knowledgeembeds the message via OpenAI β searches the tenant's Qdrant collection for top-k chunks.services/chatbuilds a Claude prompt with the retrieved chunks + recent conversation history.- Claude streams a response back over Socket.IO; tokens are persisted to
conversationsas they land. - If the agent decides to surface a product or trigger checkout, it calls
services/commercemid-stream (tool use).
- Stripe handles plans, subscriptions, and invoices.
routes/tenants.tsexposes a checkout-session endpoint that returns the Stripe Checkout URL.webhooks/(TODO) receivescustomer.subscription.*events and updates the tenant'splan+ entitlements (e.g. monthly message cap, knowledge-base size).
Once a tenant is set up, the dashboard generates a snippet:
<script src="https://your-saas.com/widget.js" data-tenant="abc123"></script>The widget loads, opens a Socket.IO connection scoped to the tenant, and renders a floating chat bubble.
- Webhooks for Stripe subscription lifecycle
- Per-tenant agent configuration UI (system prompt, model, temperature)
- Conversation transcript export (CSV / PDF)
- Multi-language support (Whisper for voice messages β text)
- Slack / WhatsApp connectors
- Self-serve analytics (response time, deflection rate, CSAT)
- Admin role + audit log
- CI: GitHub Actions workflow running
npm test+ lint + typecheck
PRs welcome. Please open an issue first if you're proposing a non-trivial change so we can align on direction.
# run linter
npm run lint
# typecheck
npx tsc --noEmit
cd frontend && npx tsc --noEmitCurrently no license file is shipped β treat the code as proprietary. A LICENSE will be added before any open-source release.
If you build something interesting on top of this, drop me a note β always curious to see how others stack chat agents with commerce.