Content
# upi-mcp
A **Model Context Protocol (MCP) server** for India's UPI. It gives AI assistants
(Claude Desktop, Cursor, Cline, the MCP Inspector, etc.) the ability to **generate and parse
UPI payment links and QR codes** — entirely **offline**, with **no API keys** and **no network calls**.
> Plenty of web-based UPI QR generators exist. This is the **agent-callable** form factor:
> an LLM can mint a `upi://pay` link or a scannable QR mid-conversation, then validate or parse one.
> It pairs naturally with payment-API MCP servers.
---
## ✨ Features
- 🔗 Generate validated `upi://pay` deep links from payee details
- 🔳 Generate scannable **PNG QR codes** — built locally, no external service
- 🔍 Parse a UPI link back into structured fields
- 🛡️ Input validation (VPA format, amount limits)
- 🔒 Zero auth, zero network — pure, deterministic logic
- ⌨️ Written in TypeScript with `strict` mode
---
## 🛠️ Tools
| Tool | Description |
|------|-------------|
| `create_upi_link` | Build a validated `upi://pay` deep link from payee details. Returns the link as text. |
| `create_upi_qr` | Build a UPI link and return it as a scannable **PNG QR code** (plus the raw link). |
| `parse_upi_link` | Parse a `upi://pay` link back into structured fields. |
### Inputs
**`create_upi_link` / `create_upi_qr`**
| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `payee_vpa` | string | ✅ | UPI ID / VPA, e.g. `name@okhdfc` |
| `payee_name` | string | ✅ | Name shown in the UPI app |
| `amount` | number | ❌ | Fixed amount in INR (must be > 0 and ≤ 1,00,000) |
| `note` | string | ❌ | Short transaction note |
| `transaction_ref` | string | ❌ | Reference id |
**`parse_upi_link`**
| Field | Type | Required |
|-------|------|----------|
| `link` | string | ✅ |
---
## 📋 Requirements
- **Node.js 18+** (developed on Node 22)
---
## 🚀 Install & build
```bash
git clone https://github.com/<your-username>/upi-mcp.git
cd upi-mcp
npm install
npm run build # compiles TypeScript -> dist/
```
## ▶️ Run
```bash
npm start # boots the server on stdio
```
You should see `upi-mcp running on stdio` — it then waits for an MCP client to connect.
---
## 🧪 Test it (MCP Inspector)
The fastest way to try the tools, no client setup needed:
```bash
npx @modelcontextprotocol/inspector node dist/index.js
```
This opens a local web UI → **Connect** → **Tools** tab → **List Tools** → pick a tool, fill the
inputs, and **Run**. The QR image renders right there.
---
## 🖥️ Use with Claude Desktop
Open **Settings → Developer → Edit Config** and add this (merge into any existing config):
```json
{
"mcpServers": {
"upi": {
"command": "node",
"args": ["/absolute/path/to/upi-mcp/dist/index.js"]
}
}
}
```
Replace the path with your project's full path + `/dist/index.js`. Then **fully quit** Claude Desktop
(`Cmd + Q`) and reopen.
Try: *"Make a UPI payment link to pay `nirav@okhdfc` ₹250 with note test."*
> ⚠️ **Note on QR images in Claude Desktop:** the desktop client currently has limited/inconsistent
> support for rendering images returned by MCP tools (and a ~1 MB content cap). The text link always
> works and is tappable on mobile. To *see* the QR image reliably, use the **MCP Inspector** (above),
> which renders it correctly.
---
## 📦 UPI link format
```
upi://pay?pa=<vpa>&pn=<name>&cu=INR&am=<amount>&tn=<note>&tr=<ref>
```
**Example output**
Input: `{ "payee_vpa": "nirav@okhdfc", "payee_name": "Nirav", "amount": 250, "note": "test" }`
```
upi://pay?pa=nirav%40okhdfc&pn=Nirav&cu=INR&am=250.00&tn=test
```
`parse_upi_link` reverses this into `{ payeeVpa, payeeName, amount, note, transactionRef }`.
---
## 🧑💻 Development
```bash
npx tsc --watch # auto-rebuild on save
```
**Project structure**
```
src/
upi.ts # pure logic: build & parse links (no MCP, fully testable)
index.ts # the MCP server: wraps the logic as 3 tools over stdio
```
---
## 🌍 Publishing to npm
```bash
npm run build
npm publish --access public
```
Make sure `package.json` includes `"files": ["dist"]` so the compiled code ships. Once published,
anyone can run it with no clone:
```json
{ "command": "npx", "args": ["-y", "upi-mcp"] }
```
---
## ⚠️ Disclaimer
- UPI supports **INR only** (`cu=INR`) and one-time payments via this link format.
- This project is **not affiliated** with NPCI or any bank. It only constructs the public UPI
deep-link URI format and a QR image of it.
- Always verify the payee name in your UPI app before paying.
---
## 📄 License
MIT