Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Ekwo OS

NPM · @EKWO-AI/MCP · SCANNED SEP 25

Open source accounting data infrastructure on your own Postgres, acting as the user under RLS.

Available components

72 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security99
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • No install/post-install scripts declared.Pass
  • 31 of 112 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency48
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
  • Clear OSI-approved license (AGPL-3.0-only).Pass
  • Actively maintained (last published 2 days ago).Pass
  • Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability77
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 11217 tokens (~203/item across 55 items; 55 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management10
  • Stability observed for 3 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage88
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 64% of tool parameters carry a description.Partial
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • All 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 56 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

How do I install the Ekwo OS MCP server?

Ekwo OS runs locally as an npm package, launched with npx -y @ekwo-ai/mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

npm · @ekwo-ai/mcp

# add to Claude Code
claude mcp add ai-ekwo-mcp -- npx -y @ekwo-ai/mcp
// .cursor/mcp.json
{
  "mcpServers": {
    "ai-ekwo-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@ekwo-ai/mcp"
      ]
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "ai-ekwo-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@ekwo-ai/mcp"
      ]
    }
  }
}
# add to Codex CLI
codex mcp add ai-ekwo-mcp -- npx -y @ekwo-ai/mcp
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ai-ekwo-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@ekwo-ai/mcp"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add ai-ekwo-mcp --command npx --arg -y --arg @ekwo-ai/mcp
# ~/.hermes/config.yaml
mcp_servers:
  ai-ekwo-mcp:
    command: "npx"
    args: ["-y", "@ekwo-ai/mcp"]
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "ai-ekwo-mcp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "@ekwo-ai/mcp"
      ]
    }
  }
}
# add to Vellum
assistant mcp add ai-ekwo-mcp -t stdio -c npx -a -y @ekwo-ai/mcp
// mcp.json
{
  "mcpServers": {
    "ai-ekwo-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@ekwo-ai/mcp"
      ]
    }
  }
}
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 25 Sept 26 +1
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 23 Sept 26 +12
    • Known CVEs: unverified → pass ▲ security
    • Dependency health: unverified → 0.88 ▲ functional
    • Stability: unverified → 0.03 ▲ functional
    • Package version: 0.7.0 → 0.8.0 functional
  • 22 Sept 26 59

    First indexed and scored.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 25 Sept 2026 · Analysed npm/@ekwo-ai/mcp@0.8.0

Provenance No attestation

The registry publishes no build provenance for this version, so there is nothing to verify.

Result No attestation
Ecosystem npm

Background: How many MCP packages publish verified provenance →

Dependencies 112 packages
Packages resolved 112
Stale 31
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 55 exposed · ~11,053 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
aged_balance ~103

What customers still owe (or what is still owed to suppliers), bucketed by how overdue it is. It reads unmatched ledger lines, not invoices, so it ties back to the balance sheet: an invoice counts as settled only once its payment has been matched.

NameTypeReqDescription
atstring–The day to age at. Defaults to today.
company_idstringyesThe company to work in. Ask list_companies if unsure.
groupstring––

No output schema declared.

No examples provided.

cancel_document ~411

Undoes a posted sale or purchase invoice in one call, the one way its country and its facts allow, and says which in undone_by. 'draft': the country's posted_edit_policy lets a posted document go back to draft and nothing about this one has left — never sent nor on Peppol, not paid, not declared, its period open and, where numbering is gapless, its number the last one drawn; its entry is taken away, its number given back, and it is a draft to correct and post again. 'credit_note' otherwise, with the reason in why: its credit note — the same lines, taxes, accounts, contact, currency and rate — is issued naming it, posted and matched against it, and the invoice is cancelled, payment state reversed; the invoice keeps its number and its entry. Tell the user which it was. A date, or credit_note: true, asks for the credit note outright. Dated on the invoice's booking day unless you give a date; refused by name when that period is locked or closed (reversal_date_needed), and then you ask the user for a date rather than choosing one. Refused for a draft, a credit note, an invoice already cancelled or credited, and one that is paid in part or in full — the payment is unmatched first with unreconcile, and only when the user says so. Ask the user before calling it.

NameTypeReqDescription
credit_noteboolean–True: undo it with a credit note even where it could go back to draft — the user wants the correction on the record.
datestring–The day a credit note is issued and booked on. Given, it asks for the credit note. Left out: the invoice's own booking day, and refused by name (reversal_date_needed) when that period is no longer op…
document_idstringyesThe posted sale or purchase invoice to undo.

No output schema declared.

No examples provided.

close_fiscal_year ~138

Closes a year: the result of the year leaves the income statement the way the country model says — straight to retained earnings, into a current-year result account, or through the appropriation accounts — every income and expense account goes back to zero, and the year stops accepting entries. Refused while the year holds a draft entry, while an earlier year with entries is open, or when a later year is already closed. It never writes what a general meeting decides to do with the result. Always ask the user before calling it.

NameTypeReqDescription
fiscal_year_idstringyesThe year to close. Every entry in it must be posted.

No output schema declared.

No examples provided.

create_api_key ~216

Issues a key so a script — a nightly import, a till, a bank feed — can work in one company without a person signing in. It carries an explicit list of capabilities and nothing else, it can never reach another company, and it cannot hold a capability you do not hold yourself. The secret comes back once and is stored only as a hash: show it to the user and say it cannot be read back. Prefer this to sharing anybody’s password, and never suggest a service key.

NameTypeReqDescription
capabilitiesarrayyesExactly what the machine may do, e.g. ["bank.write"]. You cannot put a capability on a key that you do not hold yourself.
company_idstringyesThe company to work in. Ask list_companies if unsure.
expires_atstring|null–When it stops working, as a timestamp. Left out, it does not expire on its own.
namestringyesWhat this key is for, in the words an operator will read a year from now.

No output schema declared.

No examples provided.

create_bank_account ~286

Registers a bank account of the company from its IBAN, and wires it to the bank journal and to the ledger account behind it — both of which the country template has already chosen, so neither has to be given. Running it twice with the same IBAN returns the one that exists rather than creating a second. Do this once per account: until a company has one, an invoice carries no IBAN and record_payment can only book on the journal's default account.

NameTypeReqDescription
account_codestring–The ledger account behind it. Left out, the journal's default account — 550000 in Belgium, 512000 in France.
account_idstring––
bank_namestring––
bicstring––
company_idstringyesThe company to work in. Ask list_companies if unsure.
currency_codestring–Defaults to the company's own currency.
ibanstringyesThe IBAN. Spaces are removed and the value is upper-cased; it is the natural key of a bank account in a company.
journal_codestring–The financial journal it books through. Left out, the bank journal of the company.
journal_idstring––
labelstring–What it is called in the books. Defaults to the bank name, then to the IBAN.

No output schema declared.

No examples provided.

create_bank_transaction ~189

Records one statement line by hand, for an installation without a bank feed. `amount` is signed: positive is money in. It books nothing — the line waits as pending until a payment is recorded.

NameTypeReqDescription
amountstring|numberyesSigned: positive is money in, negative is money out.
bank_account_idstringyes–
company_idstringyesThe company to work in. Ask list_companies if unsure.
contact_idstring––
counterpart_ibanstring––
counterpart_namestring––
descriptionstring––
referencestring––
statement_idstring––
structured_referencestring–A structured communication, e.g. +++000/0000/00000+++ or RF…
transaction_datestringyes–
value_datestring––

No output schema declared.

No examples provided.

create_company ~260

Creates a company on a country pack: its chart of accounts, its journals and its taxes are copied in, its first financial year is opened on the month that country opens one on, and you become its first member. Creating a company is an instance-level act — it needs an instance administrator, and being one is not the same as being on anybody’s books. Ask the user for the country rather than guessing: the wrong answer is a whole chart of accounts.

NameTypeReqDescription
chart_codestring–Which chart, where the country offers several.
countrystringyesWhich country pack: its chart of accounts, its taxes and its declaration form. list_companies shows what the installation already uses.
currency_codestring–Left out, the country pack's.
fiscal_yearinteger–Calendar year the first financial year opens in. Default this year.
fiscal_year_startstring–First day of it. Left out, the month the country pack opens a year on — and a pack that names none is a refusal, not a January.
languagestring–Language the books are kept in — it decides the labels of the chart. Left out, the country pack's.
namestringyes–

No output schema declared.

No examples provided.

create_contact ~225

Adds a customer, supplier or other third party to a company. Search first: a duplicate contact splits a customer account in two and the aged balance stops making sense. payment_terms_days drives the due date a posted invoice gets when none is given.

NameTypeReqDescription
address_line1string––
auxiliary_codestring–Sub-ledger code; the French FEC reports it.
citystring––
client_refstring–Your own reference for this creation. Calling again with the same one returns what was created the first time (`replayed: true`) instead of creating a second — use it whenever a call might be repeate…
company_idstringyesThe company to work in. Ask list_companies if unsure.
contact_typestringyes–
countrystring–ISO country code, e.g. BE.
emailstring––
namestringyes–
payment_terms_daysinteger––
postal_codestring––
vat_numberstring––

No output schema declared.

No examples provided.

create_document ~326

Creates a draft invoice, credit note or quote with its lines, and returns it with the totals the database computed — never with totals you supplied. A line may name a product_code, which fills in its text, price, unit, account and tax; anything the line carries wins over that. With no product and no account_code, the account falls back to the company default and then to its country model. A tax is different: a line with none is booked as a base with no VAT box, which is not the same as 0 %. Nothing is in the ledger yet; post_document is what books it.

NameTypeReqDescription
accounting_datestring–The date the entry is booked on, when it differs from the document date.
client_refstring–Your own reference for this creation. Calling again with the same one returns what was created the first time (`replayed: true`) instead of creating a second — use it whenever a call might be repeate…
company_idstringyesThe company to work in. Ask list_companies if unsure.
contact_idstringyes–
currency_codestring––
doc_typestringyes–
document_datestringyes–
due_datestring––
journal_idstring––
linesarrayyes–
numberstring–Your own number. Left out, posting takes the entry number.
payment_referencestring––
supplier_referencestring–The supplier's own invoice number, on a purchase.

No output schema declared.

No examples provided.

create_product ~394

Adds an item to the catalogue: a code unique in the company, a name, a unit, a price, and optionally the account and the tax a sale or a purchase of it carries. It changes nothing already booked — a product is what a new line is filled in from, never a rule applied to the past. Search first: a second code for the same thing is how a price list stops being one.

NameTypeReqDescription
codestringyesYour own reference for the item. Unique in the company, and what EN 16931 calls the seller's item identifier (BT-155).
company_idstringyesThe company to work in. Ask list_companies if unsure.
currency_codestring––
descriptionstring–The longer text under the name (BT-154).
kindstring–Defaults to service. Goods and services are not taxed alike and do not feed the same declaration boxes.
namestringyesWhat appears on the invoice line (BT-153).
purchase_account_codestring–Expense account a purchase of this books to.
purchase_account_idstring––
purchase_pricestring|number––
purchase_tax_codestring––
purchase_tax_idstring––
sale_account_codestring–Income account a sale of this books to.
sale_account_idstring––
sale_pricestring|number–Net unit price on a sale. A line may still carry another.
sale_tax_codestring–Tax applied when it is sold, by code.
sale_tax_idstring––
unit_codestring–UN/ECE recommendation 20: C62 a piece, HUR an hour, DAY a day, MON a month, KGM, LTR, MTR, KWH. Defaults to C62.

No output schema declared.

No examples provided.

describe_pack ~194

The country packs this installation holds, with their version, how much anyone has read them, and the register of texts each was built from — the title, the official publisher, an absolute link and the day somebody opened it, per text. Use it whenever you are asked where a rate, a chart of accounts or a box of the declaration comes from, and before repeating a figure a pack gave you: a community pack has not been read by an accountant, and the status says so. The article behind a single rule is on that rule itself — legal_reference on a tax or on a box — and the register is where that article can be read. It carries no copy of the law: a link that has gone quiet means the register is stale, never that the rule is wrong.

NameTypeReqDescription
countrystring–ISO 3166-1 alpha-2, upper case. Left out, every pack this installation holds.

No output schema declared.

No examples provided.

ec_sales_list ~268

Who, in another Member State, was supplied without VAT over a period, and for how much: one line per customer VAT number and per nature — goods, services — read from the treatment of the tax on each sale line, with credit notes deducted. The totals tie back to the intra-Community boxes of vat_return for the same period. A line that carries an issue cannot be filed as it stands, most often because the customer has no VAT number recorded: say so rather than leaving it out of the answer. Name a report_code to have the period checked against the cadence this company files that statement on — it has one of its own, and it is rarely the cadence of the return. No country rule lives in this tool. It prepares a statement; it files nothing.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
fromstringyes–
report_codestring–Which recapitulative statement form, when the installation carries one and you are filing it. Name it and the period is checked against the cadence this company files that statement on, which is not…
tostringyes–

No output schema declared.

No examples provided.

financial_statement ~181

A balance sheet or an income statement for a period, on the scheme the country pack declares — the Belgian abbreviated model, the French liasse — or on the generic framework by account type. Each line is summed from the accounts its rules catch and the totals are derived from the lines; no country rule lives in this tool. It also returns the accounts no line catches: if that list is not empty, say so instead of presenting a statement that does not tie out. It prepares figures; it files nothing.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
fromstringyes–
statement_codestringyesWhich scheme, from list_statements (BE-BNB-ABBR-BS, FR-2050, IFRS-SME-BS).
tostringyes–

No output schema declared.

No examples provided.

general_ledger ~137

Every posted line of an account over a period, with the balance carried forward from before it and a running balance. Give account_code for one account; leave it out for all of them, which on a real company is a lot of lines.

NameTypeReqDescription
account_codestring–The account to detail, by its code, e.g. "400000".
account_idsarray–The accounts to detail, by id. Leave both out for every account.
company_idstringyesThe company to work in. Ask list_companies if unsure.
fromstringyes–
tostringyes–

No output schema declared.

No examples provided.

generate_fec ~118

The Fichier des Écritures Comptables for a period: the eighteen columns of the arrêté du 29 juillet 2013, as text, with the checks a tax inspector applies first (mandatory fields, one side per line, entries balancing) and the filename the format wants. The file comes back in the answer; writing it to disk is the caller's business.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
fromstringyes–
tostringyes–

No output schema declared.

No examples provided.

get_company ~90

Everything needed before booking in a company: its financial years and whether they are closed, its lock dates, its journals, and the accounts that play the receivable, payable, suspense and retained-earnings roles. Read this before creating a document if you do not already know the journals and the lock dates.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.

No output schema declared.

No examples provided.

get_document ~91

One document with its lines, the account and tax of each line, the legal mentions its country requires on it, that country's payment and e-invoicing rules, and — when it has been posted — the ledger entry it produced with every ledger line. Use it to check what a document will book, what it did book, and what has to be printed on it.

NameTypeReqDescription
document_idstringyes–

No output schema declared.

No examples provided.

get_preferences ~120

The signed-in user’s own preferences — which company an interface opens on, the language they read labels in, their timezone and how they like a date and a number written — and the language chain to read labels with: theirs, then the company’s, then the country pack’s. Every one of them may be null, and null means "take the next answer in the chain" rather than a default this installation picked.

NameTypeReqDescription
company_idstring–Resolve the language chain against this company. Left out, only what the user themselves chose is returned.

No output schema declared.

No examples provided.

import_bank_statement ~481

Reads a bank statement file and writes its statements and lines. `format` says what the file is — `camt.053` (the ISO 20022 XML statement), `coda` or `cfonb120`, which are the ones this server reads today — and `content` is the file as text. It is never guessed from the content. It books nothing: every line waits as pending, to be settled afterwards. Safe to repeat: the same file imported twice creates nothing the second time, and a statement overlapping an earlier one imports only the new lines. Refused by name, with nothing written: an account the company does not have (create it first with create_bank_account — an import never creates one), a statement whose opening balance plus lines is not its closing balance, a line in another currency. Signalled in `warnings`, not refused: an opening balance that is not the previous closing one, which means a statement is missing.

NameTypeReqDescription
bank_account_idstring–Only for a file of one statement whose account the company identifies otherwise than the file does. Left out, the account is found by the identifier the statement carries, and an unknown one is refus…
company_idstringyesThe company to work in. Ask list_companies if unsure.
contentstringyesThe file itself, as text (UTF-8).
file_namestring–The name the file had, kept on the statement.
formatstringyesWhat the file is. Required, and never guessed from the content: `camt.053` is the ISO 20022 XML statement, `coda` the coded statement of account of 128-character records, `cfonb120` the statement of…
iban_countrystring–Only for `cfonb120`, which identifies an account by a bank code, a branch code and a number, and names no country. With the two letters of the country the account is held in, the statement is matched…
storage_pathstring–Where the caller stored the file, if it did. With it the file is recorded in attachments, on the statement; this server stores no bytes.

No output schema declared.

No examples provided.

import_books ~985

Takes over the books a user kept elsewhere — a FEC, an export of journal items, a journal report, a trial balance, or the export of odoo or xero by name — whole or not at all. Each file is read by the reader of its source; every account of the old chart is matched to one of this company's chart and every old journal to a journal of the company. The codes give a candidate (the same code, the same digits without the padding zeros, or the longest beginning of three digits or more), and what the files say of the old account — its type, its name, the side of its balance — is held against what the chart says the candidate is, never a country: only the same code, not contradicted, is `exact`; anything else is `suggested` with its reason, or `none`. Call it with dry_run first: it returns the correspondence proposed, the suggestions under mapping.suggested, what is unanswered, and — when everything is answered — what the database would write, rehearsed and rolled back. Show the user every suggested line and its reason first; nothing is posted while one is unconfirmed. Settle each by writing its code under mapping.accounts, or, once the user has read and approved them all, pass accept_suggestions. Every entry is posted through post_entry(); a trial balance becomes the opening entry. Imported lines carry no tax and feed no VAT box. The same files twice are refused. The files travel as text, up to 256 KiB in all: a larger export is imported from the terminal with `ekwo import`, which reads it from the disk. Ask the user before the real call.

NameTypeReqDescription
accept_suggestionsboolean–Take every account the proposal only suggested as the answer. Only after the user has read each suggested line and its reason, and said yes to all of them; left out, a suggestion stops the import.
allow_result_accountsboolean–Let an opening balance carry income and expense accounts: books taken over in the middle of a year.
company_idstringyesThe company to work in. Ask list_companies if unsure.
date_orderstring–For `journal-report`: the order of a date written only in digits, which the file does not say.
dry_runboolean–Show what would be written — the correspondence proposed, the entries, the numbers — and write nothing. Always first, and the user reads it before the real call.
filesarrayyesThe files of one source, in the order given. `journal-items` and `journal-report` take the chart of accounts and the parties beside the lines, each recognised by its header; the others take one file.
keep_numbersboolean–Post each entry under the number it had. Where the country forbids a hole in the sequence it takes the entries.import capability; left out, the journal draws the numbers and the old one is kept as th…
mappingobject–The correspondence, as a previous call with dry_run returned it and the user completed it. What it answers wins over the proposal.
open_yearsboolean–Open the fiscal years the entries fall in where the company has none, on the length and first day of its own. Off, such an entry is refused by name.
opening_datestring–For a trial balance: the first day of the fiscal year it opens. The file does not say it.
sourcestringyesWhat the files are, never guessed from their content: `trial-balance` — a trial balance as CSV — account, debit, credit, or a signed balance — which becomes the opening entry of a year; `fec` — a fic…

No output schema declared.

No examples provided.

invite_member ~241

Invites an address into a company with a preset — viewer reads, client reads and hands pieces over, accountant keeps the books, owner also administers — and any capability granted on top of it. It returns a token once and stores only its hash, so hand the token to the person you invited: they accept it themselves, signed in with that address. It does not send an e-mail, and it does not create an account. Inviting the same address again withdraws the invitation that was pending.

NameTypeReqDescription
capabilitiesarray–Capability codes granted on top of the preset, e.g. members.manage. get_company lists what this installation knows.
company_idstringyesThe company to work in. Ask list_companies if unsure.
emailstringyesThe address the invitation is for. Matched when it is accepted.
rolestring–The preset. Default viewer, which reads and changes nothing. client is the person whose company it is, invited by whoever keeps their books: it reads the same, and may also hand a file over (document…
valid_for_daysinteger–Default 14.

No output schema declared.

No examples provided.

list_accounts ~352

The accounts a company actually works with, filtered by code prefix, by account type, or by a search on the name. Use it to find the income or expense account a document line should carry. By default it returns the working chart — the accounts that carry entries, that the company's settings or an enabled module point at, or that somebody pinned — because a country pack transcribes the whole regulation and a company uses a few dozen of its several hundred accounts; `in_use_from` and `in_use_to` narrow the movements to a period, `include_all` returns the whole chart, and `include_deprecated` returns it with the retired accounts too. This is a reading and not a restriction: any account of the chart that is not deprecated may still be booked on.

NameTypeReqDescription
account_typestring–One of the eighteen account types, e.g. asset_receivable.
code_prefixstring–Only accounts whose code starts with this, e.g. "70".
company_idstringyesThe company to work in. Ask list_companies if unsure.
in_use_fromstring–Narrows the movements to entries on or after this date. References and pinned accounts are not dated and stay in.
in_use_tostring–The other end of that period.
include_allboolean–Return the whole chart instead of the accounts in use. Use it when a search over the working chart found nothing.
include_deprecatedboolean–Include deprecated accounts. A deprecated account is never in use, so this returns the whole chart.
limitinteger––
searchstring–Case-insensitive match on the account name.

No output schema declared.

No examples provided.

list_api_keys ~101

The keys a company has issued to machines, what each one may do, when it was last used and whether it is still live. Only somebody who manages members sees them, and no secret is in here: a key is shown once, when it is issued.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
include_withdrawnboolean–Also the ones withdrawn or expired. Default false.

No output schema declared.

No examples provided.

list_bank_accounts ~87

The bank accounts of a company, with their IBAN, the journal they book through and the ledger account behind each. Read it before recording a payment on a particular account, and to find out whether the company has one at all.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
include_inactiveboolean–Default false.

No output schema declared.

No examples provided.

list_bank_transactions ~124

Statement lines of a company, pending by default — the ones still waiting to be dealt with. `amount` is signed: positive is money in. A statement line is not a ledger entry; recording a payment is what books it.

NameTypeReqDescription
bank_account_idstring––
company_idstringyesThe company to work in. Ask list_companies if unsure.
fromstring––
limitinteger––
statestring–Defaults to pending: what still has to be dealt with.
tostring––

No output schema declared.

No examples provided.

list_companies ~68

The companies of this installation that you are a member of, with your role on each. Start here: every other tool needs a company_id. Returns id, name, country, currency and your role. It does not list companies you were never invited to — those are invisible, not hidden.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

list_documents ~180

Invoices, credit notes and quotes of a company, filtered by type, state, settlement state, contact or date range. `state` is the document (draft, posted, cancelled) and `payment_state` is the settlement (not_paid, partially_paid, paid) — two different questions. Returns headers and totals, not lines; use get_document for those.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
contact_idstring––
doc_typestring––
fromstring–Earliest document date.
limitinteger––
payment_statestring––
statestring––
tostring–Latest document date.
unpaidboolean–True: posted and still owed — not paid, or partially.

No output schema declared.

No examples provided.

list_invitations ~114

The people invited into a company and not yet on its books, with the preset and the capabilities each was invited with, and whether the invitation is still pending, expired, accepted or withdrawn. Only somebody who manages members sees them. The token is never in here: it is shown once, when the invitation is issued.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
include_settledboolean–Also the ones already accepted or withdrawn. Default false.

No output schema declared.

No examples provided.

list_shares ~132

The links a company has published onto its own sales documents, with how many times each was opened and when it was last opened. No token is in here: a link is shown once, when it is made. Use it to answer "did the customer open the invoice?" and to find the link to withdraw.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
document_idstring–Only the links onto this document. Left out, the whole company.
include_withdrawnboolean–Also the ones withdrawn or expired. Default false.

No output schema declared.

No examples provided.

list_statements ~92

The schemes this company can be presented on: those of its country and of its chart of accounts, plus the generic framework by account type that fits any chart. Ask this before financial_statement rather than guessing a code.

NameTypeReqDescription
atstring–The day to read the schemes in force at. Defaults to today.
company_idstringyesThe company to work in. Ask list_companies if unsure.

No output schema declared.

No examples provided.

lock_period ~135

Moves the accounting lock date, the VAT lock date, or both. After this, nothing can be booked, changed or deleted on or before that date — including corrections you may want later. Only an owner of the company may do it. Always ask the user first, and never lock a period you have just posted into without being told to.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
lock_date––Nothing may be booked on or before this date. null lifts the lock.
tax_lock_date––Additionally freezes anything carrying a VAT box. null lifts it.

No output schema declared.

No examples provided.

opening_balance ~204

Turns the trial balance of whatever kept the books before into the opening entry of a fiscal year, on the opening journal, dated on its first day. Lines are {account_code, debit, credit}; total debit must equal total credit. Balance-sheet accounts only, unless allow_result_accounts is set, which is for taking books over in the middle of a year. A year holds one opening: a second call is refused rather than added to.

NameTypeReqDescription
allow_result_accountsboolean–Default false: an opening balance is made of the balance sheet. Pass true only when taking books over in the middle of a year that has already run.
company_idstringyesThe company to work in. Ask list_companies if unsure.
fiscal_year_idstringyesThe year the balance opens. The entry is dated on its first day.
linesarrayyesThe trial balance of the previous system, one entry per row. Total debit must equal total credit.

No output schema declared.

No examples provided.

pin_accounts ~133

Adds accounts to the working chart of a company, so list_accounts offers them whether or not anything has been booked on them. Pass pinned: false to take one back out. Pinning is display and nothing else: an unpinned account may still be booked on, and a pinned one is still hidden once it is deprecated.

NameTypeReqDescription
account_codesarrayyesCodes in this company's chart. list_accounts with include_all says what exists.
company_idstringyesThe company to work in. Ask list_companies if unsure.
pinnedboolean–True pins, false unpins. Defaults to true.

No output schema declared.

No examples provided.

portfolio_filings_touched_since ~157

Which declarations, across your portfolio — every company you may read the declarations of, which for an accounting firm is its clients — had entries posted into their period after they were filed — with the company named, how many entries, and how many of the filed figures now disagree. A period stays open after its return has gone, on purpose; this is what keeps a late entry from going unnoticed. Companies with nothing to report are named too, with how many filed declarations were examined. It reads; whether a corrective is owed is for whoever keeps the books.

NameTypeReqDescription
fromstring–Only declarations whose period ends on or after this day.
tostring–Only declarations whose period starts on or before this day.

No output schema declared.

No examples provided.

portfolio_upcoming_filings ~201

What falls due between two dates in every company you may read the declarations of — the question a firm asks of all the books it keeps, and the one a person asks of the single company they run. "Portfolio" is meant as an accounting firm means it — its client portfolio — and is nothing but that: the companies you hold filings.read on, worked out at each call, never a list anybody maintains. Every one of them is in the answer, including a company whose country pack names no deadline, which is listed without a date and says so; a company left out would be indistinguishable from one that was never looked at. No country rule lives in this tool. It reads a calendar; it prepares and files nothing.

NameTypeReqDescription
fromstringyesFirst day a return may fall due on. Go back a few days to catch what is already late.
tostringyesLast day a return may fall due on.

No output schema declared.

No examples provided.

post_document ~156

Books a draft document: base lines, VAT lines from the tax configuration, and the customer or supplier counterpart, numbered and posted. A posted entry is never edited; a mistake is undone by cancel_document, which puts the document back to draft only where its country allows it and nothing has left, and issues a credit note otherwise. Ask the user before calling it. It refuses a locked period, a tax that is not in force, and a header total that disagrees with the lines.

NameTypeReqDescription
document_idstringyes–
dry_runboolean–True: the database posts for real and takes it back, and the entry it would have written is returned. Nothing is written; a refusal is the one posting would give.

No output schema declared.

No examples provided.

read_audit_log ~400

Who changed what, and when. Every change to the configuration and reference data of a company — the chart of accounts, the journals, the taxes and the accounts they post to, the bank accounts, the contacts, the products, the financial years, the members and their roles, the country pack version — and every act that changes a state: a document posted or cancelled, an entry posted or reversed, a payment booked, matched or unmatched, a financial year closed or reopened. Filter by table, by natural key, by user, by act, or by date range. The ledger itself is not in here: a posted entry is immutable and is corrected by a reversal, so what is recorded is the act of posting and never the lines. Read-only, and there is no tool that writes it: the trail is append-only and even the operator cannot edit a row.

NameTypeReqDescription
actionstring–One act: document_posted, document_cancelled, entry_posted, entry_reversed, payment_posted, payment_reconciled, payment_unreconciled, fiscal_year_closed, fiscal_year_reopened, pack_upgraded.
actor_idstring–Only what this user changed. Their auth.users id.
company_idstringyesThe company to work in. Ask list_companies if unsure.
fromstring–Earliest date, inclusive.
limitinteger––
operationstring––
record_keystring–The natural key of one row — an account code, a tax code, an invoice number.
tablestring–One table of the schema: accounts, journals, taxes, tax_postings, contacts, products, bank_accounts, companies, fiscal_years, company_members, company_packs, api_keys, documents, payments, entries, r…
tostring–Latest date, inclusive — the whole of that day.

No output schema declared.

No examples provided.

reconcile ~130

Matches a debit line against a credit line on the same reconcilable account, for an amount, defaulting to the smaller of the two open amounts. Use it to settle an invoice against a payment by hand. Matching changes no account and stays possible after a period is locked.

NameTypeReqDescription
amountstring|number–Left out: the smaller of the two open amounts.
line_astringyesA ledger line to match. Either side; the schema works out which is the debit.
line_bstringyesThe line it settles. Both must be on the same reconcilable account.

No output schema declared.

No examples provided.

record_payment ~477

Records money in or out, books it (bank against the customer or supplier account) and, unless you say otherwise, matches it against that contact's oldest open invoices up to the amount paid. Matching is what makes an invoice count as paid. The entry it produces cannot be unposted, though the matching can be undone with unreconcile.

NameTypeReqDescription
amountstring|numberyesA positive decimal string; the direction carries the sign.
bank_account_idstring–Which bank account the money moved on. list_bank_accounts says what exists. Given alone, it also names the journal; left out, the default account of the journal is used.
client_refstring–Your own reference for this creation. Calling again with the same one returns what was created the first time (`replayed: true`) instead of creating a second — use it whenever a call might be repeate…
company_idstringyesThe company to work in. Ask list_companies if unsure.
contact_idstring–Who paid or was paid. Needed for the payment to be matched against their invoices.
currency_codestring–Left out: the currency the company keeps its books in.
directionstring–inbound: a customer paid you. outbound: you paid a supplier. May be left out when document_id is given.
document_idstring–The posted document this money pays. It names the contact and the direction, read off what is still open on it, and the matching is offered to that document alone rather than to the oldest open items.
exchange_ratestring|number–Units of the payment currency for one unit of the company currency, as a rate table states it. Only needed when the payment is in another currency; the realised difference against the invoice is book…
journal_codestring–The bank or cash journal, by code, e.g. BNK. Not needed when bank_account_id is given: the account knows its journal.
journal_idstring––
match_open_itemsboolean–Default true: match the payment against the oldest open invoices of that contact, up to the amount paid.
memostring––
payment_datestringyes–
referencestring––

No output schema declared.

No examples provided.

reopen_fiscal_year ~86

Undoes a close that was run too early: the entries it wrote are reversed, never deleted, and the year accepts entries again. Refused once a later year is closed or holds entries of its own, because re-opening changes a result those years stand on. Always ask the user before calling it.

NameTypeReqDescription
fiscal_year_idstringyesThe closed year to open again.

No output schema declared.

No examples provided.

reverse_entry ~265

Undoes a posted entry in one call: writes its mirror in the same journal — every line on the other side — naming it, posts it under the next number, and matches the two. The original keeps its number and its lines. Dated on the original's day unless you give a date; refused by name when that period is locked or closed (reversal_date_needed), and then you ask the user for a date rather than choosing one. Refused for an entry a document wrote (use cancel_document), the entries of a close (reopen_fiscal_year), an opening, the entry of a payment, a bank transaction, a module or a matching, an entry already reversed or that is itself a reversal, and a matched entry — unmatch it first with unreconcile, and only when the user says so. Ask the user before calling it.

NameTypeReqDescription
datestring–The day the reversal is booked on. Left out: the original entry's day, and refused by name (reversal_date_needed) when that period is no longer open — then ask the user which open date to use; never…
entry_idstringyesThe posted entry to undo. An entry a document wrote is undone with the document, by cancel_document.

No output schema declared.

No examples provided.

revoke_api_key ~68

Stops a key working, now and for good. There is no un-withdraw: a secret that has been out of the building is issued again rather than brought back. Whatever the machine was doing with it stops, so say so before calling it.

NameTypeReqDescription
api_key_idstringyes–

No output schema declared.

No examples provided.

revoke_invitation ~64

Withdraws an invitation that has not been accepted, so its token stops working. An invitation that has already become a membership is refused: a member is removed from the company, which is a different act and not one this server does.

NameTypeReqDescription
invitation_idstringyes–

No output schema declared.

No examples provided.

revoke_share ~73

Stops a link working, now and for good. Whoever holds it sees exactly what they would see for a link that never existed. There is no un-withdraw: a secret that has been out of the building is issued again rather than brought back, so say so before calling it.

NameTypeReqDescription
share_idstringyes–

No output schema declared.

No examples provided.

search_contacts ~128

Customers, suppliers and other third parties of a company, by name, by type or by VAT number. Use it before creating a document: a document is booked against a contact, and creating a second contact for a customer who already exists splits their account.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
contact_typestring––
limitinteger––
querystring–Case-insensitive match on the contact name.
vat_numberstring–Exact match, e.g. BE0123456749.

No output schema declared.

No examples provided.

search_products ~155

The catalogue of a company: what it sells and buys, with the code, the unit, the price, the account each books to and the tax each carries. Search it before writing a line by hand — a product fills in the text, the price, the account and the tax, and keeps two invoices for the same thing consistent. Retired products are left out unless you ask for them.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
include_inactiveboolean–Default false: a retired product is hidden.
kindstring––
limitinteger––
querystring–Matches the code, the name or the description.

No output schema declared.

No examples provided.

set_preferences ~168

Writes the signed-in user’s own preferences and nobody else’s. Only the fields you name change: leave one out and it is untouched, pass null and it is cleared, which puts that question back to the company and then to the country pack. It changes nothing in the books.

NameTypeReqDescription
date_display_formatstring|null–How this person likes a date written.
languagestring|null–Two letters, optionally a region. Labels are read in it first.
number_display_formatstring|null–How this person likes a number written. Not the pattern a document number is built from, which belongs to the country.
preferred_company_id––The company to open on.
themestring|null––
timezonestring|null–An IANA name.

No output schema declared.

No examples provided.

share_document ~186

Publishes a posted sales invoice, credit note or quote behind a link the customer opens without an account and without a password: the token in the url is the whole secret. It returns that token once and stores only its hash, so give the url to the customer and say it cannot be read back. The page shows the document as it was sent and what is still owed on it today, so the link stays worth opening after a payment. A purchase document is refused — it is a third party’s own document — and so is a draft. A link is never edited: to change when it expires, withdraw it and make another.

NameTypeReqDescription
document_idstringyesThe sales document to publish. A purchase document and a draft are refused.
expires_atstring|null–When the link stops answering, as a timestamp. Left out, it answers until it is withdrawn.

No output schema declared.

No examples provided.

status ~61

The schema version, the instance this is, how this server is connected and as whom, and the companies you can see. Use it first when something does not add up — an empty company list usually means the user was never invited rather than that the books are empty.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

trial_balance ~86

Opening balance, movements of the period and closing balance for every account, from posted entries only. The debit and credit totals are equal on a healthy ledger; if they are not, say so rather than explaining it away.

NameTypeReqDescription
company_idstringyesThe company to work in. Ask list_companies if unsure.
fromstringyes–
tostringyes–

No output schema declared.

No examples provided.

Common questions

What is the Ekwo OS MCP server?

Ekwo OS is an MCP server listed in the public MCP registry as ai.ekwo/mcp. Open source accounting data infrastructure on your own Postgres, acting as the user under RLS. This page covers its npm package (@ekwo-ai/mcp).

Is the Ekwo OS MCP server safe to use?

Ekwo OS scores 72 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 25 September 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Ekwo OS MCP server expose?

Ekwo OS exposes 55 tools: list_companies, get_company, list_accounts, search_contacts, list_documents, and 50 more. Their descriptions and schemas cost roughly 11,053 tokens of context every time the server is loaded.

Is the Ekwo OS MCP server still maintained?

Ekwo OS is still listed as active in the MCP registry. We last reached this channel on 25 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the Ekwo OS MCP server under?

Ekwo OS declares the AGPL-3.0-only licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.