Skip to main content
Glama
CountBean

CountBean

Countbean plugin for Claude Code

Hosted plain-text accounting in Claude Code: a git-backed Beancount ledger, AI ingestion of statements and receipts into validated double-entry, and HTML/Excel reports.

Install

Run these one at a time — Claude Code reads a multi-line paste as a single slash command, so sending them together makes marketplace add swallow the install line and fail with URL rejected: Malformed input to a URL function.

/plugin marketplace add https://github.com/CPUtester5465/countbean-plugin.git
/plugin install countbean@countbean

Then reload, so the running session picks up the plugin's commands and MCP tools — they are bound when Claude Code starts, so a fresh install is not live until you do:

/reload-plugins

Use the full HTTPS URL, not the CPUtester5465/countbean-plugin shorthand — the shorthand resolves to git@github.com, which needs an SSH key and GitHub's host key already in your known_hosts.

Then connect it to your book. Say this to Claude with nothing after it:

/countbean:connect

It prints a short code and a link. Open the link, sign in at app.countbean.com, pick the book, and approve — Claude picks it up within a few seconds. There is no key to copy between windows. (If you would rather paste a key you already have, put it on the same line: /countbean:connect cbk_… bok_….)

Full documentation is in plugin/README.md.


Related MCP server: bookie

This repository is published, not authored

The source of truth is the plugin/ directory of the Countbean monorepo. This repo is a mirror, pushed by CI on every change.

Pull requests here cannot be merged — they would be overwritten by the next publish. The mirror exists so that installing the plugin does not require access to the private monorepo, and so plugin/mcp/countbean_mcp/ledger.py can keep being byte-compared against its ledger_core original by tests that need both in one tree.

Available Tools

21 tools
add_directivesA

Append arbitrary Beancount directives (auto-routed by kind) and commit.

Use for batch setup ("set up my whole situation"): opens, balances, transactions and prices in one validated commit.

Inputs: beancount_text (required), message. Returns: result

add_transactionsA

Append one or more transactions (raw Beancount syntax) to the book.

The text is validated with bean-check and only committed if valid; on failure nothing is written and the validation errors are returned. Postings must balance. Open any new accounts first (open_accounts).

Inputs: beancount_text (required). Returns: result

assess_bookA

Review the book and return COMPUTED facts about it as JSON.

Coverage, monthly income/expense, cash, run rate and runway, category shares, month-over-month movers, unusually large postings, and data-quality flags.

Read this and report it. Do NOT compute your own figures from it, do not extrapolate past the coverage window, and do not turn a sufficient: false into a number with a caveat — that field means the data cannot support the figure, and the honest answer is to say which data is missing.

Every month is marked complete. Only complete months are averaged: a trailing partial month makes spending look like it fell in every category.

Inputs: no named parameters. Returns: result

await_device_approvalA

Step 2: wait for the user to approve the code from start_device_authorization.

Blocks until they approve, decline, or the code expires. On success the connection is saved and every countbean tool switches to that book.

Inputs: no named parameters. Returns: result

balancesA

Show balances grouped by account, optionally filtered by a regex.

account_filter is a BQL regex like 'Assets' or 'Expenses:Food'.

Inputs: account_filter. Returns: result

book_statusA

Summarise the current book: location, account count, balances, last commits.

Inputs: no named parameters. Returns: result

connect_bookA

Connect this plugin to a hosted Countbean book, permanently.

Give it the key shown once on your book's page (cbk_…) and the book id (bok_…). Verifies the pair against the live book BEFORE saving, then stores it in ~/.countbean/credentials.json (0600). Takes effect immediately — no restart, no environment variables.

Paste both on one line and this tool sorts them out; the bok_… id can be omitted if you have already connected to that book before.

Inputs: api_key (required), book_id, control_url. Returns: result

connection_statusA

Show which book this plugin is talking to, and which config chose it.

Answers the question that actually gets asked when something looks wrong: not "is it configured" but "WHICH of my configs won". Environment beats a .env, which beats the saved connection.

Inputs: no named parameters. Returns: result

create_bookA

Initialise a new, empty cloud book (git-backed Beancount ledger).

Safe to call once per book; errors if a book already exists at the location.

Inputs: name, currency. Returns: result

disconnect_bookA

Forget the saved hosted-book connection (the key stays valid; revoke it on the book's page if you want it dead).

Inputs: no named parameters. Returns: result

generate_reportB

Generate a financial report from the book.

format: 'html' (styled, self-contained) or 'xlsx' (Excel workbook with Balance Sheet, Income Statement and Transactions sheets). Returns the path to the written file.

Inputs: as_of, format. Returns: result

get_ledgerA

Return the full plain-text ledger (accounts, transactions, prices).

Inputs: no named parameters. Returns: result

historyA

Show the book's git history (each AI or human change is one commit).

Inputs: limit. Returns: result

list_accountsA

List every account currently open in the book.

Inputs: no named parameters. Returns: result

open_accountsB

Add account open (or close/commodity) directives to the book.

Example: 2026-01-01 open Assets:Checking USD

Inputs: beancount_text (required). Returns: result

propose_receipt_transactionA

Turn what you read off a staged receipt into a PROPOSED transaction.

You supply the reading and, for every field, how sure you are of it on a 0.0-1.0 scale. Be honest about the confidences — they are the whole mechanism. Anything below the floor comes back flagged rather than as a value, and the floor can be raised by argument but never lowered, so a low confidence is not a suggestion.

expense_account and paid_from_account are yours to choose: categorisation is the part of this a model is genuinely good at. The book's open directives are read here so that two failures which would otherwise land AT THE WRITE — an account that was never opened, and an account pinned to a currency this receipt is not in — arrive now, as a sentence, instead of as a bean-check dump after the customer has already approved the entry.

exchange_rate is how much ONE unit of the receipt's currency cost in the paying account's currency. Take it off the card statement; no rate is ever invented here.

Returns JSON. It NEVER writes. Show the person the merchant, the date and the total, ask about anything flagged, and only then pass beancount to add_transactions unchanged.

Inputs: receipt_sha256 (required), tax, date, total, +15 more. Returns: result

propose_transactionsA

Parse a bank statement (CSV or OFX/QFX) into PROPOSED transactions.

THIS TOOL NEVER WRITES. It returns proposals as JSON; add_transactions is still the only way anything reaches the book, so the bean-check gate and the git commit stay where they are.

content is the statement itself — base64-encoded bytes, or the text pasted straight in. NOT a path: the hosted chat agent has no filesystem in common with your machine, and a tool that only works from one of them is the defect this replaces.

account is the book account the statement belongs to, e.g. 'Assets:Checking' or 'Liabilities:Visa'. Required — every row in an export is one side of that account and the file never says which.

WHAT YOU MUST DO WITH THE RESULT

  • Read mapping. It says which column was read as what, which date format, which decimal separator, and whether a positive amount was taken to mean money in or money out — with the evidence for each. If any of it is wrong, call again with the matching override rather than editing the numbers.

  • CATEGORISE. Every proposal's counter-account is a placeholder (Income:Unclassified / Expenses:Unclassified). Replacing those with real accounts is your job; parsing was this tool's. Keep the import-id: metadata line exactly as given — it is what stops the same statement being booked twice.

  • Keep the ! flags. A flagged row has an ambiguity the file cannot settle, listed in ambiguities. Do not silently promote one to *.

  • Open anything in accounts_to_open first (open_directives is ready to paste into open_accounts).

  • Show the user counts and anything flagged before you write.

Overrides, all optional: amount_shape ('signed' | 'debit_credit' | 'balance'), columns (a JSON object like {"date": "Posted Date", "amount": "Amount"} — header names or 0-based indices), date_format (strptime), delimiter, decimal_separator ('.' or ','), sign ('normal' | 'inverted'), opening_balance (for a running-balance file whose first row has no predecessor), counter_account, currency, file_format, content_encoding.

Inputs: account (required), content (required), sign, columns, +9 more. Returns: result

revertA

Revert a specific commit (undo a change), creating a new commit.

Inputs: commit (required). Returns: result

run_queryA

Run a Beancount Query Language (BQL) query and return CSV-style rows.

Example: SELECT account, sum(position) WHERE account ~ 'Expenses' GROUP BY account

Inputs: bql (required). Returns: result

stage_receiptA

Store a receipt photo or PDF as evidence and return a reference to it.

Call this FIRST, before proposing anything. A receipt is the source document for the entry it becomes, and an entry whose evidence was thrown away is a promise we cannot keep two years from now.

Give it EITHER file_path (a photo or PDF on this machine — the plugin path) OR content_base64 (raw bytes, for a chat agent that has no filesystem in common with the book). declared_name is recorded in the reply for your convenience and is used for NOTHING else — never for the file type, never for where the bytes are stored.

Returns JSON with the bucket key and the content hash. Pass both to propose_receipt_transaction. Then read the image yourself: this tool does not look at it.

Inputs: file_path, declared_name, content_base64. Returns: result

start_device_authorizationA

Step 1 of connecting a hosted book: get a code for the user to approve.

Returns IMMEDIATELY with a short code and a link. Show both to the user, then call await_device_approval to wait for them to approve it.

Deliberately two tools and not one. An MCP tool returns a single result, at the end — so a tool that fetched the code and then waited for approval could never show the code to the person who has to type it. It could only ever expire. That was the first version of this, and it was unusable.

Inputs: control_url. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

    TDQS

    A3.7/5.0

    Scored across 21 tools

    Disambiguation3/5

    Some overlap exists: add_transactions and add_directives can both commit transactions, and open_accounts overlaps with add_directives for account opens. The descriptions do clarify intended use cases, but an agent could still hesitate between these pairs.

    Naming Consistency4/5

    Most tools follow a clear verb_noun pattern (connect_book, add_transactions, open_accounts, run_query), but a few are bare nouns (balances, history, book_status, connection_status). The device-auth tools also mix 'authorization' and 'approval' terminology, though the overall pattern remains readable.

    Tool Count3/5

    With 21 tools, the server is in the heavy range, though the count is justified by the two-step auth flow and separate workflows for statements, receipts, and reporting. Still, some consolidation (e.g. merging open_accounts into add_directives) could tighten the surface.

    Completeness5/5

    The tool set covers the full bookkeeping lifecycle: connecting and creating books, adding validated transactions and directives, opening accounts, querying balances, generating reports, proposing from statements and receipts, and undoing changes via history/revert. No critical operations are missing for the stated purpose.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP Server to query from your Beancount ledger, or submit transaction.
      11
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      A Model Context Protocol (MCP) server that keeps the books for your personal and business finances using double-entry accounting — driven entirely from an LLM.
      60 npm
      1
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      A read-only MCP server that gives AI agents structured access to a Beancount personal finance ledger.
      1
      -
    • F
      license
      Not graded
      quality
      D
      maintenance
      MCP server for Beancount ledgers that enables querying with BQL, listing accounts, getting balances, searching transactions, validating the ledger, and appending new entries.
      -