firefly-iii-mcp-server
Enables AI agents to manage personal finances through Firefly III, supporting tasks like recording transactions, managing budgets, and generating financial summaries.
README
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_transactionswith 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.
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 / accountget_transaction— fetch one transaction with all its splitssearch_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 transactiondelete_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 oractiveget_account— single account with current balance (historic balance viadate)create_account— create asset / expense / revenue / liability / cash accountupdate_account— update account metadatadelete_account— delete an account by ID
Categories (3)
list_categories— list categoriesupsert_category— create or update a categorydelete_category— delete a category
Tags (3)
list_tags— list tagsupsert_tag— create or update a tagdelete_tag— delete a tag by ID
Budgets (3)
list_budgets— list budgets enriched with limit / spent / remaining for a periodupsert_budget— create or update a budget; optionally set its limit in the same calldelete_budget— delete a budget by ID (Firefly clears its budget-limit rows; transactions are not deleted)
Bills (3)
list_bills— recurring expected expenses withnext_expected_matchandpaid_datesupsert_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 goalupdate_piggy_bank— rename, retarget, or re-attach accounts; partial update. Does NOT acceptcurrent_amount— balance changes go throughcontribute_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; passrule_group_idto scope to one group, else lists all rulesget_rule— fetch one rule with its triggers and actionscreate_rule— create a rule in a group; triggers and actions are flat arrays (order derived from array index)update_rule— update a rule; passingtriggers: []oractions: []clears the listdelete_rule— delete a rule by ID
Rule groups (5)
list_rule_groups— list rule groupsget_rule_group— fetch one rule groupcreate_rule_group— create a rule groupupdate_rule_group— update a rule group's metadatadelete_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 currenciesget_spending_insights— breakdown bycategory/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 }.pageis 1-indexed.limitdefaults to 25 and is capped at 100 (over-limit requests are clamped, not rejected; the response includeslimit_clamped_to: 100). - Amounts, IDs, dates are strings. Amounts are decimal strings (
"-1012.12"). IDs are numeric strings ("42"). Dates areYYYY-MM-DD. - Currency by code, not ID.
currency_code: "EUR", nevercurrency_id: 1. - Errors are returned as a uniform envelope (see below); the tool result is marked
isError: trueso 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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。