Skip to main content
Glama
aderik

bitvavo-mcp

by aderik
README.md
# bitvavo-mcp

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![npm version](https://img.shields.io/npm/v/bitvavo-mcp.svg)](https://www.npmjs.com/package/bitvavo-mcp)

An [MCP](https://modelcontextprotocol.io) server that exposes a [Bitvavo](https://bitvavo.com) crypto exchange account as read-only tools for Claude (and other MCP clients).

> ⚠️ Read-only by design. The server only calls Bitvavo endpoints that view information — no trading, no withdrawals. Create your API key with the **View information** scope only.

## What it does

Once connected, Claude can answer questions like:

- *"What is my portfolio worth right now?"*
- *"How much XRP do I hold and what's my average cost basis?"*
- *"Show me my trade history on BTC-EUR."*
- *"What were my last 5 deposits and withdrawals?"*

## Tools

| Tool | Purpose |
|---|---|
| `ping` | Verify the connection and credentials, return server time + fee tier |
| `get_balance` | List per-asset balances (available + in-order) |
| `get_portfolio_value` | Total portfolio value in EUR with breakdown |
| `get_ticker` | 24-hour ticker for one market |
| `get_markets` | List tradable markets, filterable by quote / status |
| `get_trades` | Your filled trades on a specific market |
| `get_deposits` | Deposit history, optionally filtered by asset |
| `get_withdrawals` | Withdrawal history, optionally filtered by asset |
| `get_open_orders` | Orders that are placed but not yet filled |
| `get_pnl` | Average-cost P&L per position, with cost basis + unrealized/realized split |
| `import_transactions` | Import a Bitvavo CSV transaction export into a local SQLite store |
| `get_transactions` | Query the locally-stored transaction history |
| `get_candles` | Historical OHLCV candles for a market (any interval from 1m to 1d) |
| `get_trend` | Multi-period trend digest — 24h/7d/30d/90d/1y % changes plus your cost-basis comparison |

## Install

You need Node.js 18 or later and a Bitvavo API key + secret with **View information** scope ([create one](https://account.bitvavo.com/user/api)).

### Claude Desktop

Open your Claude Desktop config file:

| OS | Path |
|---|---|
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
| Linux | `~/.config/Claude/claude_desktop_config.json` |

Add an entry under `mcpServers`:

```json
{
  "mcpServers": {
    "bitvavo": {
      "command": "npx",
      "args": ["-y", "bitvavo-mcp"],
      "env": {
        "BITVAVO_API_KEY": "your_api_key",
        "BITVAVO_API_SECRET": "your_api_secret"
      }
    }
  }
}
```

Restart Claude Desktop. The Bitvavo tools appear in the tools menu (hammer icon) of any new chat. `npx -y` downloads the latest published version on first run and caches it locally — no manual install step.

### Claude Code

```bash
claude mcp add --scope user bitvavo \
  -e BITVAVO_API_KEY=your_api_key \
  -e BITVAVO_API_SECRET=your_api_secret \
  -- npx -y bitvavo-mcp
```

Use `--scope local` if you only want it active in the current project directory.

### From source

If you want to hack on the code:

```bash
git clone https://github.com/aderik/bitvavo-mcp.git
cd bitvavo-mcp
npm install
npm run build
cp .env.example .env  # then fill in BITVAVO_API_KEY and BITVAVO_API_SECRET
```

Point Claude Desktop at the built file instead of `npx`:

```json
{
  "mcpServers": {
    "bitvavo": {
      "command": "node",
      "args": ["/absolute/path/to/bitvavo-mcp/dist/server.js"]
    }
  }
}
```

The `.env` file is loaded relative to the running script, so credentials are found regardless of which directory Claude spawns the server from. `.env` is gitignored — never commit it.

## Full transaction history via CSV import

Bitvavo's `/trades` and `/orders` REST endpoints expose only **exchange (Advanced) trades**. Transactions made via the **Buy/Sell** or **Convert** UI in the Bitvavo app use a separate brokerage backend and do **not** appear in the API. Staking distributions and rebates aren't in the API either.

To get the complete picture:

1. Download your transaction CSV from Bitvavo: **Account → Transactiegeschiedenis → Exporteren → Volledige geschiedenis** → format CSV.
2. In your Claude chat: *"import_transactions van /pad/naar/Volledige geschiedenis.csv"* — or call the tool directly.
3. Run `get_pnl` again — every traded asset (including fully sold-off positions) now shows its realized P&L, sourced from the imported records.

The data lives in `~/.bitvavo-mcp/transactions.db` (override with `BITVAVO_MCP_DATA_DIR=/some/path`). Re-importing the same CSV is idempotent — rows are matched on Bitvavo's transaction_id.

## Environment variables

| Variable | Required | Purpose |
|---|---|---|
| `BITVAVO_API_KEY` | yes | API key from https://account.bitvavo.com/user/api |
| `BITVAVO_API_SECRET` | yes | The matching secret |
| `BITVAVO_MCP_DATA_DIR` | no | Override the SQLite location (default `~/.bitvavo-mcp/`) |

TDQS

A3.7/5.0

Scored across 14 tools

Disambiguation4/5

Most tools have clearly distinct purposes: ping checks connectivity, get_balance lists balances, get_portfolio_value computes total value, and so on. A few pairs like get_trades vs get_transactions (live vs local) and get_balance vs get_portfolio_value (per-asset vs total) overlap conceptually, but the descriptions clarify the boundaries.

Naming Consistency4/5

The naming is predominantly verb_noun with get_ prefix for data retrieval, import_transactions for ingestion, and ping for health checks. The deviation from get_ is minor and standard, and all names use snake_case consistently, making the set predictable and readable.

Tool Count5/5

14 tools is well within the ideal 3-15 range and appropriately scoped for a cryptocurrency exchange server. Each tool covers a distinct aspect such as market data, balances, history, or analytics, with no redundant or missing obvious tools.

Completeness3/5

The server covers market data, balances, deposits/withdrawals, trades, and local transaction history for P&L, which is substantial. However, it lacks core order management operations like place/cancel order or fetching a single order by ID, leaving a notable gap for a trading-focused exchange MCP.

Maintenance

ActivityInactive
ResponsivenessNo issues