loading…
Search for a command to run...
loading…
Enables AI assistants to query and manage personal finance data through the unofficial Money Lover REST API. It provides 27 tools covering authentication, walle
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.
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.
EMAIL/PASSWORD environment variables — no token passing required for most tools.limit parameter).~/.moneylover-mcp/ with automatic refresh on auth errors.npm install
Launch the MCP server over stdio:
npm start
Add .mcp.json at the project root:
{
"mcpServers": {
"mcp-moneylover": {
"command": "node",
"args": ["/absolute/path/to/moneylover-mcp/src/server.js"],
"env": {
"EMAIL": "[email protected]",
"PASSWORD": "your-password"
}
}
}
}
And enable it in .claude/settings.json:
{ "enabledMcpjsonServers": ["mcp-moneylover"] }
{
"mcpServers": {
"mcp-moneylover": {
"command": "npx",
"args": ["@ferdhika31/moneylover-mcp@latest"],
"env": {
"EMAIL": "[email protected]",
"PASSWORD": "your-password"
}
}
}
}
| Tool | Description | Arguments |
|---|---|---|
login |
Retrieve a JWT token. | email, password |
| Tool | Description | Arguments |
|---|---|---|
get_user_info |
Profile associated with the session. | — |
get_user_account |
Devices and active sessions. | — |
get_user_profile |
Extended profile data. | — |
| Tool | Description | Arguments |
|---|---|---|
get_wallets |
List all wallets. | — |
get_wallet_balance |
Balance summary for a wallet. | walletId |
get_shared_wallets |
Wallets shared with other users. | — |
get_awaiting_shared_wallets |
Pending share invitations. | — |
add_wallet |
Create a new wallet. | name, currencyId; optional icon |
edit_wallet |
Update wallet name, icon, or currency. | walletId, currencyId (required by API); optional name, icon |
delete_wallet |
Delete a wallet permanently. | walletId |
| Tool | Description | Arguments |
|---|---|---|
get_categories |
Categories for a specific wallet. | walletId |
get_all_categories |
All categories across every wallet. | optional limit (default 50) |
add_category |
Create 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_category |
Rename a category or change its icon. | categoryId, icon (required by API even when only renaming); optional name |
delete_category |
Delete a category. | categoryId |
| Tool | Description | Arguments |
|---|---|---|
get_transactions |
Transactions in a date range. | walletId, startDate, endDate (YYYY-MM-DD) |
add_transaction |
Create a transaction. Category IDs from get_categories are resolved to global IDs automatically. |
walletId, categoryId, amount, date; optional note, with |
edit_transaction |
Update 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_transaction |
Delete a transaction. | transactionId |
search_transactions |
Free-form search with optional filters. | optional filters, limit (default 20) |
get_debt_transactions |
Transactions flagged as debts/loans. | — |
get_related_transactions |
Related transactions by ID list. | ids (array) |
get_related_transactions_by_category |
Related transactions for a category. | categoryId |
get_related_transactions_by_wallet |
Related transactions for a wallet. | walletId |
get_transaction_search_config |
Available search filter options. | optional limit (default 20) |
| Tool | Description | Arguments |
|---|---|---|
get_events |
Saving goals/events for a wallet. | walletId; optional limit (default 50) |
get_debts |
Open debts in a wallet. | walletId |
get_icons |
Icon pack metadata. | optional pack (default "default") |
get_linked_providers |
Supported bank providers. | — |
get_currencies |
Currency catalogue. | optional limit (default 100) |
get_exchange_rates |
USD-based exchange rate snapshot. | — |
get_other_config |
Miscellaneous runtime configuration. | — |
Prompt examples, required vs optional fields, gotchas, and common multi-step patterns for every tool: docs/examples.md.
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');
Mocked unit tests — no live API calls required:
npm test
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.
pipx install --index-url https://pypi.artifacts.furycloud.io/simple/ mcp-tester
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": "[email protected]",
"PASSWORD": "your-password"
}
}
}
mcp-tester run-tests \
--mcps tests/mcp-tester/mcps.json \
--model gpt-4o-mini \
--concurrent-runs 3 \
tests/mcp-tester/read-tools.yaml
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:
token field caused LLMs to inject wallet IDs into it. The server authenticates automatically via env vars.limit parameter (default: 20–100) to keep LLM context under control.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.
| File | Phase | Tests |
|---|---|---|
write-create.yaml |
Create | add_wallet, add_category, add_transaction |
write-edit.yaml |
Edit | edit_wallet, edit_category, edit_transaction |
write-delete.yaml |
Delete | delete_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:
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.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.edit_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.~/.moneylover-mcp/ restricted to the current user.Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"money-lover-mcp-server": {
"command": "npx",
"args": []
}
}
}