npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@elnora-ai/merit-aktiva

v0.1.10

Published

Merit Aktiva accounting API for Claude Code — full CLI for the Estonian/Polish Merit Aktiva REST API, plus agents and slash commands.

Downloads

1,442

Readme

elnora-merit-aktiva

License npm version CI

Do your Merit Aktiva accounting from the command line — or let Claude Code do it for you.

Merit Aktiva is Estonia's cloud accounting platform. This repo gives you two ways to drive its API:

  • elnora-merit — a CLI that covers the entire Merit Aktiva API (invoices, payments, VAT/KMD, ledger, reports, and more) plus Merit Palk payroll. JSON in, JSON out.
  • A Claude Code plugin that wraps the CLI in skills, agents, and slash commands, so you can ask in plain English ("book this purchase invoice", "file my KMD") and Claude runs the right commands the right way.

Everything is universal — nothing about any one company is hardcoded. Point it at your own Merit credentials and it works.

Requires a Merit Aktiva Pro or Premium license — the API is not available on lower tiers.


Install

As a CLI

npm install -g @elnora-ai/merit-aktiva

This puts the elnora-merit command on your PATH. Node.js ≥ 20 required.

As a Claude Code plugin

Paste these two slash commands into Claude Code one at a time — wait for the first to finish before the second:

/plugin marketplace add Elnora-AI/elnora-merit-aktiva
/plugin install merit-aktiva-workspace@elnora-merit-aktiva

The plugin uses the elnora-merit CLI under the hood, so install that first.

Make the write agents actually fire

The plugin ships three agents that wrap the CLI with guardrails — resolve the customer, build per-rate VAT totals, preview the payload, gate on your approval:

| When you ask to… | Agent | |---|---| | create / bill a sales invoice | merit-aktiva-workspace:merit-invoice-creator | | record a payment, enter a purchase invoice, reconcile open items | merit-aktiva-workspace:merit-bookkeeper | | look up a company (legal name / VAT / address / e-invoice capability) | merit-aktiva-workspace:merit-company-lookup |

A host that only loads the merit-* skills gets a recipe and then hand-runs the CLI itself — skipping those guardrails. To make the agents fire at the right time, add one routing rule to your host's own instructions (Claude Code CLAUDE.md, AGENTS.md, .cursorrules, or persistent agent memory), e.g.:

For Merit write/lookup work (create invoice, record payment, enter purchase, reconcile, company lookup) dispatch the merit-aktiva-workspace agent above — do not hand-run the elnora-merit CLI. Read/report/VAT work (KMD, reports, Stripe/LHV import, reverse charge, payroll) has no agent — use the merit-* skills directly.

That write-vs-read split is the whole rule: agent-first only where an agent exists.


Authenticate

Generate an API ID and API Key in Merit Aktiva: Settings → Company data → API settings → "Koosta võti" (Generate key).

The CLI reads them from environment variables. On first run it also prompts and saves them to ~/.config/elnora-merit/.env (mode 0600):

export MERIT_API_ID=your-api-id
export MERIT_API_KEY=your-api-key

Or copy .env.template to .env and fill it in (.env is gitignored — never commit it).

| Variable | Required | Notes | |---|---|---| | MERIT_API_ID | yes | GUID from API settings | | MERIT_API_KEY | yes | base64 secret; the HMAC signing key | | MERIT_API_VERSION | no | v1 (default) or v2 for dual-version endpoints | | MERIT_PALK_API_ID | for palk | Merit Palk API ID (separate payroll product) | | MERIT_PALK_API_KEY | for palk | Merit Palk API key (base64 secret) | | MERIT_REFERENCES_DIR | no | Base dir for config + reference files (stripe map, ledger, overrides, company-profile.json). Default ~/.config/elnora-merit. |

Company profile (optional)

Snapshot your account's own chart of accounts, banks, VAT codes, and financial years so an agent (or you) can look up the real codes without transcribing them by hand:

elnora-merit profile sync                  # → company-profile.json (in MERIT_REFERENCES_DIR)
elnora-merit profile show --section taxes  # the VAT TaxId guids, etc.

company-profile.json holds no secrets but is company-specific, so it is gitignored. Re-run profile sync whenever the chart of accounts changes.

Estonian Business Register lookups (optional)

This step is entirely optional. Everything else in the CLI and the Merit agent works without it. Setting it up just adds one extra capability: the elnora-merit ariregister commands, which pull company data straight from the Estonian Business Register (äriregister) using RIK's free ("tasuta") API services — so an agent can fill a new customer's legal name, VAT number, and address, and check e-invoice capability, from the authoritative source instead of asking you.

One of the two lookups needs no setup at all:

# e-invoice capability — works with NO credentials:
elnora-merit ariregister e-invoice-check 16818352

The requisite lookup needs a free äriregister contract + login. To enable it:

  1. Register for the free API tier. Go to rik.ee → e-äriregister → XML teenus and conclude a contract for the "Ainult e-äriregistri tasuta API-teenused" (free API services only) tier at the e-äriregister portal. You log in with an Estonian ID-card / Mobiil-ID / Smart-ID. The free tier has no per-query cost. See RIK's contractual-client admin guide.

  2. Create an XML-authorised user. In the portal: Haldus → Kasutajate haldamine → Lisa kasutaja, and enable XML/API access for it. (Optionally set the credit limit to 0 so only free services can ever run.)

  3. Get the username + password. The username is shown in the users table; generate the password with the "Uus parool" button (note: this XML-service password is separate from your portal login, and a freshly generated one can take ~10 minutes to activate).

  4. Save them to ~/.config/elnora-merit/.env (mode 0600, gitignored — never commit):

    ARIREG_XML_USER=YOURUSERNAME
    ARIREG_XML_PASSWORD=your-xml-service-password

Then both lookups work:

elnora-merit ariregister requisites 16818352      # → name, VAT, status, address
elnora-merit ariregister e-invoice-check 16818352 # → OK/MR + e-invoice operator

Only the free services are exposed; billable queries (detailed data, beneficial owners, representation rights) are intentionally excluded. See the merit-company-lookup skill/agent.

LHV bank connection (optional — recommended if you bank with LHV)

Optional. Everything else works without it. Connecting it automates the other half of the books: instead of exporting a statement file from your internet bank and uploading it, your agent pulls the statement from LHV directly and imports it into Merit.

LHV (AS LHV Pank) publishes its own read-only MCP server, and this plugin already bundles it — there is nothing to install and no key to add. Just connect it:

  1. Run /mcp, pick lhv, choose Authenticate.
  2. Sign in exactly as you would in your internet bank — Smart-ID, Mobiil-ID, ID-card, or biometrics.
  3. On LHV's consent screen pick the scopes. Statement import needs both accounts:read and transactions:read.

The token lives in your own MCP client for 30 days. This plugin never sees or stores it, and LHV exposes no write scope at all — an assistant can read your accounts and can never move money. Revoke any time: internet bank → Settings → Active sessions.

What the connection gives you:

| Ask your agent | What it uses | |---|---| | "What's our balance?" | every account — IBAN, currency, available balance | | "How much is actually available vs reserved?" | available, settled, and reserved balance per IBAN | | "What did we spend on X last month?" | totals, top counterparties, income vs spend (max 31 days) | | "Show me last week's transactions" | the full statement — what came in, what went out | | "Import July's statement into Merit" | the statement as camt.053, straight into payments import-statement — no file export |

The last one is the point: LHV returns a real ISO 20022 camt.053 statement, which is exactly what Merit's bank import accepts, so the bank and the books talk to each other with no file in between. The merit-lhv skill drives it — and its first step is checking whether the period is already booked, because importing an already-booked month double-books it.

Estonia-only, and only for LHV customers. Other banks: export camt.053 from your internet bank and use payments import-statement --file as usual.


Quickstart

elnora-merit accounts list                              # chart of accounts
elnora-merit banks list                                 # bank accounts
elnora-merit taxes list                                 # VAT rates
elnora-merit customers list --name "Acme"               # find a customer
elnora-merit sales-invoices list --period-start 2026-01-01 --period-end 2026-03-31
elnora-merit reports income-statement --end-date 20260331 --per-count 3

# Output controls (work on any command)
elnora-merit accounts list --output table --fields Code,Name
elnora-merit accounts list --pretty                     # pretty JSON

Creating documents. Create/send commands take the Merit JSON body via --data (inline) or --file (path). Each command's --help lists the required fields:

elnora-merit sales-invoices create --file invoice.json

See the official Merit reference manual for field details.


What you can do

Full coverage of the Merit Aktiva REST API — 22 resource groups — plus four local helpers: profile (snapshot your account's codes), reconcile (book Stripe payouts), documents (audit + attach missing receipts), and ariregister (free Estonian Business Register lookups). Run elnora-merit <group> --help for per-command options and payload schemas.

| Group | Commands | |---|---| | sales-invoices | list, find, get, create, create-v2, create-credit, create-multi-payment, create-from-xml, get-pdf, send-email, send-einvoice, delete | | sales-offers | list, get, create, create-v1, update, set-status, create-invoice | | recurring-invoices | create, list, get, list-client-addresses, send-indication-values | | purchase-invoices | create, create-pending, create-pending-xml, list, find, list-pending, get, delete, pay, report | | inventory | list, list-locations, send, send-v1 | | payments | list, find, list-types, create, create-purchase, create-offer, delete, list-income, list-expense, send-income, send-expense, send-prepayment, send-prepayment-vendor, send-settlement, import-statement, list-imports | | gl | create, list, get, list-full | | fixed-assets | list, list-locations, list-responsible-persons, send | | taxes | list, create | | customers | list, create, update, create-group, list-groups | | vendors | list, create, update, update-v1, create-group, list-groups | | accounts | list | | projects | list | | cost-centers | list | | dimensions | list, create, create-values | | departments | list | | prices | list, get, send, list-discounts, send-discounts | | units | list, create | | banks | list | | financial-years | list | | items | list, list-groups, create, create-group, update | | reports | income-statement, balance-sheet, inventory, sales, purchase, customer-debts, customer-payments, more-data | | profile | sync, show — snapshot the account's chart / banks / VAT codes / financial years for lookups | | reconcile | init, preview, run, status — book Stripe payouts into Merit (see below) | | documents | list-missing, run, install-schedule — find transactions missing their receipt/invoice, locate the file, stage/attach it, digest to Slack (see below) | | ariregister | requisites, e-invoice-check — free live Business Register lookups (company name/VAT/address; e-invoice capability) |

Payroll (Merit Palk)

palk is Merit's separate payroll product. It uses its own credentials (MERIT_PALK_API_ID / MERIT_PALK_API_KEY) and needs a Merit Palk PRO license.

elnora-merit palk employees list
elnora-merit palk base-salary list --start-month 202601 --end-month 202612
elnora-merit palk gl get --month 202606                   # GL batch for a month
elnora-merit palk salary-report --start-date 2026-06-01 --end-date 2026-06-30

| Group | Commands | |---|---| | palk employees | list, create | | palk contacts | add | | palk base-salary | list, create | | palk salary | create | | palk absences | create | | palk gl | get | | palk vacation | balance, set-liability | | palk salary-report | (leaf command) | | palk dimensions | set | | palk tax-free | set | | palk reduced-capacity | set |

Palk dates are YYYY-MM-DD and months are YYYYMM. See the Palk reference manual.

Reconcile Stripe payouts

Book Stripe card sales, fees, and refunds into Merit, one payout at a time (a payout = one bank deposit). Works for any Stripe account → any Merit company.

elnora-merit reconcile init                 # write a config template to ~/.config/elnora-merit/stripe-map.json
# ...edit that file: account codes + VAT (see stripe-map.example.json)

export STRIPE_API_KEY=sk_live_...           # a read-only restricted key is enough

elnora-merit reconcile preview --output table   # read-only: shows exactly what would be booked
elnora-merit reconcile run --yes                # book it (idempotent — never books a payout twice)
elnora-merit reconcile status                   # booked vs outstanding

Each payout becomes one balanced summary GL batch: card sales debit a clearing account, revenue is credited net of VAT (the VAT posts implicitly from the revenue line's tax tag, which auto-populates the KMD), and fees are booked as a separate expense. Your real bank-import row then clears the payout net in Merit — no double posting. The connector refuses to book a payout whose figures don't balance. See docs/stripe-reconciliation-spec.md for the full design.

Import an LHV bank statement — no file export

If you bank with LHV and connected it above (/mcp → lhv), the statement comes straight from the bank as camt.053 — the format Merit's import already accepts.

elnora-merit banks list                                  # bankId + IBAN + currency (live, no config file)
elnora-merit reports balance-sheet --end-date 20260731   # STEP 0: already booked? then stop
elnora-merit payments import-statement --file statement.xml
elnora-merit payments list-imports <bankId> --booking-date-from 2026-07-01

Check the period isn't already booked before importing. If the bank account's GL balance already equals the bank's real closing balance, the month is booked and there is nothing to import — the usual case. Merit's own idempotency will not catch this for you: it cannot see payments posted through the API. Then match rows in the Merit UI, where Võlgnevused clears an invoice that already exists and Muud creates a new expense — picking Muud for an already-invoiced payment books it twice. The merit-lhv and merit-payments-bank skills carry the full procedure and the traps.

Document sync — never lose a receipt

Every transaction needs its source document. documents audits Merit for invoices with no attachment, searches the places your receipts live, stages or attaches the file, and reports the rest.

elnora-merit documents list-missing --from 2026-01-01 --to 2026-07-31   # read-only audit
elnora-merit documents run                       # audit → search sources → match → digest (read-only)
elnora-merit documents run --apply               # stage matched PDFs for a one-click UI upload
elnora-merit documents install-schedule          # unattended run on an interval (macOS launchd)

Sources are generic: local folders, plus a command adapter that lets you plug in Gmail, Google Drive, or a scanner without this package holding those credentials (your command fetches and prints candidates as JSON). A ready-made Gmail+Drive adapter ships at adapters/gmail-drive-gw.mjs — we recommend installing the companion elnora-google-workspace plugin so the two connect and your receipts flow from email/Drive into Merit automatically. Merit's API can only attach a file when an invoice is created, so the default resolves a backlog by staging the matched PDF for a two-second UI upload (--rebook delete+recreates in place). The digest posts to a Slack-compatible webhook (MERIT_DOCSYNC_WEBHOOK). See docs/document-sync.md.


What's in this repo

elnora-merit-aktiva/
├── src/                    # the elnora-merit CLI (TypeScript)
├── skills/                 # Claude Code how-to skills (the right Merit procedure for each task)
├── agents/                 # plugin agents
├── commands/               # plugin slash commands
├── docs/                   # Stripe reconciliation spec and design notes
├── .claude-plugin/         # plugin + marketplace manifest
├── AGENTS.md               # agent usage conventions
└── INSTALL_FOR_AGENTS.md   # step-by-step agent setup walkthrough

The plugin ships how-to skills for both products so Claude follows the correct Merit procedure, not just the raw API:

  • Accountingmerit-aktiva-workspace (router), merit-sales-invoices, merit-purchase-invoices, merit-payments-bank, merit-vat-kmd, merit-reports, merit-reverse-charge, merit-stripe, merit-lhv (LHV bank statements via LHV's official read-only MCP server).
  • Payrollmerit-palk-workspace (router), merit-palk-employees, merit-palk-payroll, merit-palk-reports, merit-palk-settings.

Design

  • Universal & open — no account-specific values baked in. Configure with env vars; works for any Merit company.
  • Correct by construction — HMAC-SHA256 request signing, verified against Merit's published test vector.
  • Agent-friendly — JSON by default, machine-readable error envelopes with dedicated exit codes, --data/--file for complex payloads.
  • Safe — destructive operations require an explicit --yes; credentials and signatures are redacted from all output.

Output & errors

  • Formats: --output json (default, compact), table, or csv. --pretty for indented JSON. --fields a,b to pick columns.
  • Errors are JSON on stderr with a message, a suggestion, and structured data.
  • Exit codes: 0 success · 1 general · 2 validation · 3 auth · 5 rate limited · 6 API error.

Notes & gotchas

  • Merit endpoints are POST with a JSON body, even read/query operations.
  • Dates: query fields use YYYYMMDD (the CLI also accepts YYYY-MM-DD and normalizes). Some payload fields use YYYYMMDDHHMMSS — see each command's help.
  • Period limits: invoice list queries span at most 3 months.
  • Batch limit: at most 500 rows per document.
  • Sales invoices cannot be updated via the API — there is no update endpoint, so the API route is delete and re-create. The Merit UI edits an invoice in place, which is usually the better fix for a single wrong field. A paid invoice is locked in both: remove the payment first. Merit does not issue invoice numbers; manage your own.
  • Rate limit: 100 requests/minute. The CLI auto-retries HTTP 429 honouring Retry-After.

Part of the Elnora family

Open-source agent tooling from Elnora AI — free, universal, config-driven tools that wire Claude Code (or any AI coding agent) into the systems you run your company on. Each works 100% standalone; install several and they chain into end-to-end workflows.

  • elnora-linear — Linear issue management — search, bulk edit, agents, and a config-driven curator
  • elnora-slack — the entire Slack Web API as a CLI plus agent skills with a draft-and-approve send gate
  • elnora-whatsapp — read, search, and send WhatsApp from your own paired account, 100% local
  • elnora-google-workspace — Gmail, Calendar, Drive, Docs, Sheets, Forms, Tasks, plus any Google API via Discovery
  • elnora-vanta — read-only Vanta compliance — frameworks, tests, controls, and vulnerabilities as agent-friendly JSON
  • elnora-luma — Luma (lu.ma) events — all 61 public API endpoints as a spec-driven CLI with safety guardrails
  • elnora-travel — a real travel agent — live flights, hotels, Airbnb, Booking.com, and routes in one itinerary
  • elnora-websearch-tools — web search — Exa, Tavily, Perplexity, Firecrawl, and Valyu CLIs and skills in one plugin
  • knowledge-vault — an Obsidian-compatible knowledge base for agent teams — search and save your work to any vault

Development

pnpm install
pnpm dev -- accounts list      # run from source
pnpm typecheck && pnpm lint && pnpm test && pnpm build

See CONTRIBUTING and SAFETY.

License

Apache-2.0 © Elnora AI. Not affiliated with or endorsed by Merit Tarkvara AS.