OpenLedger – Local-first double-entry accounting, MCP-native (Apache 2.0) OpenLedger, an Apache 2.0-licensed local-first double-entry accounting system with an SQLite backend and a Model Context Protocol (MCP) server exposing 15 tools, has been released by Attri Inc. The ledger enforces immutable transactions, contra-posting corrections, and an append-only audit log, and is designed to be queryable by both humans and AI agents via natural language. The project is part of a family of local-first agent services including open-crm and openwatch. Local-first double-entry accounting, queryable by humans and agents. SQLite-backed ledger. MCP server with 15 tools. Immutable transactions, contra-posting corrections, append-only audit log. Part of a family of local-first agent services: open-crm memory · openwatch observability · openledger money . cd open-ledger python3 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt python scripts/seed.py bootstrap a fresh dev DB with sample books python run mcp.py stdio transport default For Claude Code: claude mcp add openledger -s user -- \ /absolute/path/to/open-ledger/.venv/bin/python \ /absolute/path/to/open-ledger/run mcp.py See docs/claude-connector.md /Attri-Inc/open-ledger/blob/main/docs/claude-connector.md for the full setup. ┌─────────────────────────────────────┐ │ SQLite ledger │ │ accounts · transactions · │ │ entry lines · audit log · settings │ └──────────────────┬──────────────────┘ │ ▼ MCP server stdio / SSE :8791 15 tools — reads + safe writes │ ▼ Claude Desktop, Claude Code, agent frameworks A layered architecture SOLID : the transport, business rules, and persistence are separated, and each depends only on the layer's abstraction — not its implementation. Swapping SQLite for Postgres later touches only repositories/ and container.py . src/ ├── domain/ pure constants + typed error hierarchy no I/O ├── infrastructure/ Database connection, Unit of Work, id/clock helpers ├── repositories/ protocols.py — narrow Reader/Writer contracts │ sqlite.py — the only code that writes SQL aiosqlite ├── services/ accounts · ledger · reports Strategy · audit · query │ — the only layer with business rules / invariants ├── serialization.py response/error envelope helpers ├── container.py composition root — wires SQLite repos into services └── mcp server.py thin MCP transport adapter over the services run mcp.py stdio entry point for Claude Desktop / Code scripts/ seed.py sample data · schema.sql · smoke test.py tests/ service-level tests of the core invariants Querying is raw parameterized SQL over aiosqlite no ORM ; all SQL lives behind the repository protocols, so services never see a query. 1. Every transaction has ≥ 2 entry lines and sum debits == sum credits — enforced in the write path inside one DB transaction. 2. All amounts are integer minor units cents . No floats anywhere. 3. Transactions and entry lines are immutable . Corrections happen via reverse transaction contra posting , never UPDATE/DELETE. 4. Every mutation writes an audit-log row in the same DB transaction . | Group | Tools | |---|---| | Accounts | list accounts · get account · get balance · get account ledger · create account | | Journal | get transaction · search transactions · post transaction · transfer funds · reverse transaction | | Reports | get trial balance · get profit loss · get balance sheet | | Audit | get audit log | | Escape hatch | run query SQL SELECT only | | Env var | Default | Notes | |---|---|---| | OPENLEDGER DB | ./data/openledger.db | SQLite path | | MCP TRANSPORT | stdio via run mcp.py | stdio or sse | | MCP PORT | 8791 | SSE only | - "How much cash do we have right now?" - "Show me the P&L for January." - "Are the books balanced?" trial balance - "Post a $250 cash sale for today." - "Move $500 from Wallet A to Wallet B." - "What was reversed recently, and why?" Contributions welcome — see CONTRIBUTING.md /Attri-Inc/open-ledger/blob/main/CONTRIBUTING.md and our Code of Conduct /Attri-Inc/open-ledger/blob/main/CODE OF CONDUCT.md . Report vulnerabilities per SECURITY.md /Attri-Inc/open-ledger/blob/main/SECURITY.md . Licensed under the Apache License 2.0 — see LICENSE /Attri-Inc/open-ledger/blob/main/LICENSE .