Skip to main content
Glama
SoftwareSavants

Moyasar MCP Server

README.md
# Moyasar MCP Server

**Payments for AI agents.** A Stripe-style [MCP](https://modelcontextprotocol.io) server for [Moyasar](https://moyasar.com) — Saudi Arabia's payment gateway — that lets Claude create payment links, check transactions, and issue refunds in plain Arabic or English. Built with [Skybridge](https://www.skybridge.tech), so every tool renders a live React widget inside the conversation.

No regional payment provider offers this today. This repo is the proof that Moyasar can be first.

<br>

<p align="center">
  <img src="docs/assets/payment-link-demo.png" alt="Claude creating a 150 SAR Moyasar payment link — the tool renders a live widget with a scannable QR code and an Open payment page button, right inside the conversation" width="920">
</p>

<p align="center">
  <em>One sentence in — a scannable payment link out. Live widget, rendered by this server inside Claude.</em>
</p>

---

## The demo

Connect the server to Claude and the pitch plays out in five beats — live against Moyasar's sandbox, QR scan and all:

> **You:** Create a 150 SAR payment link for a consultation session.
>
> **Claude** → `moyasar_create_payment_link(amount: 15000, currency: "SAR", description: "Consultation session")`
>
> 🧾 **150.00 SAR** — `INITIATED`
> *Consultation session*
> ▪️▪️▪️ **[scannable QR code]** ▪️▪️▪️
> `https://moyasar.com/i/…` — scan with a phone, pay with a test card, right there on the call.

> **You:** Has it been paid yet?
>
> **Claude** → `moyasar_fetch_invoice(invoice_id: "…")`
>
> 🧾 **150.00 SAR** — `PAID` ✅
> *Paid by payment `a1b2c3…`*

> **You:** Show me today's transactions.
>
> **Claude** → `moyasar_list_payments(created_after: "…")`
>
> | Date | Description | Source | Amount | Status |
> |------|-------------|--------|--------|--------|
> | 2026-07-15 | Consultation session | visa •••• 1111 | 150.00 SAR | `PAID` |

> **You:** Refund that payment.
>
> **Claude** → `moyasar_create_refund(payment_id: "…")`
>
> 💸 **Refund complete** — payment is `REFUNDED`, refunded **150.00 SAR**

> **You:** How is this account doing this week?
>
> **Claude** → `moyasar_get_account_summary(days: 7)`
>
> 📊 **12 payments** · **1,840.00 SAR** volume · **8%** refund rate

Five sentences. Zero dashboards. That's the pitch.

## Why it matters

- **Agents are the new integration surface.** Stripe ships an MCP server. Every AI assistant that touches money will route through servers like this one. This is Moyasar, AI-native, today.
- **Errors teach the agent.** Every failure returns recovery guidance instead of a stack trace — *"This payment has status 'initiated' — only 'paid' payments can be refunded."* The agent self-corrects mid-conversation.
- **Card numbers never transit chat.** The recommended flow is hosted payment links; the direct-card tool exists for sandbox demos and says so in its own description.

## The 11 tools

| Tool | What it does |
|------|--------------|
| `moyasar_create_payment_link` | Hosted payment link + QR widget — the flagship flow |
| `moyasar_fetch_invoice` | Poll a link: paid or not? |
| `moyasar_list_invoices` | All payment links, as a table widget |
| `moyasar_cancel_invoice` | Kill an unpaid link |
| `moyasar_create_payment` | Direct card charge (sandbox test cards only) |
| `moyasar_fetch_payment` | Payment status card |
| `moyasar_list_payments` | Transactions table with status/date filters |
| `moyasar_create_refund` | Full or partial refund |
| `moyasar_capture_payment` | Capture a manual authorization (fetches the hold amount automatically) |
| `moyasar_void_payment` | Release a hold without charging |
| `moyasar_get_account_summary` | Counts, volume, refund rate — stat-tile dashboard |

Design follows our published [MCP server design principles](https://www.software-savants.com/news/mcp-server-design-mistakes): curated responses instead of raw API JSON, tool descriptions written as agent prompts, a focused 11-tool surface, `moyasar_` prefixes throughout.

## Quick start

```bash
npm install
MOYASAR_SECRET_KEY=sk_test_xxx npm run dev          # DevTools on http://localhost:3000
MOYASAR_SECRET_KEY=sk_test_xxx npm run dev:tunnel   # public URL → add as Claude connector
```

Keys are never hardcoded. Sandbox `sk_test_` keys only — `sk_live_` is refused unless you explicitly set `ALLOW_LIVE=true`, so the demo can never accidentally move real money.

```bash
npm test        # 28 unit tests, no network
npm run smoke   # real sandbox round-trip: link → fetch → list → cancel (skips without a key)
```

The full presenter script lives in [DEMO.md](./DEMO.md).

## Architecture

```
Claude ⇄ Skybridge MCP app (11 tools + React widgets)
              └── tool-runner (errors → agent guidance)
                    └── typed Moyasar client (Basic auth, curated responses)
                          └── api.moyasar.com/v1
```

## Productization roadmap (out of scope for the demo)

OAuth per-merchant auth · webhooks/callbacks · Apple Pay / Samsung Pay / STC Pay sources · bulk invoices · hosted deployment.

---

*Built by [Software Savants](https://www.software-savants.com).*