Zeno
by app.zeno-works.ch in Company & people data
AI bookkeeper for Swiss small companies: books invoices, reconciles the bank, keeps VAT current.
https://app.zeno-works.ch/mcp
Last 30 days
- Uptime
- 100%
- Response time
- 244 ms typical, 244 ms slowest 5%
- Last check
- 9 h ago
- Next check
- any minute now
How to call it
Add it to any MCP client that supports remote servers.
{
"mcpServers": {
"zeno": {
"type": "http",
"url": "https://app.zeno-works.ch/mcp"
}
}
}51 tools
- find_operations
Search EVERY operation this server offers, including the ones not in your tool list. The tool list you can see holds only the common operations. Several hundred more — payroll, VAT returns, year-end close, fixed assets, expenses, cash book, settings, integrations, onboarding — a
- describe_operations
Get the full argument schema for operations found via ``find_operations``. Returns each operation's description and JSON-Schema arguments — everything a listed tool would have shown you. ``include_output_schema`` is the ONLY way to obtain an operation's result shape: ``tools/li
- call_operation
Run any operation by name — the ones in your tool list and the unlisted ones alike. ``name`` is an operation name from ``find_operations``; ``arguments`` is the object described by ``describe_operations`` (omit it for an operation that takes none). The result, and any error, are
- request_api_key
Ask the user to hand this session a Zeno API key. **Use this first** — every current Zeno user already has an account. `email` is the address on their Zeno account. **Ask them for it**; you cannot guess it, and the request is aimed by it — Zeno will only show it to somebody sign
- start_signup
Create a Zeno account for somebody who does not have one yet. Use `request_api_key` first if they might already have an account — this tool cannot tell you, and deliberately never will. We email `email` a verification link. The user opens it, sees that you asked (by the name in
- collect_api_key
Collect the key once the user has approved. `status` is one of: - `pending` — nobody has approved yet, or (with `throttled: true`) we were rate-limited and learned nothing. **Wait `poll_interval_seconds`, then call again** — every answer carries it. Do not ask the user to t
- whoami
Which user this request acts as, and which company's books it is bound to (jwt or API key). Zeno serves every tenant from one host, and an API key is opaque — nothing else tells a connected agent whose books it is about to write. Call this FIRST when working over MCP: ``company_
- list_companies
List companies (jwt, scoped). Non-admins see only their member companies.
- get_company
Get one company (jwt, scoped). 403 for a non-member non-admin, 404 if absent.
- global_search
Full-text search across emails + items, ranked by ``ts_rank_cd``, scoped (A1). ``archive_status`` constrains item results only (the Documents → Archive page passes ``archived`` so its search box never surfaces pending/triage-parked items).
- get_kpi_report
Snapshot KPIs + 13-week liquidity forecast, from the GL (CompanyMember). Cash/liability balances aggregate the FY window of posted/reversed journal lines; aging + forecast read ``gl_open_item``, pending salary batches and unpaid VAT periods. Read-only. Explicit non-member ``comp
- get_work_list
Everything waiting for this user in this company, most severe first.
- list_autopost_decisions
Recent AI-accountant autonomy decisions (CompanyMember) — the activity feed. Shows what the autonomy policy posted (``posted``), would have posted in ``assist`` shadow mode (``shadow``), or held for human review (``held``). ``ai_no_match`` shadow rows (one per AI-consulted bank
- accept_autopost_decision
One-click accept of a **held** decision (accountant) — posts the AI's proposal. The accepting actor's approval replaces every soft guardrail (confidence, amount cap, risk flags); hard blocks stay enforced by the posting path (closed period / sealed FY / unresolvable accounts → 4
- upload_intake
Upload ANY file and let the system decide what it is (the unified intake queue — the same door as "Documents → Upload" in the web app). ``file_base64`` is the file's raw bytes, base64-encoded. Prefer this whenever the file is not plainly an invoice, and always for: bank statemen
- upload_document
Upload an INVOICE or RECEIPT (PDF, image, or .zip of them) for analysis. ``file_base64`` is the file's raw bytes, base64-encoded. ``direction`` is ``payable`` (incoming supplier invoice) or ``receivable`` (outgoing). Creates Item(s) and queues extraction. This door is invoices-o
- get_intake
Get one intake row by id (scoped to its company: 404/403 split).
- list_items
List/filter items, scoped to the caller's member companies (A1). Optional ``period`` (``YYYY-MM``) filters by the item's effective date (invoice date, falling back to the Europe/Zurich-local ingestion date); a malformed value returns 422 ``{"msg": "period must be YYYY-MM"}``. ``
- get_item
Item metadata (any source).
- gl_trial_balance
Per-account debit/credit columns for one fiscal year, with totals. ``fiscal_year`` (year label) defaults to the latest year posted in; ``period_id`` narrows to one period of it. No all-years mode — account identity is ``(company, fiscal year, code)``, so aggregating double-count
- gl_profit_and_loss
Revenue − expense → net result, for one fiscal year. **Window** — same rules as the trial balance: ``fiscal_year`` defaults to the latest posted year, ``period_id`` narrows to one period of it, unknown values are 404 and a contradictory pair 422. A P&L is a **flow** statement, s
- gl_balance_sheet
Assets vs liabilities + equity for one fiscal year, signed by natural side. Window rules as the trial balance (``fiscal_year`` defaults to the latest posted year; no all-years mode, ZET-155). With ``period_id`` this is a *movements* aggregate over that period, not a position. ⚠
- list_gl_accounts
List the postable chart (CompanyMember). ``fiscal_year`` filters to one year's chart (the chart is FY-scoped, so codes repeat across years).
- get_gl_account_ledger
One account's ledger (Kontoauszug) — every booking that touched it, in date order, with Soll/Haben and the running balance after each line (CompanyMember). No fiscal-year parameter: the chart is FY-owned, so ``account_id`` already fixes the year. Posted **and** reversed entries
- list_gl_periods
The company's **accounting periods** — the months a journal entry may post into (CompanyMember read). A period belongs to one fiscal year and carries ``period_no`` (1..12 within the year), ``date_from``/``date_to`` and a ``status``: ``open`` accepts postings, ``soft_closed`` sti
- list_gl_open_items
One page of the AR/AP subledger (member read). ``direction`` filters server-side (ZCT-577) — omit it for both. The screen used to filter the fetched page in the browser, which made the AR chip drop rows and the total count both directions. ``as_of`` (ZCT-577) reconstructs each
- list_gl_journal_entries
List journal entries. ``period_ids`` narrows to specific fiscal periods, and is how a caller asks for **one fiscal year** — the year's period ids (ZET-285). Without it this route listed, and counted, every fiscal year the company has: the Journal page cut the year out of the fet
- get_gl_journal_entry
One entry + lines, plus the subledger rows it produced/touched (Gap B detail surfacing): its ``gl_vat_posting`` rows, its ``gl_vat_zero_posting`` turnover-only declarations (zero-rated/exempt output — R2-13b: these have no VAT line to pair, so without them a correctly coded 0 % l
- create_gl_journal_entry
Create a **draft** journal entry by hand — accountant. It carries NO source document unless you name one. Only the pipeline paths stamp ``source_ref_type``/``source_ref_id`` (an ingested document is ``'item'``), so by default a booking made here cannot be traced back to what jus
- post_gl_journal_entry
Post a draft entry into the books — accountant. One-way. A posted entry can no longer be replaced or discarded (both refuse with 409); the only general correction is ``…/reverse``, which leaves both the original and the reversal visible. The one exception is ``PUT …/guessed-acco
- reverse_gl_journal_entry
**Storno** a posted journal entry: post its mirror image (accountant role). Nothing is deleted; the original stays, linked both ways, and the **reversal** entry is returned. The only VAT-correct storno door — VAT postings, open items and what the document spawned are all unwound
- list_bank_accounts
The company's bank accounts — the ``bank_account_id`` every statement import, bank-entry list and reconciliation call needs (CompanyMember read). Oldest first, no filter and no paging. Each row carries the ``iban``, ``currency``, ``label``/``bank_name`` and ``ledger_account_numb
- list_bank_entries
List Bank Entries
- get_bank_entry
Get Bank Entry
- entry_candidates
Entry Candidates
- settle_entry
Post this reconciled bank entry into the GL (clean-bank settlement). Matched → Dr Bank / Cr AR; unmatched → Dr Bank / Cr Suspense; a previously-suspensed entry now fully matched → Dr Suspense / Cr AR. Idempotent, and a no-op (``skipped``) when the GL chart is not configured for
- reconciliation_summary
Reconciliation summary banner. Optional ``from``/``to`` scope the **per-entry bank-entry counts** (total / matched / missing-invoice / …) to a ``booking_date`` window — mirroring the ``/bank-entries`` grid filter — so the banner agrees with a month-filtered table. The cross-mont
- list_ar_invoices
List authored AR invoices, newest first. Optional ``status`` / ``doc_type`` filter by lifecycle + document kind. Optional ``period`` (``YYYY-MM``) filters by the invoice's issue date (its month); a malformed value returns 422 ``{"msg": "period must be YYYY-MM"}``.
- get_ar_invoice
One authored outgoing invoice with its lines (CompanyMember read). Carries the header (customer, dates, currency, discounts), every line with its computed ``net_amount``/``vat_amount``/``gross_amount``, the document totals, and the lifecycle: ``status`` (``draft`` → ``issued`` →
- create_ar_invoice
Create an outgoing (sales) invoice as a **draft** — nothing is booked yet (accountant role). A draft changes no ledger balance, gets no invoice number and appears in no VAT return; it exists so it can be edited. Posting happens later, at ``POST …/ar/invoices/{invoice_id}/issue``
Security scan
- No findings. We scan names, descriptions and tool definitions for hidden instructions and other prompt-injection patterns.
Recent checks
| When | Result | HTTP | Time |
|---|---|---|---|
| 9 h ago | Passed | 200 | 201 ms |
| 19 h ago | Passed | 200 | 311 ms |
| 28 h ago | Passed | 200 | 244 ms |