146 Agent Tools. One Balanced Ledger.
How AI handles changing statement formats, match rules classify the known cases, and a double-entry ledger turns scattered financial data into a personal CFO.
Managing my finances meant rebuilding the same picture from scattered evidence. Bank accounts, credit cards, business expenses, tax records, and planned bills arrived through different websites and file formats. Canada still lacked a simple open-banking feed I could rely on. Some institutions offered QFX or OFX. Some offered changing CSV exports. Others left me with a PDF, a screenshot, or rows that had to be entered by hand. Before I could answer a basic question about cash, spending, or taxes, I first had to assemble the data again.
The hard part of personal finance is rarely the final chart. It is getting every source into one shape, then deciding what each movement means. A payment to a credit card is not new spending. A transfer is not income. A business cost paid personally may be a shareholder loan. Two identical charges may be duplicates, or they may both be real. A bank description can name the payment processor instead of the merchant. Import and classification are the real work.
I built Clovis as a small harness around those two problems. AI handles the changing edge where document layouts and instructions vary. Stable match rules classify cases that have already been learned. Uncertain rows remain pending until they are reviewed. Accepted facts enter a local SQLite double-entry ledger. The ledger then supports budgets, cash projections, net worth, runway, month-end work, and tax preparation without inventing a separate database for each question.
The deeper lesson is about where AI belongs. It is excellent at translating a near-infinite set of messy inputs into a small, known contract. It should not replace that contract. Clovis lets AI adapt at the boundary while accounting rules protect the center.
Use AI where the world refuses a schema.
A bank statement looks structured to a person. To software, it may be a PDF made from positioned text, a scan, a table with wrapped descriptions, or a page whose header and balance block interrupt the rows. The same bank can change the layout by account type, language, date, or product. A connector that works today can silently move the amount column tomorrow.
One public statement-conversion service says it supports thousands of banks. That is impressive, but it also shows the trap: every new layout creates another parser branch to write and maintain. The number of possible documents grows faster than a small team can encode them. A large catalog of hand-built templates can become a fragile map of yesterday’s PDFs.
An AI agent can build the import layer at run time. It can read the visible headings, infer which column is the date, separate money in from money out, carry wrapped text into the right row, and return a bounded list of transactions. The target is not free-form prose. It is a narrow contract: date, description, signed amount, source account, currency, and any stable source ID.
Dynamic parsing still needs proof.
Flexible extraction is not the same as trustworthy posting. The agent may reverse debit and credit signs, miss a page, merge two rows, or read a balance as a transaction. Clovis treats the source document as evidence and the extracted rows as a proposal. Row counts, totals, source IDs, date ranges, duplicate checks, and the statement’s ending balance provide tests. AI solves the shape problem; reconciliation decides whether the result deserves trust.
A statement should become a plan before it becomes history.
The direct path from file to final ledger is tempting because it feels automatic. It is also the easiest way to mix bad extraction, duplicate rows, stale pending charges, and wrong categories into trusted reports. Clovis inserts a reviewable statement plan between the source and the books.
QFX and OFX are preferred when a bank provides them because they usually include stable transaction IDs such as FITID. A stable ID gives duplicate detection a strong key. CSV is the practical fallback, but many banks omit stable IDs or change description text. Matching then relies more heavily on account, date, amount, description, and nearby history. PDF and screenshot rows can enter through the structured transaction tool after an agent has translated them.
The plan separates rows by action. Some already match posted history. Some match pending charges that should become posted. Some are truly new. Some pending rows disappeared from a refreshed statement and may be stale. Some have several plausible matches and remain ambiguous. Applying the plan performs only the reviewed actions. The plan itself stays as an immutable receipt of what the importer decided.
| Plan action | Meaning | Safe response |
|---|---|---|
| Matched | The bank row already exists | Do not write it again |
| Pending to commit | A pending row became final | Change its status instead of copying it |
| New | No trusted match exists | Create a pending or posted journal as approved |
| Stale pending | An old pending row vanished | Review and void it if appropriate |
| Ambiguous | Several explanations remain possible | Stop and ask for review |
Uncertainty belongs in the data model.
Many finance tools force a row to look finished too early. Clovis gives every journal a lifecycle: planned, pending, posted, or void. Planned means expected but not observed. Pending means visible and useful but not final. Posted means accepted accounting history. Void preserves a rejected or reversed fact without pretending it never existed.
These states prevent a common reporting error. A planned paycheque should help a forecast, but it must not increase actual cash. A pending card charge affects the practical view of available money, but a posted-only report should exclude it. When the paycheque lands, the planned row must be matched or voided so a projection does not count both the plan and reality.
This is more than bookkeeping hygiene. It gives an AI agent a safe place to put work it does not fully know. The agent does not have to choose between doing nothing and silently changing history. It can stage a row, explain the uncertainty, and ask for the missing decision.
An expected future event used for forecasts, not an observed fact.
An observed or imported row waiting for final review.
An accepted accounting fact used in finalized history.
A preserved row that no longer affects balances or reports.
Classification does not need a model call every time.
A transaction category explains why money moved. Once a stable merchant has a stable meaning, a match rule is faster, cheaper, and easier to audit than asking an LLM again. “This exact payroll description maps to Salary” can be a deterministic rule. The same text produces the same result next month.
The model is useful one level above the rule. It can inspect uncategorized descriptions, group repeated patterns, look at the account and nearby history, propose a narrow matcher, preview which old rows the rule would affect, and explain why the target category fits. The user approves the rule only after seeing its reach. Future imports then use ordinary code.
Broad rules are dangerous. A merchant can sell groceries, medicine, fuel, and household goods. A payment processor can represent thousands of businesses. A transfer, refund, reimbursement, or card payment can resemble spending while being something else. Clovis keeps Uncategorized as a review queue and treats repetition as evidence, not proof.
Dry-run recategorization makes the risk visible. The system can show every row that would move, the old category, the new category, and the totals affected. After approval, the change receives an operation record and can be reversed. The durable asset is not a one-time AI label. It is a tested rule with a known boundary.
Do not invent a financial database when accounting already did.
I could have designed a custom transaction table with stored balances, category columns, and special cases for cards, transfers, investments, and taxes. That path feels simple until the cases disagree. A card purchase raises an expense and a liability. A card payment moves cash and reduces that liability without creating new spending. A business expense paid personally changes both an expense and an amount the business owes its owner.
Double-entry accounting has spent centuries solving this representation problem. Clovis uses its small core: journals describe events, journal lines record the accounts affected, accounts describe the economic buckets, and assets define the units such as CAD, USD, or shares. Balances are calculated from accepted lines. They are not separate numbers that can drift away from history.
journals
one event: date, description, status
journal_lines
Checking CAD -1200
Dining CAD +1200
accounts
assets, liabilities, equity, income, expenses
assets
CAD, USD, securities, or other measured unitsMoney is stored as scaled integers. A CAD amount of $12.34 becomes 1234 with a scale of two. This avoids floating-point drift when thousands of rows are summed. Cross-currency transactions balance each asset separately and use explicit price records for converted reports.
The schema adds workflow memory around that core: sources, statement plans, annotations, match rules, budgets, goals, recurrences, period closes, prices, lots, and operation audit rows. These tables do not replace accounting. They explain how facts arrived, how they were reviewed, and how the same books support planning.
The balancing invariant is the hard contract.
The current Clovis engine is TypeScript, not Rust. Its core validates each journal before storage. For every asset in a transaction, the signed quantities must sum to zero. The rule is compact enough to write as a formula:
for every asset a in journal J:
Σ quantity(line) = 0
line ∈ J and line.asset = aIn code, Clovis groups lines by asset_id, adds their integer quantities, and rejects the journal when any total is not zero. A transaction must also contain at least one line, and every quantity must fit safely inside SQLite’s integer range. SQLite foreign keys and finalization triggers enforce the storage side of the contract too.
This invariant means an agent cannot make money appear or vanish inside a journal. It does not prove that the category is correct. A perfectly balanced restaurant charge posted to Office Supplies is still wrong. That is why classification review and accounting validation are separate layers. One protects meaning; the other protects mathematical integrity.
Give the agent tools, not the database.
An open SQL connection would let an agent bypass statement plans, lifecycle states, balancing checks, period closes, and audit records. Clovis exposes the same accounting core through small command-line and MCP tools instead. MCP is a standard way for an AI client to call software with named inputs and structured results.
The catalog contains 146 tools. Seventy-five are read only. Seventy-one support a dry run, and eighteen begin in dry-run mode. The exact count is less important than the boundary. A tool can answer one question, preview one import, propose one rule, reconcile one statement, post one journal, or reverse one recorded operation. The software knows which action was requested before it reaches the ledger.
| Step | Agent action | System control |
|---|---|---|
| Read | Inspect accounts, rows, reports, and rules | Read-only tool annotation |
| Plan | Build an import or classification proposal | No ledger change |
| Preview | Show row and report differences | Dry run or rolled-back transaction |
| Apply | Commit the approved narrow change | Ledger invariants and period checks |
| Verify | Run reconciliation and integrity reports | Expected balance and structural checks |
| Reverse | Correct a recorded operation | Audit-linked reversal, not silent deletion |
Applied changes record a ledger operation with structured row differences, affected reports, and accounting deltas. A supported change can be reversed through another recorded operation. The audit trail explains what happened without rewriting the past. Local-first storage keeps the ledger and source files on the user’s machine, and file policies can limit which folders the agent may read or write.
Good tools are not enough. The agent needs a way to think.
A large tool catalog can make an agent less reliable when it does not know which tool owns a question. “How much can I spend?” is not the same as “What is my chequing balance?” A raw account forecast can include money reserved for rent. A tax note from last year cannot prove today’s filing status. The agent needs rules for choosing evidence before it needs another command.
Clovis therefore has a skill layer around the ledger. The skill is a small operating architecture for AI. An index routes the question. A short memory provides orientation. The live ledger answers current money questions. An append-only journal preserves dated reconciliations, tax work, plans, and decisions. The tool registry describes the available actions. The operating manual explains the safe order in which to use them.
Memory is a map, not the truth.
Current balances, pending transactions, budget amounts, and cash projections belong in the live ledger because they change. Dated plans, reconciliations, tax evidence, and decisions belong in an append-only journal because history should not be silently rewritten. The short memory links to those records and states the durable lessons an agent needs often. It does not copy raw statements or pretend an old balance is current.
This separation prevents a common AI failure: using the most convenient context instead of the most authoritative source. The router follows an evidence order. Fresh statements and official records answer the exact facts they cover. The live ledger answers current financial questions. Journal records explain dated evidence and accepted decisions. Memory helps the agent find them. If two sources disagree, the agent reports the conflict and checks the stronger source.
| Layer | What it knows | What it must not do |
|---|---|---|
| Live ledger | Current balances, transactions, budgets, and reports | Explain old decisions without their dated evidence |
| Append-only journal | Reconciliations, plans, tax work, and accepted decisions | Pretend historical numbers are still current |
| Derived memory | Durable rules and links to deeper evidence | Store raw statements, secrets, or unsupported claims |
| Index and router | Which source and workflow own the question | Answer the financial question by itself |
The registry gives the agent machine-readable judgment.
The tool registry is more than a list of names. It describes inputs, aliases, read-only status, destructive risk, idempotence, dry-run support, default preview behavior, and file-access rules. The agent can reason about the operation before calling it. A read-only report is safe for discovery. A broad recategorization should begin as a preview. A destructive repair should require a backup and a narrow target.
The operating manual adds process knowledge that a function signature cannot hold. It teaches the agent to import statements as pending, inspect duplicates, reconcile the ending balance, remove stale planned rows, keep transfers out of spending, subtract earmarks from spendable cash, and test broad categorization rules before applying them. The same manual is available as MCP instructions, readable resources, and a read-only tool, so different AI clients receive the same playbook.
Routing turns many tools into one coherent assistant.
A monthly budget question routes to budget and cash-projection tools. A statement file routes to the import, duplicate, and reconciliation workflow. A tax-history question routes to dated evidence before the agent checks the ledger or an official portal. A correction routes through preview, operation audit, and reversal. The agent does not search 146 tools at random. The skill narrows the problem first.
This is how Clovis brings out the best in AI. The model contributes flexible reading, planning, explanation, and judgment over ambiguous cases. Software contributes exact money, accounting rules, durable state, narrow actions, and audit. Memory provides continuity. Routing provides focus. The system is strong because each part does the work it is best at.
A personal CFO is a set of views over trusted books.
Once imports and classification are reliable, the exciting features become ordinary queries. A balance sheet groups asset and liability accounts. Net worth subtracts liabilities from assets. Spending groups expense lines by category. A budget compares actual and pending expense activity with targets. Cash projection starts with liquid balances, then accounts for liabilities, remaining budget, planned income, and earmarks such as rent or taxes.
These answers stay connected because they read the same journals. A credit card payment cannot become spending in one dashboard and a transfer in another if both use the accounting model correctly. Posted, pending, and planned views can differ, but the difference is named. The system can explain whether an answer describes settled history, current exposure, or a forecast.
Tax work benefits from the same foundation. The ledger can separate personal and business books, preserve source references, classify deductible expenses, distinguish shareholder loans from revenue, track investment cost basis, and export a reviewable history. Clovis does not replace tax law, official filings, or professional advice. It reduces the expensive part before those steps: reconstructing what happened and proving where the numbers came from.
This is composition. AI handles document variation and rule maintenance. Statement plans manage ingestion. Match rules classify repeat cases. Double entry protects the facts. Reports turn facts into decisions. None of these parts needs to imitate the others. Together they create something that feels like an accountant or CFO because the system can ingest, remember, explain, plan, and correct.
What the implementation proves
The repository proves the import, accounting, and agent architecture. Clovis accepts QFX, OFX, CSV, and structured transaction rows. Statement plans separate matches, pending-to-posted rows, new rows, stale pending rows, and ambiguous cases. Schema version four contains nineteen application tables around a double-entry core. The TypeScript validator enforces a zero sum per asset before a journal is stored.
The tool catalog proves the bounded agent surface: 146 defined tools, 75 read-only tools, 71 tools with dry-run support, and 18 that start in dry-run mode. The mutation overseer can preview changes inside a rolled-back transaction, capture structured differences, record applied operations, and reverse supported changes through another auditable operation.
AI tools with defined inputs
Repository backedread-only tools
Repository backedtools with dry-run support
Repository backedtools that start in dry-run mode
Repository backedThe evidence does not prove that AI can parse every statement correctly, choose every category, or make every financial and tax decision. QFX and OFX remain stronger import sources than a model reading a PDF because stable source IDs improve duplicate detection. A balanced journal can still carry the wrong meaning. Clovis is local bookkeeping software, not a bank, tax filing product, or substitute for professional review. No independent security audit has been published.
The result is a durable answer to a personal problem. Different accounts and document shapes can enter through one reviewable pipeline. Known classifications become reusable rules. Unknown cases stay visible instead of being guessed away. Every accepted event joins one balanced set of books. An AI agent can then manage the work around those books—imports, reviews, budgets, cash plans, and tax preparation—without becoming the accounting system itself. AI owns the changing edge. The ledger owns the truth.