Skip to main content
Glama
SqREL

monobank-mcp

by SqREL
README.md
# monobank-mcp

MCP server for the [Monobank open API](https://api.monobank.ua/docs/index.html): exchange rates, account and jar balances, and statements, exposed as tools for Claude Code, Claude Desktop, or any MCP client.

## Tools

| Tool | Token | What it returns |
|------|-------|-----------------|
| `get_currency_rates` | no | Monobank buy/sell/cross rates, optionally filtered by alpha code (`USD`, `EUR`, ...) |
| `get_bank_public_key` | no | The bank's secp256k1 public key, key id, and server time (for webhook signature checks) |
| `get_client_info` | yes | Name, accounts (balance, credit limit, own funds, IBAN, masked PAN), jars, managed FOP clients |
| `get_statement` | yes | Transactions for an account or jar in a window, with per-currency income/expense totals |
| `set_webhook` | yes | Replaces (or clears, with `""`) the single HTTPS URL that receives balance-change events |

Amounts are converted from the bank's minor units to major units (`-950` UAH, not `-95000`), currency codes are mapped from ISO 4217 numeric to alpha, and timestamps are ISO 8601. A datetime without an offset is read as UTC. A rate pair `USD/UAH` with `buy` 44.46 means the bank buys 1 USD for 44.46 UAH. For a purchase in a foreign currency the bank reports the foreign leg without its currency code, so it is passed through as `operationAmountMinorUnitsInTransactionCurrency`.

## Bank-side limits the server enforces

- Personal endpoints accept one call per endpoint per 60 seconds. Identical requests inside that window share one cached response. A different request to the same endpoint (including set_webhook) waits for the next free slot for up to 35 seconds, which keeps a tool call under the usual 60-second MCP request timeout; a longer wait fails fast and says how many seconds to retry in. A slot is never handed back after a request may have reached the bank, and a real 429 pushes the next slot out a full minute. Two processes sharing one token cannot see each other's calls, so run one server per token.
- Every request has a 20-second timeout covering headers and body. Responses are shared between concurrent identical calls, so cancelling one MCP request does not abort the bank call for the others.
- A statement window may span at most 31 days plus 1 hour, measured against now when `to` is omitted. Longer windows are rejected before any network call; ask for the range in several calls.
- Times are unix seconds, `YYYY-MM-DD`, or `YYYY-MM-DDTHH:MM[:SS][Z|+HH:MM]`; nothing else is accepted, and impossible dates are rejected rather than rolled over. A bare date as `from` means midnight UTC; as `to` it means the last second of that day. An omitted `to` is the start of the current minute, sent explicitly and reported back, so consecutive windows can be chained exactly.
- Public currency rates are cached for 5 minutes, matching the bank's refresh cadence.
- Clients under 16 cannot use the API; children's accounts are visible from the parent's token.

## Setup

1. Get a personal token at <https://api.monobank.ua/> (sign in with the Monobank app). It grants read access to every account on the profile, so treat it like a password.
2. Build:

   ```sh
   npm install
   npm run build
   ```

3. Register with Claude Code:

   ```sh
   claude mcp add monobank -e MONOBANK_TOKEN=your_token -- node /absolute/path/to/monobank-mcp/dist/index.js
   ```

   Or in Claude Desktop's `claude_desktop_config.json`:

   ```json
   {
     "mcpServers": {
       "monobank": {
         "command": "node",
         "args": ["/absolute/path/to/monobank-mcp/dist/index.js"],
         "env": { "MONOBANK_TOKEN": "your_token" }
       }
     }
   }
   ```

Without `MONOBANK_TOKEN` the public tools still work; the personal ones return an error explaining how to get a token.

## Development

```sh
npm test            # vitest, no network
npm run typecheck
npm run dev         # run from source over stdio
```

Tests exercise the server through an in-memory MCP client with a fake `fetch`, so nothing touches the bank.

## API notes

The OpenAPI document is embedded in the Redoc page at `https://api.monobank.ua/docs/index.html` (there is no separate JSON URL); this server was written against version v250818. The corporate API for service providers is a different, signature-authenticated API and is out of scope here.

TDQS

A4.4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a distinct concern: public rates, public key verification, client account data, webhook configuration, and transaction statements. There is no overlap or ambiguity between their purposes.

Naming Consistency5/5

All read-oriented tools follow the consistent get_<resource> pattern, and the single mutating tool uses the equally clear set_webhook. The naming is predictable and immediately conveys the action and target.

Tool Count5/5

Five tools is an appropriate, well-scoped surface for a Monobank integration. Each tool maps to a core API capability without unnecessary duplication or bloat.

Completeness5/5

The toolset covers the essential Monobank operations: rates, client info, statements, webhook setup, and the public key needed for webhook verification. There are no obvious dead ends or missing domain-critical operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues