Beancount.io
Server Details
Query, edit, and reconcile a hosted Beancount ledger: BQL, reports, files, and bank imports.
- Status
- Healthy
- Uptime
- 100.0% over the last 24 hours
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- bex-co/beancount-io
- GitHub Stars
- 338
- Server Listing
- Beancount MCP
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 47 tools
Many tools are clearly scoped by resource (bank, ledger, PR, entry), but several write paths overlap heavily: addLedgerEntries vs appendLedgerText, createLedgerFiles vs updateLedgerFiles vs appendLedgerText, and runBqlQuery vs runBqlQueryStructured. The detailed descriptions help, but an agent must read carefully to choose the right mutation tool.
All tool names use camelCase and are generally verb-first (listLedgerEntries, createLedgerFiles, deleteEntrySource), with no mixed casing conventions. Minor semantic verb variation exists (add/append/insert, get/read/list), but the naming pattern is predictable.
47 tools is a very large surface for one server, well beyond the 3-15 sweet spot. The domain is broad, but many tools are specialized variants that could be consolidated or grouped.
The surface covers ledger lifecycle, entry/file editing, bank staging, collaborators, pull requests, and BQL queries, so core workflows are supported. Some gaps remain, such as listing collaborators or inspecting pull requests, but these are not dead ends for most tasks.
Available Tools
47 toolsaddLedgerEntriesAdd Structured Ledger EntriesAInspect
Append entries [{type,entry}]. Supports transaction, commodity, price, note, balance, open, close, pad, budget, document, event; custom and query are added with appendLedgerText, and option and plugin by editing the main file with updateLedgerFiles. Budget interval uses lowercase daily/weekly/monthly/quarterly/yearly. One posting per transaction may omit its amount and is written elided. An unbalanced transaction is refused with UNBALANCED, and entries that would add bean-check errors (a second open for an open account, a balance against an unopened account), or a budget for an account the ledger lacks, with VALIDATION_FAILED naming each error, unless allowInvalid records them deliberately. ledger is required unless pinned. The commit message is composed from the entries; there is no message argument. dry_run previews without committing.
Inputs: entries (required), dryRun, ledger, dry_run, +3 more. Returns: ok, error, result
appendLedgerTextAppend Beancount Directive TextAInspect
Append Beancount directive text as you would write it into a file; postings indented under their transaction. Routes each directive to its file by type and date (path overrides) and inserts it in date order. Max 50 directives. Non-directive text, and text introducing new bean-check errors (UNBALANCED when a transaction does not balance), are refused unless allowInvalid. dry_run returns the diff and projected errors without committing. Adds directives without rewriting files, unlike updateLedgerFiles. The commit message is composed from the appended text; there is no message argument. Syntax: https://beancount.github.io/docs/beancount_language_syntax/
Inputs: text (required), path, dryRun, ledger, +4 more. Returns: ok, error, result
checkLedgerCheck Ledger ValidityARead-onlyIdempotentInspect
Check one ledger's validity in one call: bean-check errors with file and line, entry counts per directive type, and the latest commit.
Inputs: ledger. Returns: ok, error, result
createLedgerCreate LedgerAInspect
Create a ledger owned by the authenticated user. Requires name; accepts description, private, template (STARTER default, including null: options and accounts without transactions; SAMPLE: demonstration transactions), a currency for a STARTER ledger (ISO 4217, default USD), a setup specification (mutually exclusive with template and currency), and a requestId for idempotent retries. Refused for ledger-pinned credentials.
Inputs: name (required), setup, private, currency, +3 more. Returns: ok, error, result
createLedgerFilesCreate Ledger FilesAInspect
Create new text files in one atomic commit; each file gets plain UTF-8 content. To move existing entries into a new file, use moveEntrySources. Each new/resulting file is limited to 1 MiB of UTF-8 bytes, including dry runs. dry_run previews without committing: the same refusal as the commit, plus a unified diff per touched file and bean-check's verdict over the projected contents. A commit that adds bean-check errors is refused with VALIDATION_FAILED; dry_run returns them with valid: false instead; allow_invalid commits anyway, e.g. one step of a multi-step edit.
Inputs: files (required), dryRun, ledger, dry_run, +4 more. Returns: ok, error, result
createPullRequestCreate Pull RequestAInspect
Propose a set of file changes as a pull request. Requires title, description, clearCommitMessage, and changes [{path,content}]; an omitted baseBranch targets main. A repository server failure is SERVICE_UNAVAILABLE naming the failed step.
Inputs: title (required), changes (required), description (required), clearCommitMessage (required), +3 more. Returns: ok, error, result
deleteEntrySourceDelete Entry SourceADestructiveInspect
Delete one entry's source text, addressed by the entry_hash listLedgerEntries returns (as entryHash or entry_hash) and sha256sum from getEntryContext (or listLedgerEntries with include_source). The commit message is composed from the operation; there is no message argument. A write that would add a bean-check error the ledger did not have — deleting an entry a balance assertion depends on, re-dating it past one — is refused with VALIDATION_FAILED naming each new error; pass allowInvalid: true to commit it anyway. dry_run previews without committing.
Inputs: sha256sum (required), dryRun, ledger, dry_run, +4 more. Returns: ok, error, result
deleteEntrySourcesDelete Several Entry SourcesADestructiveInspect
Delete several entries' source text in one commit; entries is a list of {entryHash or entry_hash, sha256sum} — the entry_hash listLedgerEntries returns under either spelling; with include_source it also returns each sha256sum. The commit message is composed from the operation; there is no message argument. Returns the deleted count. A write that would add a bean-check error the ledger did not have — deleting an entry a balance assertion depends on, re-dating it past one — is refused with VALIDATION_FAILED naming each new error; pass allowInvalid: true to commit it anyway. dry_run previews without committing.
Inputs: entries (required), dryRun, ledger, dry_run, +2 more. Returns: ok, error, result
deleteLedgerDelete LedgerADestructiveInspect
Permanently delete a ledger, including its history; dry_run previews without committing, rendering the destroy summary.
Inputs: dryRun, ledger, dry_run. Returns: ok, error, result
deleteLedgerFilesDelete Ledger FilesADestructiveIdempotentInspect
Delete files in one atomic commit; pass each file's sha from readLedgerFiles to refuse the delete if it changed since. Deleting a file still included by another ledger file is refused as BAD_USER_INPUT naming the includers; remove the include from the including file(s) first, then delete. An include counts when its target resolves to the deleted path the way the ledger loads it, relative to the directory of the file that declares it, and glob includes never count. removeIncludes (alias remove_includes) drops those exact include lines in the same commit; globs stay. Each new/resulting file is limited to 1 MiB of UTF-8 bytes, including dry runs. dry_run previews without committing: the same refusal as the commit, plus a unified diff per touched file and bean-check's verdict over the projected contents. A commit that adds bean-check errors is refused with VALIDATION_FAILED; dry_run returns them with valid: false instead; allow_invalid commits anyway, e.g. one step of a multi-step edit.
Inputs: files (required), dryRun, ledger, dry_run, +6 more. Returns: ok, error, result
discardStagedBankTransactionsDiscard Staged Bank TransactionsBDestructiveInspect
Remove staged bank transactions so they are never imported. dry_run reports what would be removed.
Inputs: dryRun, ledger, dry_run, transactionIds, +1 more. Returns: ok, error, result
generateTempAssetUploadUrlCreate Temporary Asset Upload URLAInspect
Create a presigned PUT URL bound to the current user. Optional filename and mimeType preserve the upload metadata; a given mimeType is signed, so PUT with the uploadHeaders returned (Content-Type: ). Upload the bytes to uploadUrl before using objectKey in an ingestion workflow.
Inputs: filename, mimeType. Returns: ok, error, result
getEntryContextRead Entry Source ContextARead-onlyIdempotentInspect
Read the source context around one entry, addressed by the entry_hash listLedgerEntries returns (as entryHash or entry_hash); updateEntrySource and deleteEntrySource take the same hash and this result's sha256sum. Same data as the entry-context resource. A result with generated_from is a copy a plugin or a pad generated from that source entry (amortize_over, forecast, padding): it shares the source's slice and sha256sum, so editing or deleting it would change the source and every other copy; address the generated_from entry instead. An entry with not_booked: true is a transaction the ledger could not book (for example a sale with no matching lot): it is listed so it can be opened and fixed, but no balance counts it.
Inputs: ledger, entryHash, entry_hash. Returns: ok, error, result
getLedgerContextRead Ledger VocabularyARead-onlyIdempotentInspect
Read a ledger's working vocabulary in one call: attributes, open accounts, currencies, payees, years, and source files. Counts accompany truncated lists so a large ledger does not flood context.
Inputs: ledger, payeeLimit. Returns: ok, error, result
importStagedBankTransactionsImport Staged Bank TransactionsAInspect
Write staged bank transactions into the ledger as directives, each booked against the given target account. dry_run returns the result and projected validation without committing.
Inputs: transactions (required), dryRun, ledger, dry_run, +1 more. Returns: ok, error, result
insertReceiptTransactionInsert Receipt TransactionADestructiveInspect
Promote the caller-owned temporary receipt named by receiptObjectKey (the objectKey generateTempAssetUploadUrl returned), append the confirmed transaction, then delete the temporary upload. input carries date, payee, description, postings [{account,amountNumber,amountCurrency}], and documentAccount. ledger is required unless pinned. Applies immediately.
Inputs: input (required), ledger, objectKey, requestId, +2 more. Returns: ok, error, result
leaveLedgerLeave LedgerADestructiveInspect
Remove the authenticated user's own access to a ledger they collaborate on; dry_run previews without committing, rendering the would-be self-removal.
Inputs: dryRun, ledger, dry_run. Returns: ok, error, result
listBankConnectionsList Linked Banks And Their AccountsARead-onlyIdempotentInspect
List linked bank connections and their accounts. The bank tools take a row's own id: a connection's id (pitm_…) as itemId, not its itemId field, which is Plaid's; an account's id (pacc_…) as accountId, not its accountId field.
Inputs: ledger. Returns: ok, error, result
listLedgerEntriesList Journal EntriesARead-onlyIdempotentInspect
List journal entries, each with the entry_hash getEntryContext, updateEntrySource, and deleteEntrySource take; include_source adds each entry's text and sha256sum, so a bulk edit needs no getEntryContext call. Narrows by account, filter, time, directiveTypes, and the transactionSubtypes, documentSubtypes, and customSubtypes filters (each narrows only its own directive family); pages with limit and offset; total counts every match. Same data as the journal resource.
Inputs: time, limit, filter, ledger, +8 more. Returns: ok, page, error, result
listLedgerFilesList Ledger Files & DirectoriesARead-onlyIdempotentInspect
List files and directories in the ledger repo, one directory level at a time, directories first.
Inputs: ledger, dir_path. Returns: ok, error, result
listLedgersList Accessible LedgersARead-onlyIdempotentInspect
List the ledgers this credential can reach — every one when page and limit are omitted. A pinned credential returns its one ledger; for an unpinned credential, ledger tools take one of these as ledger: owner/name.
Inputs: page, limit. Returns: ok, page, error, result
listStagedBankTransactionsList Bank Transactions Staged For ImportARead-onlyIdempotentInspect
List bank transactions staged for import, newest first. Each row's transactionId — not its id — is what importStagedBankTransactions and discardStagedBankTransactions take; optional accountId filter, an account's id (pacc_…) from listBankConnections. Pass limit (at most 100) to read a large staging area in pages; page.hasMore says whether more remain. Imported and discarded rows leave the list, so after acting on a page read page 1 again rather than the next page. Omit limit for every staged row.
Inputs: page, limit, ledger, accountId. Returns: ok, page, error, result
mapBankAccountMap Bank Account To Ledger AccountBDestructiveIdempotentInspect
Point a linked bank account at a ledger account; replaces any existing mapping.
Inputs: ledger, accountId, account_id, ledgerAccount, +1 more. Returns: ok, error, result
mergePullRequestMerge Pull RequestADestructiveInspect
Merge a pull request into its base branch; the merge applies immediately. A merge that would take a free ledger past its directive limit is RESOURCE_LIMIT_REACHED. A repository server failure is SERVICE_UNAVAILABLE naming the failed step.
Inputs: prNumber (required), ledger. Returns: ok, error, result
moveEntrySourcesMove Entry SourcesADestructiveInspect
Move entries into another ledger file in one commit: each entry's source text leaves its file byte for byte and is appended to toPath in ledger order. listLedgerEntries with include_source returns each entry's hash and sha256sum. Refused, writing nothing: a toPath the ledger does not load unless includeFrom is given, a stale sha256sum (CONFLICT), an entry already in toPath, and a move that adds a bean-check error (VALIDATION_FAILED, unless allowInvalid). dry_run previews without committing. revertCommit undoes the commit.
Inputs: toPath (required), entries (required), dryRun, ledger, +4 more. Returns: ok, error, result
parseFileParse Uploaded FileAInspect
Parse a caller-owned temporary upload into transaction rows. s3ObjectKey is the objectKey generateTempAssetUploadUrl returned; fileFormat names the format (csv, pdf, xlsx, json, etc.). Consumes AI quota. Does not write ledger entries.
Inputs: fileFormat (required), objectKey, s3ObjectKey, receiptObjectKey. Returns: ok, error, result
parseReceiptParse Receipt and Recommend AccountsAInspect
Parse the caller-owned temporary image/PDF named by objectKey (from generateTempAssetUploadUrl) and recommend accounts. Pinned credentials may omit ledger; others must select it. Consumes extraction and recommendation tokens, without inserting entries.
Inputs: ledger, objectKey, s3ObjectKey, receiptObjectKey. Returns: ok, error, result
previewLedgerSetupPreview Ledger SetupARead-onlyIdempotentInspect
Preview a ledger setup (ADR026) without creating anything: returns the files, account list, and validation result the specification would produce. Accepts the same setup object as createLedger.
Inputs: setup (required). Returns: ok, error, result
readLedgerFilesRead Ledger File ContentsARead-onlyIdempotentInspect
Read one or more beancount ledger files in a single call. content is raw text; the 1-based startLine/endLine it spans and the file's totalLines come alongside it, not in the text. Use start_line/end_line per file to limit tokens for large files. A file that is not valid UTF-8 comes back with lossy: true: its undecodable bytes read as U+FFFD, and edits to it are refused.
Inputs: files (required), ledger. Returns: ok, error, result
reconcileBankAccountsReconcile Linked Bank AccountsADestructiveInspect
Re-read which accounts a linked bank shares; accounts the bank no longer shares can be deleted along with their staged transactions. dry_run reports the changes without applying them.
Inputs: dryRun, itemId, ledger, dry_run, +1 more. Returns: ok, error, result
refreshBankConnectionRefresh Bank Connection StatusAIdempotentInspect
Re-read a linked bank connection's health status from the bank.
Inputs: itemId, ledger, item_id. Returns: ok, error, result
refreshManagedPricesRefresh Managed Price FeedsAIdempotentInspect
Re-fetch the ledger's managed price feeds now and return each source's status (the ledgerManagedPrices records). Never edits the ledger. ledger is required unless pinned.
Inputs: ledger. Returns: ok, error, result
rejectPullRequestReject Pull RequestBDestructiveInspect
Reject a pull request by closing it without merging; applies immediately.
Inputs: prNumber (required), ledger. Returns: ok, error, result
removeLedgerCollaboratorRemove Ledger CollaboratorBDestructiveInspect
Remove a collaborator's access to a ledger; dry_run previews without committing, rendering the would-be revocation.
Inputs: collaborator (required), dryRun, ledger, dry_run. Returns: ok, error, result
renameAccountRename AccountADestructiveInspect
Rename an account and every account under it across the ledger's loaded files in one commit: account tokens outside strings and comments, whole names only. Bank mappings move with it. Refused for an invalid name, another root, or a name the ledger already uses; new bean-check errors refuse the commit unless allowInvalid. Pinned credentials can omit ledger. dry_run previews without committing: the changed lines and bank mappings. revertCommit undoes the commit.
Inputs: to (required), from (required), dryRun, ledger, +3 more. Returns: ok, error, result
renameLedgerFileRename Ledger FileADestructiveIdempotentInspect
Move oldPath to newPath preserving content in one atomic commit. Refuses when oldPath is still included unless updateIncludes rewrites those lines in the same commit. Pinned credentials can omit ledger. dry_run previews without committing.
Inputs: newPath (required), oldPath (required), dryRun, ledger, +4 more. Returns: ok, error, result
revertCommitRevert CommitADestructiveInspect
Undo one commit as a new commit. sha is the commit any write result returned (createLedgerFiles, appendLedgerText, addLedgerEntries, …), or main for the latest. Each file it touched goes back to its parent's contents in one atomic commit; CONFLICT if a later commit changed any of them. Pinned credentials can omit ledger. dry_run previews without committing.
Inputs: sha (required), dryRun, ledger, dry_run, +1 more. Returns: ok, error, result
runBqlQueryRun Beancount Query (BQL)ARead-onlyIdempotentInspect
Execute a BQL (Beancount Query Language) query against the user's ledger and return results. BQL: SELECT cols [WHERE expr] [GROUP BY] [ORDER BY] [LIMIT n] | JOURNAL | BALANCES. Columns: date, year, month, flag, payee, narration, account, number, currency, cost, weight, balance, position, tags, links, meta. An unaggregated query returns one row per posting, not per transaction, so LIMIT 5 can span 3 transactions; GROUP BY and DISTINCT return one row per group or value. LIMIT bounds the returned rows. Output past 1,000 lines or 100 KB is cut and ends with a truncation line; add LIMIT or a narrower WHERE to see the rest. The query travels in a POST body end to end, so long queries have no URL-length ceiling, up to 262144 bytes. Reference: https://beancount.github.io/docs/beancount_query_language/
Inputs: query (required), ledger. Returns: ok, error, result
runBqlQueryStructuredRun BQL with Typed ResultsARead-onlyIdempotentInspect
Execute BQL and return the typed table (column names, types, and rows) or structured text result. Uses the same query contract as REST JSON and GraphQL queryShell. The query travels in a POST body end to end, so long queries have no URL-length ceiling, up to 262144 bytes.
Inputs: query (required), ledger. Returns: ok, error, result
setBankAccountCurrencySet Bank Account CurrencyADestructiveIdempotentInspect
Set a linked bank account's currency; replaces the current value.
Inputs: currency (required), ledger, accountId, account_id. Returns: ok, error, result
setLedgerCollaboratorAdd or Update Ledger CollaboratorADestructiveIdempotentInspect
Add a collaborator to a ledger, or change an existing collaborator's permission (read, write, or admin); dry_run previews without committing, rendering the would-be grant.
Inputs: collaborator (required), dryRun, ledger, dry_run, +1 more. Returns: ok, error, result
setLedgerStarStar or Unstar a LedgerADestructiveIdempotentInspect
Set starred:true to star a ledger or false to unstar it for the authenticated user. ledger selects owner/name and defaults to the credential pin. No dry_run: this personal preference applies immediately; false removes an existing star relationship.
Inputs: starred (required), ledger. Returns: ok, error, result
syncBankTransactionsSync Bank TransactionsADestructiveInspect
Synchronize linked bank transactions into staging, adding, replacing or deleting staged rows. Never writes ledger entries. dry_run previews the changes.
Inputs: dryRun, itemId, ledger, dry_run, +1 more. Returns: ok, error, result
unlinkBankConnectionUnlink Bank ConnectionADestructiveInspect
Sever a linked bank connection. Linking a new bank happens in a browser through the bank's own widget, not here. dry_run reports what would be removed.
Inputs: dryRun, itemId, ledger, dry_run, +1 more. Returns: ok, error, result
updateEntrySourceUpdate Entry SourceADestructiveInspect
Replace one entry's source text with newContent, addressed by the entry_hash listLedgerEntries returns (as entryHash or entry_hash) and sha256sum from getEntryContext (or listLedgerEntries with include_source). The commit message is composed from the operation; there is no message argument. Returns the entry's new hash as newEntryHash; the request's hash is stale after the commit. A replacement that would take a free ledger past its directive limit is RESOURCE_LIMIT_REACHED. A write that would add a bean-check error the ledger did not have is refused with VALIDATION_FAILED naming each new error — lone imbalance refuses as UNBALANCED with the residual; pass allowInvalid: true to commit it anyway. dry_run previews without committing.
Inputs: sha256sum (required), newContent (required), dryRun, ledger, +5 more. Returns: ok, error, result
updateLedgerUpdate Ledger SettingsADestructiveIdempotentInspect
Change a ledger's name, description, or privacy; omitted fields stay as they are; dry_run previews without committing, rendering the current→new diff.
Inputs: name, dryRun, ledger, dry_run, +2 more. Returns: ok, error, result
updateLedgerFilesUpdate Ledger FilesADestructiveIdempotentInspect
Change existing text files in one atomic commit: per file, either replace an exact text (old_string must appear exactly once) with new_string, or overwrite the whole file with content (pass its sha from readLedgerFiles to refuse it if the file changed since). Several items for one file apply in order, each to the text the previous one produced. Each new/resulting file is limited to 1 MiB of UTF-8 bytes, including dry runs. dry_run previews without committing: the same refusal as the commit, plus a unified diff per touched file and bean-check's verdict over the projected contents. A commit that adds bean-check errors is refused with VALIDATION_FAILED; dry_run returns them with valid: false instead; allow_invalid commits anyway, e.g. one step of a multi-step edit.
Inputs: files (required), dryRun, ledger, dry_run, +4 more. Returns: ok, error, result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
Related MCP Connectors
Personal finance ledger: log expenses, track bills and cards, import statements.
Bookkeeping for owner-operated businesses. Query transactions, invoices, and reports.
Personal finance tracker: accounts, transactions, budgets, investments and analytics over OAuth.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables interaction with local Beancount accounting ledgers through structured tools for viewing accounts, balances, and transactions, as well as inserting/removing transactions and answering natural-language questions via BeanQuery. Provides deterministic, validated, and auditable financial data operations with offline-first functionality.1-
- FlicenseNot gradedqualityDmaintenanceMCP server for Beancount ledgers that enables querying with BQL, listing accounts, getting balances, searching transactions, validating the ledger, and appending new entries.-
- AlicenseAqualityCmaintenanceMCP server for Beancount plain-text accounting: turns plain English into double-entry transactions, runs bean-check, and commits each change to git so it can be diffed and reverted. Works on a local ledger file with no account, or on a hosted book.2124MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants and scripts to read, analyze and safely write self-hosted personal finance books, covering accounts, transactions, categories, tags, monthly and category reports, net worth, cash flow, recurring payments, installment plans and bulk imports. Writes are safeguarded with dry runs, delete confirmation, and an optional read-only mode, while amounts are returned exactly as both minor units and decimal strings with totals kept per currency.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.