Security-first, self-hosted MCP server for Firefly III β 152 operations behind 5 scoped tools.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag β we're steadily working through the catalog.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Inspect callable tools, capabilities, and parameters exposed to AI agents by MCP Firefly Iii.
firefly_queryread-only
firefly_mutatewrites
firefly_destructivecannot be undone
firefly_list_operationsread-only
firefly_get_schemaread-only
A Model Context Protocol server that gives an AI assistant access to your own Firefly III instance β 152 operations behind 5 scoped tools, with reading, writing and deleting kept as three separate, explicitly-authorized surfaces instead of one tool that can do all three.
TΓΌrkΓ§e: README.tr.md
Everyone runs this against their own Firefly instance with their own token β there is no hosted backend or relay in between.
Listed in the official MCP Registry as io.github.YakupEmreYerli/mcp-firefly-iii, on Glama, and in Firefly III's own third-party apps documentation. Every release is built and published by CI from a tagged commit, with npm provenance attesting that the tarball came from this repository.
https://github.com/user-attachments/assets/4866f13e-ff09-43b0-b99c-2b4789a30224
38-second demo: ask a financial question, read the answer through MCP, preview a change with dry_run, approve it, and write it back to Firefly III. Recorded against a synthetic instance β all financial data shown is fabricated.
firefly_query, firefly_mutate, firefly_destructive, plus firefly_list_operations and firefly_get_schema for discovery β a typed registry maps every Firefly endpoint onto these instead of flooding the model's tool list.dry_run on every write, returning the exact request β resolved record IDs included β without sending it.max_matches and refuse an incomplete scan before the first write; multi-split transaction groups are rejected outright rather than risk folding their amounts together.linux/amd64/linux/arm64, and a self-checking documentation pipeline that keeps the tool catalogue in sync with the code.MCP_UPDATE_CHECK=false turns it off.| Method | Transport | Best for |
|---|---|---|
npx β stdio | stdio | Claude Code, Claude Desktop, Cursor β simplest setup |
| Static token | HTTP | n8n, automation, headless callers |
| OAuth | HTTP + OAuth | Claude web, Claude mobile, ChatGPT β can't hold a static token |
| Docker | HTTP | Self-hosted, either auth mode above |
Let setup do it β it asks for your Firefly III address and token, checks that they actually work, then configures Claude Code and Claude Desktop if it finds them: npx -y @yakupemreyerli/firefly-mcp setup. For any other client it prints the configuration to paste.
By hand, Claude Code:
By hand, Claude Desktop / Cursor / other clients β add to the MCP config file:
For n8n, automation, or any caller that can't drive a browser-based OAuth flow. Set MCP_HTTP_TOKEN in .env, then run npx -y -p @yakupemreyerli/firefly-mcp firefly-mcp-http. Every request to /mcp must carry Authorization: Bearer <token> β one token, full access, no per-connection scoping.
None of these clients can hold a static token, and none of them can spawn a local process β they connect to a public HTTPS URL and expect OAuth. With MCP_AUTH_PASSWORD set, this server is the OAuth 2.1 authorization server: it handles client registration, PKCE and token exchange itself, so there is no Keycloak, no Google sign-in, and no token to copy anywhere.
Step 1 β give the server a public HTTPS address. Cloudflare Tunnel is the easiest route for a home server (no port forwarding, no certificate); Caddy or Traefik work on a VPS. compose.example.yml ships cloudflare and caddy profiles for exactly this. Say the result is https://mcp.example.com.
Step 2 β configure .env:
MCP_RESOURCE_URL is the external origin, character for character, with no path β not the internal http://firefly-mcp:3000, and not the /mcp connection URL. A mismatch fails the token audience check and the client only reports "invalid token". MCP_AUTH_STATE_DIR must sit on a persistent volume (compose.example.yml mounts one) or every restart de-authorizes every client.
Step 3 β start it and verify:
If auth says bearer instead, the password never reached the process and the client will report that the server doesn't support OAuth.
Step 4a β Claude (web, Desktop, iOS/Android). Settings β Connectors β Add custom connector, URL https://mcp.example.com/mcp. Leave the authentication choices as detected β Claude probes the server and picks the flow it supports. The connector then works on every Claude surface you're signed into, phone included.
Step 4b β ChatGPT. In the custom connector / MCP screen, enter the same https://mcp.example.com/mcp and choose OAuth as the authentication method.
Step 5 β enter the password. A Firefly login screen opens in the browser; type MCP_AUTH_PASSWORD. That one screen is the whole decision β the connection is granted all three scopes (firefly:read, firefly:write, firefly:destructive), whatever the client itself asked for. There is no second consent screen: whoever holds the password could have ticked every box on it. To hand out a connection that genuinely cannot write, give the server a read-only Firefly Personal Access Token instead.
Full TLS recipes and troubleshooting: docs/oauth.md.
Recommended for either HTTP mode above:
Swap build: . in compose.example.yml for image: ghcr.io/yakupemreyerli/mcp-firefly-iii:latest to use the prebuilt image β pin a version tag, not :latest, for anything you depend on. Single container without Compose: docker run -d --env-file .env -p 3000:3000 ghcr.io/yakupemreyerli/mcp-firefly-iii:latest. It refuses to start without one of the two auth modes above, and /mcp needs TLS in front β compose.example.yml has optional cloudflare and caddy profiles for that. /health is open, for container probes.
| Variable | Default | Purpose |
|---|---|---|
FIREFLY_API_URL | β | Required. A bare domain, or a full base URL including /api/v1. |
FIREFLY_API_TOKEN | β | Required. Personal Access Token. |
FIREFLY_DISABLE_SSL_VERIFY | false | Only for a local instance with a self-signed certificate. |
MCP_UPDATE_CHECK | true | Daily check for a newer release. The only request this server makes to anywhere but your Firefly instance, and it carries no data. |
Every variable, including HTTP and OAuth mode: docs/configuration.md.
Factual signals from GitHub, npm, and our automated checks β not a rating.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/mcp-firefly-iii)<a href="https://allmcps.com/mcp/mcp-firefly-iii"><img src="https://allmcps.com/api/badge/mcp-firefly-iii?style=directory" alt="MCP Firefly Iii on AllMCPs" /></a>