firefly-iii-mcp-server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@firefly-iii-mcp-serveradd a transaction for $50 groceries"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 installNo 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 |
| Base URL of your Firefly III instance, no trailing slash. Example: |
| 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 startOn 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.tsThe 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
This server cannot be installed
Maintenance
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
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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