Skip to main content
Glama
robshox

Lunch Money MCP Server

by robshox
README.md
# Lunch Money MCP Server

[TypeScript](https://www.typescriptlang.org/)
[Node.js](https://nodejs.org/)
[License](LICENSE)

A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that enables AI agents to interact with your [Lunch Money](https://lunchmoney.app/) personal finance data.

## Features

This MCP server exposes 15 tools for managing your financial data:

### User & Account

- `get_user` — Get your profile and account information

### Categories

- `get_categories` — List all categories (flattened or nested)
- `create_category` — Create new custom categories
- `update_category` — Modify existing categories

### Transactions

- `get_transactions` — Query transactions with filters (date range, category, status, etc.)
- `create_transaction` — Add new transactions (single or batch up to 500)
- `update_transaction` — Update transactions or split them into multiple entries

### Assets & Accounts

- `get_assets` — List manually managed assets
- `create_asset` — Add new manual assets
- `get_plaid_accounts` — List Plaid-connected bank accounts
- `trigger_plaid_fetch` — Trigger Plaid account sync

### Budgets & Planning

- `get_budgets` — View budgets and spending for any date range
- `upsert_budget` — Set or update budget amounts
- `get_recurring_items` — View recurring expenses and income

### Tags

- `get_tags` — List all transaction tags

## Prerequisites

- [Node.js](https://nodejs.org/) 18 or newer
- A Lunch Money account with API access
- A Lunch Money API key from [the developers page](https://my.lunchmoney.app/developers)

## Installation

### Option 1: Clone and Build (Local stdio transport)

For local use with Cursor, Claude Desktop, or other stdio-based MCP clients:

```bash
# Clone the repository
git clone https://github.com/yourusername/lunchmoney-mcp.git
cd lunchmoney-mcp

# Install dependencies
npm install

# Build the TypeScript
npm run build
```

### Option 2: Cloudflare Workers (Remote HTTP transport)

Deploy as a remote MCP server accessible via HTTP:

```bash
# Clone the repository
git clone https://github.com/yourusername/lunchmoney-mcp.git
cd lunchmoney-mcp

# Install dependencies
npm install

# Set your API key as a secret
npx wrangler secret put LUNCH_MONEY_API_KEY
# Enter your Lunch Money API key when prompted

# Deploy to Cloudflare Workers
npm run deploy
```

### Option 3: Use with npx (Local only)

You can run the MCP server directly without cloning:

```bash
npx -y lunchmoney-mcp
```

*Note: You'll still need to set the `LUNCH_MONEY_API_KEY` environment variable.*

## Configuration

### Getting Your API Key

1. Log in to [Lunch Money](https://my.lunchmoney.app/)
2. Go to [Settings → Developers](https://my.lunchmoney.app/developers)
3. Generate a new API key
4. Copy the key (keep it secure!)

### Cursor IDE

Add to your Cursor MCP configuration (`~/.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "lunchmoney": {
      "command": "node",
      "args": ["/path/to/lunchmoney-mcp/dist/index.js"],
      "env": {
        "LUNCH_MONEY_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

Or with npx:

```json
{
  "mcpServers": {
    "lunchmoney": {
      "command": "npx",
      "args": ["-y", "lunchmoney-mcp"],
      "env": {
        "LUNCH_MONEY_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

### Claude Desktop

Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):

```json
{
  "mcpServers": {
    "lunchmoney": {
      "command": "node",
      "args": ["/path/to/lunchmoney-mcp/dist/index.js"],
      "env": {
        "LUNCH_MONEY_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

### Other MCP Clients

Any MCP client that supports stdio transport can use this server. Set the `LUNCH_MONEY_API_KEY` environment variable and run:

```bash
node /path/to/lunchmoney-mcp/dist/index.js
```

### Remote MCP via Cloudflare Workers (BYO API Key)

The Cloudflare Workers deployment is designed as a **public MCP server** where each user brings their own API key. The server never stores any API keys.

**How it works:**

1. Deploy the server to Cloudflare Workers (or use a shared instance)
2. Each user connects with their own Lunch Money API key
3. The API key is sent with each request in the `X-LunchMoney-API-Key` header

**Connecting with mcp-remote proxy:**

```json
{
  "mcpServers": {
    "lunchmoney": {
      "command": "npx",
      "args": ["mcp-remote", "https://lunchmoney-mcp.your-subdomain.workers.dev/mcp"],
      "env": {
        "MCP_HEADERS": "X-LunchMoney-API-Key: your_api_key_here"
      }
    }
  }
}
```

**Note:** The `mcp-remote` proxy must support custom headers. Some MCP clients may not support this yet.

> ⚠️ **Treat your `mcp.json` file like a credentials file.** It now contains your Lunch Money API key. Never commit it to a Git repository (including dotfiles repos). Add it to `.gitignore` if it lives inside one. Anyone with read access to this file can read and modify your Lunch Money data.

**Security:** This is the most secure model because:

- The server never stores any API keys
- Each user only accesses their own data
- API keys are passed per-request, not stored on the server
- The public worker enforces per-IP rate limiting and never logs request bodies or headers

## Cloudflare Workers Deployment (Public Server)

This creates a **public MCP server** that anyone can use with their own API key. The server doesn't store any credentials.

### Prerequisites

- A Cloudflare account (free tier works)
- [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/) installed

### Deploy

1. **Install dependencies:**
  ```bash
   npm install
  ```
2. **Deploy to Cloudflare Workers:**
  ```bash
   npm run deploy
  ```
3. **Your public MCP server is now live!** The URL will be shown in the output:
  ```
   https://lunchmoney-mcp.your-account.workers.dev/mcp
  ```

**Optional:** You can set a default API key for testing:

```bash
npx wrangler secret put LUNCH_MONEY_API_KEY
```

### How Users Connect

Users connect to your public server with their **own** Lunch Money API key:

```json
{
  "mcpServers": {
    "lunchmoney": {
      "command": "npx",
      "args": ["mcp-remote", "https://lunchmoney-mcp.your-account.workers.dev/mcp"],
      "env": {
        "MCP_HEADERS": "X-LunchMoney-API-Key: their_api_key_here"
      }
    }
  }
}
```

### Local Development with Wrangler

```bash
# Run locally with hot reload
npm run dev:worker
```

### Security Model

- **Server never stores API keys** — keys are passed per-request via header
- **Users only access their own data** — each request uses the user's own key
- **Publicly accessible** — anyone can use the server, but they need their own Lunch Money account

This is similar to how public API gateways work — the infrastructure is shared, but credentials are per-user.

## Usage Examples

Once configured, you can ask your AI assistant questions like:

- "Show me my spending by category this month"
- "What was my largest expense last week?"
- "Categorize all my uncategorized transactions from March"
- "Create a new category called 'Freelance Income'"
- "How much did I spend on groceries in Q1?"
- "List all my recurring subscriptions"

## Development

### Local stdio mode (for Cursor, Claude Desktop)

```bash
# Install dependencies
npm install

# Run in development mode with hot reload
npm run dev

# Build for production
npm run build

# Type check without emitting
npm run typecheck

# Test with MCP Inspector
npm run inspect
```

### Cloudflare Workers mode (for remote HTTP access)

```bash
# Build the Worker
npm run build

# Run locally with Wrangler
npm run dev:worker

# Deploy to production
npm run deploy
```

### Project Structure

```
src/
├── index.ts           # MCP server entry point (stdio mode)
├── worker.ts          # Cloudflare Workers entry point (HTTP mode)
├── client.ts          # Lunch Money API client
├── types.ts           # TypeScript type definitions
├── tool-utils.ts      # Shared tool utilities
└── tools/             # Individual tool implementations
    ├── user.ts
    ├── categories.ts
    ├── transactions.ts
    ├── assets.ts
    ├── plaid.ts
    ├── budgets.ts
    ├── recurring.ts
    └── tags.ts
```

### Deployment Modes


| Mode                   | Transport       | Use Case                   | Entry Point     |
| ---------------------- | --------------- | -------------------------- | --------------- |
| **Local**              | stdio           | Cursor, Claude Desktop     | `src/index.ts`  |
| **Cloudflare Workers** | Streamable HTTP | Remote access, web clients | `src/worker.ts` |


Both modes share the same tool implementations and API client.

## Security

### API Key Protection

- **Never commit your API key.** The `.env` file is in `.gitignore` for this reason.
- Store your key in environment variables or secure MCP configuration files.
- If your key is exposed, revoke it immediately at [Lunch Money Developers](https://my.lunchmoney.app/developers) and generate a new one.

### Data Privacy

- This server acts as a proxy between your AI assistant and Lunch Money.
- Your financial data is processed according to [Lunch Money's privacy policy](https://lunchmoney.app/privacy).
- Error messages are sanitized to prevent accidental information disclosure.

### Permissions

The API key you provide determines what actions the MCP server can perform. Lunch Money API keys can:

- Read all your financial data
- Create, update, and delete transactions
- Modify categories and budgets
- Trigger Plaid syncs

## API Reference

This MCP server uses the [Lunch Money API v1](https://lunchmoney.dev/).

### Rate Limits

The Lunch Money API has rate limits. The MCP server will pass through any rate limit errors from the API. If you encounter rate limiting, wait a few minutes before trying again.

### Error Handling

The server handles Lunch Money API errors and returns them as MCP tool errors. Some notes:

- Lunch Money sometimes returns logical errors as HTTP 200 responses — these are normalized into proper errors
- The server sanitizes error messages to remove potential sensitive information
- Full error details are logged to stderr for debugging

## Troubleshooting

### "Missing LUNCH_MONEY_API_KEY" error

The `LUNCH_MONEY_API_KEY` environment variable is not set. Check your MCP configuration and ensure the key is properly configured.

### "Unauthorized" error

Your API key may be invalid or revoked. Verify your key at [https://my.lunchmoney.app/developers](https://my.lunchmoney.app/developers)

### Transactions not appearing

If you use Plaid-connected accounts, you may need to trigger a sync:

- Use the `trigger_plaid_fetch` tool to queue a background sync
- Note that this only queues the job — it may take a few minutes for transactions to appear

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the ISC License — see the [LICENSE](LICENSE) file for details.

## Acknowledgments

- Built with the [Model Context Protocol SDK](https://github.com/modelcontextprotocol/typescript-sdk)
- Powered by [Lunch Money](https://lunchmoney.app/)

## Support

- For issues with this MCP server, please open a GitHub issue
- For Lunch Money API questions, see the [Lunch Money API docs](https://lunchmoney.dev/)
- For MCP protocol questions, see the [MCP documentation](https://modelcontextprotocol.io/)

---

**Disclaimer:** This is an unofficial community project. It is not affiliated with or endorsed by Lunch Money.

TDQS

B3.2/5.0

Scored across 15 tools

Disambiguation5/5

Each tool targets a distinct resource or action, with clear separation between asset, category, transaction, budget, account, recurring item, tag, and user operations. No overlapping functionality.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern (e.g., create_asset, get_transactions, update_category), using the same set of verbs (create, get, update, upsert, trigger) throughout.

Tool Count5/5

With 15 tools, the server covers the core aspects of personal finance management without being overloaded or underdeveloped. Each tool has a clear purpose.

Completeness2/5

The server provides create, read, and update operations for several resources, but lacks delete operations for all resources and missing update for assets and recurring items. Tags only have a get operation, leaving significant gaps in the lifecycle.

Maintenance

ActivityInactive
ResponsivenessNo issues