/SKILL.md
Double-entry, full-cycle accounting suite built for AI agents. Converts bank CSVs, OFX, and QBO files into balanced, auditable books — balance sheet, income statement, general ledger, trial balance. All data stays in a single local SQLite file.
npx skillsauth add 737999/gridtrx gridtrxInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when the user asks you to "do the books," "categorize expenses," "import bank transactions," "run a balance sheet," or any bookkeeping task. GridTRX is a full-cycle double-entry accounting engine. You prompt in plain English, and the agent completes the books correctly. Every transaction balances. Every amount is deterministic. All data is local — no cloud services, no external APIs.
GridTRX produces a full set of auditable books: balance sheet, income statement, general ledger, trial balance, adjusting journal entries, retained earnings rollforward. Reports are exportable to CSV and PDF for any time period.
GridTRX has three interfaces to the same engine (models.py → books.db):
models.py directly. No text parsing, typed parameters, deterministic output.python cli.py. Zero dependencies beyond Python 3.7+ standard library. Any terminal-based agent can drive it via subprocess.localhost:5000 via python run.py. Ledger browsing, report viewer with drill-down, comparative reports up to 13 columns, bank import with rule preview, reconciliation marking, dark mode.All three hit the same models.py data layer. Nothing is out of sync. Use MCP when available. Fall back to CLI otherwise. The browser UI is for human review.
Install dependencies before first use (one-time setup):
pip install -r requirements.txt
Or install individually: pip install mcp (MCP server), pip install flask (browser UI). The CLI has no dependencies beyond the Python 3.7+ standard library.
No packages are installed at runtime. All dependencies must be pre-installed.
Add to the agent's MCP config with GRIDTRX_WORKSPACE set to the user's client folder:
{
"command": "python",
"args": ["/path/to/mcp_server.py"],
"env": {"GRIDTRX_WORKSPACE": "/path/to/clients"}
}
GRIDTRX_WORKSPACE is mandatory — the MCP server will refuse to start without it. Any db_path outside the workspace is rejected at runtime. Every MCP tool takes db_path as its first parameter, which must resolve to a books.db file inside the workspace.
GRIDTRX_WORKSPACE=/path/to/clients python cli.py /path/to/clients/acme/books.db <command>
Runs one command, prints plain text to stdout, exits. When GRIDTRX_WORKSPACE is set, the CLI enforces the same workspace boundary as the MCP server — paths outside the workspace are rejected.
books.db file or its parent folder)..csv, .ofx, or .qbo).BANK.CHQ for chequing).(1,500.00) = Credit. — = Zero.BANK. EX. REV. AR. AP. GST. RE. SHL. — When importing a trial balance or creating accounts, ALWAYS use GridTRX naming. Never use numeric account codes. If the source data has numeric codes (1010, 5800, etc.), ignore the codes and map by description to the nearest GridTRX account name. If no match exists, create the account using the EX. or REV. prefix convention. Always call list_accounts first before creating anything.models.py) — CLI, MCP server, and browser UI all call the same functions.MCP: No direct tool — use exec to run CLI.
CLI: python cli.py then new /path/to/folder "Company Name"
This creates books.db with a full chart of accounts (~60 posting accounts), five reports (BS, IS, AJE, TRX, RE.OFS), 60+ import rules, and four tax codes. Always use starter books as the base — they include the critical perpetual retained earnings chain (IS → NI → RE.CLOSE → RE on BS, plus RE.OFS/RE.OPEN for year-end). Never build reports from scratch without this chain. The fiscal year ceiling (fy_end_date) is automatically set to the current fiscal year end.
After setup, run validate to confirm the report chain is intact:
CLI: python cli.py /path/to/books.db validate
| Data source | Tool | Notes |
|---|---|---|
| Bank CSV (3-col: Date, Description, Amount) | import_csv | Rule-based categorization, unmatched → EX.SUSP |
| Bank OFX/QBO | import_ofx | Rule-based categorization, FITID dedup |
| GL export / system conversion (4-col: Date, Description, Amount, CrossAccount) | import_gl | Cross-account specified per row, no rules needed |
| CaseWare AJE (IIF or Venice) | import_aje | Routes through journal account |
| Single manual entry | post_transaction | One at a time only |
Never call post_transaction in a loop to import bank data. Use the appropriate bulk tool.
MCP (preferred):
import_csv(db_path, csv_path, "BANK.CHQ")import_ofx(db_path, ofx_path, "BANK.CHQ")CLI fallback:
python cli.py /path/to/books.db importcsv /path/to/file.csv BANK.CHQpython cli.py /path/to/books.db importofx /path/to/file.qbo BANK.CHQCSV format required: 3 columns — Date, Description, Amount. Deposits positive, withdrawals negative. Header row optional. The import applies all rules automatically. Check the result summary: posted, skipped, to_suspense.
MCP: import_gl(db_path, csv_path, "BANK.CHQ")
CSV format required: 4 columns — Date, Description, Amount, CrossAccount. Positive = debit to the primary account, negative = credit. All cross-accounts must already exist in the chart of accounts. No import rules are applied — the cross-account column is used directly.
Use this when converting from another accounting system (NV1, QuickBooks GL, Sage, etc.) where every transaction already has its cross-account known. Prepare one CSV per primary account (bank, credit card, etc.) per fiscal year.
import_aje(db_path, file_path, "25AJE")python cli.py /path/to/books.db importaje /path/to/aje_export.iif 25AJEMCP: get_ledger(db_path, "EX.SUSP")
CLI: python cli.py /path/to/books.db ledger EX.SUSP
Every entry here is an unrecognized transaction. Note the description and transaction ID for each.
Present each suspense item to the user. Ask: "What category is this?"
Do NOT guess. If the description is ambiguous (e.g., "AMAZON", "BEST BUY", "TRANSFER"), ask the user for business context before categorizing.
Once the user answers, add a rule so future imports are automatic:
MCP: add_rule(db_path, "AMAZON", "EX.OFFICE", "G5", 0)
CLI: python cli.py /path/to/books.db addrule AMAZON EX.OFFICE G5 0
Tax code is optional. Common codes: G5 (GST 5%), H13 (HST 13%), H15 (HST 15%), E (exempt).
Delete each suspense transaction, then re-import so the new rules apply:
MCP: delete_transaction(db_path, txn_id) for each, then import_csv(...) or import_ofx(...) again.
CLI: python cli.py /path/to/books.db delete <txn_id> for each, then re-run the import command.
Repeat Steps 3-5 until suspense is empty.
MCP:
trial_balance(db_path) — debits must equal creditsgenerate_report(db_path, "BS") — Balance Sheetgenerate_report(db_path, "IS") — Income StatementCLI:
python cli.py /path/to/books.db tbpython cli.py /path/to/books.db report BSpython cli.py /path/to/books.db report ISWhen the fiscal year is complete:
MCP: rollforward(db_path, "2025-12-31")
CLI: python cli.py /path/to/books.db rollforward 2025-12-31
This reads RE.CLOSE from the IS, posts Dr RE.OFS / Cr RE.OPEN, sets the lock date, and advances the FY ceiling to the next year. Then repeat from Step 2 for the next fiscal year. Rows beyond the ceiling are automatically skipped during import.
When importing multiple fiscal years of historical data:
get_info(db_path) — note the fy_end_date.import_csv, import_ofx, or import_gl for each bank account. Rows after the ceiling are automatically skipped.year_end(db_path, "YYYY-MM-DD") — this posts the RE closing entry, sets the lock date, and advances the ceiling to the next FY.Example (3-year backfill, Dec 31 FY):
# FY2022 — ceiling is 2022-12-31
import_gl(db, "fy2022_bank_cdn.csv", "BANK.CDN")
import_gl(db, "fy2022_cc_visa.csv", "CC.VISA")
year_end(db, "2022-12-31")
# FY2023 — ceiling is now 2023-12-31
import_gl(db, "fy2023_bank_cdn.csv", "BANK.CDN")
import_gl(db, "fy2023_cc_visa.csv", "CC.VISA")
year_end(db, "2023-12-31")
# FY2024 — ceiling is now 2024-12-31
import_csv(db, "fy2024_bank_cdn.csv", "BANK.CDN") # current year, use rules
import_csv(db, "fy2024_cc_visa.csv", "CC.VISA")
If the user uploaded the wrong file or you imported against the wrong account:
search_transactions(db_path, "some description") or via CLI search <keyword>.delete_transaction(db_path, txn_id) or CLI delete <txn_id>.There is no bulk undo. Deletions are individual and respect the lock date — you cannot delete transactions in a locked period.
| Tool | Purpose |
|------|---------|
| list_accounts(db_path, query?) | List/search chart of accounts |
| get_balance(db_path, account_name, date_from?, date_to?) | Single account balance |
| get_ledger(db_path, account_name, date_from?, date_to?) | Account ledger with running balance |
| trial_balance(db_path, as_of_date?) | Trial balance — all accounts, Dr/Cr columns |
| generate_report(db_path, report_name, date_from?, date_to?) | Run a report (BS, IS, AJE, etc.) |
| get_transaction(db_path, txn_id) | Single transaction with all journal lines |
| search_transactions(db_path, query, limit?) | Search by description/reference |
| list_reports(db_path) | List available reports |
| list_rules(db_path) | List import rules |
| get_info(db_path) | Company name, fiscal year, lock date |
| Tool | Purpose |
|------|---------|
| post_transaction(db_path, date, description, amount, debit_account, credit_account) | Post a simple 2-line entry |
| delete_transaction(db_path, txn_id) | Delete a transaction (respects lock date) |
| add_account(db_path, name, normal_balance, description?) | Add a posting account |
| add_rule(db_path, keyword, account_name, tax_code?, priority?) | Add an import rule |
| delete_rule(db_path, rule_id) | Delete an import rule |
| import_csv(db_path, csv_path, bank_account) | Import bank CSV (3-col, rule-based) |
| import_ofx(db_path, ofx_path, bank_account) | Import bank OFX/QBO (rule-based) |
| import_gl(db_path, csv_path, bank_account) | Import GL CSV (4-col, cross-account per row) |
| import_aje(db_path, file_path, ref_prefix) | Import CaseWare AJE export (IIF or Venice) |
| rollforward(db_path, ye_date) | Year-end rollforward (posts RE closing, sets lock, advances ceiling) |
| year_end(db_path, ye_date) | Alias for rollforward |
| set_lock_date(db_path, lock_date?) | Show or set the lock date |
| set_ceiling(db_path, date?) | Show or set the fiscal year ceiling |
| bulk_report_layout(db_path, report_name, items, after_account?, mode?) | Batch-place items on a report (accounts, totals, labels, separators) |
EX.SUSP and ask the user. Do not assume "AMAZON" is office supplies — it could be inventory, personal, or cost of sales.cli.py commands or MCP tools. Never use file tools to read or write the SQLite database.books.db files within the user's GridTRX workspace. Both the MCP server and CLI enforce this when GRIDTRX_WORKSPACE is set — the MCP server will not start without it, and both interfaces reject any path outside the workspace.get_info(). You cannot post on or before the lock date, or after the FY ceiling. Run rollforward to advance to the next fiscal year.python cli.py commands against books within the workspace. Do not run arbitrary shell commands, install packages, start background processes, or execute scripts other than cli.py. The MCP server is the preferred interface — use CLI only when MCP is unavailable.testing
Create, edit, improve, or audit AgentSkills. Use when creating a new skill from scratch or when asked to improve, review, audit, tidy up, or clean up an existing skill or SKILL.md file. Also use when editing or restructuring a skill directory (moving files to references/ or scripts/, removing stale content, validating against the AgentSkills spec). Triggers on phrases like "create a skill", "author a skill", "tidy up a skill", "improve this skill", "review the skill", "clean up the skill", "audit the skill".
testing
Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).
testing
Create, edit, improve, or audit AgentSkills. Use when creating a new skill from scratch or when asked to improve, review, audit, tidy up, or clean up an existing skill or SKILL.md file. Also use when editing or restructuring a skill directory (moving files to references/ or scripts/, removing stale content, validating against the AgentSkills spec). Triggers on phrases like "create a skill", "author a skill", "tidy up a skill", "improve this skill", "review the skill", "clean up the skill", "audit the skill".
testing
Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).