npm package: @mangoswapio/mcp-server
Description: MCP server exposing MangoSwap swap tools to AI agents (Cursor, Claude Desktop, etc.)
Latest version: 0.2.0

# @mangoswapio/mcp-server

> MangoSwap swap tools for AI agents — powered by the [Model Context Protocol](https://modelcontextprotocol.io).

Expose MangoSwap's cross-chain swap capabilities directly to AI hosts like **Claude Desktop**, **Cursor**, and any other MCP-compatible agent. Check swap routes, get live price quotes, and track swap status — all from within your AI workflow.

---

## Tools

### Read-only (always available)

| Tool | Description |
|------|-------------|
| `get_routes` | List available swap routes between two tokens/chains |
| `get_quote` | Get a price estimate for a specific swap (amountOut, fee, provider, time) |
| `get_swap_status` | Check the current status of an existing swap by ID |

### Write tools (require `MANGO_ALLOW_WRITE_TOOLS=true`)

| Tool | Description |
|------|-------------|
| `create_swap` | Create and initiate a cross-chain swap — **moves real funds** |

> `create_swap` is disabled by default. Enable it deliberately with `MANGO_ALLOW_WRITE_TOOLS=true` only in autonomous agent contexts where you trust the agent's decision-making.

---

## 5-Minute Quickstart

Get your first `get_quote` call working in under 5 minutes:

**Step 1** — Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):

```json
{
  "mcpServers": {
    "mango-swap": {
      "command": "npx",
      "args": ["@mangoswapio/mcp-server"],
      "env": {
        "MANGO_API_KEY": "your-key-here",
        "MANGO_API_BASE_URL": "https://api.mangoswap.xyz"
      }
    }
  }
}
```

**Step 2** — Restart Claude Desktop.

**Step 3** — Ask Claude:
> "What's the current rate to swap 100 USDC from Base to ETH on Ethereum?"

Claude will call `get_quote` and return an estimate with fee, provider, and time. Done.

> No API key yet? The server works anonymously at a lower rate limit — just omit `MANGO_API_KEY`.

---

## Quick Start (terminal)

### npx (no install)

```bash
MANGO_API_KEY=your-key npx @mangoswapio/mcp-server
```

### Global install

```bash
npm install -g @mangoswapio/mcp-server
MANGO_API_KEY=your-key mangoswap-mcp
```

---

## Configuration

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `MANGO_API_BASE_URL` | No | `https://api.mangoswap.xyz` | MangoSwap API base URL |
| `MANGO_X402_SESSION` | No | — | x402 JWT session token → `Authorization: Bearer` (highest priority) |
| `MANGO_API_KEY` | No | — | API key → `X-Api-Key` header (second priority; bypasses 402 gate) |
| `MANGO_X402_AUTO_PAY` | No | `false` | Auto-pay HTTP 402 responses using the configured wallet |
| `MANGO_WALLET_PRIVATE_KEY` | If auto-pay | — | Hex private key for Base USDC payments. **Never logged.** |
| `MANGO_ALLOW_WRITE_TOOLS` | No | `false` | Expose `create_swap` tool (moves real funds) |

### Auth priority order

The server picks the **first** credential that is set:

1. `MANGO_X402_SESSION` → `Authorization: Bearer <jwt>`
2. `MANGO_API_KEY` → `X-Api-Key: <key>`
3. Anonymous — rate-limited; premium endpoints return HTTP 402

### x402 Auto-pay

When `MANGO_X402_AUTO_PAY=true` and the API returns HTTP 402:
1. The server parses the `accepts` array from the 402 body.
2. Signs an EIP-3009 `transferWithAuthorization` using `MANGO_WALLET_PRIVATE_KEY` (Base USDC).
3. Retries the original request once with the signed `X-Payment` header.
4. If the retry also fails, surfaces the error to the MCP host.

When `MANGO_X402_AUTO_PAY=false` (default), the agent receives a structured error:
```
Payment required to use this tool. Set MANGO_X402_AUTO_PAY=true or provide MANGO_API_KEY.
```

---

## Claude Desktop Setup

Add to your Claude Desktop config file:

- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

### Read-only mode (default — no funds movement)

```json
{
  "mcpServers": {
    "mango-swap": {
      "command": "npx",
      "args": ["@mangoswapio/mcp-server"],
      "env": {
        "MANGO_API_KEY": "your-key-here",
        "MANGO_API_BASE_URL": "https://api.mangoswap.xyz"
      }
    }
  }
}
```

### Write mode (enables `create_swap`)

```json
{
  "mcpServers": {
    "mango-swap": {
      "command": "npx",
      "args": ["@mangoswapio/mcp-server"],
      "env": {
        "MANGO_API_KEY": "your-key-here",
        "MANGO_API_BASE_URL": "https://api.mangoswap.xyz",
        "MANGO_ALLOW_WRITE_TOOLS": "true"
      }
    }
  }
}
```

### Autonomous agent mode (x402 auto-pay)

```json
{
  "mcpServers": {
    "mango-swap": {
      "command": "npx",
      "args": ["@mangoswapio/mcp-server"],
      "env": {
        "MANGO_API_BASE_URL": "https://api.mangoswap.xyz",
        "MANGO_X402_AUTO_PAY": "true",
        "MANGO_WALLET_PRIVATE_KEY": "YOUR_PRIVATE_KEY_NEVER_SHARE",
        "MANGO_ALLOW_WRITE_TOOLS": "true"
      }
    }
  }
}
```

After saving, restart Claude Desktop. The MangoSwap tools will appear in the tool panel.

See [`examples/agent-swap-example.md`](./examples/agent-swap-example.md) for a full worked conversation.

---

## Cursor Setup

Add to `.cursor/mcp.json` in your project root (or `~/.cursor/mcp.json` globally):

```json
{
  "mcpServers": {
    "mango-swap": {
      "command": "npx",
      "args": ["@mangoswapio/mcp-server"],
      "env": {
        "MANGO_API_KEY": "your-api-key-here",
        "MANGO_API_BASE_URL": "https://api.mangoswap.xyz"
      }
    }
  }
}
```

The Cursor rule at `.cursor/rules/mango-swap.mdc` (included in this package) will automatically surface MangoSwap tool guidance when you have `.ts` or `.js` files open.

---

## Staging / Development

Point the server at a local or staging MangoSwap API:

```json
{
  "mcpServers": {
    "mangoswap-staging": {
      "command": "npx",
      "args": ["-y", "@mangoswapio/mcp-server"],
      "env": {
        "MANGO_API_BASE_URL": "https://staging-api.mangoswap.xyz",
        "MANGO_API_KEY": "staging-key"
      }
    }
  }
}
```

---

## Example Agent Interaction

Once installed, you can ask Claude or Cursor:

> "What's the current quote to swap 1 ETH from Base to Arbitrum?"

The agent will call `get_quote` with:
```json
{
  "sourceChainId": 8453,
  "destChainId": 42161,
  "tokenIn": "0x0000000000000000000000000000000000000000",
  "tokenOut": "0x0000000000000000000000000000000000000000",
  "amountIn": "1.0"
}
```

And receive a structured response like:
```
Quote: 1 ETH → ~0.9985 ETH via layerswap (est. 180s, fee: 0.0015)

{
  "amount": "0.9985",
  "amountOut": "0.9985",
  "fee": "0.0015",
  "estimatedTime": 180,
  "provider": "layerswap",
  ...
}
```

---

## Tool Reference

### `get_routes`

List available swap corridors.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sourceChainId` | integer | ✓ | Source chain ID |
| `destChainId` | integer | ✓ | Destination chain ID |
| `tokenIn` | string | ✓ | Token address or symbol (source) |
| `tokenOut` | string | ✓ | Token address or symbol (destination) |

---

### `get_quote`

Get price estimate for a swap.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sourceChainId` | integer | ✓ | Source chain ID |
| `destChainId` | integer | ✓ | Destination chain ID |
| `tokenIn` | string | ✓ | Source token (address or `0x000...000` for native) |
| `tokenOut` | string | ✓ | Destination token |
| `amountIn` | string | ✓ | Amount in human-readable decimals (`"0.05"`) |
| `recipient` | string | – | Recipient address (improves accuracy) |
| `userAddress` | string | – | Sender address (required for BTC source) |

The response always returns HTTP 200. Check the `error` field:
- `null` → quote is valid; use `amountOut`, `fee`, `provider`, `estimatedTime`
- non-null → `minAmount`/`maxAmount` tell you the valid range

---

### `get_swap_status`

Track an in-progress swap.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `swapId` | string | ✓ | Swap UUID from `create_swap` |

Possible statuses: `user_transfer_pending`, `depositing`, `processing`, `swapping`, `completed`, `failed`, `cancelled`

Poll every 10–30 seconds until the status is terminal (`completed`, `failed`, `cancelled`).

---

## Common Chain IDs

| Chain | ID |
|-------|----|
| Ethereum | 1 |
| Base | 8453 |
| Arbitrum | 42161 |
| Optimism | 10 |
| BSC | 56 |
| Polygon | 137 |
| Avalanche | 43114 |
| Solana | 501111 |
| Bitcoin | 0 |

---

## Error Handling

The server returns structured errors with:
- **HTTP 429** — Rate limited. Wait and retry. Provide `MANGO_API_KEY` for higher limits.
- **HTTP 402** — Payment required. Set `MANGO_API_KEY` or use x402 payment (task 16).
- **code: NO_ROUTE** — No bridge path for this pair. Try different tokens or chains.
- **code: AMOUNT_TOO_LOW / AMOUNT_TOO_HIGH** — Adjust `amountIn` to the returned `minAmount`/`maxAmount`.

---

## Contributing

```bash
git clone https://github.com/mangoswap/mango
cd mangoswap/packages/mcp-server
npm install
npm run build
MANGO_API_BASE_URL=https://staging-api.mangoswap.xyz node dist/index.js
```

### Run the MCP Inspector (for debugging)

```bash
npx @modelcontextprotocol/inspector node dist/index.js
```

---

## Roadmap

| Phase | Feature |
|-------|---------|
| D.1 ✅ | Read-only tools: `get_routes`, `get_quote`, `get_swap_status` |
| D.2 ✅ | `create_swap`, x402 auto-pay, tiered auth, secret redaction |
| D.3 ✅ | `@mangoswap/agent-cli` — terminal and CI usage |
| D.4 ✅ | Cursor rule, Claude Desktop config, example conversation |
| D.5 | `get_privacy_quote` — privacy-routed swaps via Houdini Swap |
| D.6 | `get_swap_history` — list past swaps for a wallet address |

---

## License

MIT — © MangoSwap