Skip to main content
Glama
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 |