mcpbeat Sign in

Zeno MCP Server

by zeno-works Your server? Claim it
answering

Zeno is answering right now. Last checked 5 min ago. It exposes 43 tools.

AI bookkeeper for Swiss small companies: books invoices, reconciles the bank, keeps VAT current.

Uptime history 28 days of history · worst day 99%
28 days agonow
100.0%
Uptime 24h
92 of 92 checks
43
Tools
read from the server
212 ms
Response time
average over 24h
open, no key
Access
streamable-http

What changed 65

Every tool that appeared, vanished or quietly changed what it asks for. Recorded since 13 October 2026. No other catalogue keeps this.

8 Nov a tool changed version3 times that day
7 Nov 8 tools disappeared create_ar_invoice, get_kpi_report, gl_balance_sheet and 5 more
7 Nov a tool changed version
6 Nov 8 tool descriptions were rewritten get_bank_status, get_financial_statements, gl_profit_and_loss and 5 more
6 Nov 6 tools changed the parameters they ask for accept_autopost_decision, get_financial_statements, list_autopost_decisions and 3 more
6 Nov a tool changed version
4 Nov a tool changed version3 times that day
4 Nov a tool description was rewritten reverse_gl_journal_entry
3 Nov a tool changed version2 times that day
2 Nov 3 tools changed the parameters they ask for list_autopost_decisions, list_gl_open_items, list_items
and 34 more, back to 13 October 2026

Zeno missed one check this week

Everything else answered, so this is steady rather than shaky. We check every 15 minutes, which is how a one-off gets told apart from the start of a pattern, and how you hear about the next one within the hour instead of from your users.

Three servers free · no card

Connect this server

Endpoint below is the one we actually reach during checks — not the one copied from a README. Last verified 5 min ago.

run in your terminal
claude mcp add zeno --transport http https://app.zeno-works.ch/mcp
Settings → Connectors → Add custom connector, then paste this address
https://app.zeno-works.ch/mcp
~/.codex/config.toml
[mcp_servers.zeno]
url = "https://app.zeno-works.ch/mcp"
.cursor/mcp.json
{
  "mcpServers": {
    "zeno": {
      "url": "https://app.zeno-works.ch/mcp"
    }
  }
}
.vscode/mcp.json
{
  "servers": {
    "zeno": {
      "type": "http",
      "url": "https://app.zeno-works.ch/mcp"
    }
  }
}

Available tools 43

Read directly from the server with tools/list, grouped by what they act on. If a tool disappears, we record the date.

bank
get_bank_entry
Get Bank Entry
get_bank_status
Composed bank snapshot — "is my banking up to date?" (CompanyMember). "Reconciled" means entries matched, NOT ledger = statement balance (the close check ``BANK_BALANCE_DOES_NOT_TIE_OUT`` compares that). Per-account entry-status and ``in_suspense`` counts, each account's latest closing balance, and the **company-level cumulative GL Suspense balance**. Non-zero suspense blocks a clean VAT close. Read-only. Gaps come from the account's **full** history: coverage windows are merged and every internal hole reported (ZCT-509), so a run of missing statements is ONE gap. Not period-scoped; use ``…/reconciliation/completeness`` per month. ``period_gaps`` caps at 10/account, ``period_gap_count`` stays exact — HOLES, not missing months. Explicit non-member ``company_id`` → 403.
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_number`` — the chart code this account posts through; **without one a bank movement cannot be coded**, and it is set with ``PUT /bank-accounts/{account_id}``. ``auto_created`` marks an account inferred from an imported statement rather than declared by a human; it starts ``ownership_status`` unconfirmed with ``needs_ownership_review: true`` — confirm it before trusting its balances, since an unconfirmed IBAN may not be the company's at all. ``statement_count`` / ``entry_count`` are ``null`` here (filled by the single-account ``GET /bank-accounts/{account_id}``), which is not the same as zero.
list_bank_entries
List Bank Entries
journal
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 justified it. ``document_id`` is the retrofit: name an existing ``gl_document`` (create one with ``POST …/gl/documents``) and it is attached as the entry's source document, so the entry is not evidence-less. The same attach is available afterwards at ``POST …/gl/journal-entries/{id}/documents`` — including on a posted entry. Use it for bookings with genuinely no document behind them — reclassifications, provisions, accruals, year-end adjustments. **Do not transcribe a document into it and then attach the file** — that files the evidence beside a booking nobody derived from it. Each of these has a door that keeps the evidence attached: - an invoice, receipt or statement → ingest the file (``POST …/uploads/`` or ``…/intake``), then accept what the coder proposes (``…/autopost-decisions``); - an already-ingested item → ``POST …/gl/items/{item_id}/coding``; - a bank movement with no document → ``POST /bank-entries/{entry_id}/manual-coding``; - opening balances → ``POST …/opening-entries`` and post the proposal. ``auto_reverse_date`` arms the entry as a one-shot accrual (ZCT-527): once posted, the auto-reversal executor reverses it in full on/after that date. It must be after ``posting_date`` (422 otherwise), and it can only be set while the entry is a draft — on the create here or on the ``PUT`` replace. Drafts do not touch the books until ``…/post``. See ``doc/pipeline.md §"Accounting"``.
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 % line is indistinguishable from an untagged one) and referenced ``gl_open_item`` rows. A declared base line also carries the resolved code on ``lines[].vat_code``. Drafts carry empty lists. ``documents`` carries the accounting documents explicitly attached to the entry (``POST …/documents``) — the evidence for a hand-booked entry; a pipeline-created entry carries its document through ``source_ref_*`` instead and lists nothing here. Member read, like the rest of the detail.
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 the route lists every fiscal year. ``total`` is the filtered total. ``untagged_subledger_control=true`` narrows to the entries that posted to an AR/AP control account **without** touching the subledger, under ``allow_untagged_control`` (ZET-150) — the postings a subledger-vs-control divergence traces back to. ``origin``: one entry origin (ZEN-42). ``account_id``: entries with a line on it; ``date_from``/``date_to``: posting date; ``amount_min``/``amount_max``: the entry total.
upload
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-only: it never routes a file onward by type, so a bank statement, a journal export or a balance sheet sent here is analysed and then just sits as a document. For anything that is not an invoice — or when you are not sure what the file is — use ``upload_intake``.
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 statements (CAMT.053 XML, CSV, PDF or Excel exports) — these become BankStatement + BankEntry rows, matched to the registered bank account by IBAN; journal/accounting exports; and balance sheets, P&L statements and VAT filings. Mixed .zip archives are expanded and routed per file. Returns 202 with the queue row: routing happens asynchronously, so poll ``get_intake`` for the outcome and its targets. An unroutable file becomes a failed queue row carrying the reason — it is never silently dropped.
zeno
zeno_info
What this server is, which MCP revision it speaks, and how to get a credential. **Needs no credential.** Call it first if a tool has just refused you: the `authentication` block names the tools that can get this session connected.
zeno_overview
What Zeno does, in one page — the platform's capabilities and its limits. **Needs no credential.** Read this before telling a user that Zeno cannot do something; it covers VAT, payroll, reconciliation and the AI accountant.
accept
accept_autopost_decision
One-click accept of a **held** decision (accountant) — posts the AI's proposal. A person's accept overrides the soft guardrails. An agent's is refused (403) unless the row is ``agent_acceptable`` or an expense receipt. Closed period, sealed year, unknown account: 409/422. The row flips ``held → posted`` (again: 409); ``accepted_by_kind`` records the channel (``mcp`` over MCP). Optional ``body``: ``expense:receipt:item:`` needs ``employee_id`` + ``category_id``; ``autopost:capitalize:`` needs ``fixed_asset_category_id`` when the hold has none, and ``needs_split_source`` a ``reclassify_from_account_code``.
account
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 are included (a reversal is a second posted entry, so both legs must show or the balance is wrong); drafts are not. The running balance is carried across pages by the server — ``page_opening_balance`` enters this page's first row, while ``closing_balance``/``total_debit``/``total_credit`` describe the whole window. 404 when the account is not this company's; 422 when ``date_from`` is later than ``date_to``.
accounts
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).
autopost
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 entry with no verdict) are feed noise and hidden by default; ``include_no_match=true`` surfaces them for audit. ``outcome`` / ``source_ref_id`` narrow server-side (ZET-75). Newest first, ordered ``(created_at DESC, id DESC)``. ``limit`` caps at 200 and ``offset`` walks the rest (R2-21): page with ``offset += limit`` until a call returns fewer than ``limit`` rows. The response is a bare list. ``cause`` keeps the held rows of one hold cause. An agent may accept only rows with ``agent_acceptable`` true. ``date_from`` / ``date_to`` keep rows whose ``effect_date`` (the date it affects the books) is in the period.
call
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 exactly what calling the operation directly would give you.
collect
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 tell you when they are done: you cannot detect it any other way, and handing the wait back to the user is how these sessions die. - `ready` — `api_key` is the credential. **Follow the `note` that comes with it before anything else**: the key does nothing until the client's configuration holds it, and calling again issues nothing. `scope` says what it can reach (`onboarding`, `company` or `full`) and `company_id` which company, if any. **When `scope` is `onboarding` the user has no company yet and this key exists to make one: call `onboarding_guide` next** — it needs no key, so read it while the user installs this one. It is the only place that says which documents to ask them for, and asking for them all at once is the difference between one conversation and seven. - `collected` — this request already issued its key and nothing new was issued. Follow the `note`. - `denied` — **stop.** Do not start another request; a human refused it ("that was not me"). Raising a second one is how a refusal turns into a prompt the user has to refuse repeatedly. - `expired` — the request timed out. **Do not simply open another one**, and what to do depends on which door you opened, which only you know. `request_api_key`: ask whether they saw the approval page, and call it again if they want to retry. `start_signup`: they may have finished registering in the browser meanwhile, in which case they now HAVE an account and `request_api_key` is the path — ask. If they did not, tell them plainly that it timed out; starting another signup without asking is how a refusal turns into a prompt they have to refuse repeatedly. A `pending` answer is a success, not an error; it is deliberately not an error status, because an error would be read as "do not retry" and retrying is the entire protocol. A rate limit mid-wait is reported the same way, with `throttled: true` and a longer `poll_interval_seconds` — slow down, do not stop.
companies
list_companies
List companies (jwt, scoped). Non-admins see only their member companies.
company
get_company
Get one company (jwt, scoped). 403 for a non-member non-admin, 404 if absent.
counterparties
list_counterparties
List a company's counterparties (filter by ``kind``/``q``, paginated). ``kind`` repeats to filter on a set (``?kind=customer&kind=both``) — a role-shaped picker asks for every kind that plays the role. A single ``?kind=supplier`` keeps its original meaning.
customer
customer_statement
One customer's open items + totals (the aging row's drill-down). ``as_of`` mirrors ``GET …/ar/aging`` — set, it reconstructs the items open at that date so the statement agrees with a historical aging report.
describe
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/list`` publishes no output schema for any operation, listed or not (they are 67 % of the payload, and a schema describing a *result* is not what you need to *choose* a tool). Ask for it when you must know the shape in advance; the result itself comes back as JSON either way, so usually you do not. Up to 10 operations per call; anything beyond that is reported in ``omitted`` rather than dropped.
entry
entry_candidates
Entry Candidates
financial
get_financial_statements
Computed balance sheet + P&L for a fiscal year, from the journal (CompanyMember). Aggregates every posted GL journal line whose **posting date** falls in the fiscal year's window, classifies each account against the chart of accounts, and reports problems (unbalanced trial balance, unclassified accounts, year-not-opened, mixed currency). **Read-only and distinct** from the uploaded balance-sheet snapshots (``GET .../balance-sheets``): nothing here reads a snapshot. ``fiscal_year`` optional → the latest FY with journal data. ``month`` (``YYYY-MM``, inside the FY — **422** otherwise) narrows the statement to one month: the balance sheet stays cumulative (as of month end, YTD equity fold) while the P&L + cash flow cover that month's flows. Explicit non-member ``company_id`` → 403. **The cut**: ``posting_date`` inside the fiscal year's own window (``fiscal_year_cut``; ``period_start``..``period_end`` is what was aggregated, ZET-166). ``/gl/reports/*`` cuts by the line's stamped ``fiscal_year_id``, so the two can differ on a line dated outside the year it is stamped to.
global
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).
intake
get_intake
Get one intake row by id (scoped to its company: 404/403 split).
invoice
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`` → ``cancelled``), ``document_no`` (assigned at issue — ``null`` on a draft), ``commercial_document_id`` / ``snapshot_document_id`` (the booked document and the frozen PDF), plus the derived ``payment_status`` and ``open_amount`` read from the linked open item. This is the **authored** arm only. A receivable that arrived as an ingested document is an ``item``, not an ``ar_invoice``; the two arms are listed together by ``GET …/ar/receivables``. Use ``GET …/ar/invoices/{invoice_id}/related`` for the journal entry, the settling bank transactions and the credit-note chain.
invoices
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"}``.
item
get_item
Item metadata (any source).
items
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"}``. ``exclude_triage_status`` drops items carrying that triage verdict (NULL-safe; for ``unrelated`` not a booked one, ZCT-954). Optional ``q`` is free text: a case-insensitive **partial (substring)** match over the filename and the counterparty name from *both* of its sources (the linked counterparty and the extracted ``data.company``). ``duplicate`` filters on the row's ``is_duplicate`` flag (ZET-413); ``credit_note`` on its ``is_credit_note`` flag (ZET-429) — both server-side, so ``total`` stays exact. ``posted`` filters on the posting badge (ZCT-811): ``true`` = posted, ``false`` = held, reversed or not booked; a copy filed with the booking of the same invoice ("Already booked", ``posting.filed_with``) is in neither (ZEN-1). ``overdue`` (D08-G14): due before today (Zurich), still owing, not a credit note. Owing is the open item's rest; a document with no open item is owing until a bank movement is linked to it (R2-2).
onboarding
onboarding_guide
How to onboard and create a NEW company: what to ask the user for, which documents to request, and the order to run the setup in. Discovery does not depend on search: this tool is in the tier, so it is listed for every caller, and `BASE_INSTRUCTIONS` names it. `find_operations` does reach it ("new company setup" ranks it first), but a query made only of common words is still decided by whichever tool happens to contain them. **Read this before you start a company setup**, and before you tell a user that something cannot be done here. It answers the questions the create's own schema cannot: which of fifteen sections actually matter, which documents produce them, and what it costs to skip one. If your API key's purpose is `onboarding`, this is the only job it has.
open
list_gl_open_items
One page of the AR/AP subledger (member read). ``direction`` filters server-side (ZCT-577) — omit it for both. ``commercial_document_id`` narrows to one document's item (D09-G13); not with ``as_of``. ``as_of`` (ZCT-577) reconstructs each item's open amount from posted journal lines dated on or before that date, instead of reading today's cached amount. Items are considered **regardless of their current status** — one settled since that date was open on it — so ``status`` is refused alongside it rather than silently ignored: a filter that appears to apply and does not is worse than an error. ``original_amount`` and ``status`` on each row remain the item's own, which are current facts, not as-of ones; the screen says so.
operations
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 — are available but unlisted, and this is how you find them. **Search here before concluding that Zeno cannot do something.** Call with no arguments to browse the catalogue of areas (tags) with their operation counts; with ``tag`` to list one area; with ``query`` to search by keyword. **Every word contributes and matching all of them doubles the score**, so extra words widen the search rather than narrowing it — the AND-then-fall-back- to-OR behaviour this said before was removed in `ef47aa9ab`. A word matching an operation's *name* counts for far more than one found in its description, so prefer the noun you are looking for over a sentence. ``limit`` is capped at 100 per call; when more matched, ``next_offset`` gives the ``offset`` that returns the following page, so an area of any size can be read in full. Paging is stable — the ranking is deterministic and the registry is fixed at startup, so no operation is dropped or repeated between pages. Pass a promising ``name`` to ``describe_operations`` for its arguments, then run it with ``call_operation``.
periods
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`` still accepts them, and ``closed``/``year_closed`` refuse them — a posting date inside a closed period fails until an accountant explicitly reopens the period (``POST …/gl/periods/{period_id}/reopen``, reason required, recorded in the close-run ledger — ZET-161). ``fiscal_year_id`` narrows to one year; omitted, every year's periods come back. This is **not** the VAT filing calendar — those are the ``gl_vat_period`` rows of ``GET …/gl/vat/periods``, which have their own quarterly/monthly cadence and their own ``filed``/``paid`` sealing. Use this list to find the ``period_id`` a manual journal entry needs, and to check *why* a posting date was refused.
post
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-account``, which re-points a ``coding_guessed`` entry's expense account in place — and it works *only* on a posted entry. Check the draft before posting rather than after.
request
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 signed in as the owner of that address. Pass `client_name` too: it is the only thing identifying you on the approval page, and without it the person is asked to trust "an unnamed client". Returns a plain `verification_uri`. Tell the user to open it, sign in, and approve the request waiting there; we also email them a notice. **There is no code**, in either direction: nothing to read out, nothing to type, and nothing for you to put in a link. Then call `collect_api_key` with the `claim_token` returned here, waiting `poll_interval_seconds` between calls, until its `status` stops being `pending`. The user chooses on the page what the key may reach — usually a single company — so expect the key to be scoped, and read a 403 elsewhere as that scope rather than as a failure. The answer is the same whether or not that address has a Zeno account. If nothing ever arrives, the likeliest cause is a mistyped address — ask, do not assume.
reverse
reverse_gl_journal_entry
**Storno** a posted journal entry: post its mirror image (accountant role). Nothing is deleted; the original stays, linked, and the **reversal** entry is returned. The only VAT-correct storno door — VAT postings, open items and what the document spawned are all unwound. ``body.posting_date`` dates the reversal and decides its period; omitted, it reuses the original's. A closed-period entry needs one in an open period and a person: the reversal is booked there; the entry stays unchanged. **409** when: the entry is a reversal or already corrected; a payroll run holds it; the date falls in a filed VAT period; an open item still carries a live settlement; the target period is closed or sealed; or a closed-period entry cannot be corrected (the reason is named).
settle
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 native settlement. The matcher still owns ``reconciliation_status``. See doc/architecture.md §"Posting general ledger".
start
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 `client_name`, shown as an unverified claim), chooses their own password, and decides separately whether to connect you. **You never see the link**, and you must not ask for it: it is what proves they own the mailbox, and a link you could repeat is a link anyone could. Then poll `collect_api_key` with the `claim_token` returned here. `denied` is terminal and means the person chose to create the account without connecting you, or refused outright — tell them plainly and stop; do not start another.
trial
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-counts silently (ZET-155). Unknown year/period → 404; period outside the year → 422. Cut by the line's stamped ``fiscal_year_id``, not its posting date; ``…/financial-statements`` cuts by posting date inside the same year's stored window, so the two differ only on a line dated outside the year it is stamped to. ``fiscal_year_cut`` names the cut (ZET-166).
vat
list_gl_vat_periods
List Gl Vat Periods
whoami
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_scoped: true`` means this connection's data access is confined to ``company_id`` — ``company_name`` names it (null here means the bound company no longer exists), no other tenant is reachable, and the admin endpoints are refused however privileged the owner is. ``is_admin`` is that owner's bit: worth nothing outside this company, still full authority inside it, so a scoped key with ``is_admin: true`` may write these books even when ``company_role`` is null. ``company_scoped: false`` means the credentials carry the owner's full principal and ``memberships`` lists the companies it can act in. Read-only and cheap — at most one lookup. ZET-171, ZET-176. ``credential_purpose`` says which kind of credential this is, and is what the withholding rule keys on (SP-08): anything that is neither ``full`` nor ``session`` is confined, and gets ``memberships`` **withheld — null, not empty**. Working over MCP, what you book or accept is recorded as MCP — not as this user acting in person — and the app displays it that way. ``capabilities`` says what this caller may do, each verdict computed from the predicate the gate itself evaluates (SP-12) — so an agent learns what it cannot do before it collides rather than after. A credential confined **to a company** gets the entries whose verdict is a fact about the *credential*; the one that would read the owner's estate (``create_company``) is omitted, because its verdict would disclose a sibling tenant. A credential confined to **no** company — an onboarding key — has no sibling to disclose and does get it, which is the one operation such a key exists to call. ``pending_admin_actions`` is present and empty until PRE-03/PRE-04 fill it.
work
get_work_list
Everything waiting for this user in this company, most severe first.

Tools removed

Tools this server used to expose. Anything built against them stopped working on the day they went.

create_ar_invoice
removed 7 Nov 2026
get_kpi_report
removed 7 Nov 2026
gl_balance_sheet
removed 7 Nov 2026
gl_profit_and_loss
removed 7 Nov 2026
issue_ar_invoice
removed 7 Nov 2026
list_payroll_employees
removed 7 Nov 2026
list_payroll_runs
removed 7 Nov 2026
reconciliation_summary
removed 7 Nov 2026

Endpoints

URLTransportStateLatencyChecked
https://app.zeno-works.ch/mcp streamable-http answering 184 ms 5 min ago

Alternatives to Zeno

same job, measured the same way
Lumabill
by lumabill

Swiss invoicing and bookkeeping: QR-invoices, clients, expenses, bank import, VAT and reports.

answering
DanBooks — AI Bookkeeping
by jeremiahclark79-ai

AI bookkeeping for small business. Create invoices, log expenses, and check P&L by voice or text.

37 installs/wk local only
Conecto
by conecto

The whole back office for your AI agent: CRM, invoices, books, email and more. Pay per action.

answering
SubCenter for Teams
by subcenter

Track SaaS and AI-tool spend, renewals, seats, invoices and client bill-back for small teams.

answering
Kvickd
by kvickd

Bookkeeping for Swedish small businesses: AB, enskild firma, handelsbolag. Invoices, VAT, payroll.

answering
Dobl
by dobl

Norwegian accounting for small AS and holding companies: vouchers, invoices, VAT, payroll, Altinn.

answering
HelloBooks AI Agents MCP Server
by hellobooksaiagents

AI agents for bookkeeping, reconciliation, and financial close for SMBs.

29 tools answering
FacturaSmart Pro
by facturasmartpro

Invoicing your AI agent runs for you: invoices, quotes, expenses, VAT books. Veri*factu for Spain.

answering

Zeno — questions

Answers built from our own checks of this server.

What can Zeno do?
It exposes 43 tools, read directly from the server on our last check. Among them: accept_autopost_decision, call_operation, collect_api_key, create_gl_journal_entry, customer_statement, describe_operations and 37 more. The full list with descriptions is on this page — we take it from the server itself via tools/list, not from a README. How MCP servers expose tools in the first place →
What is Zeno mostly used for?
Its tools cluster around bank, journal and upload. That is what this server is built to work with — the grouping comes from the actual tool names, not from a category we assigned.
Is Zeno working right now?
We send a real MCP handshake every 15 minutes. Over the last 24 hours 92 of 92 checks got a reply (100.0%), average response time 212 ms. The bar chart above shows every period we have measured.
Did Zeno ever remove tools?
Yes. create_ar_invoice, get_kpi_report, gl_balance_sheet, gl_profit_and_loss and 4 more are no longer exposed — we recorded the date each one disappeared. A tool vanishing usually means a breaking change for anything that depended on it.
How do I connect Zeno?
Copy the ready config from this page. We generate it for Claude Code, Claude Desktop, Codex, Cursor and VS Code, each in the form that client actually reads. It is a remote server, so there is nothing to install — the client connects to the address.
Does Zeno need an API key?
No. Zeno completed a full MCP handshake with us as an anonymous client and listed its tools without asking for anything. All 43 of them are readable on this page. This is what we observed, not what the docs claim.
How fast is Zeno?
It answers our handshake in 212 ms on average, which is faster than 63% of all working MCP servers we measure. The comparison comes from our own checks across the whole registry, every 15 minutes.