{"data":{"name":"ch.zeno-works/zeno","title":"Zeno","description":"AI bookkeeper for Swiss small companies: books invoices, reconciles the bank, keeps VAT current.","version":"0.1.0","websiteUrl":"https://zeno-works.ch","repositoryUrl":null,"remotes":[{"url":"https://app.zeno-works.ch/mcp","type":"streamable-http","headers":[{"name":"X-API-Key","isSecret":true,"description":"Zeno API key. Get one via the request_api_key tool or see https://zeno-works.ch/skill.md"}]}],"packages":[],"status":"active","isLatest":true,"publishedAt":"2026-10-11T18:36:40.726Z","updatedAt":"2026-10-11T18:36:40.726Z","source":"official-registry","verification":"official","confidence":100,"stars":null,"sources":[{"stars":null,"title":"Zeno","source":"official-registry","sourceId":"ch.zeno-works/zeno","updatedAt":"2026-10-11T18:36:40.726Z","confidence":100,"websiteUrl":"https://zeno-works.ch","description":"AI bookkeeper for Swiss small companies: books invoices, reconciles the bank, keeps VAT current.","verification":"official","repositoryUrl":null}],"toolIndex":{"tools":[{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"accept_autopost_decision","title":null,"description":"One-click accept of a **held** decision (accountant) — posts the AI's proposal.\n\nA person's accept overrides the soft guardrails. An agent's is refused (403) unless\nthe row is ``agent_acceptable`` or an expense receipt. Closed period, sealed year,\nunknown account: 409/422. The row flips ``held → posted`` (again: 409);\n``accepted_by_kind`` records the channel (``mcp`` over MCP).\n\nOptional ``body``: ``expense:receipt:item:`` needs\n``employee_id`` + ``category_id``; ``autopost:capitalize:`` needs\n``fixed_asset_category_id`` when the hold has none, and ``needs_split_source`` a\n``reclassify_from_account_code``.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"decision_id":{"type":"string"},"body":{"anyOf":[{"properties":{"employee_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"category_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"fixed_asset_category_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"useful_life_months":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"reclassify_from_account_code":{"anyOf":[{"type":"string"},{"type":"null"}]},"confirm_not_card_statement":{"type":"boolean","default":false},"separate_document":{"type":"boolean","default":false}},"type":"object","description":"Optional ``POST /autopost-decisions/{id}/accept`` body; omit it for other kinds."},{"type":"null"}]}},"required":["company_id","decision_id"]},"annotations":null,"definitionHash":"971ba77c2a355a40a9da6852e8fad4a0728f5b7decce655f0dcf3d6cad3afd6f","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"call_operation","title":null,"description":"Run any operation by name — the ones in your tool list and the unlisted ones alike.\n\n``name`` is an operation name from ``find_operations``; ``arguments`` is the\nobject described by ``describe_operations`` (omit it for an operation that\ntakes none). The result, and any error, are exactly what calling the\noperation directly would give you.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"arguments":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"default":null}},"required":["name"],"additionalProperties":false},"annotations":null,"definitionHash":"bf8f28161ec7a8bfeaf0593978fb817e0be1ade4f49f08902b43e571fd96c2dd","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"collect_api_key","title":null,"description":"Collect the key once the user has approved.\n\n`status` is one of:\n\n- `pending` — nobody has approved yet, or (with `throttled: true`) we were\n  rate-limited and learned nothing. **Wait `poll_interval_seconds`, then call\n  again** — every answer carries it. Do not ask the user to tell you when they\n  are done: you cannot detect it any other way, and handing the wait back to the\n  user is how these sessions die.\n- `ready` — `api_key` is the credential. **Follow the `note` that comes with it\n  before anything else**: the key does nothing until the client's configuration\n  holds it, and calling again issues nothing. `scope` says what it can reach\n  (`onboarding`, `company` or `full`) and `company_id` which company, if any. **When\n  `scope` is `onboarding` the user has no company yet and this key exists to make\n  one: call `onboarding_guide` next** — it needs no key, so read it while the user\n  installs this one. It is the only place that says which documents to ask them\n  for, and asking for them all at once is the difference between one conversation\n  and seven.\n- `collected` — this request already issued its key and nothing new was issued.\n  Follow the `note`.\n- `denied` — **stop.** Do not start another request; a human refused it (\"that\n  was not me\"). Raising a second one is how a refusal turns into a prompt the\n  user has to refuse repeatedly.\n- `expired` — the request timed out. **Do not simply open another one**, and\n  what to do depends on which door you opened, which only you know.\n  `request_api_key`: ask whether they saw the approval page, and call it again if\n  they want to retry. `start_signup`: they may have finished registering in the\n  browser meanwhile, in which case they now HAVE an account and\n  `request_api_key` is the path — ask. If they did not, tell them plainly that it\n  timed out; starting another signup without asking is how a refusal turns into a\n  prompt they have to refuse repeatedly.\n\nA `pending` answer is a success, not an error; it is deliberately not an error\nstatus, because an error would be read as \"do not retry\" and retrying is the\nentire protocol. A rate limit mid-wait is reported the same way, with\n`throttled: true` and a longer `poll_interval_seconds` — slow down, do not stop.","inputSchema":{"type":"object","properties":{"claim_token":{"type":"string"}},"required":["claim_token"],"additionalProperties":false},"annotations":null,"definitionHash":"ce6d06b804bfe2e0c4893e043809cdc11d7a8e3c57f25b15f41e9f650e7fdfaa","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"create_ar_invoice","title":null,"description":"Create an outgoing (sales) invoice as a **draft** — nothing is booked yet\n(accountant role).\n\nA draft changes no ledger balance, gets no invoice number and appears in no VAT\nreturn; it exists so it can be edited. Posting happens later, at\n``POST …/ar/invoices/{invoice_id}/issue``.\n\nBody: ``issue_date`` (required), ``counterparty_id`` (the customer — required\nbefore it can be issued), ``currency``/``language``, ``due_date`` (filled from the\ncustomer's payment terms when omitted), ``doc_type`` (``invoice``, the default — a\n``credit_note`` draft can never be issued: credit an issued invoice with\n``POST …/ar/invoices/{invoice_id}/credit-note`` instead), and ``lines``: each line\ncarries ``quantity``, ``unit_price``, a revenue ``account_code`` and a\n``vat_code_id`` (the id from ``GET …/gl/vat-codes``; a line without one declares no\nVAT). Totals, per-line net/VAT/gross and discounts are computed server-side — do\nnot send them.\n\nReturns the created invoice with its lines and computed totals. Check\n``GET …/ar/invoices/{invoice_id}/readiness`` for what still blocks issuing.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"doc_type":{"type":"string","enum":["invoice","credit_note"],"default":"invoice"},"counterparty_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"issuer_profile_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"issue_date":{"type":"string","format":"date"},"due_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]},"service_period_start":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]},"service_period_end":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]},"currency":{"type":"string","maxLength":3,"minLength":3,"pattern":"^[A-Za-z]{3}$","default":"CHF"},"language":{"anyOf":[{"type":"string","enum":["de","en","fr","it"]},{"type":"null"}]},"payment_terms_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"invoice_discount_kind":{"type":"string","enum":["none","percent","amount"],"default":"none"},"invoice_discount_value":{"anyOf":[{"type":"number","minimum":0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"default":"0"},"footer_text":{"anyOf":[{"type":"string"},{"type":"null"}]},"legal_text":{"anyOf":[{"type":"string"},{"type":"null"}]},"notes":{"anyOf":[{"type":"string"},{"type":"null"}]},"credited_invoice_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"lines":{"items":{"properties":{"line_type":{"type":"string","enum":["product","service","text","section","discount"],"default":"product"},"sort_order":{"anyOf":[{"type":"integer"},{"type":"null"}]},"group_label":{"anyOf":[{"type":"string"},{"type":"null"}]},"product_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"item_code":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string","maxLength":8000},{"type":"null"}]},"quantity":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}]},"unit_price":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}]},"unit_label":{"anyOf":[{"type":"string"},{"type":"null"}]},"account_code":{"anyOf":[{"type":"string"},{"type":"null"}]},"vat_code_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"line_discount_kind":{"type":"string","enum":["none","percent","amount"],"default":"none"},"line_discount_value":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"default":"0"},"service_period_start":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]},"service_period_end":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]}},"type":"object"},"type":"array"}},"required":["company_id","issue_date"]},"annotations":null,"definitionHash":"0884e4d4a12b11e5dd5b2a01d84353790807fd352f648aec919fa3085a18b7b9","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"create_gl_journal_entry","title":null,"description":"Create a **draft** journal entry by hand — accountant. It carries NO source document\nunless you name one.\n\nOnly the pipeline paths stamp ``source_ref_type``/``source_ref_id`` (an ingested\ndocument is ``'item'``), so by default a booking made here cannot be traced back to\nwhat justified it. ``document_id`` is the retrofit: name an existing ``gl_document``\n(create one with ``POST …/gl/documents``) and it is attached as the entry's source\ndocument, so the entry is not evidence-less. The same attach is available afterwards\nat ``POST …/gl/journal-entries/{id}/documents`` — including on a posted entry.\n\nUse it for bookings with genuinely no document behind them — reclassifications,\nprovisions, accruals, year-end adjustments. **Do not transcribe a document into it and\nthen attach the file** — that files the evidence beside a booking nobody derived from\nit. Each of these has a door that keeps the evidence attached:\n\n- an invoice, receipt or statement → ingest the file (``POST …/uploads/`` or\n  ``…/intake``), then accept what the coder proposes (``…/autopost-decisions``);\n- an already-ingested item → ``POST …/gl/items/{item_id}/coding``;\n- a bank movement with no document → ``POST /bank-entries/{entry_id}/manual-coding``;\n- opening balances → ``POST …/opening-entries`` and post the proposal.\n\n``auto_reverse_date`` arms the entry as a one-shot accrual (ZCT-527): once posted, the\nauto-reversal executor reverses it in full on/after that date. It must be after\n``posting_date`` (422 otherwise), and it can only be set while the entry is a draft —\non the create here or on the ``PUT`` replace.\n\nDrafts do not touch the books until ``…/post``. See ``doc/pipeline.md §\"Accounting\"``.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"period_id":{"type":"string"},"posting_date":{"type":"string","format":"date"},"currency":{"anyOf":[{"type":"string","maxLength":3},{"type":"null"}]},"entry_type":{"type":"string","enum":["manual","invoice","payment","bank","vat","payroll","accrual","deferral","depreciation","inventory","closing","adjustment","reversal"],"default":"manual"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"lines":{"items":{"properties":{"account_id":{"type":"string"},"amount_base":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}]},"amount_currency":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}]},"line_role":{"type":"string","enum":["bank","ar","ap","revenue","expense","vat","payroll_liability","salary_expense","fixed_asset","depreciation","inventory","cogs","clearing","rounding","fx_gain_loss","suspense"]},"currency":{"anyOf":[{"type":"string","maxLength":3},{"type":"null"}]},"counterparty_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"open_item_id":{"anyOf":[{"type":"string","maxLength":21},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"vat":{"anyOf":[{"properties":{"code":{"type":"string"},"amount":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}]}},"type":"object","required":["code"],"description":"VAT tag for a manual journal line (Gap B — manual-booking metadata completeness).\n\nTag **both** legs of a taxable movement with the same ``code`` (a company\n``gl_vat_code``): the taxable **base** line *and* its paired **VAT-control** line —\nposting groups the entry's lines by this tag to pair base with VAT line, and the\ncomposition guard refuses (409) any VAT-control line left untagged (ZET-158: a\nbase-line-only tag has no working path). One tagged control line per code.\n``amount`` (the tax, a magnitude) is read from the **base** line's tag and falls\nback to the paired VAT line's amount — when several base lines share one VAT line,\ngive each base line its own ``amount``, or every pair books the full VAT-line\namount. Exception: a catalog-linked **zero-rated output** code (0 % rate) books no\nVAT-control line at all — tag only the base line(s); each line tagged with such a\ncode declares its turnover once. On post the entry gains ``gl_vat_posting`` rows so\nthe lines reach the MWST-Abrechnung (``doc/pipeline.md §\"VAT\"``)."},{"type":"null"}]},"open_item":{"anyOf":[{"properties":{"create":{"type":"boolean","default":false},"due_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]}},"type":"object","description":"Open a new AR/AP subledger item from a manual control line (Gap B).\n\nSet ``create=true`` on the line posting to the AR/AP control account; ``due_date`` seeds\naging. Direction is derived from the account's ``control_type``. To settle/adjust an\n*existing* item instead, pass ``open_item_id`` on the line (its balance is rebuilt on post)."},{"type":"null"}]}},"type":"object","required":["account_id","line_role"]},"type":"array","minItems":1},"auto_reverse_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["company_id","period_id","posting_date","lines"]},"annotations":null,"definitionHash":"88ebaf728612a7a9acaf3718add4dbc72d3b4f2b3bed7d25f701bbe782a22b42","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"customer_statement","title":null,"description":"One customer's open items + totals (the aging row's drill-down).\n\n``as_of`` mirrors ``GET …/ar/aging`` — set, it reconstructs the items open at\nthat date so the statement agrees with a historical aging report.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"counterparty_id":{"type":"string"},"as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]}},"required":["company_id","counterparty_id"]},"annotations":null,"definitionHash":"897437838973f05f787a088df127687d380bf0890a079935c2c6c1e9beb49297","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"describe_operations","title":null,"description":"Get the full argument schema for operations found via ``find_operations``.\n\nReturns each operation's description and JSON-Schema arguments — everything\na listed tool would have shown you.\n\n``include_output_schema`` is the ONLY way to obtain an operation's result\nshape: ``tools/list`` publishes no output schema for any operation, listed or\nnot (they are 67 % of the payload, and a schema describing a *result* is not\nwhat you need to *choose* a tool). Ask for it when you must know the shape in\nadvance; the result itself comes back as JSON either way, so usually you do not.\n\nUp to 10 operations per call; anything beyond that is reported in\n``omitted`` rather than dropped.","inputSchema":{"type":"object","properties":{"names":{"items":{"type":"string"},"type":"array"},"include_output_schema":{"default":false,"type":"boolean"}},"required":["names"],"additionalProperties":false},"annotations":null,"definitionHash":"f145e0a99b688c5bcc29cc8549d7b368f6af3f86a776c25e85ad9ece9a8ba55f","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"entry_candidates","title":null,"description":"Entry Candidates","inputSchema":{"type":"object","properties":{"entry_id":{"type":"string"}},"required":["entry_id"]},"annotations":null,"definitionHash":"364e632026e58fc4872b0e5f5bcfb533d70ff4f5fdb901470990ff83fb2dcf56","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"find_operations","title":null,"description":"Search EVERY operation this server offers, including the ones not in your tool list.\n\nThe tool list you can see holds only the common operations. Several hundred\nmore — payroll, VAT returns, year-end close, fixed assets, expenses, cash\nbook, settings, integrations, onboarding — are available but unlisted, and\nthis is how you find them. **Search here before concluding that Zeno cannot\ndo something.**\n\nCall with no arguments to browse the catalogue of areas (tags) with their\noperation counts; with ``tag`` to list one area; with ``query`` to search by\nkeyword. **Every word contributes and matching all of them doubles the score**,\nso extra words widen the search rather than narrowing it — the AND-then-fall-back-\nto-OR behaviour this said before was removed in `ef47aa9ab`. A word matching an\noperation's *name* counts for far more than one found in its description, so\nprefer the noun you are looking for over a sentence.\n\n``limit`` is capped at 100 per call; when more matched, ``next_offset`` gives\nthe ``offset`` that returns the following page, so an area of any size can be\nread in full. Paging is stable — the ranking is deterministic and the registry\nis fixed at startup, so no operation is dropped or repeated between pages.\n\nPass a promising ``name`` to ``describe_operations`` for its arguments, then\nrun it with ``call_operation``.","inputSchema":{"type":"object","properties":{"query":{"default":"","type":"string"},"tag":{"default":"","type":"string"},"limit":{"default":25,"type":"integer"},"offset":{"default":0,"type":"integer"}},"additionalProperties":false},"annotations":null,"definitionHash":"a86c285ebdc08d106dadf315febb652c27f2f258bdad3b5e1b917ff9f0cf777c","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_ar_invoice","title":null,"description":"One authored outgoing invoice with its lines (CompanyMember read).\n\nCarries the header (customer, dates, currency, discounts), every line with its\ncomputed ``net_amount``/``vat_amount``/``gross_amount``, the document totals, and\nthe lifecycle: ``status`` (``draft`` → ``issued`` → ``cancelled``), ``document_no``\n(assigned at issue — ``null`` on a draft), ``commercial_document_id`` /\n``snapshot_document_id`` (the booked document and the frozen PDF), plus the derived\n``payment_status`` and ``open_amount`` read from the linked open item.\n\nThis is the **authored** arm only. A receivable that arrived as an ingested\ndocument is an ``item``, not an ``ar_invoice``; the two arms are listed together by\n``GET …/ar/receivables``. Use ``GET …/ar/invoices/{invoice_id}/related`` for the\njournal entry, the settling bank transactions and the credit-note chain.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"invoice_id":{"type":"string"}},"required":["company_id","invoice_id"]},"annotations":null,"definitionHash":"1077288f12c3dcaed559163599c47bcc70874425bfcd23b5c2f42980d1a9c18a","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_bank_entry","title":null,"description":"Get Bank Entry","inputSchema":{"type":"object","properties":{"entry_id":{"type":"string"}},"required":["entry_id"]},"annotations":null,"definitionHash":"b5648776190410ebde06010f5437ed7ab27eb3288fdef4b14173a54abc13d2e2","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_bank_status","title":null,"description":"Composed bank snapshot — \"is my banking up to date?\" (CompanyMember). \"Reconciled\" means\nentries matched, NOT ledger = statement balance (the close check\n``BANK_BALANCE_DOES_NOT_TIE_OUT`` compares that).\n\nOne call for what otherwise takes ``GET …/bank-accounts`` + one\n``GET /bank-accounts/{id}/coverage`` per account + ``GET …/reconciliation/summary``\n— and which those three still do not answer: per-account entry-status counts, the\n``in_suspense`` counts, each account's latest closing balance, and the **company-level\ncumulative GL Suspense balance** (elsewhere reachable only through a VAT period's\nclose-checks). Non-zero suspense blocks a clean VAT close.\n\nRead-only. Gaps come from the account's **full** history: coverage windows are merged and\nevery internal hole reported (ZCT-509), so a run of missing statements is ONE gap. Not\nperiod-scoped; use ``…/reconciliation/completeness`` per month. ``period_gaps`` caps at\n10/account, ``period_gap_count`` stays exact — HOLES, not missing months. Explicit\nnon-member ``company_id`` → 403.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"}},"required":["company_id"]},"annotations":null,"definitionHash":"4273adf6643fe23086d1348c395c8f9a570d7798ef45f11ed28f033aeaada157","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_company","title":null,"description":"Get one company (jwt, scoped). 403 for a non-member non-admin, 404 if absent.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"}},"required":["company_id"]},"annotations":null,"definitionHash":"151021bc050c8c27331bb6c9fb73004aeba5829a63fd97e05434da0715cb15f5","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_financial_statements","title":null,"description":"Computed balance sheet + P&L for a fiscal year, from the journal (CompanyMember).\n\nAggregates every posted GL journal line whose **posting date** falls in the fiscal\nyear's window, classifies each account against the chart of accounts, and reports\nproblems (unbalanced trial balance, unclassified accounts, year-not-opened, mixed\ncurrency). **Read-only and distinct** from the uploaded balance-sheet snapshots\n(``GET .../balance-sheets``): nothing here reads a snapshot. ``fiscal_year`` optional\n→ the latest FY with journal data. ``month`` (``YYYY-MM``, inside the FY — **422**\notherwise) narrows the statement to one month: the balance sheet stays cumulative\n(as of month end, YTD equity fold) while the P&L + cash flow cover that month's\nflows. Explicit non-member ``company_id`` → 403.\n\n**The cut** — a line is included because its ``posting_date`` falls inside the fiscal\nyear's own window, read off the ``gl_fiscal_year`` row; the response's\n``fiscal_year_cut`` says so (``method=\"posting_date_window\"``, dates = that window;\nthe aggregated window is ``period_start``..``period_end``, narrower when\nmonth-scoped, ZET-166). The ``/gl/reports/*`` family cuts by the line's stamped\n``fiscal_year_id`` FK instead. Both read the same window, so they agree on where the\nyear starts and ends; they can still differ on a line dated outside the year it is\nstamped to.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"fiscal_year":{"anyOf":[{"type":"integer"},{"type":"null"}]},"month":{"anyOf":[{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},{"type":"null"}]}},"required":["company_id"]},"annotations":null,"definitionHash":"fb00a136a8bd76975ddaf04df73578babb3462134d52cada323067420964d6c4","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_gl_account_ledger","title":null,"description":"One account's ledger (Kontoauszug) — every booking that touched it, in date\norder, with Soll/Haben and the running balance after each line (CompanyMember).\n\nNo fiscal-year parameter: the chart is FY-owned, so ``account_id`` already\nfixes the year. Posted **and** reversed entries are included (a reversal is a\nsecond posted entry, so both legs must show or the balance is wrong); drafts\nare not. The running balance is carried across pages by the server —\n``page_opening_balance`` enters this page's first row, while\n``closing_balance``/``total_debit``/``total_credit`` describe the whole\nwindow. 404 when the account is not this company's; 422 when ``date_from`` is later\nthan ``date_to``.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"account_id":{"type":"string"},"date_from":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]},"date_to":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]},"limit":{"type":"integer","maximum":200,"minimum":1,"default":100},"offset":{"type":"integer","minimum":0,"default":0}},"required":["company_id","account_id"]},"annotations":null,"definitionHash":"f4e5763e41691ef85c3029da87d4a5c1f67809f2419490f27b8c0c149636febd","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_gl_journal_entry","title":null,"description":"One entry + lines, plus the subledger rows it produced/touched (Gap B detail\nsurfacing): its ``gl_vat_posting`` rows, its ``gl_vat_zero_posting`` turnover-only\ndeclarations (zero-rated/exempt output — R2-13b: these have no VAT line to pair, so\nwithout them a correctly coded 0 % line is indistinguishable from an untagged one)\nand referenced ``gl_open_item`` rows. A declared base line also carries the resolved\ncode on ``lines[].vat_code``. Drafts carry empty lists. ``documents`` carries the\naccounting documents explicitly attached to the entry (``POST …/documents``) — the\nevidence for a hand-booked entry; a pipeline-created entry carries its document\nthrough ``source_ref_*`` instead and lists nothing here. Member read, like the rest of\nthe detail.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"entry_id":{"type":"string"}},"required":["company_id","entry_id"]},"annotations":null,"definitionHash":"cd78262736e67a1a7f5514949ad67f05ee69145d80a16d35b15af35c70c5b1f7","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_intake","title":null,"description":"Get one intake row by id (scoped to its company: 404/403 split).","inputSchema":{"type":"object","properties":{"intake_id":{"type":"string"}},"required":["intake_id"]},"annotations":null,"definitionHash":"1183a6cab4805ca418953497963cd44c5f5230b49e300cd54055e8d1776c5e61","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_item","title":null,"description":"Item metadata (any source).","inputSchema":{"type":"object","properties":{"item_id":{"type":"string"}},"required":["item_id"]},"annotations":null,"definitionHash":"98500bf80e2dced89637f28a507484d7ae6ab17d8f8bdca4487e73c0e6d9976a","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_kpi_report","title":null,"description":"Snapshot KPIs + 13-week liquidity forecast, from the GL (CompanyMember).\n\nCash/liability balances aggregate the FY window of posted/reversed journal lines;\naging + forecast read ``gl_open_item``, pending salary batches and unpaid VAT\nperiods. Read-only. Explicit non-member ``company_id`` → 403.\n\n``fiscal_year`` optional → latest FY with journal data; FY figures as of that\nyear's end once past. Aging and forecast anchor to today.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"fiscal_year":{"anyOf":[{"type":"integer","maximum":2200,"minimum":1900},{"type":"null"}]}},"required":["company_id"]},"annotations":null,"definitionHash":"ce9e2418c983d809806e29781ac2e35a9c79914c9bf4f80a2b53d410a020cc8d","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"get_work_list","title":null,"description":"Everything waiting for this user in this company, most severe first.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"}},"required":["company_id"]},"annotations":null,"definitionHash":"92d7082ec0076e61cd934f3ed5c1050b29c98521af6c56739dccd9bb2a3035d2","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"gl_balance_sheet","title":null,"description":"Assets vs liabilities + equity for one fiscal year, signed by natural side.\n\nWindow rules as the trial balance (``fiscal_year`` defaults to the latest posted\nyear; no all-years mode, ZET-155). With ``period_id`` this is a *movements*\naggregate over that period, not a position.\n\n⚠️ Balances as ``assets == liabilities_and_equity``, NOT ``liabilities + equity``:\nthe GL has no P&L→equity closing entry, so ``equity`` is the equity accounts alone\nand ``net_result`` is folded into ``liabilities_and_equity``. It is a *position*\nonly for a year whose book carries its opening batch; otherwise it is that year's\nmovements and equity is empty.\n\nCut by the stamped ``fiscal_year_id``, not posting date (``fiscal_year_cut``,\nZET-166).","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"period_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"fiscal_year":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["company_id"]},"annotations":null,"definitionHash":"312bc03eaff7c6fe9332c663ba81b9c7a1be2edca3c3775669efadc158ec232c","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"gl_profit_and_loss","title":null,"description":"Revenue − expense → net result, for one fiscal year.\n\n**Window** — same rules as the trial balance: ``fiscal_year`` defaults to the latest\nposted year, ``period_id`` narrows to one period of it, unknown values are 404 and a\ncontradictory pair 422. A P&L is a **flow** statement, so no reading makes the sum\nof every fiscal year a company's result — hence no all-years mode (ZET-155). Opening\nbatches post only to balance-sheet accounts, so they never enter this figure.\n\n**The cut** — by the line's stamped ``fiscal_year_id`` FK, not by posting date; the\nresponse's ``fiscal_year_cut`` says so (see the trial balance; ``null`` only for a\ncompany that has posted nothing, ZET-166). For the full statement — per-account\nsections, the year's own account names, the problems list and the cash flow — use\n``GET /companies/{id}/financial-statements``, which cuts by a posting-date window\ninstead, so the two can disagree for a short/long or shifted fiscal year; this\nroute returns the three totals.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"period_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"fiscal_year":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["company_id"]},"annotations":null,"definitionHash":"201e974ebc10f52aecfda669c77ffc5f2740c7e149930e13babae32ce995cc62","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"gl_trial_balance","title":null,"description":"Per-account debit/credit columns for one fiscal year, with totals.\n\n``fiscal_year`` (year label) defaults to the latest year posted in; ``period_id``\nnarrows to one period of it. No all-years mode — account identity is\n``(company, fiscal year, code)``, so aggregating double-counts silently (ZET-155).\nUnknown year/period → 404; period outside the year → 422.\n\nCut by the line's stamped ``fiscal_year_id``, not its posting date;\n``…/financial-statements`` cuts by posting date inside the same year's stored\nwindow, so the two differ only on a line dated outside the year it is stamped to.\n``fiscal_year_cut`` names the cut (ZET-166).","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"period_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"fiscal_year":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["company_id"]},"annotations":null,"definitionHash":"b98cd44cdbb331fe60a66b77a1f86e463927037815e930ef701ea9b1e15625be","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"global_search","title":null,"description":"Full-text search across emails + items, ranked by ``ts_rank_cd``, scoped (A1).\n\n``archive_status`` constrains item results only (the Documents → Archive page\npasses ``archived`` so its search box never surfaces pending/triage-parked items).","inputSchema":{"type":"object","properties":{"q":{"type":"string","minLength":1},"type":{"anyOf":[{"type":"string","pattern":"^(email|item)$"},{"type":"null"}]},"source":{"anyOf":[{"type":"string","pattern":"^(email|epost|upload|bexio|abacus)$"},{"type":"null"}]},"direction":{"anyOf":[{"type":"string","pattern":"^(payable|receivable)$"},{"type":"null"}]},"archive_status":{"anyOf":[{"type":"string","enum":["pending","archiving","archived","failed"]},{"type":"null"}]},"company_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","maximum":200,"minimum":1,"default":20},"offset":{"type":"integer","minimum":0,"default":0}},"required":["q"]},"annotations":null,"definitionHash":"ea05d60ea20a1bb580bd87aee8197af24b4d0fd5872ca5493f3344003fe96a92","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"},{"serverName":"ch.zeno-works/zeno","endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","name":"issue_ar_invoice","title":null,"description":"Issue a draft — **this is the booking step** (accountant role).\n\nIn one transaction it assigns the next invoice number, posts the journal entry\n(debit the AR control account, credit revenue per line, credit output VAT per VAT\ncode), opens the receivable open item the customer's payment will settle, freezes\nthe invoice against further edits (``status`` → ``issued``) and renders the PDF+QR\nsnapshot. The turnover reaches the VAT return from here — a draft never does.\n\nOnly a **draft** can be issued: re-issuing an issued invoice is a 409. It is also\nrefused when the invoice is not ready (no customer, no lines, a line without a\nrevenue account…) — call ``GET …/ar/invoices/{invoice_id}/readiness`` first, whose\n``blocking`` list is exactly what this refuses on — when the ``issue_date`` is not\ninside an **open** accounting period, or when the fiscal year has no AR control\naccount configured.\n\nReturns the issued invoice (now with ``document_no`` and\n``commercial_document_id``). A renderer outage does not fail the issue: the booking\nstands and the snapshot stays pending, re-rendered on demand by\n``GET …/ar/invoices/{invoice_id}/pdf``. To undo one, reverse its journal entry; there\nis no un-issue.","inputSchema":{"type":"object","properties":{"company_id":{"type":"string"},"invoice_id":{"type":"string"}},"required":["company_id","invoice_id"]},"annotations":null,"definitionHash":"9bf47a54e998233c995009e291ce004beacdb68f72c4262902a2835d05c1ce7b","schemaStatus":"valid","origin":"official-registry","observedAt":"2026-11-02T18:47:01.894Z","metadataTrust":"untrusted"}],"endpoints":[{"endpointFingerprint":"2ee5a78a93b812640f600b5e52ba26b8d4b291c86fedd5530617ea56a14e0a08","protocol":"streamable-http","status":"indexed","toolCount":50,"observedAt":"2026-11-02T18:47:01.894Z"}],"authentication":"unknown"},"connectionConfigurations":{"status":"ready","authentication":"not embedded","clients":{"Claude Desktop":{"mcpServers":{"ch.zeno-works/zeno":{"url":"https://app.zeno-works.ch/mcp"}}},"Cursor":{"mcpServers":{"ch.zeno-works/zeno":{"url":"https://app.zeno-works.ch/mcp"}}},"VS Code":{"servers":{"ch.zeno-works/zeno":{"type":"http","url":"https://app.zeno-works.ch/mcp"}}}}},"resourceType":"mcp-server","callable":true,"runtime":{"callable":true,"protocols":["mcp"]},"interfaces":[{"protocol":"mcp","transport":"streamable-http","url":"https://app.zeno-works.ch/mcp"}],"profile":{"apiVersion":"1","schemaVersion":"1","id":"mcp-server:ch.zeno-works%2Fzeno","resourceType":"mcp-server","canonicalUrl":"https://www.agentsjunction.com/api/v1/servers/ch.zeno-works%2Fzeno","name":"ch.zeno-works/zeno","description":"AI bookkeeper for Swiss small companies: books invoices, reconciles the bank, keeps VAT current.","interfaces":[{"protocol":"mcp","transport":"streamable-http","url":"https://app.zeno-works.ch/mcp"}],"capabilities":[],"identity":{"source":"official-registry","websiteUrl":"https://zeno-works.ch","repositoryUrl":null,"version":"0.1.0"},"verification":{"state":"official","confidence":100},"operations":{"resourceType":"mcp-server","name":"ch.zeno-works/zeno","status":"online","lastCheckedAt":"2026-11-03T20:15:57.560Z","lastSuccessfulCheck":"2026-11-03T20:15:57.560Z","latencyMs":345,"consecutiveFailures":0,"isStale":false,"checks":{"endpointReachable":true,"protocolValid":true,"agentCardValid":null,"mcpHandshakeValid":true},"lastSeen":null,"lastSuccessfulInteraction":null,"lastHealthCheck":"2026-11-03T20:15:57.560Z","source":{"type":"health-check","url":null},"observedAt":"2026-11-03T20:15:57.560Z"},"security":null,"timestamps":{"createdAt":"2026-10-11T18:36:40.726Z","updatedAt":"2026-10-11T18:36:40.726Z","observedAt":"2026-11-03T20:15:57.560Z"},"compatibility":{"serverVersion":"0.1.0","protocolVersions":[{"protocol":"mcp","version":null}]}}}}