Skip to main content
Glama
Unicorn-Commander

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: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-8B5CF6?style=flat-square)](LICENSE)
[![Self-host](https://img.shields.io/badge/self--host-one%20command-22D3EE?style=flat-square)](#quickstart)
[![Agent-native](https://img.shields.io/badge/agent--native-MCP%20%C2%B7%20A2A-8B5CF6?style=flat-square)](#agent-native-the-whole-app-is-a-tool)
[![MCP server](https://img.shields.io/badge/MCP-full%20server-8B5CF6?style=flat-square)](#agent-native-the-whole-app-is-a-tool)
[![Telemetry](https://img.shields.io/badge/telemetry-none%20by%20default-34D399?style=flat-square)](#security--your-data)
[![Models](https://img.shields.io/badge/models-bring%20your%20own-22D3EE?style=flat-square)](#bring-your-own-model)

**๐ŸŒ [accounting-ops.unicorncommander.ai](https://accounting-ops.unicorncommander.ai)**

**[The problem](#the-problem)&nbsp; ยท &nbsp;[How it solves it](#how-accounting-ops-solves-it)&nbsp; ยท &nbsp;[What you get](#what-you-get)&nbsp; ยท &nbsp;[How it works](#how-it-works)&nbsp; ยท &nbsp;[Architecture](#architecture)&nbsp; ยท &nbsp;[How it compares](#how-it-compares)&nbsp; ยท &nbsp;[Quickstart](#quickstart)&nbsp; ยท &nbsp;[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>