Actual Budget 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., "@Actual Budget MCP Serverwhat's my net worth?"
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.
English | Español
Actual Budget MCP Server
An MCP (Model Context Protocol) server that connects LLMs — Claude Desktop and any MCP-capable client — to a self-hosted Actual Budget instance. It is purpose-built for LLM consumption: correct financial semantics (transfers excluded from spending summaries, net worth including off-budget accounts), amounts converted server-side so the model never does cents math, compact outputs, fresh data via sync-with-TTL, and real split transactions backed by subtransactions.
Feature highlights
The design rests on five pillars:
Correct financial semantics — transfers (
transfer_id) are excluded from spending summaries so amounts are never double-counted, and net worth includes off-budget accounts (pensions, funds, mortgage).Server-side unit conversion — Actual stores amounts in cents; every tool returns values already divided by 100, with an
amount_formattedfield. The LLM never does the math.Compact, LLM-friendly outputs — responses are trimmed to what a model needs to answer, keeping token usage low.
Fresh data with sync-with-TTL — the server syncs with Actual before serving, caching the sync for a short TTL to stay fast without going stale.
Real split transactions —
split_transactioncreates genuine subtransactions in Actual, not fake notes or workarounds.
Related MCP server: Lunch Money MCP Server
Install in Claude Desktop (recommended)
Requirements: a Mac with Apple Silicon (M1 or later), Claude Desktop, and a self-hosted Actual Budget server you can reach. On Intel Macs, Windows or Linux, use Manual installation instead.
Download the latest
actual-budget-mcp-es.mcpbfrom the Releases page.Find your Sync ID — open Actual Budget in the browser, go to Settings → Advanced Settings → IDs, and copy the Sync ID.
Install — in Claude Desktop, open Settings → Extensions, drag the downloaded
.mcpbfile onto the page, review what it declares, and select Install. Claude Desktop will note the extension is not signed — that's expected for a self-distributed bundle.Fill the form Claude Desktop shows:
Actual server URL — e.g.
https://actual.example.org/Server password — the one you use to open Actual in the browser (stored by Claude Desktop's secure storage, not in a config file)
Budget Sync ID — from step 2
Locale and Currency — e.g.
es-ESandEUR; defaults areen-USandUSDEnable write tools — leave this off for now (see below)
Message language —
esoren; defaults toes
Check it works — start a new conversation and ask "what accounts do I have?". You should get your account list with balances.
Turning on write access
With the checkbox off you get the 8 read-only tools. Turn it on (Settings → Extensions → this extension → configure) to add the 8 write tools: editing and categorizing transactions, real splits, scheduled transactions, budget assignment and category notes. Claude Desktop asks for your approval before each call unless you grant it standing permission, and there are no delete tools.
Updating
Download the newer .mcpb and drag it in again — your configuration is kept.
If every tool fails after a Claude Desktop update
The bundle ships a native SQLite module (better-sqlite3) compiled for one specific Node
ABI. Claude Desktop does not run extensions with the system's Node: it starts them inside
its own Electron runtime, so the module has to match that runtime. When a Claude Desktop
update changes it, the module can no longer be loaded and the extension cannot work.
The server detects this at startup and says so plainly: every tool answers with the two version numbers involved and tells you to install a newer bundle, instead of failing with a confusing message about the budget being closed.
Nothing on your side fixes this — the bundle has to be rebuilt for the new runtime. Get a
newer release, or build one yourself with npm run bundle on a machine that has the updated
Claude Desktop installed.
This affects the .mcpb bundle only. A manual installation runs
under your own Node and is immune to it.
Manual installation
For other MCP clients, Intel Macs, Windows and Linux. Requires Node.js >= 22 and a self-hosted Actual Budget server (>= 25.x; built against API 26.7) reachable over the network.
The project is written in TypeScript, so build it before use:
git clone https://github.com/marcoaperez/actual-budget-mcp-es.git
cd actual-budget-mcp-es
npm install
npm run build # compiles TypeScript to dist/This produces dist/index.js, the entry point your MCP client runs.
Need your Sync ID? See step 2 of Install in Claude Desktop above.
Client configuration
Add this to your claude_desktop_config.json
(macOS: ~/Library/Application Support/Claude/claude_desktop_config.json), or the
equivalent configuration file for your MCP client.
Point command at node and args at the compiled dist/index.js using an absolute path:
{
"mcpServers": {
"actual-budget": {
"command": "node",
"args": ["/absolute/path/to/actual-budget-mcp-es/dist/index.js"],
"env": {
"ACTUAL_SERVER_URL": "https://actual.example.org/",
"ACTUAL_SERVER_PASSWORD": "your-password",
"ACTUAL_SYNC_ID": "00000000-0000-0000-0000-000000000000",
"LOCALE": "es-ES",
"CURRENCY": "EUR",
"ENABLE_WRITE": "false"
}
}
}
}Use "LOCALE": "en-US" and "CURRENCY": "USD" for US formatting, or "es-ES" / "EUR" for Spain. Set "ENABLE_WRITE": "true" only when you want the write tools (see below). Restart Claude Desktop after saving so it detects the new MCP server.
During development you can skip the build and run TypeScript directly with tsx:
"command": "npx", "args": ["tsx", "/absolute/path/to/actual-budget-mcp-es/src/index.ts"].
Environment variables
The first three variables are required; the rest have defaults.
Variable | Required | Default | Description |
| Yes | — | URL of the self-hosted Actual server |
| Yes | — | Actual server password |
| Yes | — | Budget Sync ID (Settings → Advanced → Sync ID) |
| No |
| Folder where the local copy of the budget is downloaded |
| No |
| Locale for formatting amounts and dates (e.g. |
| No |
| 3-letter ISO currency code (e.g. |
| No |
| Seconds the sync is cached before re-syncing |
| No |
| Enables the 8 write tools (categorize, splits, schedules, budget, notes) |
| No |
| Language of the server's error messages: |
Tools
Read tools (8)
Always available.
Tool | Description |
| Accounts with current balance; includes off-budget accounts (pensions, funds, mortgage) by default |
| Full net worth: on-budget + off-budget with a per-account breakdown |
| Category groups and categories with their IDs (needed by the write tools) |
| Transactions by date range with optional filters (account, category, text, amount, uncategorized). Excludes transfers. Paginated (max 200) |
| Spending aggregated by category, payee or month. Always excludes transfers |
| A month's budget state: to-budget, income, totals and budgeted/spent/balance per category |
| Mean, median and max spending per category over the last N full months — input for preparing the budget |
| Scheduled/recurring transactions configured in Actual (name, next date, amount) |
Write tools (8)
Registered only when ENABLE_WRITE=true.
Tool | Description |
| Fix a transaction (amount, category, payee, notes, date) |
| Categorize in bulk (max 50), with a per-item result |
| Split a transaction into real parts — replaces the transaction (new id) |
| Record an expense/income, with optional splits at creation |
| Create a scheduled/recurring transaction |
| Assign budget in bulk to several categories of a month |
| Move assigned budget between categories |
| Category notes and goal templates |
Notes on the write tools
They only appear when
ENABLE_WRITE=trueis set in theenvblock (restart the client after changing it).Input amounts are in currency units (euros/dollars, not cents); the server handles the conversion.
split_transactionreplaces the original transaction with a new one carrying subtransactions, so the resulting transaction has a new id.
Safety
No delete tools — the server cannot remove transactions, accounts or budgets.
Write disabled by default — write tools are never registered unless
ENABLE_WRITE=true.Split guards — the write tools guard against editing split parts or split parents directly.
Never commit your
.env. The Actual password lives only in your local.envor the client config.
Three things worth knowing before you enable writes:
data/holds a plain, unencrypted copy of your whole budget (created owner-only, mode0700).Payee names and notes come from bank sync or CSV imports: they are untrusted text, not instructions. Keep per-call approval on in your MCP client.
split_transactionreplaces the transaction, so it gets a new id.Every MCP client you connect starts its own server process. Only one process can open a budget at a time, so extra instances automatically use their own local copy (
<data dir>-instance-<pid>). In a manual installation you can setACTUAL_DATA_DIRper client if you prefer to control it (the Claude Desktop bundle does not expose this setting).
The full security model — trust boundary, credentials, destructive operations, input validation and how to report a vulnerability — is documented in SECURITY.md.
Privacy Policy
This software collects nothing: no telemetry, no analytics, no update checks. It runs on your machine and talks only to your own Actual Budget server and to the MCP client you connect it to — which sees the financial data you ask about, under its own privacy policy. The local copy of your budget is unencrypted and lives only on your machine.
Full text: PRIVACY.md · en español
Development
npm test # full suite with Vitest (127 tests)
npm run dev # runs src/index.ts with tsx (no build)
npm run smoke # manual check against the real Actual server (requires .env; not part of CI)The server talks over stdio (stdin/stdout), so running it manually shows no interactive output — logs go to stderr.
Adding a new tool
Create a file in
src/tools/my_new_tool.tsExport a
ToolDef(name,description,readOnly,inputSchemawith Zod,handler)Import and register it in the
allToolsarray ofsrc/tools/index.ts
The handler(input, ctx) receives an initialized { api, config } context; use moneyFields/toUnits from src/core/money.js to always return amounts in units (never cents).
Releasing a bundle
The bundle is tied to Claude Desktop's Electron ABI. Extensions run inside Claude Desktop's own Electron, not the system's Node, so
better-sqlite3has to be compiled for that runtime.npm run bundlereads the Electron version out of the installedClaude.app, reinstalls the prebuilt binary for it, and then verifies what actually ships bydlopen-ing it with the packaging Node — which must fail, reporting Electron's ABI. If it loads, the Node-targeted binary slipped in and packaging aborts.So: package on a machine running the Claude Desktop you are targeting, or pass
ELECTRON_TARGET=x.y.z npm run bundle. Re-release whenever Claude Desktop bumps its Electron major — the previous bundle stops working for everyone on the new version.
Bump
versioninpackage.jsonandmanifest.json(a test enforces they match).npm test && npm run build && npm run bundle— the last line reports the Electron version and ABI the bundle was built for. Note it in the release description.Verify the bundle:
npx mcpb validate manifest.json unzip -l build/actual-budget-mcp-es.mcpb | grep -E 'tests/|docs/|\.env' | grep -v 'node_modules/' # expect no output unzip -l build/actual-budget-mcp-es.mcpb | grep -c 'better_sqlite3.node' # expect at least 1npx mcpb info <file>(CLI 2.1.2) only prints file name, size and signature status — it does not check the manifest, so it's not a substitute forvalidate. Thenode_modules/exclusion in the grep is there because vendored dependency files aren't the project's own code and legitimately contain paths liketests/— don't remove it.Install
build/actual-budget-mcp-es.mcpblocally and check it works.gh release create vX.Y.Z build/actual-budget-mcp-es.mcpb, noting in the release description that the bundle targets macOS on Apple Silicon.
License
MIT — see LICENSE. Copyright (c) 2026 Marco Antonio Pérez.
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/marcoaperez/actual-budget-mcp-es'
If you have feedback or need assistance with the MCP directory API, please join our Discord server