Link copied
BlogI Built an AI Accounting Agent for Malaysian SMEs. The e-Invoice Mandate Makes It Urgent Now.
Product Pipeline

I Built an AI Accounting Agent for Malaysian SMEs. The e-Invoice Mandate Makes It Urgent Now.

KG
Teh Kim GuanACMA · CGMA
2026-05-26 · 8 min read · Updated 2026-05-27
I Built an AI Accounting Agent for Malaysian SMEs. The e-Invoice Mandate Makes It Urgent Now.

Malaysia's accounting software market is one of the most interesting technology gaps I know of. SQL Accounting, built by eStream, runs on more than 600,000 desktops across the country. It is the default. Most SME bookkeepers in Malaysia have touched it. Many have been using it for a decade. And until now, it had no AI layer at all.

I have been building on top of it for months, first for my own consultancy work, then for clients. What started as a personal tool has become something I think the broader community can use. I shipped the first version yesterday: my-accounting-agent, a free, open-source accounting agent that works with SQL Accounting, Xero, and Bukku through three lightweight CLI tools and a universal AI skill.

This is why I built it, how it works, and why the timing matters.

The problem is not the software. It is the gap between the software and the human.

Two-column comparison: without the agent showing 5 manual steps in grey versus with my-accounting-agent showing 2 steps in navy

SQL Accounting has a REST API. Xero has a well-documented API. Bukku has one too. The underlying data is accessible. The problem is that accessing it requires technical knowledge that most finance managers and bookkeepers simply do not have, and should not need.

To pull an AR aging report from SQL Accounting via API, you need to understand AWS SigV4 authentication. You need to know that the base URL is api.sql.my, that the service is execute-api, and that the region is ap-southeast-1. You need to handle pagination, because the API returns at most 50 records per call. You need to know that dockey is read-only and dtlkey: -1 is required on every new line item.

None of that knowledge is about accounting. It is about API plumbing.

A bookkeeper asking "which customers owe us more than RM10,000 and haven't paid in 60 days" should not have to learn any of that. They should just ask the question.

That is the gap this project closes.

What I built: three CLIs and a universal skill

Three-layer architecture diagram showing CLI Commands on top, AI Skill kg-accounting-agent in the middle, and Reference Files at the bottom

The architecture has three layers.

The first layer is three pip-installable CLI packages, one per platform:

  • sqlacc covers SQL Accounting's 13 modules: customers, suppliers, invoices, payments, orders, stock, journals, cash book entries. It handles SigV4 authentication, pagination, and the updatecount guard that prevents conflicting writes.
  • bukku covers Bukku's API for contacts, invoices, expenses, payments, and AR aging. One critical detail: Bukku's base URL is https://api.bukku.my with no /api/v1/ prefix, and every request needs both an Authorization: Bearer header and a Company-Subdomain header. Getting either wrong returns a silent 401.
  • xero covers Xero's accounting API via OAuth2 Client Credentials, which means no user login flow required. There is a well-known bug in the xero-python library: if you store scopes as a string instead of a list, refresh_oauth2_token() returns None silently, and every subsequent API call fails. I guard against this at config load time.

The second layer is a universal Claude Code skill, kg-accounting-agent. When you install it to ~/.claude/skills/, Claude Code auto-triggers on any accounting task and routes to the correct platform. The skill covers seven workflows out of the box: creating invoices, debtor aging with collection triage, recording payments, AP pre-payment briefing with anomaly detection, cash flow projection, duplicate invoice detection, and month-end close status reporting.

The third layer is a set of reference files covering the Malaysian context in depth: SST-02 returns, e-Invoice compliance checking, PCB/MTD payroll tax, EPF/SOCSO/EIS contributions, withholding tax, CP204 instalments, and a month-end close playbook. Five chart of accounts templates for Malaysian entity types are bundled as JSON: Sdn Bhd, Enterprise, PLT, Berhad, and Nonprofit.

The same skill works with ChatGPT / Codex and Gemini Code Assist via AGENTS.md and GEMINI.md files in the project root.

What it looks like in practice

Horizontal flowchart with five nodes: User Question flows through Skill Triggers, CLI Runs, AI Processes to Output Delivered

Here is a real example. You open Claude Code and type:

"Pull our AR aging and flag anyone over 60 days. Draft a WhatsApp reminder for the top three."

The skill picks this up, runs:

sqlacc --json customer aging

Gets the aging data back as JSON, identifies customers in the 61-90 day and 90+ day buckets, ranks them by outstanding balance, and drafts three tiered collection messages. Polite for 61-90 days. Firm for 91-120 days. Formal for over 120 days.

The whole thing takes under a minute. Without the agent, pulling the aging report alone requires logging into SQL Accounting, navigating to the aging report, exporting to Excel, and then manually writing the messages.

Another example: month-end close status.

"Is the May close done?"

The agent pulls all sales invoices, purchase invoices, payments, and journals for May. It checks whether AR aging matches the GL debtor control total, whether any journal entries are unbalanced, whether the suspense account has uncleared items. It reports which phases are complete and what is still outstanding. The close target in Malaysia's accounting industry is the 3rd of the following month. The agent knows this.

Why the e-Invoice mandate changes the urgency

Vertical timeline showing MyInvois milestones from August 2024 to January 2026 with a navy callout box highlighting non-compliance penalties

Malaysia's MyInvois e-invoice mandate has been live since August 2024. By November 2024, over 64.5 million e-invoices had been submitted to the system.

Phase 4 of the mandate, which covers businesses with annual turnover up to RM5 million, applies from January 2026. From that date, individual invoices above RM10,000 are mandatory to submit individually to MyInvois. No more consolidated invoices. The government raised the exemption threshold from RM500,000 to RM1 million in December 2025 after SME pushback on readiness, and cancelled the fifth wave for businesses below that threshold. But the mandate extends in one direction only.

Non-compliance carries fines up to RM20,000 per invoice, or six months in prison under tax law.

SQL Accounting and Bukku have native MyInvois integration. Every sales invoice in SQL Accounting has an eiv_utc field that records the submission timestamp. If it is null on an invoice that falls within the mandate scope, the invoice is non-compliant. My agent can check this across an entire invoice listing in seconds:

sqlacc --json invoice list --type sales --offset 0

It then scans for null eiv_utc values on invoices above the threshold, reports the non-compliant list, and flags the risk. An accountant managing multiple clients on SQL Accounting can run this check monthly. Before this tool existed, you had to open each client's SQL Accounting manually and check.

This is not a novelty use case. It is a compliance audit that every firm managing Malaysian SME clients should be running.

The browser fallback matters

Decision tree: API available branches YES to CLI path via sqlacc, bukku, xero and NO to browser fallback via Chrome DOM scraping

One design decision that sets this apart from a straightforward API wrapper: all three AI platforms I targeted, Claude Code, ChatGPT / Codex, and Gemini Code Assist, ship computer-use and browser capabilities. When an API cannot do something, which is more common than you would expect in legacy accounting software, the skill falls back to the web portal.

For Xero specifically, I have been using Chrome MCP DOM scraping as the primary data extraction method for live accounts payable monitoring. The approach: confirm the user has an authenticated Xero tab open, run a single JavaScript extraction call against the bills table, and check for an auth wall before proceeding. This method has been running reliably in production for months. I have documented the exact JavaScript and the auth wall detection pattern in the skill.

The point is that the agent does not stop when the API stops. It reaches into the browser.

The roadmap

Horizontal product roadmap with five milestones: v0.1 SHIPPED in navy, v0.2 through v0.5 in grey showing the planned release sequence

This is v0.1.0. The plan:

v0.2: Unit tests for Bukku and Xero to match the 34 unit tests already in place for SQL Accounting.

v0.3: Extended Bukku modules including credit notes and customer statements. Xero bank feed support. A recurring anomaly check workflow, which compares current month transactions against a prior-month baseline and flags what is missing or spiked.

v0.4: A management accounting layer. Budgeting versus actual analysis. Department and cost centre reporting. Working capital management. Intercompany reconciliation.

v0.5: AutoCount support. AutoCount is the second most widely-used accounting software in Malaysia, with over 240,000 companies on it. It deserves the same treatment.

Every real engagement I do with SQL Accounting, Xero, or Bukku will surface new patterns that feed back into this repo. The product gets better through use.

How to install it

git clone https://github.com/tehkimguan/my-accounting-agent
cd my-accounting-agent
./setup

The setup script installs all three CLIs via pip and copies the Claude Code skill to ~/.claude/skills/. You will need to restart Claude Code for the skill to appear.

Then configure whichever platforms you use:

# SQL Accounting
sqlacc config save --host api.sql.my --access-key YOUR_KEY --secret-key YOUR_SECRET

# Bukku
bukku config save --subdomain your-subdomain --token YOUR_TOKEN

# Xero
xero config save --client-id YOUR_ID --client-secret YOUR_SECRET --tenant-id PLACEHOLDER
xero config tenants   # lists your organisations + their IDs
xero config save --client-id YOUR_ID --client-secret YOUR_SECRET --tenant-id CORRECT_ID

After that, open Claude Code and ask it anything about your accounting data.

Not comfortable with the command line? You can still get value from the reference layer without installing anything. Open the SKILL.md file on GitHub, copy its contents, and paste it at the start of a conversation in ChatGPT, Claude.ai, or Gemini. The AI will then understand Malaysian accounting workflows, the e-Invoice compliance requirements, the SST-02 structure, and the month-end close checklist. You will not get live queries against your accounting system (those need the CLI tools), but you get the analysis frameworks and Malaysian tax reference material in plain conversation. Export your AR aging report to CSV, paste the data, and ask the question. That alone is more than most accountants are doing today.

If you find a workflow that is not covered, or an endpoint I got wrong, open an issue or send a PR. This is a community tool. It improves because practitioners feed back what they learn.

The gap between accounting software and AI has been there for years. The tools to close it are now mature. The regulatory pressure from the e-Invoice mandate is pushing Malaysian SMEs toward their accounting APIs whether they intended to go there or not. The agent is ready.

Star the repo and run ./setup.

Part of the Product Pipeline series from KG Consultancy.

About the Author
KG
Teh Kim Guan
Product Consultant · General Manager, PEPS Ventures

Strategy and technology are the same decision. Over 15 years in fintech (CTOS, D&B), prop-tech (PropertyGuru DataSense), and digital startups, I have built frameworks that help founders and executives make both moves at once. Based in Kuala Lumpur.

Work with KG

Working on a 0→1 product?

I help founders and operators go from idea to validated product. Let's talk about yours.

Get in touch →