ledger-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ledger-mcp Run the month-end review and tell me which vendors I need to contact."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ledger-mcp
An MCP server that lets LLM agents (Claude, ChatGPT, Cursor, any MCP client) query and reconcile an accounts-payable ledger, plus an eval suite that measures how well the server does the job.
It ships with a synthetic ledger (8 vendors, 131 invoices, 125 payments) where real-world problems are planted on purpose: underpayments, duplicate payments, payments in the wrong currency, overdue invoices, payments without a reference, and a payment that could belong to two invoices. The eval suite checks the server against that ground truth.
Why
Reconciling invoices against payments is a classic job for an agent: lots of rows, fuzzy references, and a few exceptions that matter. Letting a model write arbitrary SQL against financial data is risky, so this server gives it:
Safe access: the database is opened read-only, and free-form SQL is limited to a single
SELECTwith a row cap.Deterministic tools for the hard parts: matching logic lives in tested Python, not in the model's head.
Measurable quality: precision and recall per exception type, a hostile-SQL safety check, and a contract check, all runnable in CI.
Related MCP server: Payables MCP
What it exposes
Type | Name | What it does |
Tool |
| Read-only |
Tool |
| Billed, paid and open balance per vendor |
Tool |
| Matches invoices to payments and lists exceptions by type |
Tool |
| Raw invoice, payment and vendor rows behind an exception |
Resource |
| Table definitions, so the agent writes valid SQL |
Prompt |
| Step-by-step month-end close workflow |
Matching rules
Reference match: the payment reference contains the invoice number (case-insensitive).
Fuzzy match: same vendor and currency, amount within tolerance, paid within N days of issue, and exactly one candidate invoice. If more than one invoice fits, the payment is flagged as
ambiguous_paymentinstead of guessed.
Exception types: underpaid, overpaid, duplicate_payment, currency_mismatch, overdue_unpaid, unmatched_payment, ambiguous_payment.
Quick start
pip install -e ".[dev]"
ledger-seed # creates data/ledger.db and evals/golden.json
ledger-mcp # stdio transport, for Claude Desktop / Cursor
ledger-mcp --transport streamable-http --port 8000 # HTTP transportInspect it interactively with the MCP Inspector:
mcp dev src/ledger_mcp/server.pyUse it from Claude Desktop
Add this to claude_desktop_config.json:
{
"mcpServers": {
"ledger": {
"command": "ledger-mcp",
"env": { "LEDGER_DB": "/absolute/path/to/data/ledger.db" }
}
}
}Then ask: "Run the month-end review and tell me which vendors I need to contact."
Docker
docker build -t ledger-mcp .
docker run -p 8000:8000 ledger-mcp # streamable HTTP on :8000/mcpTests and evals
pytest -q # unit tests + protocol tests through an in-memory MCP client
python evals/run_evals.py # golden-set eval, exits 1 if a quality gate failsSample eval output:
kind exp pred precision recall
underpaid 3 3 1.00 1.00
duplicate_payment 2 2 1.00 1.00
currency_mismatch 2 2 1.00 1.00
overdue_unpaid 4 4 1.00 1.00
unmatched_payment 3 3 1.00 1.00
ambiguous_payment 1 1 1.00 1.00
fuzzy_matched 2 2 1.00 1.00
hostile SQL rejected: 100% data intact: True
PASSThe golden file is written by the seed script when it plants each anomaly, so the eval never grades the code against its own output. CI runs lint, tests, evals and a Docker build on every push.
Project layout
src/ledger_mcp/
server.py MCP tools, resource and prompt (FastMCP)
reconcile.py matching logic, pure functions
db.py read-only SQLite access and SQL guard
seed.py synthetic data with planted anomalies + golden file
tests/ unit and protocol tests
evals/ end-to-end eval suite over MCPIdeas for next steps
Migrate to MCP Python SDK 2.x (
MCPServer), currently pinned to 1.x.Postgres backend behind the same tools.
An agent-level eval: run a model through
month_end_reviewand score its final table against the golden file.Multi-currency matching with FX rates.
License
MIT
Available Tools
4 toolsexplain_exceptionC
Return the raw invoice and payment rows behind an exception, plus the vendor.
Inputs: invoice_id, payment_id. Returns: object
reconcile_ledgerA
Match invoices to payments and list every exception.
Exception kinds: underpaid, overpaid, duplicate_payment, currency_mismatch, overdue_unpaid, unmatched_payment, ambiguous_payment.
Args: as_of: ISO date used to decide which unpaid invoices are overdue. amount_tolerance: max difference (same currency) still treated as equal. date_window_days: how far after issue date a reference-less payment can land. include_matches: also return every matched invoice (large output).
Inputs: as_of, include_matches, amount_tolerance, date_window_days. Returns: object
run_sqlA
Run a read-only SELECT (or WITH ... SELECT) against the ledger.
Returns columns, rows and whether the result was truncated. Write statements, multiple statements and PRAGMAs are rejected.
Inputs: query (required), limit. Returns: object
vendor_balancesA
Billed, paid and open balance per vendor, optionally filtered by currency.
Payments are counted in the vendor's own currency only, so a payment sent in the wrong currency shows up as an open balance (and as an exception in reconcile_ledger).
Inputs: currency. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
run_sql is a generic read-only query escape hatch that could overlap with vendor_balances, but vendor_balances provides currency-aware aggregation that SQL alone wouldn't easily replicate. reconcile_ledger and explain_exception form a clear drill-down pair, so boundaries are mostly distinct.
Three tools follow a verb_noun pattern (run_sql, reconcile_ledger, explain_exception), while vendor_balances is a noun phrase. All are snake_case and readable, but the verb-first consistency is not universal.
Four tools are well-scoped for a read-only reconciliation server: a generic query, a balance report, a reconciliation engine, and an exception inspector. Each has a distinct role and none feels redundant.
The read-only surface covers querying, balances, reconciliation, and exception drill-down. A direct structured tool for listing invoices or payments is absent, but run_sql provides a viable workaround, leaving only minor gaps.
Maintenance
Related MCP Connectors
Accounts-payable exception environment with a pass/fail verifier and proof packet: AI agents work AP
Personal finance ledger for AI agents — query spending, track bills, forecast cash flow.
AI agents for bookkeeping, reconciliation, and financial close for SMBs.
Primary-source SEC filing intelligence and financial/disclosure reconciliation for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAn accounting-ops agent that reconciles payments against open orders, auto-books provably safe payments through a deterministic policy gate, and escalates exceptions to a human queue with audit trails.MIT
- FlicenseAqualityCmaintenanceEnables an AI agent to handle accounts payable tasks against a mock ERP, including reading and writing bills and vendors, checking duplicates, matching invoices, recommending approvals, and queuing payment releases, with configurable profiles that limit available tools.11-
- AlicenseNot gradedqualityCmaintenanceEnables LLMs to query a synthetic general ledger and trial balance through read-only tools for account lookups, GL drill-down, variance analysis, and naive forecasting, with every answer cited to specific transactions or periods.66 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables natural-language-driven purchase-to-pay workflows against mock procurement and payment APIs, including invoice matching, exception handling, human approvals, and idempotent payment scheduling with a tamper-evident audit log.MIT