Accounting-Ops MCP Server
README.md
<div align="center">
<h1>Accounting-Ops</h1>
### Books that can answer for themselves
**A verifiable financial operating system โ append-only, tamper-evident books where every number shows its source. Agents do the work, you keep the authority, on your own infrastructure.**
[](LICENSE)
[](#quickstart)
[](#agent-native-the-whole-app-is-a-tool)
[](#agent-native-the-whole-app-is-a-tool)
[](#security--your-data)
[](#bring-your-own-model)
**๐ [accounting-ops.unicorncommander.ai](https://accounting-ops.unicorncommander.ai)**
**[The problem](#the-problem) ยท [How it solves it](#how-accounting-ops-solves-it) ยท [What you get](#what-you-get) ยท [How it works](#how-it-works) ยท [Architecture](#architecture) ยท [How it compares](#how-it-compares) ยท [Quickstart](#quickstart) ยท [Learn more](#learn-more)**
<br/>
<img src="docs/assets/hero-dashboard.png" alt="Accounting-Ops dashboard โ net cash, a CFO brief of what needs you, and a live feed of agents categorizing, reconciling, and flagging transactions against your rules" width="100%" />
<sub><i>Shown on fictional demo data. Your real books never leave your machine.</i></sub>
</div>
---
> [!WARNING]
> **Not tax, legal, or accounting advice.** Accounting-Ops is software, not a licensed
> professional, and using it creates no professional relationship. You alone are responsible
> for anything you file, sign, or pay โ verify every figure against your own records and
> consult a qualified CPA / EA / attorney for anything with legal or financial consequence.
> See **[DISCLAIMER.md](DISCLAIMER.md)**.
## The problem
If you keep the books โ for your own company, or for a stack of clients โ the month looks the same
every month:
- **Categorization never ends.** Hundreds of bank lines, card charges, and payment-processor
payouts, each needing a category, a memo, and (for travel and meals) a matching receipt.
- **Reconciliation is a slog.** Feeds, receipts, and invoices that almost agree, and a queue of
"almost" that someone has to sit down and clear.
- **Month-end close eats the week.** Chasing the last few transactions, running the statements,
finding the one number that doesn't tie out.
- **Tax prep is a fire drill.** Pulling a year of activity into 1120 / 1120-S / 1065 / 1040 packages,
schedules, state forms, and quarterly estimates โ usually against a deadline.
And the tools that promise to help ask for the one thing you can't give: your entire general ledger,
uploaded to someone else's cloud, categorized by a model you can't see, on servers you don't
control. If a number ever gets questioned, "the software did it" is not an answer you can defend.
You are stuck choosing between **someone else runs your books** and **you do it all by hand.**
## How Accounting-Ops solves it
Accounting-Ops is a third option: software *you* run, that *agents* operate, that can *prove every
number.* Agents do the repetitive work end to end; you keep sign-off and a ledger that explains
itself.
- **๐ฅ The grind gets done for you.** Bank feeds, Stripe, eBay, and photographed receipts flow in.
Agents categorize, match receipts, work the reconciliation queue, and assemble tax packages โ
the categorization, reconciliation, and close work that used to eat your week.
- **โ๏ธ Agents propose, you dispose.** Nothing hits your ledger until a deterministic rule clears it
or a human approves it. Every suggestion cites its source and the policy behind it. A materiality
gate auto-posts the small stuff, queues the mid-size items for a *Confirm*, and hard-blocks the
consequential ones until you approve them with a memo.
- **๐ Every number can answer for itself.** The ledger is append-only and hash-chained. Click any
figure and the provenance chain unrolls: report line โ journal entries โ source document โ the
agent decision that created it โ the human who approved it, ending in a verified SHA-256 hash.
If a fact about your business can't be explained, it can't be posted.
- **๐ It stays on your infrastructure.** Self-host on your own hardware, air-gapped if you need to.
Local-model-first inference, bring-your-own-key when you want a bigger model, your encryption keys,
your egress policy. No mandatory cloud account. No telemetry. We never see your books.
> *We sit above the model providers and below the human reviewer โ the substrate your agents
> actually run on when the numbers have to be right.*
## What you get
<img src="docs/assets/dashboard-light.png" alt="Accounting-Ops in light mode โ the same dashboard, reports, and agent feed rendered on a light canvas" width="100%" />
**A ledger you can trust**
- Provenance-native double-entry general ledger โ **append-only and hash-chained** (tamper-evident).
- Every posted number traces to its source document *and* the decision that created it.
- Cryptographic **chain verification** walks the journal from genesis and pinpoints the exact index
of any tampering. Corrections are new reversing entries โ history is never overwritten.
**Get your data in**
- **SimpleFIN** bank feeds, **Stripe**, and **eBay** connectors.
- **Receipt ingestion** via vision-model OCR โ photograph or drop in a receipt and it becomes a
matched, substantiated line.
**Agents do the categorization and reconciliation**
- **AI categorization** that is local-model-first, with optional cloud escalation for the hard cases.
- Suggestions are provenance-safe and **require human approval** before posting.
- A **reconciliation queue** where *Confirm* posts to the journal and *Reject* trains a reusable
category override.
**See where you stand**
- **Reports:** Profit & Loss, Balance Sheet, Cash Flow, Trial Balance, Cash Position, and Runway โ
rendered in-app, straight from the journal, with full lineage on every line.
- **CFO briefs and chat:** ask your live books a question and get the number *and* where it came from.
**Bill and get paid**
- **AR / invoicing:** draft invoices, record payments, and track receivables โ every posting lands on
the same hash-chained ledger.
**Multi-entity from day one**
- One workspace, many legal entities: **C-corp, S-corp, LLC, partnership, sole-proprietor, personal,
and trust.** Consolidated and per-entity views come from the same ledger.
**Tax, end to end**
- Draft packages for **1120, 1120-S, 1065, and 1040** with schedules and **state forms**.
- **IRS-form rendering and prefill**, **quarterly estimates**, **tax narratives**, and a **tax review
queue** for the items a human should look at.
- A **tax knowledge base** (retrieval-augmented) you can search and cite.
- A **submission and e-signature rail** โ e-file, state portal, EFTPS, e-sign โ that ships
**disabled by default.** Out of the box, Accounting-Ops produces documents you print, sign, and
file; turning on any transmission channel is an explicit, gated decision you make. Generated tax
documents are watermarked **draft / do not file** until you say otherwise.
**Sentinel โ an autonomous CPA daemon**
- Runs periodic checks across your books, **drafts memos**, and **flags items for review** before
they become month-end surprises. Cadence-gated and pausable per workspace.
**Sovereign and private by default**
- Self-hosted on your own infrastructure; **local-model-capable**; **bring-your-own-key**.
- **SSO via Keycloak / OIDC**, or a single local admin โ no identity provider required.
- **Row-level tenant isolation** so workspaces stay cleanly separated.
- **No telemetry by default** โ nothing about your books leaves the host unless you configure it.
---
## How it works
A bank line or a receipt comes in. A **deterministic rule** handles it if it can; a model only
assists on what the rules leave uncertain, and that draft is queued โ never silently posted. A
**materiality gate** decides what can auto-post, what needs your *Confirm*, and what is hard-blocked
until you approve it with a memo. Only then does it become an immutable, hash-chained journal entry โ
and every report line built on it can be traced right back to this moment.
```mermaid
flowchart LR
A["Bank feed ยท Stripe ยท eBay<br/>or a receipt"] --> B{"Deterministic<br/>vendor rules"}
B -->|"match"| D["Draft entry<br/>+ cited rule"]
B -->|"no match"| C["AI categorizer<br/>(local-first, optional assist)"]
C --> D
D --> M{"Materiality<br/>gate"}
M -->|"small"| P["Auto-post"]
M -->|"mid-size"| Q["Queue for<br/>your Confirm"]
M -->|"large / no receipt"| H["Block until<br/>approved + memo"]
Q -->|"Confirm"| P
H -->|"Approve"| P
Q -->|"Reject"| R["Train a<br/>category override"]
P --> J["Append-only<br/>hash-chained journal"]
J --> RPT["Reports with<br/>full lineage"]
style J fill:#8B5CF6,color:#fff
style RPT fill:#22D3EE,color:#000
style H fill:#F59E0B,color:#000
style P fill:#34D399,color:#000
```
### Every number traces to its source
Click any figure and the provenance chain unrolls, ending in a verified `sha256` hash. **If a fact
about your business can't be explained, it can't be posted** โ a missing source is an error, not a
guess. `verify_chain` re-derives the hash of every entry from genesis and reports the first index
that disagrees, so tampering has a coordinate.
```mermaid
flowchart LR
RLINE["Report line<br/>e.g. Net Cash"] --> JE["Journal entries"]
JE --> TXN["Source transaction<br/>+ receipt / document"]
TXN --> DEC["Agent decision<br/>+ the rule that validated it"]
DEC --> APR["Human who approved it"]
APR --> HASH["Verified SHA-256 โ"]
style HASH fill:#34D399,color:#000
style RLINE fill:#22D3EE,color:#000
```
<div align="center">
<img src="docs/assets/provenance-lineage.png" alt="Provenance popover tracing net cash through hash-chained journal entries down to the source transaction and the agent decision, ending in a verified SHA-256 hash" width="88%" />
</div>
### Ask your books anything
<div align="center">
<img src="docs/assets/command-palette.png" alt="Command palette โ asking what's my runway if the slow season hits, and the CFO agent answering from live books with monthly burn, cash on hand, and cash cushion" width="88%" />
</div>
---
## Architecture
A legible stack you can run on a single box. The FastAPI app is the system of record; the web UI and
every external agent operate it through the **same** surfaces โ there is no shadow API and no second
set of rules for machines.
```mermaid
flowchart TB
subgraph clients["People + agents โ one authenticated surface"]
UI["Web UI ยท Next.js 15"]
EXT["External agents<br/>any MCP client ยท A2A ยท federation hooks"]
end
UI -->|"OIDC SSO / local admin"| MCP
EXT -->|"/mcp ยท /a2a ยท RBAC"| MCP
MCP{{"MCP / A2A surface<br/>every capability = a tool"}} --> APP
APP["app ยท FastAPI ยท system of record<br/>ledger ยท reports ยท tax ยท rules<br/>specialist agents: CPA team ยท CFO ยท Sentinel ยท tax + research"]
APP --> GATE{{"Materiality gate โ you"}}
GATE --> PG[("Postgres ยท schema-per-workspace + RLS<br/>append-only hash-chained ledger")]
APP --> GAR[("Garage ยท S3-compatible<br/>receipts / documents")]
APP --> LLM["Local model (Ollama / vLLM / BYO)<br/>OpenAI-compatible ยท optional cloud escalation"]
APP -.->|"optional"| EMB["Infinity โ Tax-Knowledge RAG<br/>FalkorDB โ agent memory"]
style MCP fill:#22D3EE,color:#000
style APP fill:#8B5CF6,color:#fff
style GATE fill:#F59E0B,color:#000
style PG fill:#1e293b,color:#fff
style GAR fill:#1e293b,color:#fff
```
- **Deterministic where it matters.** Categorization's first tier and the double-entry posting engine
are rule-based and model-free; models are an optional assist, never the system of record. You can
run the whole categorizer with no model at all.
- **Optional services degrade gracefully.** Infinity (Tax-Knowledge RAG embeddings) and FalkorDB
(best-effort agent memory) are both optional โ the app runs fully without either.
See **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** for the full runtime picture, data flows, and the
hash-chain spec.
### Agent-native: the whole app is a tool
Accounting-Ops is operable by AI agents, not just by people. A **full MCP server exposes every
capability as an agent tool** โ the same operations the UI calls, reachable by any MCP client โ plus
**agent-to-agent (A2A)** and **federation hooks** so agents in other systems can call in and your
agents can call out. Access is authenticated and RBAC-scoped on every call.
Specialist agents each own a job and report through a coordinator: a **CPA team** for categorize /
reconcile / close, **CFO briefs and chat**, **Sentinel** for periodic checks and memos,
and **tax specialists and tax research** for the form packages. They *draft* โ the materiality gate
and your approval decide what becomes real, and tax packages stay watermarked **draft / do not file**
until you release them.
---
## How it compares
Most tools make you choose between *someone else runs your books* and *you own a spreadsheet.*
Accounting-Ops competes on three things those options give up: **sovereignty**, **provenance**, and
**agent-operability.**
| | **Accounting-Ops** | Cloud accounting SaaS<br/>(hosted books & AI bookkeepers) | Rolling your own<br/>(spreadsheets + scripts) |
|---|:---:|:---:|:---:|
| Runs on **your** infrastructure | โ
| โ | โ
|
| **Append-only + hash-chained** ledger | โ
| โ | build it yourself |
| Every number **traces to its source** | โ
| partial | build it yourself |
| **Agent-operable** over MCP / A2A | โ
| partial | build it yourself |
| **Local-model / bring-your-own** runtime | โ
| โ | โ
|
| Human-approval gates on posting | โ
| varies | manual |
| Multi-entity + tax drafting **out of the box** | โ
| varies | โ |
| Source you can **read and change** | โ
AGPL | โ | โ
(it's yours) |
| Data stays on **your** machine | โ
| โ | โ
|
- **Versus cloud accounting SaaS.** It's convenient and managed โ and your general ledger lives on
someone else's servers, categorized by a model you can't inspect. Accounting-Ops keeps the books,
the keys, and the model on hardware you control, and every number carries its own audit trail.
- **Versus rolling your own.** Spreadsheets and scripts give you control but not the ledger
guarantees, the reconciliation and tax engines, or the agent tooling. Accounting-Ops gives you the
control *and* a defensible ledger, without a build project.
---
## Quickstart
**Prerequisites:** Docker + Docker Compose v2, and (for the bootstrap helper) Python 3.12 and
`openssl` on the host. No GPU required โ a CPU-only Ollama works, just slower.
### One command (self-host)
```bash
git clone <this-repo> accounting-ops && cd accounting-ops
make selfhost
```
`make selfhost` (โ `scripts/selfhost_bootstrap.sh`) is idempotent and will:
1. create `.env` from `.env.example`;
2. generate strong secrets (Postgres, Garage, NextAuth) and the local auth secret;
3. configure local single-admin auth (no identity provider required);
4. prompt you for a local admin password and store only its scrypt hash;
5. generate the credential master key (`secrets/accounting_ops_master_key`);
6. build + start the stack โ **postgres + garage + ollama + app + web**;
7. run migrations, provision one workspace + entity, grant your admin the owner role, and seed a
chart of accounts.
Then open **http://localhost:3000**, sign in with your admin email + password, and you're in.
Pull a vision model so the agent can categorize and read receipts:
```bash
docker compose -f docker-compose.selfhost.yml exec ollama ollama pull qwen2.5vl:7b
```
Add a manual journal entry (or import a bank CSV), open **Reports**, and render a P&L โ all with
**no external dependency.**
### Bring your own model
The bundled **Ollama** service (`http://ollama:11434/v1`) is the default target for the categorizer
and receipt OCR. Set `LLM_ENDPOINT_URL` / `LLM_MODEL` in `.env` to point anywhere OpenAI-compatible โ
a remote Ollama, vLLM, an on-prem gateway, or a hosted API. Choose a **vision** model for receipt
reading. Inference is local-first; cloud escalation is opt-in.
### Optional services (compose profiles)
| Profile | Service | What it adds | Degrades gracefully? |
|---|---|---|---|
| `embeddings` | Infinity | embedding backend for the Tax-Knowledge RAG index | Yes โ app runs fine without it |
| `graph` | FalkorDB | best-effort agent-memory projection | Yes โ a no-op if absent |
```bash
docker compose -f docker-compose.selfhost.yml --profile embeddings --profile graph up -d
```
### Demo data (optional)
```bash
make demo # seeds generic sample workspaces (no PII)
```
<details>
<summary><b>Single sign-on (Keycloak / OIDC)</b> โ for teams and firms</summary>
The same image authenticates people through **Keycloak / OIDC** instead of a local admin. Point it
at your realm and set the OIDC environment variables; RBAC still resolves every call against
workspace membership and a role floor. See **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** for the
identity and tenancy model.
</details>
---
## Security & your data
- **No telemetry by default.** The OTEL endpoint defaults to none; there is no analytics SDK. Nothing
about your books leaves the host unless you configure an egress yourself.
- **Authenticated on every call.** People authenticate via Keycloak / OIDC or a local admin; agents
via owner-scoped access tokens โ all resolved against workspace membership and an RBAC role floor.
- **Tenant isolation in the schema.** Schema-per-workspace, backed by a row-level-security fence; the
runtime DB role is non-superuser and does not own its objects, so the append-only guarantee is
enforced by Postgres, not merely by app code.
- **Encrypted credentials.** Connector credentials are encrypted at rest with a local master key
(`secrets/accounting_ops_master_key`). **Back it up out-of-band** โ losing it orphans all encrypted
credentials.
- Found a vulnerability? See **[SECURITY.md](SECURITY.md)**.
## The design stance
Accounting-Ops is built as an **autonomous professional-substitute you supervise** โ not a co-pilot
that only suggests, and not a black box that just decides. It never fabricates provenance (a missing
source is an error, not a guess), it watermarks anything unfiled as *draft*, and it routes anything
it isn't sure about to you. Human review is a control you turn up or down, not a tax on every action.
Read the full posture in **[docs/PROFESSIONAL-SUBSTITUTE.md](docs/PROFESSIONAL-SUBSTITUTE.md)**.
## Who it's for
- **Founders & small businesses** who want their books *actually kept* โ not just a dashboard โ
without handing their financials to a SaaS.
- **Bookkeepers, accountants & fractional CFOs** who want agents to do the grind while a human keeps
sign-off, and need an audit trail that holds up.
- **Privacy- and sovereignty-minded operators** (regulated, air-gapped, or simply careful) who need
the ledger and the keys to stay on their own hardware.
- **Developers & AI builders** who want a real, agent-operable financial backend to build on via
MCP / A2A, instead of gluing together closed APIs.
## Learn more
- **๐ Product site โ [accounting-ops.unicorncommander.ai](https://accounting-ops.unicorncommander.ai)**
โ positioning, screenshots, and the story behind the design.
- **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** โ full runtime picture, data flows, and the
hash-chain spec.
- **[docs/PROFESSIONAL-SUBSTITUTE.md](docs/PROFESSIONAL-SUBSTITUTE.md)** โ the autonomy-with-guardrails
design stance.
- **[docs/AGENT-ACTIVITY-SPEC.md](docs/AGENT-ACTIVITY-SPEC.md)** โ the agent-activity event model.
- **[CHANGELOG.md](CHANGELOG.md)** โ what's shipped.
## Contributing
Issues and PRs are welcome. By contributing you agree to the **Developer Certificate of Origin** (sign
your commits with `git commit -s`). Start with **[CONTRIBUTING.md](CONTRIBUTING.md)** and our
**[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)**.
If Accounting-Ops is useful to you, **starring the repo** genuinely helps others find it. โญ
## License
**[GNU AGPL-3.0-or-later](LICENSE)** โ you may run, study, share, and modify it; if you offer it as a
network service, your users are entitled to the source of your version. See **[NOTICE](NOTICE)**.
<div align="center">
<br/>
<sub>Built by <b>Magic Unicorn</b>.</sub>
<br/>
<sub><b>Accounting-Ops is not a CPA, EA, tax preparer, attorney, or fiduciary.</b><br/>
It is a tool that helps you do that work โ and you are responsible for what you do with it.</sub>
<br/><br/>
<sub><i>The books are yours. We just gave them better hands.</i></sub>
</div>
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues