{"_id":"@alemuenchen/moneymoney-mcp","_rev":"2-48d951c7980327525aa3fd48fd1bc163","name":"@alemuenchen/moneymoney-mcp","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@alemuenchen/moneymoney-mcp","version":"1.0.0","keywords":["mcp","model-context-protocol","moneymoney","banking","personal-finance","macos","applescript","claude","anthropic"],"author":{"name":"Alessandro Melazzini"},"license":"MIT","_id":"@alemuenchen/moneymoney-mcp@1.0.0","maintainers":[{"name":"alemuenchen","email":"alessandro@melazzini.com"}],"homepage":"https://github.com/alemuenchen/moneymoney-mcp#readme","bugs":{"url":"https://github.com/alemuenchen/moneymoney-mcp/issues"},"os":["darwin"],"bin":{"moneymoney-mcp":"dist/index.js"},"dist":{"shasum":"77feb15e31cf0d5bf1f42158dcc52888645ba864","tarball":"https://registry.npmjs.org/@alemuenchen/moneymoney-mcp/-/moneymoney-mcp-1.0.0.tgz","fileCount":95,"integrity":"sha512-siT80JJXwxeSDmUMuh4kqJR8dXnP4E3e08W8JBoBLTg0gIuxWdoYdsrwfRc3KQbAiiGU6XFdjmdTRoCbC25Yjw==","signatures":[{"sig":"MEUCIQDTyMMPvfXux9aPccR3vv3GpCmslPKX9kYzT011jT7zLgIgIyzk1T2vZKdr1dXQ6F2yI+I/wUbZywwE+nTaWvuZF5s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alemuenchen%2fmoneymoney-mcp@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":215776},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"932da6914e67478757ebb382abdfda64e4cd7d6f","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","start":"node dist/index.js","inspect":"npx @modelcontextprotocol/inspector node dist/index.js","prepack":"npm run build","test:watch":"vitest"},"_npmUser":{"name":"alemuenchen","email":"alessandro@melazzini.com"},"repository":{"url":"git+https://github.com/alemuenchen/moneymoney-mcp.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP server for the MoneyMoney macOS banking app. Exposes accounts, transactions, categories, portfolio, and analytics tools to LLM hosts via the Model Context Protocol. macOS-only, single-user, AppleScript-based.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"zod":"^3.23.0","plist":"^3.1.0","moneymoney":"^1.3.0","@modelcontextprotocol/sdk":"^1.12.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.7.0","@types/node":"^22.0.0","@types/plist":"^3.0.5"},"_npmOperationalInternal":{"tmp":"tmp/moneymoney-mcp_1.0.0_1778944224427_0.7273710261540787","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@alemuenchen/moneymoney-mcp","version":"1.0.2","description":"MCP server for the MoneyMoney macOS banking app. Exposes accounts, transactions, categories, portfolio, and analytics tools to LLM hosts via the Model Context Protocol. macOS-only, single-user, AppleScript-based.","type":"module","main":"dist/index.js","bin":{"moneymoney-mcp":"dist/index.js"},"scripts":{"build":"tsc","start":"node dist/index.js","dev":"tsc --watch","test":"vitest run","test:watch":"vitest","inspect":"npx @modelcontextprotocol/inspector node dist/index.js","prepack":"npm run build"},"engines":{"node":">=20"},"os":["darwin"],"keywords":["mcp","model-context-protocol","moneymoney","banking","personal-finance","macos","applescript","claude","anthropic"],"license":"MIT","author":{"name":"Alessandro Melazzini"},"repository":{"type":"git","url":"git+https://github.com/alemuenchen/moneymoney-mcp.git"},"bugs":{"url":"https://github.com/alemuenchen/moneymoney-mcp/issues"},"homepage":"https://github.com/alemuenchen/moneymoney-mcp#readme","dependencies":{"@modelcontextprotocol/sdk":"^1.12.0","moneymoney":"^1.3.0","plist":"^3.1.0","zod":"^3.23.0"},"devDependencies":{"@types/node":"^22.0.0","@types/plist":"^3.0.5","typescript":"^5.7.0","vitest":"^2.1.0"},"gitHead":"219ad57175c3df8be20a4711be06c859532bd9e4","types":"./dist/index.d.ts","_id":"@alemuenchen/moneymoney-mcp@1.0.2","_nodeVersion":"20.20.2","_npmVersion":"11.16.0","dist":{"integrity":"sha512-bicJ0Qy1700cu+RKefRuhHWvcE/Y6r5oolC6SJnxBynHrcdgxFhuDQkS9/pYl7E0X+aFByq5BH1+P39ZsiBoEg==","shasum":"cdbdaaa50b41c7320a50122bebd2f5731a38056d","tarball":"https://registry.npmjs.org/@alemuenchen/moneymoney-mcp/-/moneymoney-mcp-1.0.2.tgz","fileCount":95,"unpackedSize":219077,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alemuenchen%2fmoneymoney-mcp@1.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGPG12c1xKr9PiL17OQS7uN21I2XSi5U3SwP4ijBLmIqAiAxKnG9pxT2ok9pnPyFphAWa/OCdahGpSwHKlt4X04Dfg=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fa3e8838-2543-4063-b5a9-d50f03bfb8af"}},"directories":{},"maintainers":[{"name":"alemuenchen","email":"alessandro@melazzini.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/moneymoney-mcp_1.0.2_1780237667566_0.08930954130970692"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-16T15:10:24.313Z","modified":"2026-05-31T14:27:47.998Z","1.0.0":"2026-05-16T15:10:24.581Z","1.0.2":"2026-05-31T14:27:47.751Z"},"bugs":{"url":"https://github.com/alemuenchen/moneymoney-mcp/issues"},"author":{"name":"Alessandro Melazzini"},"license":"MIT","homepage":"https://github.com/alemuenchen/moneymoney-mcp#readme","keywords":["mcp","model-context-protocol","moneymoney","banking","personal-finance","macos","applescript","claude","anthropic"],"repository":{"type":"git","url":"git+https://github.com/alemuenchen/moneymoney-mcp.git"},"description":"MCP server for the MoneyMoney macOS banking app. Exposes accounts, transactions, categories, portfolio, and analytics tools to LLM hosts via the Model Context Protocol. macOS-only, single-user, AppleScript-based.","maintainers":[{"name":"alemuenchen","email":"alessandro@melazzini.com"}],"readme":"# moneymoney-mcp\n\nMCP server for the [MoneyMoney](https://moneymoney-app.com) macOS banking app.\nExposes accounts, categories, transactions, portfolio, and analytics tools to\nLLM hosts via the Model Context Protocol.\n\nSingle-user, runs locally, AppleScript-only — no remote authentication, no\nexternal services. The MoneyMoney app must be **running and unlocked** while\nthe connector is in use.\n\n> **Platform:** macOS only. Requires Node.js ≥ 20 and a recent build of\n> MoneyMoney (the AppleScript dictionary used here has been stable since\n> MoneyMoney 2.4).\n\n## Tools\n\n13 tools, all prefixed `moneymoney_`. Read tools are always available; write\ntools are gated by `MONEYMONEY_ENABLE_WRITES=true`.\n\n### Accounts\n\n- **`moneymoney_list_active_accounts`** — operational accounts only (default\n  recommended starting point).\n- **`moneymoney_list_accounts(include_closed?)`** — all accounts, including\n  archived ones if `include_closed=true`.\n- **`moneymoney_get_account_balance(account_name)`** — balance for a single\n  named account.\n\n### Categories\n\n- **`moneymoney_list_categories`** — all categories with full `path`\n  (e.g. `\"Business > Office > IT\"`) so the LLM can disambiguate\n  duplicate-name branches.\n\n### Transactions\n\n- **`moneymoney_get_transactions(from, to, account_name?, include_closed?,\n  resolve_category?, limit?)`** — date-range export, optionally restricted to\n  one account or one account-group. Each transaction is enriched with\n  `categoryName`/`Path`/`Root` by default. The response is capped at `limit`\n  (default 1000) and reports `total_matched` / `truncated`.\n- **`moneymoney_search_transactions(...)`** — same as above + filters on\n  counterparty name (substring), purpose (substring), amount range, exact\n  category UUID, **or `category_path_prefix`** (entire subtree, e.g.\n  `\"Business\"`), with an optional `limit`.\n\n### Analytics\n\n- **`moneymoney_top_counterparties`** — top N counterparties by absolute\n  total.\n- **`moneymoney_get_recurring`** — subscription / recurring-payment\n  detection by clustering on (counterparty, amount within ±5% with an\n  absolute floor of 1.0).\n- **`moneymoney_compare_periods`** — side-by-side comparison of two date\n  ranges with category-path labels (no UUID cross-reference needed).\n  Totals are reported per currency (`summaryByCurrency`).\n- **`moneymoney_get_category_total`** — sum + count by `category_uuid` OR\n  `category_path_prefix`. Totals are reported per currency\n  (`totalsByCurrency`); the scalar `totalAmount`/`currency` appear only when\n  all matching transactions share one currency.\n- **`moneymoney_get_portfolio`** — securities (stocks, bonds, ETFs) per\n  portfolio account.\n\n### Writes (gated by `MONEYMONEY_ENABLE_WRITES=true`)\n\n- **`moneymoney_add_transaction`** — manual entry on offline accounts.\n- **`moneymoney_create_transfer`** — opens a pre-filled SEPA transfer form\n  (the user must confirm in the MoneyMoney UI; the connector never sends\n  autonomously).\n\n## Account closure heuristic\n\nIf you keep historical accounts in groups whose name matches one of a small\nset of keywords, every tool that returns transactions or aggregates them\n**excludes those accounts by default**. The closure is exposed as\n`isClosed: bool` (plus `parentGroupName` and `parentPath` for context) on\nevery account record.\n\nDefault keywords (case-insensitive, word-bounded, with simple inflection\ntolerance for German/Italian):\n\n```\nclosed, archived, archive, geschlossen, archiv, archiviert,\ninaktiv, chiuso, inattivo\n```\n\nOverride the list with `MONEYMONEY_CLOSED_KEYWORDS` (comma-separated). Set it\nto an empty string to disable the heuristic (every account is treated as\nactive).\n\n```jsonc\n// list_active_accounts (or list_accounts)\n{\n  \"name\": \"Checking — Bank A\",\n  \"uuid\": \"abc-123\",\n  \"isClosed\": false,\n  \"parentGroupName\": \"Personal\",\n  \"parentPath\": \"Personal\",\n  \"balance\": [{ \"amount\": 12345.67, \"currency\": \"EUR\" }],\n  // ...\n}\n```\n\n```jsonc\n// list_accounts(include_closed=true) returns also:\n{\n  \"name\": \"Old account\",\n  \"isClosed\": true,\n  \"parentGroupName\": \"Personal closed\",\n  \"parentPath\": \"Personal > Personal closed\",\n  // ...\n}\n```\n\nTo inspect history (e.g. \"what did I spend in 2018?\"), pass\n`include_closed=true` to `get_transactions` / `search_transactions` /\n`top_counterparties` / etc.\n\n## Category disambiguation\n\nLarger MoneyMoney libraries often have the same category leaf name\n(`Hotel`, `Fees`, `IT`, …) appearing in different branches. Every category\nand every transaction-with-resolution is enriched with `path` so the LLM\ndoesn't mis-classify.\n\n```jsonc\n// list_categories\n{\n  \"name\": \"IT\",\n  \"uuid\": \"cat-IT-business\",\n  \"path\": \"Business > Office > IT\",\n  \"rootName\": \"Business\",\n  \"parentUuid\": \"uuid-business-office\"\n}\n```\n\nTo filter by branch:\n\n```js\n// All business spend, regardless of category leaf\nmoneymoney_search_transactions({ from_date: \"2026-01-01\", category_path_prefix: \"Business\" })\n\n// Only \"office\" spend within business\nmoneymoney_search_transactions({ from_date: \"2026-01-01\", category_path_prefix: \"Business > Office\" })\n\n// Sum of \"Travel > Flights\" for the year\nmoneymoney_get_category_total({ category_path_prefix: \"Travel > Flights\", from_date: \"2026-01-01\" })\n```\n\n`category_path_prefix` is **segment-aware**: `\"Bus\"` does NOT match\n`\"Business\"`. Matching is case-insensitive.\n\n## Account-name expansion\n\n`account_name` accepts either a leaf account name or a group name. Group\nnames expand to all leaf accounts inside (recursively, including nested\ngroups), excluding closed sub-groups unless `include_closed=true`.\n\n```js\n// All transactions on personal accounts in the last 90 days\nmoneymoney_get_transactions({ from_date: \"2026-01-25\", account_name: \"Personal\" })\n\n// All business transactions\nmoneymoney_get_transactions({ from_date: \"2026-01-01\", account_name: \"Business\" })\n\n// One specific account\nmoneymoney_get_transactions({ from_date: \"2026-01-01\", account_name: \"Checking — Bank A\" })\n```\n\nIf the name doesn't resolve, the error includes a list of similar names.\n\n## Configuration\n\n### Claude Desktop\n\nEdit `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"moneymoney\": {\n      \"command\": \"/path/to/moneymoney-mcp/run.sh\",\n      \"args\": [],\n      \"env\": {\n        \"MONEYMONEY_ENABLE_WRITES\": \"false\"\n      }\n    }\n  }\n}\n```\n\n### Claude Code (CLI)\n\nEdit `~/.claude.json` and add to the top-level `mcpServers`:\n\n```json\n{\n  \"mcpServers\": {\n    \"moneymoney\": {\n      \"command\": \"/path/to/moneymoney-mcp/run.sh\",\n      \"args\": [],\n      \"env\": {\n        \"MONEYMONEY_ENABLE_WRITES\": \"false\"\n      }\n    }\n  }\n}\n```\n\nThe `run.sh` is self-healing: it rebuilds `dist/` if `src/` changes and\nruns `npm ci` if `package-lock.json` changes (lockfile-strict, reproducible).\nThis means the first invocation after a clone — or after pulling updates —\nwill block briefly while it installs/builds. If your MCP host is sensitive\nto startup latency, run `npm ci && npm run build` once manually after\ncloning so subsequent launches are instant.\n\n### Environment variables\n\n| Variable | Default | Effect |\n|---|---|---|\n| `MONEYMONEY_ENABLE_WRITES` | `false` | Set to `true` to enable `add_transaction` and `create_transfer`. |\n| `MONEYMONEY_CLOSED_KEYWORDS` | _(see above)_ | Comma-separated keywords used by the closed-account heuristic. Empty string disables it. |\n| `MONEYMONEY_LOG_LEVEL` | `info` | Set to `debug` for verbose logs in `logs/moneymoney_mcp.log`. **Warning:** at any level, error log lines may include account names, category paths, counterparty names, or other parameters echoed by MoneyMoney; `debug` additionally captures the first 80 chars of every AppleScript command, which can contain partial IBANs or amounts. |\n| `MONEYMONEY_LOG_DIR` | `<project>/logs` | Absolute path of the directory for the log files. `run.sh` sets this to the project's `logs/`. If the directory is not writable, file logging is disabled and logs go to stderr only. |\n| `MONEYMONEY_DEBUG_ERRORS` | `false` | Set to `true` to include raw `osascript` stderr in error responses sent to the model. Off by default because that output can echo account names, counterparties, or amounts; when off, errors carry `raw_stderr_suppressed: true` and the full stderr is still written to the local error log. |\n\n## Security notes\n\n- All AppleScript built by this connector goes through an explicit escape\n  layer (`escapeAppleScriptString`); injection regressions are covered by\n  the tests in `tests/applescript.test.ts` and `tests/writes.test.ts`.\n- Write tools never trigger a transfer autonomously: `create_transfer`\n  opens the MoneyMoney payment window pre-filled, and the user must confirm.\n- The connector requires the MoneyMoney database to be unlocked. It does\n  not store, transmit, or attempt to discover the database password.\n- `npm audit --omit=dev` returns **0 vulnerabilities**. The dev-only\n  toolchain (`vitest` / `vite` / `esbuild`) carries advisories that only\n  apply when their dev server is exposed to the network; they have no\n  effect on the published runtime.\n- Report security issues privately by opening a draft security advisory\n  on the GitHub repo (Security → Report a vulnerability).\n\n## Development\n\n```bash\nnpm ci                # reproducible install (uses package-lock.json)\nnpm run build         # tsc → dist/\nnpm test              # vitest run\nnpm run dev           # tsc --watch\n```\n\nTest suite covers: AppleScript escape and write-script injection regression,\nISO date validation (incl. `2026-02-31` rejection and timezone-correct\nformatting), error classification, recurring-detection clustering,\naccount/category hierarchy reconstruction, `isClosed` inference (with env\noverride), `resolveAccountUuids` (leaf, group expansion,\ncase-insensitivity), category path-prefix matching with duplicate-name\ndisambiguation.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","readmeFilename":"README.md"}