erp-report-engine is a read-only, self-verifying data layer for ERP databases, whose main purpose is to automatically generate weekly reports and provide AI agents with guarded database access. It is suitable for databases used by Turkish small and medium-sized enterprise ERPs such as Logo Tiger, Netsis, and Mikro (all of which are MSSQL), and can also be used with SQLite, PostgreSQL, and others. The materials state that it requires no BI license, no agent installed on the ERP server, and performs no write operations.
Main capabilities
- Scheduled runs execute 9 audited SELECT statements and output a self-contained HTML report: four KPIs relative to an 8-week baseline, findings with named drivers, data quality gates, and row counts reconciled against the source data.
- A built-in demo database allows running demo commands to view a sample report; the sample report contains three intentionally planted data quality issues, all of which are caught by the gates.
- Exposes the ERP to AI agents through an MCP server; agents interact using normalized entities (such as orders, rather than LG_001_01_ORFICHE) and are subject to the same read-only protections and audit trail.
- Provides an optional AI summary feature (--narrate): only audited aggregate data (KPIs, findings, aging/concentration, never raw rows) is provided to the model, and the report prints the full payload the model saw for verification. The flag has no effect when no key is configured. Supports any OpenAI-compatible endpoint, including local keyless models (Ollama / LM Studio).
- Built-in delivery: run --send can send the report via SMTP email, publish a summary to Slack or Teams (Power Automate Workflows), and ping healthchecks.io's dead-man's-switch on success or failure. All secrets come from environment variables, and channel failures are only logged rather than fatal.
- Provides a Power BI Command Center: written as code in the form of a PBIP project, including a TMDL semantic model (star schema, 28 documented DAX measures, including SVG microchart measures that use DAX to draw a mini sparkline for each customer and a coverage bar for each project, accounts receivable aging facts and measures, and Time based on gapless week sequence numbers Shift calculation groups, field parameters), PBIR reports (5 pages / 30 visuals, generated by script from a compact spec), and a dark futuristic theme (validated against Microsoft's official theme schema).
- Provides a standalone read-only SQL guard package readonly-sql-guard (pip install readonly-sql-guard), depending only on re and sqlglot.
Usage
- 60-second demo (no ERP required): installable via pipx, with commands such as pipx install "erp-report-engine[mssql]" (for Logo Tiger / Netsis / Mikro, SQL Server) or [postgres]. Docker support is also provided: docker build -t erp-report-engine . then docker run --rm -v "$PWD:/work" erp-report-engine run -c config.demo.yaml. SQLite and PostgreSQL work out of the box; MSSQL requires adding Microsoft's ODBC driver.
- Connect to your own ERP: put the connection URL in an environment variable (never write it to a file), copy config.example.yaml → config.yaml, then first verify with a dry-run: validate checks the connection, verifies the profile contract, and reconciles counts, without touching anything else.
- Can be run with a scheduler; each run appends to state.db, enabling reports to express cross-run memory such as "declining for the third consecutive week". Exit codes allow schedulers to branch: 0 success, 2 configuration error, 3 database/connection error, 4 contract error (profile schema error or source counts cannot be reconciled), 5 data quality failure under --strict, 1 other unexpected. Machine-readable results are output to stdout, logs to stderr, optionally written to a JSON lines file via --log-file run.jsonl. It is recommended to run validate --strict in CI to fail the pipeline when numbers cannot be reconciled.
- The MCP server provides six tools, all viaguarded paths; the normalized model is also published as a machine-readable contract model.json (or erp-report-engine schema).
Security model
- Read-only is enforced at four layers: lexical, parse tree, side-effect function guard, read-only session.
- Ad-hoc SQL (agent path) is stricter: query and guarded_query run in strict mode, by default rejecting every function the guard cannot name; sqlglot's function registry serves as the allow list. All four built-in profiles pass this check.
- Notes that MSSQL has no session-level read-only switch, so it is recommended to run the engine under a least-privilege read-only login (db_datareader for MSSQL, SELECT-only grants for PostgreSQL, ideally a read replica). The guard is defense in depth; authorization is the final layer of assurance.
- The guard ships with a reproducible trust benchmark: 28 well-formed SQL attacks across four dialects, all rejected, plus legitimate reads that must still pass. The benchmark also shows the gaps of weaker guards (a header check starting with SELECT, a write-keyword blacklist) on the same 28 cases: they reject 6 and 9 respectively, and keyword scanning even blocks legitimate reads containing the word "delete" in text, whereas this guard rejects all 28 and blocks no legitimate reads.
- Profile variable identifiers are safe (^[A-Za-z0-9_]{1,16}$), secrets are never placed in configuration files (the loader rejects any form of embedded credentials, use url_env), every executed statement is published with the report audit trail, and a single query has a row limit (default 500k).
- The test suite throws a large number of injection attempts at the guard (multi-statement, comment smuggling in three syntaxes, transaction control splicing ROLLBACK / COMMIT, SELECT INTO, locking hints, DELETE hidden in a CTE), expecting every one of them to throw an exception.
Included profiles
- generic — normalized schema, and also the template for writing your own profile.
- logo_tiger — Logo Tiger / GO on MSSQL: LG_{firm}_{period}_ORFICHE order headers with CLCARD customers, ORFLINE lines, STINVTOT inventory totals, TRCODE = 2 sales filtering, plus optional AR aging from PAYTRANS (installment TOTAL − PAID, MODULENR = 4). Logo architecture varies by version, and profiles carry field notes.
- netsis — Logo Netsis 3 on MSSQL (one database per company): TBLSIPAMAS / TBLSIPATRA sales orders (FTIRSIP = '6'), TBLCASABIT customers, TBLSTOKPH inventory totals, and optional AR aging from TBLCAHAR. Field mappings come from real production integrations, and weak points (order status, delivery date, AR settlement method) are flagged inline.
- mikro — Mikro ERP on MSSQL (Mikro Yazılım, Fly/Jump/V16–V17): SIPARISLER (sip_ prefix, line-level) sales orders, CARI_HESAPLAR customers, STOK_HAREKETLERI current stock (sth_tip in/out), and optional AR aging from CARI_HESAP_HAREKETLERI (cha_vade due date). Weak points (sip_tip sales filtering, whether totals include VAT, no shipment date on orders, pure running-balance AR ledger with no open-item flag) are flagged inline.
Together, Logo Tiger, Netsis, and Mikro cover most of the Turkish SME ERP market (all MSSQL). Writing a profile for other ERPs (SAP B1, Odoo, custom systems) means writing three SELECT statements that output normalized columns, either as standalone YAML pointed to via profile:, or placed in erp_report_engine/profiles/ and shipped with the package.
When to use
- Enterprises that need to automatically generate weekly business reports from an ERP database and do not want to use or purchase BI tools.
- Scenarios that need to let an AI agent query ERP data in a provably read-only, auditable way.
- Developers who want to safely expose ERP entities (such as orders) in the MCP ecosystem rather than raw tables.
- Scenarios that need standalone read-only SQL protection that can be embedded into their own MCP server or database tooling.
Limitations
- MaterialsIt is clear that MSSQL has no session-level read-only switch, so the ultimate guarantee depends on a least-privilege read-only login or read-only replica at the database layer.
- Built-in profiles have weak points that need to be verified against specific versions, such as netsis's order status, delivery date, and AR settlement method, and mikro's sip_tip sales filtering, VAT inclusiveness, absence of shipment date, and AR ledger weak points.
- The materials do not provide charges, prices, platform support scope, performance metrics, or specific outcome commitments; apart from the above, other details are not yet provided.