# vexorpay MCP

Remote vexorpay MCP server to connect your account from Claude Code, Cursor, VS Code and other MCP clients, with OAuth.

> [!WARNING]
> El SDK `vexor` de npm (Stripe, MercadoPago, PayPal, Square, Talo) está **deprecado**: ya no se mantiene y no debe usarse. vexorpay es hoy una **API REST de links de pago en USD sobre Polar (Merchant of Record), sin SDK oficial**. Migración: <https://developers.vexorpay.com/docs/migracion-desde-el-sdk>

Fuente: <https://developers.whop.vexorpay.com/docs/mcp>

The vexorpay MCP server exposes the v1 API operations as **MCP tools** (Model Context Protocol). You can connect it to Claude Code, Cursor, VS Code or any MCP client to create payment links, query sales, manage subscriptions and disputes and more in natural language.

The connection uses **OAuth**: you authorize access from the browser (login + consent) and the MCP client obtains an access token to call the tools.

## Connect

Choose your client and follow the steps. The server URL is always the same,
`https://mcp.vexorpay.com`, and the connection uses **OAuth**: the first time you
use the server the browser opens so you can sign in, authorize the app, choose the
**mode** (test or production) and the **permissions** (scopes) you grant it.

### opencode

Add the server to your `opencode.json`:

**opencode.json**

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "vexorpay": {
      "type": "remote",
      "url": "https://mcp.vexorpay.com",
      "enabled": true,
      "oauth": {}
    }
  }
}
```

Then authenticate with OAuth from the terminal:

**Terminal**

```bash
opencode mcp auth vexorpay
```

### Cursor

Edit `~/.cursor/mcp.json` (or `.cursor/mcp.json` in your project):

**mcp.json**

```json
{
  "mcpServers": {
    "vexorpay": {
      "url": "https://mcp.vexorpay.com"
    }
  }
}
```

Cursor opens the browser to sign in and authorize the first time you use the server.

### Claude Code

Add the server with the Claude Code CLI:

**Terminal**

```bash
claude mcp add --transport http vexorpay https://mcp.vexorpay.com
```

Start Claude Code and run `/mcp` to authenticate with OAuth.

### Claude Desktop

Open **Settings → Connectors → Add custom connector** and use this URL:

```text
https://mcp.vexorpay.com
```

You sign in and authorize access in the browser.

### Codex

Add the server with the Codex CLI:

**Terminal**

```bash
codex mcp add vexorpay --url https://mcp.vexorpay.com
```

Authenticate with OAuth when the client asks for it.

### ChatGPT

Open **Settings → Connectors → Add connector** (developer mode) and use this URL:

```text
https://mcp.vexorpay.com
```

You authorize access with OAuth in the browser.

### VS Code

Add the server to your workspace `.vscode/mcp.json`:

**mcp.json**

```json
{
  "servers": {
    "vexorpay": {
      "type": "http",
      "url": "https://mcp.vexorpay.com"
    }
  }
}
```

VS Code prompts you to authorize with OAuth when the server starts.

### Other

Any MCP client that supports **Streamable HTTP** and OAuth connects to:

```text
https://mcp.vexorpay.com
```

If your client uses the classic `mcpServers` configuration:

**mcp.json**

```json
{
  "mcpServers": {
    "vexorpay": {
      "type": "http",
      "url": "https://mcp.vexorpay.com"
    }
  }
}
```

Using a client that is not on the list? Connect it to
`https://mcp.vexorpay.com` (Streamable HTTP + OAuth).

## Mode: test or production

There is **a single URL** for all clients; the mode is chosen on the authorization
screen:

| Mode | What it does |
| --- | --- |
| **Test (sandbox)** | Operates with test data (Polar sandbox). Ideal for development; never moves real money. |
| **Production** | Operates with your real account: real money and data. |

The connection is locked to the mode chosen at authorization: it cannot be switched per call. To change the mode, reconnect the app choosing the other mode.

## Tools

There are 27 tools covering the v1 API operations (all except `GET /health` and the order refund `POST /orders/{id}/refund`).

### Read (scope `read`)

| Tool | v1 API |
| --- | --- |
| `get_balance` | `GET /balance` |
| `list_payment_links` | `GET /payment-links` |
| `get_payment_link` | `GET /payment-links/{id}` |
| `get_payment_link_stats` | `GET /payment-links/{id}/stats` |
| `list_orders` | `GET /orders` (filters `status`, `payment_link_id`) |
| `get_order` | `GET /orders/{id}` |
| `list_subscriptions` | `GET /subscriptions` |
| `get_subscription` | `GET /subscriptions/{id}` |
| `list_disputes` | `GET /disputes` (filters `status`, `order_id`) |
| `get_dispute` | `GET /disputes/{id}` |
| `list_events` | `GET /events` |
| `list_payouts` | `GET /payouts` |
| `get_payout_estimate` | `GET /payouts/estimate` |
| `list_customers` | `GET /customers` |
| `get_customer` | `GET /customers/{id}` |

### Write

| Tool | v1 API | Scope |
| --- | --- | --- |
| `create_payment_link` | `POST /payment-links` | `links:write` |
| `update_payment_link` | `PATCH /payment-links/{id}` | `links:write` |
| `delete_payment_link` | `DELETE /payment-links/{id}` (archives the link and its Polar product) | `links:write` |
| `create_checkout` | `POST /payment-links/{id}/checkout` (Polar checkout session) | `charges:write` |
| `update_subscription_seats` | `PATCH /subscriptions/{id}` | `subscriptions:write` |
| `cancel_subscription` | `POST /subscriptions/{id}/cancel` | `subscriptions:write` |
| `open_subscription_portal` | `POST /subscriptions/{id}/portal` | `subscriptions:write` |
| `accept_dispute` | `POST /disputes/{id}/accept` | `disputes:write` |
| `create_payout` | `POST /payouts` | `payouts:write` |

### Connected accounts (scope `account:operate`)

| Tool | v1 API | Scope |
| --- | --- | --- |
| `list_connected_accounts` | `GET /connected-accounts` | `account:operate` |
| `get_connected_account` | `GET /connected-accounts/{id}` | `account:operate` |
| `revoke_connected_account` | `DELETE /connected-accounts/{id}` | `account:operate` |

The `create_payment_link` and `create_checkout` tools also accept `connected_account` (operate on behalf of a connected account; the proxy translates it to the `Vexor-Account` header). See [connected accounts](/docs/api/connected-accounts).

Destructive tools (`delete_payment_link`, `cancel_subscription`, `accept_dispute`, `create_payout`, `revoke_connected_account`) are flagged as destructive so the client asks for explicit confirmation before they run. `create_payout` moves money: the tool also tells the assistant to show `get_payout_estimate` first.

## Scopes

When you authorize the app you choose which permissions to grant. You can grant read-only access or add the write permissions you need:

| Scope | What it allows | Endpoints |
| --- | --- | --- |
| `read` | Read-only | All the `GET` endpoints above. |
| `links:write` | Create, update and delete payment links | `POST/PATCH/DELETE /payment-links`. |
| `charges:write` | Create checkouts and refund sales | `POST /payment-links/{id}/checkout`, `POST /orders/{id}/refund`. |
| `subscriptions:write` | Modify and cancel subscriptions, open the portal | `PATCH /subscriptions/{id}`, `POST /subscriptions/{id}/cancel`, `POST /subscriptions/{id}/portal`. |
| `disputes:write` | Accept disputes (Polar defends them; accepting is the only action) | `POST /disputes/{id}/accept`. |
| `payouts:write` | Withdraw the full available Polar balance to the payout account (moves money) | `POST /payouts`. |
| `account:operate` | Operate connected accounts (marketplace) | `GET /connected-accounts`, `GET` / `DELETE /connected-accounts/{id}`, and create links/checkouts with `connected_account`. |
| `offline_access` | Issue a refresh token so the app stays authorized | — |

A connection without the scope a tool requires receives `403 insufficient_scope` (from the v1 API, with `detail.required_scope` indicating which one is missing).

## Security and revocation

- Access tokens are **opaque** (`vxo_at_…`), live for 1 hour and are stored only hashed on the server.
- `offline_access` issues a refresh token (30 days) to re-issue access without re-authorizing.
- You can view all your connected apps and **revoke** their access from **Desarrolladores → Apps conectadas** in the dashboard; when revoked, that app's tokens stop working.

## See also

- [v1 API reference](/docs/api) — the operations the tools invoke.
- [Sandbox mode](/docs/sandbox-mode) — how to test without moving real money.
- [OpenAPI specification](/docs/openapi) — the spec with the scopes per operation.
