Exact-decimal double-entry for agents. Call MCP tools; do not do money math in tokens.
Money.from · validateEntry · Ledger.apply. Invalid entries are rejected, never posted.
Do not add, split, convert, or balance amounts yourself. Call the kernel.
npx -y @eternal-roman/ledger-mcp
{
"mcpServers": {
"ledger": { "command": "npx", "args": ["-y", "@eternal-roman/ledger-mcp"] }
}
}
Then:
ledger://canon/rules and ledger://canon/workflow.money_compute. Validate with entry_validate. Post with ledger_post.ledger_verify_equation + ledger_audit_hash. Never invent an audit hash.cite_lookup. Bundle proof with artifact_make.Rules live in AGENTS.md. Protocol: docs/CORE-PROTOCOL.md. Machine index: llms.txt. Full tool list: mcp/.
Host plugins (Grok and compatible) load /ledger-verify, /ledger-audit, /ledger-cite, /ledger-reconcile, /ledger-sim, /ledger-review from this repo. Copy AGENTS.md or skills/ledger/SKILL.md if the host has no plugin loader.
Token-level arithmetic is indifferent to scale, balance, and currency. The kernel is not.
| Failure | Kernel |
|---|---|
| Float drift / sub-scale | Money.from rejects |
| Unbalanced entry | validateEntry + Ledger.apply reject |
| Silent currency mix | Per-currency; FX must be explicit |
| Tamper / non-repro | SHA-256 auditHash (ledger-audit-v2) + determinism harness |
| Ungrounded treatment | Starter IFRS/GAAP graph via cite_lookup |
| Exact money | Double-entry | Immutable + audit hash | Deterministic | No DB | Agent / MCP | |
|---|---|---|---|---|---|---|
| Ledger | yes | kernel | yes | yes | yes | yes |
| dinero.js | yes | — | — | — | yes | — |
| medici | partial | yes | — | — | MongoDB | — |
| Formance / TigerBeetle | yes | yes | yes | partial | service | — |
npm install @eternal-roman/ledger
import { Money, Account, AccountType, createBalancedEntry, emptyLedger, validateEntry } from '@eternal-roman/ledger';
const cash = new Account('1000', 'Cash', AccountType.Asset);
const equity = new Account('3000', 'Owner Equity', AccountType.Equity);
const contribution = createBalancedEntry(
'cap-001', '2026-06-21', cash, equity,
Money.from('10000', 'USD'), 'Initial capital'
);
if (!validateEntry(contribution).ok) throw new Error('Invariant violation');
const ledger = emptyLedger().apply(contribution).ledger;
ledger.balance(cash).toString(); // "10000.00 USD"
ESM and CommonJS. Kernel-only import: @eternal-roman/ledger/core.
Mechanical check (no LLM):
npx ledger-verify --scan .
npx ledger-verify --prove entries.json
All of these emit validated JournalEntrys. None reimplement money.
fillToEntries, deposits, withdrawals, taker/maker feesvaluePortfolioplanRebalanceAsset scales (BTC=8, ETH=18, …) are installed with installAssetScales(defaultAssetRegistry()). Fiat is unchanged. See examples/.
npm test
npm run verify # determinism harness
npm run verify:full # build + typecheck + tests + versions + MCP smoke
npm run eval # unguarded vs kernel benchmark
| Doc | For |
|---|---|
AGENTS.md | Agent contract |
llms.txt | Machine-readable map |
docs/CORE-PROTOCOL.md | Zero-Skip protocol |
docs/SUCCESS-CHECKLIST.md | Pre-ship checklist |
docs/ANTI-PATTERNS.md | What the kernel rejects |
docs/SCOPE-AND-LAYERS.md | What ships today |
mcp/README.md | MCP tools, resources, prompts |
CONTRIBUTING.md | Developing this repo |
Python kernel port: reference-implementations/python/ (same invariants; install an asset-scale resolver for non-fiat).
MIT. See LICENSE.
Deterministic primitives and verification tools. Not financial, tax, legal, or accounting advice. You are responsible for inputs, assumptions, rates, jurisdiction, and compliance. Tests and benchmarks are due diligence, not a certification. See LICENSE.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @eternal-roman/ledger-mcpMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-eternal-roman-ledger": {
"command": "npx",
"args": [
"-y",
"@eternal-roman/ledger-mcp"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceio.github.eternal-roman/ledger works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.