Skip to main content
Glama
braindaamage

firefly-iii-mcp

by braindaamage
README.md
# firefly-iii-mcp

An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server for [Firefly III](https://www.firefly-iii.org/), exposing 114 tools across 13 resource categories so AI agents (Claude, Cursor, etc.) can manage your personal finances directly.

## Features

- **114 tools** covering every major Firefly III resource
- **Dual transport**: stdio (Claude Desktop) and Streamable HTTP (remote / multi-client)
- **Docker-first**: single-image deployment, no external dependencies beyond Firefly III
- **Full Firefly III v6 support**: piggy-bank v6 API, recurrences v6, exchange rates v6
- **Optional HTTP auth** via bearer token (`MCP_AUTH_TOKEN`)
- **TypeScript** with strict types, ES2022, Node 22

## Requirements

| Requirement | Version |
|---|---|
| Node.js | 22+ |
| Firefly III | v6.x (tested on v6.5.9) |
| npm | 10+ |

## Installation

```bash
# Clone
git clone https://github.com/your-org/firefly-iii-mcp.git
cd firefly-iii-mcp

# Install dependencies
npm ci

# Build
npm run build
```

## Configuration

All configuration is via environment variables.

| Variable | Required | Default | Description |
|---|---|---|---|
| `FIREFLY_BASE_URL` | Yes | — | Base URL of your Firefly III instance, e.g. `http://localhost:8080` |
| `FIREFLY_API_TOKEN` | Yes | — | Personal access token from Firefly III → Profile → OAuth → Personal Access Tokens |
| `TRANSPORT` | No | `http` | Transport mode: `stdio` or `http` |
| `PORT` | No | `3000` | HTTP server port (HTTP transport only) |
| `HOST` | No | `0.0.0.0` | HTTP server bind host (HTTP transport only) |
| `MCP_AUTH_TOKEN` | No | — | Bearer token required on `Authorization` header for all HTTP requests. Leave unset to disable auth |
| `FIREFLY_API_TIMEOUT` | No | `30000` | Firefly III API request timeout in milliseconds |
| `MAX_PAGE_FETCH` | No | `10` | Maximum pages to auto-fetch when listing resources |
| `LOG_LEVEL` | No | `info` | Log verbosity: `debug`, `info`, `warn`, `error` |
| `FIREFLY_TOOL_PROFILE` | No | `default` | Tool profile controlling which of the 114 tools are exposed. See [Tool Profiles](#tool-profiles) |

Create a `.env` file for local development:

```bash
cp .env.example .env
# Edit FIREFLY_BASE_URL and FIREFLY_API_TOKEN
```

## Usage

### Claude Desktop — stdio transport

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "firefly-iii": {
      "command": "node",
      "args": ["/absolute/path/to/firefly-iii-mcp/dist/index.js"],
      "env": {
        "FIREFLY_BASE_URL": "http://localhost:8080",
        "FIREFLY_API_TOKEN": "your-personal-access-token",
        "TRANSPORT": "stdio"
      }
    }
  }
}
```

Restart Claude Desktop. The 114 Firefly III tools will be available in every conversation.

### Claude Desktop — remote HTTP transport

Claude Desktop only supports stdio-based servers natively. To connect to a remote MCP server over HTTP, use the [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) bridge:

```json
{
  "mcpServers": {
    "firefly-iii": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://your-mcp-server.example.com/mcp"
      ]
    }
  }
}
```

If the server requires authentication (`MCP_AUTH_TOKEN`), pass the headers flag:

```json
{
  "mcpServers": {
    "firefly-iii": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://your-mcp-server.example.com/mcp",
        "--header",
        "Authorization: Bearer your-mcp-auth-token"
      ]
    }
  }
}
```

Restart Claude Desktop after saving.

### Claude.ai — remote HTTP transport

On [claude.ai](https://claude.ai), remote MCP servers are configured as connectors:

1. Go to **Settings > Connectors**
2. Click **Add custom connector**
3. Enter the server URL: `https://your-mcp-server.example.com/mcp`
4. Configure authentication if required
5. Set tool permissions

### Docker — HTTP transport

**Build:**
```bash
docker build -t firefly-iii-mcp .
```

**Run (HTTP, stateless):**
```bash
docker run -d \
  -p 3000:3000 \
  -e FIREFLY_BASE_URL=http://your-firefly-host:8080 \
  -e FIREFLY_API_TOKEN=your-token \
  -e MCP_AUTH_TOKEN=your-mcp-secret \
  -e FIREFLY_TOOL_PROFILE=default \
  -e LOG_LEVEL=info \
  firefly-iii-mcp
```

MCP endpoint: `POST http://localhost:3000/mcp`
Health check: `GET http://localhost:3000/health`

**Run (stdio via Docker):**
```bash
docker run --rm -i \
  -e FIREFLY_BASE_URL=http://your-firefly-host:8080 \
  -e FIREFLY_API_TOKEN=your-token \
  -e TRANSPORT=stdio \
  -e FIREFLY_TOOL_PROFILE=default \
  firefly-iii-mcp
```

### docker-compose — Local development stack

`docker-compose.dev.yml` spins up a complete local stack: MariaDB, Firefly III, and the MCP server in development (hot-reload) mode.

```bash
# Start everything (MariaDB → Firefly III → MCP)
FIREFLY_API_TOKEN=your-token FIREFLY_TOOL_PROFILE=default docker compose -f docker-compose.dev.yml up

# Stop
docker compose -f docker-compose.dev.yml down
```

Services:

| Service | Port | Description |
|---|---|---|
| `firefly-db` | — | MariaDB database for Firefly III |
| `firefly-iii` | `8080` | Firefly III web UI & API |
| `firefly-mcp` | `3000` | MCP server (hot-reload via `tsx watch`) |

After startup, open Firefly III at `http://localhost:8080` to create your account and generate a personal access token. Set `FIREFLY_API_TOKEN` accordingly.

## Tool Profiles

The `FIREFLY_TOOL_PROFILE` environment variable controls which tools are exposed to the AI. This keeps the LLM context focused on what's relevant for your workflow.

### The 7 presets

| Preset | Tools | Best for |
|--------|-------|----------|
| `minimal` | 26 | Read-only queries: balances, transactions, reports |
| `default` | 62 | Daily expense management (default when unset) |
| `reporting` | 64 | Financial analysis, dashboards, auditing — zero writes |
| `budget` | 39 | Budget tracking and management |
| `automation` | 39 | Configuring rules and recurring transactions |
| `admin` | 32 | System administration: accounts, currencies, attachments |
| `full` | 114 | Unrestricted access to all tools |

### The 15 categories

Each category supports two access levels: read-only (default) and `write` (includes read).

| Category | Read tools | Write tools (additional) | Total |
|----------|-----------|--------------------------|-------|
| `accounts` | list, get, transactions | create, update, delete | 6 |
| `transactions` | list, get, journals_get | create, update, delete, journals_delete | 7 |
| `categories` | list, get, transactions | create, update, delete | 6 |
| `tags` | list, get, transactions | create, update, delete | 6 |
| `budgets` | list, get, transactions, limits_list | create, update, delete, limits_create, limits_update, limits_delete | 10 |
| `bills` | list, get, transactions, rules | create, update, delete | 7 |
| `piggy_banks` | list, get, events | create, update, delete | 6 |
| `recurrences` | list, get | create, update, delete, trigger | 6 |
| `currencies` | list, get, get_primary | enable, disable, set_primary, create, update, delete | 9 |
| `exchange_rates` | list, get | create | 3 |
| `rules` | list, get, groups_list, groups_get, groups_rules | create, update, delete, test, trigger, groups_create, groups_update, groups_delete, groups_test, groups_trigger | 15 |
| `search` | search_transactions, search_accounts | *(read-only)* | 2 |
| `autocomplete` | 9 autocomplete tools | *(read-only)* | 9 |
| `reports` | 15 report and chart tools | *(read-only)* | 15 |
| `attachments` | list, get, download | create, update, delete, upload | 7 |

### Composition

Tokens are combined with union semantics — the highest access level wins per category:

```bash
# Single preset
FIREFLY_TOOL_PROFILE=minimal

# Preset + extra write access
FIREFLY_TOOL_PROFILE=default,bills:write        # 65 tools
FIREFLY_TOOL_PROFILE=default,budgets:write       # 68 tools

# Combine two presets
FIREFLY_TOOL_PROFILE=budget,automation           # 67 tools

# Custom category mix
FIREFLY_TOOL_PROFILE=accounts:write,transactions:write,reports

# Read-only analysis + ability to record transactions
FIREFLY_TOOL_PROFILE=reporting,transactions:write  # 68 tools
```

**Rules:**
- `category` without suffix → read-only access
- `category:write` → read + write access
- Multiple tokens are unioned; higher level wins per category
- Invalid tokens log a warning and are ignored
- If all tokens are invalid → falls back to `default`
- Unset variable → `default` (62 tools)

### Claude Desktop example

```json
{
  "mcpServers": {
    "firefly-iii": {
      "command": "node",
      "args": ["/path/to/firefly-iii-mcp/dist/index.js"],
      "env": {
        "FIREFLY_BASE_URL": "http://localhost:8080",
        "FIREFLY_API_TOKEN": "your-token",
        "TRANSPORT": "stdio",
        "FIREFLY_TOOL_PROFILE": "default"
      }
    }
  }
}
```

## Tools Reference

### Accounts (6 tools)

| Tool | Description |
|---|---|
| `accounts_list` | List accounts; filter by type (asset, expense, revenue, liability, cash) |
| `accounts_get` | Get a single account by ID |
| `accounts_create` | Create a new account |
| `accounts_update` | Update an existing account |
| `accounts_delete` | Delete an account (irreversible) |
| `accounts_transactions` | List transactions for an account; supports date range and type filters |

### Transactions (7 tools)

| Tool | Description |
|---|---|
| `transactions_list` | List transactions; filter by date range, type, page |
| `transactions_get` | Get a transaction group (all splits) by ID |
| `transactions_create` | Create a transaction (single or split); supports multi-currency |
| `transactions_update` | Update a transaction group; use `transaction_journal_id` to target splits |
| `transactions_delete` | Delete an entire transaction group (irreversible) |
| `transaction_journals_get` | Get a single transaction split by journal ID |
| `transaction_journals_delete` | Delete a single split from a multi-split transaction |

### Categories (6 tools)

| Tool | Description |
|---|---|
| `categories_list` | List all categories |
| `categories_get` | Get a category by ID |
| `categories_create` | Create a category |
| `categories_update` | Update a category |
| `categories_delete` | Delete a category |
| `categories_transactions` | List transactions for a category; supports date range |

### Tags (6 tools)

| Tool | Description |
|---|---|
| `tags_list` | List all tags |
| `tags_get` | Get a tag by tag string |
| `tags_create` | Create a tag |
| `tags_update` | Update a tag |
| `tags_delete` | Delete a tag |
| `tags_transactions` | List transactions for a tag |

### Rules & Rule Groups (15 tools)

| Tool | Description |
|---|---|
| `rule_groups_list` | List all rule groups |
| `rule_groups_get` | Get a rule group by ID |
| `rule_groups_create` | Create a rule group |
| `rule_groups_update` | Update a rule group |
| `rule_groups_delete` | Delete a rule group |
| `rule_groups_rules` | List rules within a group |
| `rule_groups_test` | Test all rules in a group against existing transactions (dry-run) |
| `rule_groups_trigger` | Apply all rules in a group to existing transactions |
| `rules_list` | List all rules |
| `rules_get` | Get a rule by ID |
| `rules_create` | Create a rule with triggers and actions |
| `rules_update` | Update a rule |
| `rules_delete` | Delete a rule |
| `rules_test` | Test a rule against existing transactions (dry-run) |
| `rules_trigger` | Apply a rule to existing transactions |

### Budgets & Budget Limits (10 tools)

| Tool | Description |
|---|---|
| `budgets_list` | List all budgets; optional date range for spending info |
| `budgets_get` | Get a budget by ID |
| `budgets_create` | Create a budget; supports auto-budget (reset/rollover/adjusted) |
| `budgets_update` | Update a budget |
| `budgets_delete` | Delete a budget |
| `budgets_transactions` | List transactions assigned to a budget |
| `budget_limits_list` | List spending limits for a budget |
| `budget_limits_create` | Create a spending limit for a date period |
| `budget_limits_update` | Update a spending limit |
| `budget_limits_delete` | Delete a spending limit |

### Piggy Banks (6 tools)

| Tool | Description |
|---|---|
| `piggy_banks_list` | List all piggy banks |
| `piggy_banks_get` | Get a piggy bank by ID |
| `piggy_banks_create` | Create a piggy bank linked to an asset account |
| `piggy_banks_update` | Update a piggy bank |
| `piggy_banks_delete` | Delete a piggy bank |
| `piggy_banks_events` | List events (deposits/withdrawals) for a piggy bank |

### Bills (7 tools)

| Tool | Description |
|---|---|
| `bills_list` | List all bills |
| `bills_get` | Get a bill by ID |
| `bills_create` | Create a bill |
| `bills_update` | Update a bill |
| `bills_delete` | Delete a bill |
| `bills_transactions` | List transactions linked to a bill |
| `bills_rules` | List rules linked to a bill |

### Recurrences (6 tools)

| Tool | Description |
|---|---|
| `recurrences_list` | List all recurring transactions |
| `recurrences_get` | Get a recurring transaction by ID |
| `recurrences_create` | Create a recurring transaction |
| `recurrences_update` | Update a recurring transaction |
| `recurrences_delete` | Delete a recurring transaction |
| `recurrences_trigger` | Trigger recurrence processing (runs the cron job) |

### Currencies & Exchange Rates (12 tools)

| Tool | Description |
|---|---|
| `currencies_list` | List all currencies |
| `currencies_get` | Get a currency by code |
| `currencies_create` | Create a custom currency |
| `currencies_update` | Update a currency |
| `currencies_delete` | Delete a currency |
| `currencies_enable` | Enable a currency |
| `currencies_disable` | Disable a currency |
| `currencies_set_primary` | Set a currency as the default |
| `currencies_get_primary` | Get the current default currency |
| `exchange_rates_list` | List available exchange rate pairs |
| `exchange_rates_get` | Get the exchange rate between two currencies |
| `exchange_rates_create` | Create a manual exchange rate |

### Search & Autocomplete (11 tools)

| Tool | Description |
|---|---|
| `search_transactions` | Full-text search across transactions; supports operators like `amount_more:`, `category_is:`, `date_after:`, etc. |
| `search_accounts` | Full-text search across accounts |
| `autocomplete_accounts` | Account name autocomplete |
| `autocomplete_categories` | Category name autocomplete |
| `autocomplete_tags` | Tag autocomplete |
| `autocomplete_budgets` | Budget name autocomplete |
| `autocomplete_bills` | Bill name autocomplete |
| `autocomplete_currencies` | Currency autocomplete |
| `autocomplete_piggy_banks` | Piggy bank name autocomplete |
| `autocomplete_rules` | Rule title autocomplete |
| `autocomplete_descriptions` | Transaction description autocomplete |

### Reports & Charts (15 tools)

| Tool | Description |
|---|---|
| `reports_summary` | Overall financial summary for a date range |
| `reports_expense_by_category` | Expenses grouped by category |
| `reports_expense_by_budget` | Expenses grouped by budget |
| `reports_expense_by_account` | Expenses grouped by account |
| `reports_expense_by_tag` | Expenses grouped by tag |
| `reports_expense_by_bill` | Expenses grouped by bill |
| `reports_expense_total` | Total expenses for a period |
| `reports_income_by_category` | Income grouped by category |
| `reports_income_by_account` | Income grouped by account |
| `reports_income_by_tag` | Income grouped by tag |
| `reports_income_total` | Total income for a period |
| `reports_transfer_total` | Total transfers for a period |
| `charts_account_overview` | Account balance chart data |
| `charts_budget_overview` | Budget spending chart data |
| `charts_category_overview` | Category spending chart data |

### Attachments (7 tools)

| Tool | Description |
|---|---|
| `attachments_list` | List all attachments |
| `attachments_get` | Get an attachment by ID |
| `attachments_create` | Create an attachment record linked to a transaction or other object |
| `attachments_update` | Update an attachment record |
| `attachments_delete` | Delete an attachment |
| `attachments_upload` | Upload file content for an attachment (base64) |
| `attachments_download` | Download attachment content (returns base64) |

## Development

```bash
# Run in dev mode (hot reload)
npm run dev

# Run unit tests (requires .env.test with a live Firefly III instance)
npm test

# Run E2E tests
npm run test:e2e

# Lint
npm run lint

# Type-check
npx tsc --noEmit
```

## License

MIT License

Copyright (c) 2025

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.