Skip to main content
Glama
Xerrion

firefly-iii-mcp-server

by Xerrion

firefly-iii-mcp-server

An MCP (Model Context Protocol) server that exposes a curated, task-shaped surface of 41 tools over the Firefly III personal-finance API. Designed for an AI agent doing personal accounting on behalf of a human: record, review, budget, save, summarise.

Rather than mirroring Firefly's ~230 REST operations 1:1, this server is a facade with a thin anti-corruption layer that:

  • strips the JSON:API envelope (data: { type, id, attributes: {...} }) on every response,

  • flattens Firefly's currency-keyed maps into { currency_code, ... } arrays,

  • collapses per-account/per-bill/per-budget/per-category transaction list variants into a single list_transactions with filters,

  • normalises errors into one envelope with stable codes,

  • keeps amounts, IDs, and dates as strings (no float drift, no silent coercion).

The 41-tool catalogue and the capability groups deliberately not exposed in v1 are documented below.

Install

Requires Bun ≥ 1.3.

bun install

No build step — Bun runs TypeScript directly from src/index.ts.

Related MCP server: Firefly III MCP Server

Configuration

Two environment variables, both required. The server fails fast at startup if either is missing.

Variable

Description

FIREFLY_III_URL

Base URL of your Firefly III instance, no trailing slash. Example: https://demo.firefly-iii.org.

FIREFLY_III_TOKEN

Personal Access Token. Get one in Firefly III: Options → Profile → OAuth → Personal Access Tokens → Create New Token.

A .env.example is provided. Copy it to .env for local development (never commit .env).

Run

# stdio transport (the only supported transport in v1)
FIREFLY_III_URL=https://demo.firefly-iii.org \
FIREFLY_III_TOKEN=your-pat-here \
bun start

On success the server logs firefly-iii-mcp-server: ready on stdio to stderr (stdout is reserved for the MCP protocol).

MCP client configuration

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "firefly-iii": {
      "command": "bun",
      "args": ["run", "/absolute/path/to/firefly-iii-mcp/src/index.ts"],
      "env": {
        "FIREFLY_III_URL": "https://demo.firefly-iii.org",
        "FIREFLY_III_TOKEN": "your-pat-here"
      }
    }
  }
}

opencode

Add to ~/.config/opencode/opencode.json (or your project-local opencode.json):

{
  "mcp": {
    "firefly-iii": {
      "type": "local",
      "command": ["bun", "run", "/absolute/path/to/firefly-iii-mcp/src/index.ts"],
      "environment": {
        "FIREFLY_III_URL": "https://demo.firefly-iii.org",
        "FIREFLY_III_TOKEN": "your-pat-here"
      },
      "enabled": true
    }
  }
}

Tools

All 41 tools are listed below. Their schemas are exposed to MCP clients through the server's tool catalogue.

Transactions (6)

  • list_transactions — browse recent transactions, filter by date / type / account

  • get_transaction — fetch one transaction with all its splits

  • search_transactions — free-text and operator search (amount_min:, category:, tag:, …)

  • create_transaction — record a withdrawal, deposit, or transfer (single or multi-split)

  • update_transaction — edit fields on an existing transaction

  • delete_transaction — delete a transaction by ID

create_transaction and update_transaction may return an overridden_fields envelope alongside the projected transaction. It lists fields the agent sent that Firefly's rule engine then overwrote (e.g. you sent category: "Food" and a rule rewrote it to "Groceries"). The envelope is absent when no diff is detected. v1.1 limitation: only the first split is diffed.

Accounts (5)

  • list_accounts — list accounts, filter by type or active

  • get_account — single account with current balance (historic balance via date)

  • create_account — create asset / expense / revenue / liability / cash account

  • update_account — update account metadata

  • delete_account — delete an account by ID

Categories (3)

  • list_categories — list categories

  • upsert_category — create or update a category

  • delete_category — delete a category

Tags (3)

  • list_tags — list tags

  • upsert_tag — create or update a tag

  • delete_tag — delete a tag by ID

Budgets (3)

  • list_budgets — list budgets enriched with limit / spent / remaining for a period

  • upsert_budget — create or update a budget; optionally set its limit in the same call

  • delete_budget — delete a budget by ID (Firefly clears its budget-limit rows; transactions are not deleted)

Bills (3)

  • list_bills — recurring expected expenses with next_expected_match and paid_dates

  • upsert_bill — create or update a bill (subscription, etc.)

  • delete_bill — delete a bill by ID (matched transactions are detached, not deleted)

Piggy banks (5)

The piggy-bank cluster uses an explicit create_* + update_* rather than a single upsert_* because Firefly's create-side schema requires four fields (name, accounts, target_amount, start_date) while the update-side schema requires none — the same asymmetric-required-fields pattern as rules CRUD.

  • list_piggy_banks — savings goals with progress (current_amount, target_amount, percentage)

  • create_piggy_bank — define a new savings goal

  • update_piggy_bank — rename, retarget, or re-attach accounts; partial update. Does NOT accept current_amount — balance changes go through contribute_piggy_bank, which is the single auditable path for moving money into or out of a piggy bank.

  • delete_piggy_bank — delete a savings goal by ID (linked accounts and transactions are untouched)

  • contribute_piggy_bank — add to (positive) or withdraw from (negative) a piggy bank

Rules (5)

  • list_rules — list rules; pass rule_group_id to scope to one group, else lists all rules

  • get_rule — fetch one rule with its triggers and actions

  • create_rule — create a rule in a group; triggers and actions are flat arrays (order derived from array index)

  • update_rule — update a rule; passing triggers: [] or actions: [] clears the list

  • delete_rule — delete a rule by ID

Rule groups (5)

  • list_rule_groups — list rule groups

  • get_rule_group — fetch one rule group

  • create_rule_group — create a rule group

  • update_rule_group — update a rule group's metadata

  • delete_rule_group — delete a rule group (cascades: all rules in the group are deleted)

Summary & insights (2)

  • get_financial_summary — net worth, income, expense, balance for a period; flattened across currencies

  • get_spending_insights — breakdown by category / budget / tag × expense / income

System (1)

  • get_system_info — Firefly version, primary currency, authenticated user

Shared conventions

  • Pagination on every list_* / search_* tool: { items, page, total_pages, total_items, has_more }. page is 1-indexed. limit defaults to 25 and is capped at 100 (over-limit requests are clamped, not rejected; the response includes limit_clamped_to: 100).

  • Amounts, IDs, dates are strings. Amounts are decimal strings ("-1012.12"). IDs are numeric strings ("42"). Dates are YYYY-MM-DD.

  • Currency by code, not ID. currency_code: "EUR", never currency_id: 1.

  • Errors are returned as a uniform envelope (see below); the tool result is marked isError: true so clients can detect failure.

Error envelope

{
  "ok": false,
  "error": {
    "code": "validation_error",
    "message": "The amount is required.",
    "field_errors": { "transactions.0.amount": ["The amount is required."] },
    "http_status": 422,
    "trace_id": "f54f1c80-7d9b-4a3e-9b71-1c0c7b3d3a1b"
  }
}

code is one of: validation_error, not_found, unauthenticated, forbidden, rate_limited, upstream_error, network_error, internal_error. HTML error pages from upstream are never leaked — they are converted into a safe synthetic upstream_error.

Example tool calls

List recent withdrawals in March 2026

Input to list_transactions:

{ "start": "2026-03-01", "end": "2026-03-31", "type": "withdrawal", "limit": 3 }

Output (structuredContent):

{
  "items": [
    {
      "id": "1042",
      "type": "withdrawal",
      "date": "2026-03-15",
      "amount": "42.50",
      "currency_code": "EUR",
      "description": "Groceries",
      "category": "Food",
      "source_name": "Checking",
      "destination_name": "Supermarket"
    }
  ],
  "page": 1,
  "total_pages": 4,
  "total_items": 12,
  "has_more": true
}

Record a withdrawal

Input to create_transaction:

{
  "type": "withdrawal",
  "date": "2026-03-20",
  "amount": "12.99",
  "description": "Coffee",
  "source": "Checking",
  "destination": "Daily Cafe",
  "category": "Food",
  "tags": ["weekly"]
}

source / destination accept either a numeric account ID ("7") or a free-form name; the server routes to Firefly's *_id vs *_name automatically.

Set a monthly budget for groceries with a limit

Input to upsert_budget:

{
  "name": "Groceries",
  "active": true,
  "limit": {
    "start": "2026-03-01",
    "end": "2026-03-31",
    "amount": "400.00",
    "currency_code": "EUR"
  }
}

Output (structuredContent):

{
  "id": "5",
  "name": "Groceries",
  "active": true,
  "limit": {
    "start": "2026-03-01",
    "end": "2026-03-31",
    "amount": "400.00",
    "currency_code": "EUR"
  }
}

Not exposed in v1

The following capability groups are deliberately omitted from v1 to keep the tool catalogue small and the agent's planning surface tractable: user / group admin, server configuration, currency admin, destructive admin (destroyData/purgeData), chart endpoints, autocomplete (*AC), webhooks, attachments (binary I/O over MCP is a separate design problem), per-currency / per-parent transaction list duplicates, exports, bulk update, currency exchange rates, recurrences, transaction links, object groups, available budgets, preferences, per-resource event/attachment sub-lists, and narrow insight slices.

Development

bun install           # install dependencies
bun run typecheck     # tsc --noEmit (TypeScript kept as a dev dep purely for typechecking)
bun test              # bun's built-in test runner (shape helpers, error mapping, tool catalogue, decimal, integration)
bun run dev           # bun --watch run src/index.ts

The catalogue test (tests/tool-catalogue.test.ts) asserts that exactly the 41 tools named in EXPECTED_TOOL_NAMES in src/tools.ts are registered. Update the catalogue, its expected names, and this README together when adding or removing a tool.

License

MIT

A
license - permissive license
-
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Xerrion/firefly-iii-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server