{"id":51673070,"url":"https://github.com/daniel5151/lunch-money-mcp-ro","last_synced_at":"2026-07-15T02:34:02.872Z","repository":{"id":364184002,"uuid":"1261388093","full_name":"daniel5151/lunch-money-mcp-ro","owner":"daniel5151","description":"Allow LLMs to read and analyze your financial data from Lunch Money, without granting them the ability to change anything.","archived":false,"fork":false,"pushed_at":"2026-06-19T21:36:18.000Z","size":100,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-19T23:13:32.002Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daniel5151.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-06T16:07:40.000Z","updated_at":"2026-06-19T21:36:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/daniel5151/lunch-money-mcp-ro","commit_stats":null,"previous_names":["daniel5151/lunch-money-mcp-ro"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/daniel5151/lunch-money-mcp-ro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel5151%2Flunch-money-mcp-ro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel5151%2Flunch-money-mcp-ro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel5151%2Flunch-money-mcp-ro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel5151%2Flunch-money-mcp-ro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daniel5151","download_url":"https://codeload.github.com/daniel5151/lunch-money-mcp-ro/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel5151%2Flunch-money-mcp-ro/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35488230,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-15T02:00:06.706Z","response_time":131,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-15T02:34:02.744Z","updated_at":"2026-07-15T02:34:02.864Z","avatar_url":"https://github.com/daniel5151.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lunch Money MCP Server (Read-Only)\n\nA lightweight, token-efficient Model Context Protocol (MCP) server for [Lunch Money](https://lunchmoney.dev/), a developer-friendly personal finance and budgeting platform.\n\nThis server allows LLMs (like Claude Desktop, Cursor, or other MCP clients) to read and analyze your financial data—including transactions, accounts, categories, and budget summaries—in a secure, **read-only** manner.\n\n\u003e [!TIP]\n\u003e **Why Read-Only? (Security \u0026 Philosophy)**\n\u003e\n\u003e Ideally, Lunch Money API keys would be permission-scoped. However, because they currently grant full access to your account, this implementation explicitly omits all write capabilities to provide defense-in-depth security.\n\u003e\n\u003e Unlike [other Lunch Money MCP servers](https://lunchmoney.app/developers#mcp-servers), this codebase does not offer *any* APIs or tools for tweaking or modifying your data. While you might be comfortable letting LLMs skim through your sensitive financial data to analyze trends, you likely do *not* want a tool-using agent (especially when run with options like `--dangerously-skip-permissions`) to be able to make edits or alter your finances.\n\n---\n\n## Features\n\n- **Read-Only Security**: Only retrieves data (`GET` requests). No destructive or modifying actions are supported.\n- **Strict Input Validation**: Uses `ajv` (v8) and `ajv-formats` for validating input arguments against defined tool schemas.\n- **MCP Resources**: Exposes system-level data such as accounts list and budget settings directly as MCP resources.\n- **MCP Prompts**: Includes handy pre-packaged prompts (`analyze_spending` and `find_untagged`) for spending analysis and tag suggestion.\n- **Performance Caching**: In-memory caching for `categories` and `tags` (60s TTL) to minimize redundant external API requests and lower latency.\n- **Token Efficient**: Structurally optimized JSON payloads designed to minimize prompt token overhead. Empty arrays, empty objects, null, undefined, and empty string properties are stripped recursively. Highly meaningful boolean states (like `false` for pending status) are preserved.\n- **Strict UTC Date Math**: Timeframe resolutions (like `this_month` or `last_year`) are calculated relative to UTC timezone, preventing local timezone offset shifts from altering query boundaries.\n- **Flexible Output Formatting**: All tools support a global `output_format` parameter (`\"markdown\"` or `\"json\"`). The default `\"markdown\"` output renders data into clean, readable Markdown tables and bullet points for the LLM.\n\n---\n\n## Prerequisites\n\n- **Node.js**: Version `20.6.0` or higher (utilizes native `process.loadEnvFile`).\n- **Lunch Money API Token**: A developer API key. You can generate one in your [Lunch Money Developer Settings](https://lunchmoney.dev/developers).\n\n---\n\n## Installation\n\n1. Clone or copy this repository to your local machine:\n   ```bash\n   git clone \u003crepository-url\u003e\n   cd lunch-money-mcp-ro\n   ```\n\n2. Install dependencies:\n   ```bash\n   npm install\n   ```\n\n---\n\n## Configuration\n\nThe server requires your Lunch Money API key, set as `LUNCHMONEY_API_KEY`.\n\nYou can configure this in two ways:\n\n### 1. Using a `.env` File\nCreate a `.env` file in the project's root directory:\n```env\nLUNCHMONEY_API_KEY=your_lunch_money_api_key_here\n```\n\n### 2. Environment Variable\nAlternatively, set the environment variable when configuring your MCP server:\n```json\n\"lunchmoney-readonly\": {\n  \"command\": \"node\",\n  \"args\": [\n    \"/path/to/lunch-money-mcp-ro.js\"\n  ],\n  \"env\": {\n    \"LUNCHMONEY_API_KEY\": \"your_lunch_money_api_key_here\"\n  }\n}\n```\n\n### Optional: targeting a different API base\n\nBy default the server talks to `https://api.lunchmoney.dev/v2`. Set\n`LM_API_BASE_URL` to point it at a different host — used by the test suite to\nrun against a local mock, and useful for a staging endpoint:\n\n```sh\nLM_API_BASE_URL=http://127.0.0.1:8787/v2 node lunch-money-mcp-ro.js\n```\n\n---\n\n## Testing\n\nEnd-to-end tests run the real server against the official Lunch Money v2 static\nmock API (`mock.lunchmoney.dev/v2`) — no real API key and no account needed.\n`npm test` starts a local relay automatically, then drives the server over\nstdio JSON-RPC and asserts on the rendered output:\n\n```sh\nnpm test\n```\n\nSee [`test/README.md`](test/README.md) for what is covered and how to extend\nit, and [`test/MOCK-SERVER.md`](test/MOCK-SERVER.md) for the mock and relay\ndetails.\n\n---\n\n## MCP Resources\n\nThe following resources are exposed:\n\n- **`lunchmoney://budget/settings`**: General budget settings including primary currency.\n- **`lunchmoney://accounts`**: List of all manual and Plaid-synced accounts.\n\n---\n\n## MCP Prompts\n\nThe following prompts are preconfigured:\n\n- **`analyze_spending`**: Analyzes spending trends and budget summaries for a given timeframe.\n  - *Arguments*: `timeframe` (string, optional - e.g., `this_month`, `last_month`, `year_to_date`)\n- **`find_untagged`**: Identifies transactions that do not have any tags applied and suggests relevant tags.\n\n---\n\n## Available MCP Tools\n\nAll tools accept a global parameter:\n- `output_format` (string, optional, default: `\"markdown\"`): Renders response as `\"markdown\"` (formatted tables/lists) or `\"json\"`.\n\n### 1. `list_transactions`\nSearch, filter, and list historical transactions.\n\n\u003e [!NOTE]\n\u003e **Performance \u0026 Recursive Fetching**\n\u003e Using `search`, `category_ids`, or `category_group_id` triggers in-memory filtering because the Lunch Money API doesn't support these parameters natively. The server will recursively page through the API (up to a safety limit of 50,000 transactions) to retrieve the complete candidate set. Always specify a timeframe (e.g. `this_month`, `year_to_date`) when using these filters to optimize performance and avoid excessive API requests.\n\n- **Arguments**:\n  - `start_date` (string, optional): Format `YYYY-MM-DD`\n  - `end_date` (string, optional): Format `YYYY-MM-DD`\n  - `timeframe` (string, optional): Predefined timeframe (`this_month`, `last_month`, `year_to_date`, `this_year`, `last_year`). Mutually exclusive with `start_date`/`end_date`.\n  - `created_since` (string, optional): Filter transactions created after this ISO 8601 timestamp.\n  - `updated_since` (string, optional): Filter transactions updated after this ISO 8601 timestamp.\n  - `manual_account_id` (integer, optional): Filter by manual account ID.\n  - `plaid_account_id` (integer, optional): Filter by Plaid-synced account ID.\n  - `recurring_id` (integer, optional): Filter by recurring transaction ID.\n  - `category_id` (integer, optional): Filter by single category ID.\n  - `category_ids` (array of integers, optional): Filter by multiple category IDs.\n  - `category_group_id` (integer, optional): Filter by parent category group ID (resolves to all child categories).\n  - `tag_id` (integer, optional): Filter by tag ID.\n  - `is_group_parent` (boolean, optional): Filter to return only parent transactions of a group.\n  - `status` (string, optional): Filter by transaction status (`reviewed`, `unreviewed`, `delete_pending`).\n  - `is_pending` (boolean, optional): Filter for pending transactions.\n  - `include_pending` (boolean, optional, default: `false`)\n  - `include_metadata` (boolean, optional, default: `false`)\n  - `include_split_parents` (boolean, optional, default: `false`)\n  - `include_group_children` (boolean, optional, default: `false`)\n  - `include_children` (boolean, optional, default: `false`)\n  - `include_files` (boolean, optional, default: `false`)\n  - `limit` (integer, optional, minimum: `1`, maximum: `2000`, default: `1000`): Maximum transactions to return.\n  - `offset` (integer, optional, minimum: `0`): Number of transactions to skip for pagination.\n  - `search` (string, optional, max 100 characters): Search term matched against payee, notes, or original name.\n  - `include_category_names` (boolean, optional, default: `false`): Resolves and includes `category_name` on each transaction.\n  - `include_tag_names` (boolean, optional, default: `false`): Resolves and includes `tag_names` and `tags` objects on each transaction.\n\n### 2. `list_tags`\nList all custom tags.\n- **Arguments**: None\n\n### 3. `get_tag`\nGet details of a single tag by ID.\n- **Arguments** (Required):\n  - `id` (integer): The unique tag ID.\n\n### 4. `get_tags_by_ids`\nGet details for a specific subset of tags by their IDs.\n- **Arguments** (Required):\n  - `ids` (array of integers): An array of tag IDs to resolve.\n\n### 5. `list_recurring_items`\nList recurring transaction items.\n- **Arguments** (Optional):\n  - `start_date` (string): Format `YYYY-MM-DD`\n  - `end_date` (string): Format `YYYY-MM-DD`\n  - `include_suggested` (boolean): Include system-suggested recurring items.\n  - `status` (string, enum: `[\"suggested\", \"manual\", \"reviewed\"]`): Filter by status.\n\n### 6. `get_recurring_item`\nGet details of a recurring transaction item by ID.\n- **Arguments**:\n  - `id` (integer, Required): The unique recurring item ID.\n  - `start_date` (string, optional): Start date for calculating occurrences (YYYY-MM-DD).\n  - `end_date` (string, optional): End date for calculating occurrences (YYYY-MM-DD).\n\n### 7. `get_budget_settings`\nGet general budget settings including currency.\n- **Arguments**: None\n\n### 8. `get_budget_summary`\nGet budget summary with category totals and usage.\n- **Arguments**:\n  - `start_date` (string, optional): Start date (Required if `timeframe` is omitted).\n  - `end_date` (string, optional): End date (Required if `timeframe` is omitted).\n  - `timeframe` (string, optional): Predefined timeframe (`this_month`, `last_month`, `year_to_date`, `this_year`, `last_year`). Mutually exclusive with `start_date`/`end_date`.\n  - `include_exclude_from_budgets` (boolean, optional, default: `false`)\n  - `include_occurrences` (boolean, optional, default: `false`)\n  - `include_past_budget_dates` (boolean, optional, default: `false`)\n  - `include_totals` (boolean, optional, default: `false`)\n  - `include_rollover_pool` (boolean, optional, default: `false`)\n\n### 9. `list_categories`\nList all categories.\n- **Arguments** (Optional):\n  - `format` (string, enum: `[\"nested\", \"flattened\"]`, default: `\"nested\"`): Format of the categories list.\n  - `is_group` (boolean): Filter for category groups.\n\n### 10. `get_category`\nGet details of a single category by ID.\n- **Arguments** (Required):\n  - `id` (integer): The unique category ID.\n\n### 11. `get_categories_by_ids`\nGet details for a specific subset of categories by their IDs.\n- **Arguments** (Required):\n  - `ids` (array of integers): An array of category IDs to resolve.\n\n### 12. `list_accounts`\nList all manual and Plaid-synced accounts.\n- **Arguments**: None\n\n### 13. `get_manual_account`\nGet details of a manual account by ID.\n- **Arguments** (Required):\n  - `id` (integer): The unique manual account ID.\n\n### 14. `get_plaid_account`\nGet details of a Plaid-synced account by ID.\n- **Arguments** (Required):\n  - `id` (integer): The unique Plaid account ID.\n\n### 15. `get_account`\nGet details of an account by ID, checking both manual and Plaid-synced accounts.\n- **Arguments** (Required):\n  - `id` (integer): The unique account ID.\n\n### 16. `get_current_user`\nGet the current user's profile information.\n- **Arguments**: None\n\n### 17. `get_transaction`\nGet details of a single transaction by ID.\n- **Arguments** (Required):\n  - `id` (integer): The unique transaction ID.\n\n### 18. `get_transaction_attachment_url`\nGet a temporary download URL for a transaction attachment.\n- **Arguments** (Required):\n  - `file_id` (integer): The ID of the attachment file.\n\n### 19. `clear_cache`\nClear the cached accounts data.\n- **Arguments**: None\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniel5151%2Flunch-money-mcp-ro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaniel5151%2Flunch-money-mcp-ro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniel5151%2Flunch-money-mcp-ro/lists"}