BooksKey features

Bookkeeping, AI-assisted

Let the bots do the data entry. You keep the ledger.

Books is a bookkeeping workspace for small and medium organizations anywhere, where AI does the repetitive heavy lifting - bringing in transactions from a connected feed or the statement you uploaded, categorizing them, reading receipts and invoices, deriving the bank reconciliation workpaper, and drafting journal entries - and a person reviews, posts, and signs. The assistant is now built into the app - chat with the live ledger, attach documents, approve postings from the chat - and you can still connect your own AI agent over MCP; both run through the same audited tool layer. Nothing shaky lands in the ledger without a human confirming it, and no reconciliation is signed by anything but a person. The screens below are illustrative and use synthetic sample data only. Here is each feature and how it flows.

AI bot

Does the repetitive heavy lifting — reading, extracting, drafting, matching.

You

Keep the judgement calls — review, correct, approve, and sign off.

Platform

Moves data between modules so nothing is re-typed or re-uploaded.

Built-in Books Assistant (new)

An assistant already inside the books - no setup

Books now ships with its own chat panel - multiple chats with history, like ChatGPT or Claude. It answers from the live ledger, reads the documents you attach or pick from the Documents & Storage library, and does real bookkeeping work - with every posting stopping at an in-chat approval card first.

The old way
The AI lived somewhere else. You copied figures out of the books into a chat window, pasted suggestions back by hand, and hoped both sides were still current.
What the bot does now
Answers from the live trial balance, balance sheet, P&L, AR/AP aging, and account activity - real numbers, not summaries. Reads attached files and the indexed, OCR'd document library. Creates journal entries, categorizes and matches bank-feed transactions, runs bank reconciliations, and drafts invoices and bills. You pick the model per chat - Gemini, Claude, GPT, or an open model - and every plan can use every model.
Where you sign off
Every posting stops at an in-chat approval card - AI prepares, people approve the ledger - and every action goes through the same audited, firm-scoped tool layer as the MCP connector. AI is included with any subscription; AI Core ($39/mo) and AI Advanced ($129/mo) add weekly credits, and pay-as-you-go is $10 for 250 credits.

What it looks like

Google AntigravityBooks Assistant · in-app chat
Categorize my unmatched bank transactions.
12 unmatched in June - 9 categorize with high confidence and 2 match open bills. Approval cards are queued in this chat; nothing posts until you tap one.
books_bank_suggest_categorization{ month: "2026-06" }done
propose_categorization{ batch: 9 }awaiting your review
propose_journal_entry{ memo: "Meridian - June" }awaiting your review

Your own assistant - Antigravity, Claude, ChatGPT, or Gemini Spark - calling real WorkpaperOS tools over MCP. Anything that changes the file waits for your review and sign-off in the app. Synthetic data shown.

How it flows

An assistant already inside the books - no setup: Open the chat then Answer from the ledger then Draft the work then Approve the cardYouOpen the chatinside BooksAI botAnswer from theledgerlive numbersAI botDraft the workJEs, categorizationsYouApprove the cardthen it posts

Connect an AI agent (MCP)

Point your AI agent at your books and let it work

Books exposes an MCP server, so you can connect Gemini Spark, ChatGPT, Claude, Google Antigravity, or another compatible MCP client and have it do real bookkeeping tasks against your authorized data. Provider availability and approval requirements apply.

The old way
AI assistance meant copying figures out of the accounting system into a chatbot and pasting suggestions back by hand. The assistant never actually touched the books.
What the bot does now
Connected over MCP, the agent uses real Book tools - reading transactions and reports, drafting journal entries and importing and validating them, attaching supporting documents, importing statement lines, and running operations helpers. The payroll tools read the United States payroll module, which is the only one that exists today.
Where you sign off
Access is scoped, and the things that move money or hit the ledger - posting a journal entry, for example - stay a deliberate human step. The agent drafts; you post.

Grounded in the Books MCP tool registry and its company-scoped journal, document, operations, firm-admin, and payroll tools.

What it looks like

Google Antigravitybook.workpaperos.com/api/book/mcp
Where are we on the June books?
Feeds are synced and categorized - 38 proposals await your approval, and the June operating-cash workpaper derives to a $0.00 difference with two adjusting entries sitting as drafts. Nothing posts without you, and I cannot sign it.
books_journal_instructions{}done
books_journal_upload_drafts{ entries: [...] }done
books_journal_queue_post{ journal_entry_ids: ["..."] }awaiting your review

Your own assistant - Antigravity, Claude, ChatGPT, or Gemini Spark - calling real WorkpaperOS tools over MCP. Anything that changes the file waits for your review and sign-off in the app. Synthetic data shown.

How it flows

Point your AI agent at your books and let it work: Open your AI agent then Connect via MCP then It runs real tools then Review + postYouOpen your AI agentGemini Spark, Claude...PlatformConnect via MCPscoped accessAI botIt runs real toolson your booksYouReview + postyou commit it

Books Files

Let your AI analyze originals and return finished files

The same Books MCP connection covers the ledger, indexed documents, and original-file exchange. The download, analysis, and return-upload workflow is validated with ChatGPT, Claude, and Google Antigravity. No separate Files connector or continuously mirrored desktop folder is required.

The old way
You downloaded evidence from one system, attached copies to an AI chat, then manually uploaded its work into the book and checked which copy was current.
What the bot does now
Requests the current original Excel, PDF, Word, or image file through a short-lived HTTPS download; analyzes it in a permitted execution environment; and returns generated files through reserved uploads. Heavy file bytes travel outside MCP messages, supported large uploads can resume, and completion validates the file before indexing.
Where you sign off
You authorize the companies the AI may access, retain its file and network permissions, and review the returned work. A file upload does not post a journal entry, approve a payment, or sign a reconciliation. Host capabilities and file limits still apply.

Built on scoped MCP authorization, private document storage, signed HTTPS transfers, and the Books document indexing pipeline.

How it flows

Let your AI analyze originals and return finished files: Authorize Books then Analyze the original then Validate returned file then Review and approveYouAuthorize Booksone product connectionAI botAnalyze the originalsigned HTTPS downloadPlatformValidate returnedfileupload + indexingYouReview and approveposting stays separate

Bank feeds, and the statement path

Transactions arrive on their own - or the statement does the same job

In the United States, connect an account once and Books pulls transactions in automatically. Everywhere else there is no automatic feed yet, so you upload the statement - and an account with no feed at all still reconciles, because the statement you upload IS the bank side.

The old way
Someone downloads a CSV from the bank each week, cleans it up, and imports it - or types transactions off a paper statement. And the software that could not connect to your bank treated your statement as a second-class import that never quite tied out.
What the bot does now
Where the feed is available, a Plaid-powered connection links the account, verifies it, and syncs new transactions on an ongoing basis. Where it is not, the upload parser reads a CSV or a PDF statement - the PDF goes through the same tiered extractor as the document inbox - and reports which column it read as which field, how it resolved DD/MM against MM/DD, and any line it could not read, with the physical line number.
Where you sign off
You approve which accounts are connected. On the upload path you correct any column the parser read wrong, and the statement's closing balance is a derived starting point you can always type over - a figure a person typed wins over every derived one.

Grounded in the Plaid link-token route, which requests country_codes: ["US"] - so the automatic feed is United States institutions today - and in src/lib/book/recons/statement-import.ts and statement-pdf.ts, which turn a CSV or PDF upload into the same rows the derivation engine reads from a feed.

How it flows

Transactions arrive on their own - or the statement does the same job: Connect, or upload then Rows either way then Prepare for review then Own what postsYouConnect, or uploadfeed (US) or statementPlatformRows either waysame shape downstreamAI botPrepare for reviewready to categorizeYouOwn what postsyou decide

Any country

The ledger does not know which country you are in

Books is bookkeeping software for small and medium organizations anywhere. The double-entry ledger, the journal entries, the reconciliation workpaper, the close, the reports, and the MCP assistant carry no country's tax rules - what varies is a short, named list of things, not the product.

The old way
You bought a country edition, and the parts of it you could not use were still in your way - a chart of accounts shaped like someone else's tax return, and amounts printed in someone else's currency.
What the bot does now
Each organization carries a country and a base currency, and amounts are formatted for that currency and locale everywhere they appear - including currencies written without decimal places. The seed chart of accounts is chosen by entity type, for-profit or not-for-profit, rather than by country.
Where you sign off
You set the country and currency in setup, and you own the chart from the moment it is seeded - rename accounts, delete the ones that do not apply, add your own. What is United States only today is short and named: the automatic bank feed, payroll processing, sales tax by state, and 1099 vendor reporting. Payroll for other countries is being built, and we are not attaching a date to it.

Grounded in src/lib/book/locale.ts (per-country locale and currency, zero-decimal currency handling, and the country list offered in setup) and src/lib/accounting/coa-templates.ts, whose only two templates are for_profit and not_for_profit.

How it flows

The ledger does not know which country you are in: Set country + currency then Seed the chart then Money reads right then Edit anythingYouSet country +currencyin setupYouSeed the chartby entity typePlatformMoney reads rightcurrency + localeYouEdit anythingthe chart is yours

AI categorization

Suggest the right account for every transaction

Books proposes a category for each incoming transaction with a confidence level and a plain-English reason - so categorization becomes a quick confirm, not a decision from scratch.

The old way
A bookkeeper reads each payee and memo and manually picks a GL account, transaction by transaction, every month.
What the bot does now
The categorization engine ranks candidates from your firm rules, your firm's historical categorization of similar counterparties, and heuristics - returning a top suggestion, alternates to consider, and a confidence score.
Where you sign off
Low-confidence items wait for you; only high-confidence matches under an explicit rule can auto-post. You accept, change, or split the categorization - the ledger reflects your call, not the bot's guess.

Grounded in src/lib/accounting/bank/ai-categorization.ts (rule / history / heuristic tiers, confidence, auto_post gate) and the bank_ai_categorization migration.

What it looks like

book.workpaperos.com/banking

For review - checking ****2841

Bank feed synced - AI suggested a category for each

Feed live
Cedar Point Fuel Stop-84.206210 - Vehicle fuelrule - auto - 95%
Northgate Office Depot-212.996130 - Office suppliestop match - 88%
ACH Deposit - Sample Advocacy Group+3,500.004000 - Consulting revenueconfirm - 74%
SQ *Riverside Cafe-41.756410 - Meals (50%)confirm - 58%

Only a high-confidence rule match auto-posts; the rest wait for you to confirm. Synthetic transactions.

How it flows

Suggest the right account for every transaction: New transaction then Rank candidates then Score confidence then Confirm or changePlatformNew transactionfrom the feedAI botRank candidatesrule, history, heuristicAI botScore confidence+ reasonYouConfirm or changeyou code it

Document inbox

Pull the fields off a receipt or invoice for you

Drop a receipt, bill, or invoice into the inbox and Books reads it, extracts the vendor, date, amount, tax, and currency, and pre-fills the form - keeping the original file as the source of record.

The old way
You squint at a receipt and retype the vendor, date, and totals into a bill form, then file the paper somewhere you hope to find it again.
What the bot does now
A tiered extractor runs a fast OCR pass, escalates to Google Document AI's invoice/expense parser for real structured fields and confidences, falls back to an LLM and then heuristics, and maps everything onto the bill form with per-field confidence.
Where you sign off
When overall or a key field's confidence is below the review threshold, the item is flagged for review with the reasons listed - it will not silently post a shaky number. You confirm the fields before it becomes a transaction.

Grounded in src/lib/accounting/documents/docai-inbox.ts + inbox-extraction.ts (Doc AI -> LLM -> heuristic tiers, reviewRequired at 82/72 confidence), the tiered OCR in file-indexing/ocr-escalate.ts, and the book_document_review_flags migration.

What it looks like

book.workpaperos.com/inbox

Original file

receipt-mar08.pdf kept as source

Extracted fields

2 fields flagged for review
VendorHarbor Freight Ltd.96%
Date2026-03-0894%
Amount1,248.50 USD91%
Tax78.50 USD63%
Account6120 - Shop supplies71%
Confirm & saveYou approve before it posts. Synthetic data.

How it flows

Pull the fields off a receipt or invoice for you: Upload document then Extract fields then Flag low confidence then Confirm + saveYouUpload documentoriginal keptAI botExtract fieldsDoc AI + fallbacksAI botFlag low confidencewith reasonsYouConfirm + saveyou approve

Reconciliation

The bank reconciliation workpaper, derived instead of typed

One Recons tab opens the six-sheet workpaper every CPA already knows - Reconciliation, Reconciling Items, Journal Entries, Book Register, Bank Activity, and How this works. The difference between bank and books is never a bare number: it decomposes into named, categorised, sourced items, each stating whether it needs a journal entry.

The old way
Reconciliation sat under each bank account as a tick-off screen. You ticked statement lines against the ledger one at a time, and when the last few cents would not close you had nothing but a number to argue with.
What the bot does now
Books rebuilds the workpaper from the ledger and whatever the bank side is - a connected feed, or the statement you uploaded - every time you open it: outstanding checks, deposits in transit, bank service charges, interest, NSF returns, and bank debits and credits not yet on the books. A GL account with no feed connected to it at all reconciles in full, because its book entries match against the statement lines you uploaded. The statement ending balance is calculated from whichever source applied, and labelled with which one. Anything the matcher cannot confidently place is surfaced as its own reviewable item, never folded into Outstanding Checks and never hidden.
Where you sign off
Bank-side items are timing and need no entry; book-side items are missing entries and always do - and those arrive as drafts you review and post, never auto-posted. A closed period stops the whole batch and asks you to open it rather than re-dating the entry into a month it did not happen in. The statement balance stays editable, and a figure you type wins over the derived one. A person signs as preparer and a different person signs as reviewer.

Grounded in src/lib/book/recons/derive.ts (the workpaper is re-derived from the ledger on every call; whether an item needs a journal entry is asserted to be exactly whether it is book-side) and the /api/book/recons routes - post-entries, finalize, signoff, and reopen.

How it flows

The bank reconciliation workpaper, derived instead of typed: Derive the workpaper then Name every item then Post the drafts then Prepare + reviewPlatformDerive the workpaperledger + bank feedAI botName every itemtype, side, sourceYouPost the draftsyou pick whichYouPrepare + reviewan AI cannot sign

Human sign-off

An AI can prepare the reconciliation. It cannot sign it.

Everything in Recons is reachable by an AI connected over MCP, because everything else is work. Sign-off is not work - it is a named person asserting they did the work and stand behind it - so it is the one door an AI is refused at.

The old way
Sign-off was a checkbox with whatever user account happened to be logged in behind it, which told a reviewer nothing about who actually looked at the workpaper.
What the bot does now
Your assistant can derive the workpaper, explain each reconciling item, draft the adjusting entries, and drive the difference to zero - the whole preparation, end to end.
Where you sign off
The sign-off route turns an MCP caller away outright and says why, rather than recording a human's user id against something that human did not do. A preparer signs first; the reviewer must be a different person; and a workpaper cannot be finalized until a preparer has signed it.

Grounded in the sign-off route's MCP refusal (HUMAN_SIGNOFF_REQUIRED), its SELF_REVIEW and PREPARER_REQUIRED checks, and the finalize gate that requires a prepared sign-off before a workpaper can complete.

How it flows

An AI can prepare the reconciliation. It cannot sign it.: Prepares everything then Preparer signs then A second person reviews then FinalizeAI botPrepares everythingover MCPYouPreparer signsa named personYouA second personreviewsnever the preparerPlatformFinalizerefused without a signature

Native journal-entry import - direct upload

Upload journal-entry drafts, then post them yourself

Bring journal entries in as a native CSV or Excel file - drafted by your assistant or built by hand - and Books validates them and hands you a draft, but the entry only hits the ledger when a person posts it. There is no cloud storage to connect: you upload the drafts directly and the built-in assistant works exactly the same.

The old way
You build a journal entry by hand in a spreadsheet, retype it into the accounting system, and hope the debits and credits balance.
What the bot does now
The Book journal tools take a native CSV or Excel journal-entry draft, import it once (idempotent by file hash) through the existing import-validate-draft pipeline, and attach any supporting documents you have uploaded to the book. Debits and credits are checked on import, and the batch lands in the journal queue as drafts - nothing touches the ledger yet.
Where you sign off
Posting is a deliberate step, and the imported batch is locked to the journal on post and becomes immutable. If you ask your assistant to post the queue it can, and the entry is still undoable afterwards - a true undo that removes the effect rather than stacking a reversal - until you lock the period.

Grounded in the books_journal_upload_drafts tool and the import-validate-draft pipeline (idempotent by file hash, post-lock immutability).

How it flows

Upload journal-entry drafts, then post them yourself: Draft + upload JE then Import + validate then Review the draft then Post to ledgerAI botDraft + upload JECSV or ExcelPlatformImport + validatedebits = creditsYouReview the draftyou check itYouPost to ledgerlocked on post

Review, undo, lock

Let an AI keep the books without losing control of them

Posting is not what makes work final in Books. There are two states - posted, which is still a draft, and locked, which is final - and only you can move work between them.

The old way
You either let software post automatically and hope, or you approve every line by hand and lose the time the automation was supposed to save.
What the bot does now
Your assistant categorizes, matches, splits, excludes, and posts through MCP - and will summarize what it intends to post and where before it acts, if you ask it to. When it hits a locked period it reports the lock instead of routing around it.
Where you sign off
A posted row is still a draft: one click undoes it, and the undo removes the effect rather than posting a reversal. That holds until you set a closing date - then the period cannot be posted into or undone out of at all, by you or by the assistant, without your password. Signing a bank reconciliation records who prepared and who reviewed it and freezes that report as signed; it does not freeze the ledger, and we say so rather than implying a second lock. Your closing date is your acceptance of the month, and it is the only thing that makes one final.

Grounded in src/lib/book/bank-undo-guards.ts, which now carries exactly one guard - the closing date - on the shared executor both the app and MCP queue into, and the matching closing-date check in src/lib/accounting/journal-entry-engine.ts that refuses to post into a locked period.

How it flows

Let an AI keep the books without losing control of them: Posts the work then Review the ledger then Undo anything then Lock the periodAI botPosts the workor proposes firstYouReview the ledgerat your paceYouUndo anythingone click, no reversalYouLock the periodnow it is final

Clean books with less typing.

Start a 5-day trial of Books. The bots draft the entries and categorize the transactions; you review and post. No card required.

Start Books free