RZP Trident
by hrsh-kr
README.md
# RZP Trident ⚡
> The agentic commerce layer for Razorpay merchants — MCP server · bounded wallet · proactive upsell · human override · blockchain audit
RZP Trident makes any Razorpay merchant AI-transactable. Drop in a YAML config, run one command, and any MCP-compatible AI agent (Claude, GPT, Gemini) can search your catalog, create real Razorpay orders, and complete purchases — with enforced spend limits and a full audit trail.
---
## What it does 🎯
| | |
|---|---|
| 🔌 | **MCP Server** — 5 tools over stdio; any MCP-compatible agent connects, zero network config |
| 🔐 | **Agent Wallet** — per-tx limits, category rules, one-time spend tokens; lives in agent code, not accessible to the LLM |
| 🤖 | **Buyer Agent** — Mistral Nemo 12B on NVIDIA NIM; strict 5-step purchase workflow with Mistral quirk recovery |
| 💡 | **Post-purchase Upsell** — after a cold-medicine buy, agent surfaces Knorr Soup without being asked |
| 🛒 | **Preemptive Cross-sell** — before the agent runs, clicking A4 Paper surfaces a pantry suggestion; clicking Coffee surfaces cleaning supplies |
| 🚨 | **OTP Override** — over-limit transactions pop a human-in-the-loop modal; block → escalate → approve |
| 📊 | **Blockchain Ledger PDF** — one-click export of all wallet events, hash-chained per block with merchant labels |
| 🎨 | **Live Demo UI** — two merchants side-by-side (B2C + B2B), fully scrollable stores, clickable products, floating trident FAB |
---
## Live Demo — Two Merchant Archetypes
| | QuickMart | SupplyHub |
|---|---|---|
| **Type** | B2C quick-commerce | B2B procurement |
| **Theme** | Green · consumer grid | Amber · procurement table |
| **Wallet** | ₹1,000 · ₹800/tx · grocery + pharma | ₹10,000 · ₹5,000/tx · office + pantry |
| **Products** | Crocin ₹30 · Vicks ₹108 · Knorr Soup ₹65 · Amul Milk ₹65 · Bournville ₹110 · Whey ₹999 | A4 Paper · Nescafé · HP Ink · Dettol · Markers · Tape |
| **Demo 1** | Click Crocin → cold medicine ordered → Knorr Soup upsell appears | Click A4 Paper → preemptive pantry suggestion (Nescafé) |
| **Demo 2** | Click Whey ₹999 → exceeds ₹800 limit → OTP modal → approve | Click Nescafé → preemptive cleaning suggestion (Dettol) |
---
## Architecture 🏗️
```
Browser (localhost:8000 → Live Demo)
├── QuickMart card (B2C, green) SupplyHub card (B2B, amber)
│ Scrollable product grid Scrollable procurement table
│ Click product → pre-fill agent Click row → pre-fill + cross-sell
│ Trident FAB → agent panel (50%) Trident FAB → agent panel (50%)
│
│ POST /buy GET /events/{merchant} (SSE)
│
dashboard/app.py (FastAPI + per-merchant wallet instances)
│
buyer_agent/agent.py (Mistral Nemo 12B via NVIDIA NIM)
│ _handle_tool interceptor
│ ├── wallet.authorize(amount, category) ← hard gate, not LLM-accessible
│ ├── wallet.debit(token)
│ └── MCP over stdio → mcp_server/server.py
│
mcp_server/server.py — 5 tools
│ ├── search_catalog
│ ├── get_product_details
│ ├── create_razorpay_order ← REAL Razorpay Orders API
│ ├── process_payment ← test-mode simulation
│ └── get_order_status
│
agent_wallet/wallet.py
└── authorize → one-time token → debit → SQLite audit log
```
**3 key design decisions:**
🔌 **MCP over stdio** — server is a process not a service; zero network config; works with Claude Desktop, Continue, LangChain out of the box
🔒 **Wallet outside MCP** — lives in agent code, not in the LLM's tool list; the model cannot read its state or call its methods; it is a hard gate
✅ **Real Razorpay orders** — every `order_id` is verifiable in the Razorpay test dashboard; payment capture is test-mode simulated (Razorpay has no server-side capture without browser checkout)
---
## Project layout 📁
```
rzp/
├── main.py # one command to run everything
├── requirements.txt
├── .env.example # RAZORPAY_KEY_ID · RAZORPAY_KEY_SECRET · NVIDIA_API_KEY
├── merchant.example.yaml
│
├── merchants/ # wallet config per merchant
│ ├── quickmart.yaml # B2C · ₹800/tx · grocery + pharma
│ └── supplyhub.yaml # B2B · ₹5,000/tx · office + pantry + electronics
│
├── data/merchants/ # product catalogs (JSON → SQLite via ingestion)
│ ├── quickmart_catalog.json # 8 products incl. Knorr Soup + Whey Protein
│ └── supplyhub_catalog.json # 6 B2B SKUs with MOQ
│
├── ingestion/
│ └── normalizer.py # LLM normalizer — any catalog format → SQLite
│
├── mcp_server/ # MCP tools + Razorpay client
├── agent_wallet/ # spend wallet with authorize/debit/token system
├── buyer_agent/ # Mistral agent loop with Mistral quirk recovery
│
└── dashboard/
├── app.py # FastAPI · SSE · per-merchant wallet init · reset API
└── static/
└── index.html # full-stack demo UI — single self-contained file
```
---
## Setup ⚡
```bash
# 1. Install
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
# 2. Keys
cp .env.example .env
# → fill RAZORPAY_KEY_ID, RAZORPAY_KEY_SECRET, NVIDIA_API_KEY
# 3. Run
python main.py
# → open http://localhost:8000 → click Live Demo
```
---
## MCP tools 🔧
| Tool | Does what | Wallet-gated |
|---|---|:---:|
| `search_catalog` | Full-text search with optional max_price | — |
| `get_product_details` | Price, category, stock for a product_id | — |
| `create_razorpay_order` | Creates a real Razorpay order | ✅ pre-auth |
| `process_payment` | Debits wallet + simulates payment capture | ✅ token |
| `get_order_status` | Order status lookup | — |
---
## Wallet mechanics 💳
```
authorize(amount, category)
├── amount > per_tx_limit → ❌ BLOCKED (frontend shows OTP modal for QuickMart)
├── category not allowed → ❌ BLOCKED (agent explains gracefully)
├── balance < amount → ❌ BLOCKED (agent explains gracefully)
└── all clear → ✅ one-time token issued
debit(token)
└── valid + unused token → ✅ balance decremented + event written to audit log
```
---
## Demo UI — Interaction Model 🖱️
- **Click any product** → agent input pre-filled, panel auto-opens, preemptive suggestion shown in feed
- **Trident FAB** (bottom-right of each card) → toggles agent panel between 0% and 50% of card height
- **Run →** → input clears immediately, SSE events stream into the feed live
- **Upsell chips** → appear post-purchase (QuickMart cold flow) or pre-emptively on product click (SupplyHub B2B flow)
- **Ledger PDF** (demo bar) → downloads blockchain-style PDF of all wallet events, hash-chained
---
## Reset between demos
```bash
curl -X POST http://localhost:8000/reset/quickmart
curl -X POST http://localhost:8000/reset/supplyhub
```
Then reload the page.
---
## Stack 🛠️
| Layer | Tech |
|---|---|
| LLM | Mistral Nemo 12B via NVIDIA NIM (OpenAI-compatible API) |
| Agent protocol | MCP over stdio (Python `mcp` SDK) |
| Payments | Razorpay Orders API — real orders, test-mode payment capture |
| Backend | FastAPI + uvicorn + SSE |
| Storage | SQLite (catalog + agent events + wallet events) |
| PDF export | jsPDF — blockchain-style ledger with prev/hash per block |
| Frontend | Vanilla JS + HTML/CSS — single `index.html`, no build step |
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues