MCP Hub
Back to servers

Money Lover MCP Server

Enables AI assistants to query and manage personal finance data through the unofficial Money Lover REST API. It provides 27 tools covering authentication, wallets, categories, transactions, events, debts, and static configuration with both read and write capabilities.

glama
Updated
Apr 19, 2026

Money Lover MCP Server

Node.js implementation of a Model Context Protocol (MCP) server that wraps the unofficial Money Lover REST API. The server exposes 27 MCP tools covering authentication, wallets, categories, transactions, events, debts, and static configuration — enabling AI assistants or MCP-compatible clients to query and manage personal finance data.

Money Lover Server MCP server

Features

  • Auto-authentication via EMAIL/PASSWORD environment variables — no token passing required for most tools.
  • 23 read tools covering user info, wallets, categories, transactions, events, debts, icons, providers, and static config.
  • 4 write tools: create, update, and delete transactions, wallets, and categories.
  • Large responses truncated automatically to keep LLM context manageable (configurable via limit parameter).
  • Stdio-based server compatible with Claude Code, Claude Desktop, Cursor, and any MCP host.
  • Token caching per email under ~/.moneylover-mcp/ with automatic refresh on auth errors.

Prerequisites

  • Node.js 22 or newer.
  • Money Lover account credentials.

Installation

npm install

Usage

Launch the MCP server over stdio:

npm start

Project-scoped Configuration (Claude Code)

Add .mcp.json at the project root:

{
  "mcpServers": {
    "mcp-moneylover": {
      "command": "node",
      "args": ["/absolute/path/to/moneylover-mcp/src/server.js"],
      "env": {
        "EMAIL": "your@email.com",
        "PASSWORD": "your-password"
      }
    }
  }
}

And enable it in .claude/settings.json:

{ "enabledMcpjsonServers": ["mcp-moneylover"] }

Global Configuration (Claude Desktop / Cursor)

{
  "mcpServers": {
    "mcp-moneylover": {
      "command": "npx",
      "args": ["@ferdhika31/moneylover-mcp@latest"],
      "env": {
        "EMAIL": "your@email.com",
        "PASSWORD": "your-password"
      }
    }
  }
}

Available Tools

Auth

ToolDescriptionArguments
loginRetrieve a JWT token.email, password

User

ToolDescriptionArguments
get_user_infoProfile associated with the session.
get_user_accountDevices and active sessions.
get_user_profileExtended profile data.

Wallets

ToolDescriptionArguments
get_walletsList all wallets.
get_wallet_balanceBalance summary for a wallet.walletId
get_shared_walletsWallets shared with other users.
get_awaiting_shared_walletsPending share invitations.
add_walletCreate a new wallet.name, currencyId; optional icon
edit_walletUpdate wallet name, icon, or currency.walletId, currencyId (required by API); optional name, icon
delete_walletDelete a wallet permanently.walletId

Categories

ToolDescriptionArguments
get_categoriesCategories for a specific wallet.walletId
get_all_categoriesAll categories across every wallet.optional limit (default 50)
add_categoryCreate a category in a wallet.walletId, name, icon (use get_icons to get valid names, e.g. icon_3), type (1=income, 2=expense)
edit_categoryRename a category or change its icon.categoryId, icon (required by API even when only renaming); optional name
delete_categoryDelete a category.categoryId

Transactions

ToolDescriptionArguments
get_transactionsTransactions in a date range.walletId, startDate, endDate (YYYY-MM-DD)
add_transactionCreate a transaction. Category IDs from get_categories are resolved to global IDs automatically.walletId, categoryId, amount, date; optional note, with
edit_transactionUpdate a transaction. The API requires the full payload on every edit — fetch the transaction first if you need current values. categoryId is resolved to global automatically.transactionId, walletId, categoryId, amount, date; optional note, with
delete_transactionDelete a transaction.transactionId
search_transactionsFree-form search with optional filters.optional filters, limit (default 20)
get_debt_transactionsTransactions flagged as debts/loans.
get_related_transactionsRelated transactions by ID list.ids (array)
get_related_transactions_by_categoryRelated transactions for a category.categoryId
get_related_transactions_by_walletRelated transactions for a wallet.walletId
get_transaction_search_configAvailable search filter options.optional limit (default 20)

Static & Config

ToolDescriptionArguments
get_eventsSaving goals/events for a wallet.walletId; optional limit (default 50)
get_debtsOpen debts in a wallet.walletId
get_iconsIcon pack metadata.optional pack (default "default")
get_linked_providersSupported bank providers.
get_currenciesCurrency catalogue.optional limit (default 100)
get_exchange_ratesUSD-based exchange rate snapshot.
get_other_configMiscellaneous runtime configuration.

Tool Usage Examples

Prompt examples, required vs optional fields, gotchas, and common multi-step patterns for every tool: docs/examples.md.

Library Usage

import { MoneyloverClient } from './src/moneyloverClient.js';

const token = await MoneyloverClient.getToken(email, password);
const client = new MoneyloverClient(token);

const wallets = await client.getWallets();
const txns = await client.getTransactions(walletId, '2026-01-01', '2026-04-30');
await client.addTransaction({ walletId, categoryId, amount: '50000', date: '2026-04-18' });
await client.editTransaction('txn-id', { amount: '60000', note: 'updated' });
await client.deleteTransaction('txn-id');

Testing

Unit Tests

Mocked unit tests — no live API calls required:

npm test

Integration Tests (mcp-tester)

mcp-tester is a ReAct-agent-based MCP testing framework. It starts the server, drives an LLM to call tools in response to natural-language prompts, and asserts the correct tools were called with correct arguments.

Install

pipx install --index-url https://pypi.artifacts.furycloud.io/simple/ mcp-tester

Configure

tests/mcp-tester/mcps.json — point at the local server with your credentials:

{
  "mcp-moneylover": {
    "command": "node",
    "args": ["/absolute/path/to/src/server.js"],
    "transport": "stdio",
    "env": {
      "EMAIL": "your@email.com",
      "PASSWORD": "your-password"
    }
  }
}

Run

mcp-tester run-tests \
  --mcps tests/mcp-tester/mcps.json \
  --model gpt-4o-mini \
  --concurrent-runs 3 \
  tests/mcp-tester/read-tools.yaml

Results

tests/mcp-tester/read-tools.yaml contains 25 integration tests covering every read tool:

total 25, success 25, failures 0

Key decisions that make the tests stable:

  • No token parameter on read tools — exposing an optional token field caused LLMs to inject wallet IDs into it. The server authenticates automatically via env vars.
  • Response truncation — several endpoints return hundreds of thousands of records from the shared MoneyLover database. Tools accept a limit parameter (default: 20–100) to keep LLM context under control.
  • Dict wrapping — all tool responses return a JSON object (never a bare array) so MCP framework validation passes.

Write-Tool Tests (mcp-tester)

Three additional YAML files test the full CRUD lifecycle for wallets, categories, and transactions across three sequential phases. Each phase runs all three resource types concurrently.

FilePhaseTests
write-create.yamlCreateadd_wallet, add_category, add_transaction
write-edit.yamlEditedit_wallet, edit_category, edit_transaction
write-delete.yamlDeletedelete_wallet, delete_category, delete_transaction

Run phases in order — each depends on the previous:

# Phase 1: Create
mcp-tester run-tests --mcps tests/mcp-tester/mcps.json --model gpt-4o-mini --concurrent-runs 3 tests/mcp-tester/write-create.yaml

# Phase 2: Edit (after Phase 1 passes)
mcp-tester run-tests --mcps tests/mcp-tester/mcps.json --model gpt-4o-mini --concurrent-runs 3 tests/mcp-tester/write-edit.yaml

# Phase 3: Delete (after Phase 2 passes)
mcp-tester run-tests --mcps tests/mcp-tester/mcps.json --model gpt-4o-mini --concurrent-runs 3 tests/mcp-tester/write-delete.yaml

Results across all three phases:

Phase 1 (Create): total 3, success 3, failures 0
Phase 2 (Edit):   total 3, success 3, failures 0
Phase 3 (Delete): total 3, success 3, failures 0

Key design decisions for write-tool tests:

  • Discovery before mutation — Edit and delete tests instruct the agent to first call a read tool (get_wallets, get_categories, get_transactions) to locate the target by name, then call the mutation tool. This mirrors real-world agent behaviour where IDs are not known in advance.
  • args: !any for write tool assertions — The framework requires exact arg matching. Write tools accept optional fields (icon, with, etc.) that the agent may include at its discretion; !any verifies the tool was called and succeeded without failing on harmless extras. Read-tool assertions can use exact arg matching because their schemas have no optional fields the LLM would add spontaneously.
  • Predictable identifiers — Test resources use fixed names (MCP-Test-Wallet, MCP-Test-Category) and a fixed note (MCP test transaction) so the agent can locate them by name during the edit and delete phases without needing to share state between test runs.
  • Full-payload edit assertionsedit_transaction is a full-replace operation; the test prompt instructs the agent to fetch the existing transaction first (get_transactions) and carry forward all current field values, only changing the note. This validates the multi-step reasoning the tool description requires.

Security Notes

  • Never commit real credentials or tokens.
  • Cached tokens live in ~/.moneylover-mcp/ restricted to the current user.
  • Delete that directory to revoke all cached sessions.

Reviews

No reviews yet

Sign in to write a review