ComplyEaze Bridge: TallyPrime MCP server for Claude Desktop
OfficialComplyEaze Bridge is an MCP server that lets Claude Desktop read TallyPrime accounting data, check ledger and voucher existence, verify manual imports, and inspect local audit logs.
List loaded companies and check TallyPrime gateway status.
Read financial statements: trial balance, Profit & Loss, Balance Sheet, outstandings with ageing, ledger movement, and stock summary.
Read registers and masters: sales and purchase registers, voucher types, godowns, units, stock groups, account groups, and ledger masters with compliance data.
Read vouchers in a date window with search/filter and curated metadata.
Validate proposed ledger names against the live book.
Check which proposed vouchers already exist in a window.
Verify manually imported voucher batches and write proof files.
Inspect local evidence: tool-call receipts, recent reads, local data report, and voucher-file schema.
ComplyEaze Bridge: TallyPrime MCP server for Claude Desktop
ComplyEaze Bridge is an open-source (Apache-2.0) MCP server that connects Claude Desktop to the TallyPrime (also written Tally Prime) running on your own computer. It is built for chartered accountants, CA firms and accountants. It reads your books; from a password-protected SBI, HDFC or Union Bank of India statement PDF it proposes Payment, Receipt and Contra vouchers, and once every ledger name is exact and every question is answered it writes them to a file that you import in TallyPrime yourself. What Claude reads from your books goes to your AI provider as part of the chat. You can ask about the trial balance, outstanding receivables and payables with ageing, ledger movement and vouchers, the purchase and sales registers, the stock summary, and the Profit and Loss and Balance Sheet (a book with stock items is expected to be refused for these two). It checks ledger names before you post, and prepares Journal, Payment, Receipt and Contra vouchers as an import file that you review and import into TallyPrime yourself. Posting is off by default in a new install, so as installed it never posts to TallyPrime: it reads from it and prepares files on your computer. If you turn posting on in the extension, it posts one voucher at a time, or a saved batch of up to 50, after you approve each post.
Tally Solutions also offers its own TallyPrime MCP plug-in for Claude Desktop; its help pages (last updated 18 September 2026) list tools in six groups: company, master, accounting, inventory, outstanding and transaction. ComplyEaze Bridge is not made by, or affiliated with, Tally Solutions, and we have not run the two side by side. TallyPrime also has its own Bank Statement import, which takes statement files in the formats Tally lists for each bank.
Current release: mcp-v0.6.0 (16 October 2026),
for Windows x64 and Apple Silicon Macs, as a Claude Desktop extension (an .mcpb
file); it has not been run in other MCP clients. We check each release before
we publish it: the release check confirms that each package launches, lists its
tools and parses a synthetic encrypted bank statement. It does not run against
TallyPrime, and nothing we can run covers every
Tally edition, set of books or setting. What has been run against a real
TallyPrime, and what has not, is listed below.
Install it · What changed ·
Security and privacy ·
How to connect Claude to TallyPrime ·
How to choose a TallyPrime MCP server safely
Not yet code-signed; your computer may warn you before opening it.
Try asking (on a test company first):
"List the loaded companies."
"Show the outstanding receivables and payables, with ageing, as of 31 March."
"Show the trial balance for 1 April to 31 March."
"Check these ledger names against the book before I post: …"
Its tools. In name order; release 0.6.0 installs 28 of them, none of which changes your TallyPrime books; with posting on, two more appear, described below the table. Every call adds a receipt line, with no figures, to a log on this computer.
Tool | What it gives you | What it writes besides that receipt |
| The Balance Sheet for a date range, by primary group, from TallyPrime’s Trial Balance (a book with stock items is expected to be refused) | Nothing |
| Checks a Journal, Payment, Receipt or Contra batch and writes an import file | An import file and a ledger record on this computer |
| Tally’s own Cash Flow for whole months: the month-wise movement of the cash and bank ledgers, returned only after its net total matches the trial balance; the split into months is Tally’s own and is not checked (not a cash flow statement under AS 3) | Nothing |
| Three settings the company’s record in Tally holds today (cost centres, GST and batch-wise stock; each yes, no or not reported) and the currency symbol; no ledger, voucher, amount or narration. Each of the three settings equalled Tally’s F11 screen on three synthetic books, not on this company; a setting changed inside a sitting has not been measured | Nothing |
| The receipts ComplyEaze Bridge keeps of its own tool calls, with no figures | Nothing |
| Tally’s own GSTR-1 status flags on the vouchers of one voucher type in a period of at most 93 days: for each voucher its number, date, a status (included, uncertain, excluded, not in return, cancelled, optional or post-dated; for the last three also what the three status flags read) and whether a person accepted it as it stands; no amount, party, ledger or narration. A status is Tally’s own flag and not a judgement of ComplyEaze Bridge. Measured on one synthetic book of TallyPrime 7.1 Silver, where | Nothing |
| Ledgers with their opening balances; optionally GSTIN, PAN and other party details | Nothing |
| A ledger’s opening, debits, credits and closing for a period | Nothing |
| The companies loaded in TallyPrime (start here) | Nothing |
| What ComplyEaze Bridge keeps on this computer | Nothing |
| Voucher types, godowns, units, stock groups, cost centres, cost categories or account groups | Nothing |
| Tally’s own month-wise Sales Register or Purchase Register for whole months: one row per month with Tally’s debit, credit and closing columns exactly as printed; not tied to the vouchers or the trial balance, and not compared with Tally’s register screen | Nothing |
| Receivables and payables with ageing, the top parties and the open bills | Nothing |
| Reads a password-protected SBI, HDFC or Union Bank of India statement PDF and proposes Payment, Receipt and Contra vouchers | A private proposals file on this computer |
| The Profit and Loss for a date range, by primary group (a book with stock items is expected to be refused) | Nothing |
| Purchase and Debit Note vouchers that touch a ledger under Duties & Taxes, as the books record them (not a GST return) | Nothing |
| ComplyEaze Bridge’s own recent reads, as fingerprints, with no figures | Nothing |
| Sales and Credit Note vouchers that touch a ledger under Duties & Taxes, as the books record them (not a GST return) | Nothing |
| Whether the bank ledger stands where a parsed bank statement says it stood at the start and at the end of the statement's dates, or of whole calendar months of it: three gaps and the dates; the balances themselves are not returned | Nothing |
| The closing stock value of each item as of a 31 March, and its closing quantity where Tally's own Stock Summary shows the item on a line of its own; an item inside a stock group returns no quantity; small books only (a book with many masters of any kind is refused, and so is any other date); only the year ending 31 March 2026 has been checked | Nothing |
| Whether TallyPrime’s gateway answers, and which companies are loaded | Nothing |
| The ledger-wise Trial Balance for a date range | Nothing |
| Checks ledger names against the live book before you build an import file | Nothing |
| Reads back a batch you imported by hand in TallyPrime | Proof files and status records on this computer |
| Which proposed vouchers are already in the book | Nothing |
| Before a call to | Nothing |
| The voucher-file format, without asking TallyPrime | Nothing |
| The vouchers in a period. Search by voucher number, reference, narration or amount, and summaries by ledger, month, voucher type, group or primary group, are in release 0.5.0 and not in 0.4.2 (search and the first three summaries checked once, and the group and primary-group summaries in a second run, on a synthetic book of 67 vouchers; not checked on a large book) | Nothing |
With posting turned on in the extension, two more appear: post_import posts one saved voucher, or a saved batch of 2 to 50,
after you approve it in a ComplyEaze Bridge window (for a batch, its summary), and acknowledge_post_review asks you, in its own window, to record that you reviewed a posted voucher
whose ledger now points to a different master.
How it handles your books
Local connection only. It talks to Tally's own XML gateway on a loopback address, so it cannot be pointed at a remote Tally host. It cannot tell whether that local port is forwarded to another machine; do not forward one across the internet. The Tally connection sends nothing to a ComplyEaze server.
Your AI provider sees what the assistant reads, just as it sees the rest of the conversation, including company, party and ledger names, amounts, dates, narrations, references, GSTINs and, when it reads ledger details, PAN, bank account numbers, IFSC, MSME or Udyam registration numbers, email, phone and address, and, when it builds a voucher file, that file's local path (which can include your computer user name). The setting takes one value, not both: shorten party and ledger names and bank account numbers to their first two and last two characters (four or fewer become “…”), or drop narrations. Neither hides amounts, company names, PAN, GSTIN, IFSC, MSME or Udyam registration numbers, contact details or references, or the last four digits of a bank statement's account number, and a shortened name can still be identified, not least from the GSTIN or PAN sent beside it. See Before you use it with client data below.
Posting is off by default in the extension. Note that this is a new setting: if you turned posting on in an earlier version, turn it on again. When you turn posting on, each post waits for your approval in a separate ComplyEaze Bridge window (for a batch, its summary). No Bridge tool lets the assistant approve it, and an approval counts only when that window returns a fresh one-time token. After posting, the voucher is read back from Tally so you can see what landed. Four known limits remain: ComplyEaze Bridge cannot undo a posted voucher (you correct it in Tally); a company renamed to, or loaded under, the target company's name (or one differing only in case or spacing) just after its last check could still receive the voucher, if it has the voucher's ledgers, and ComplyEaze Bridge cannot always say where it went or prevent it; a ledger renamed and replaced in that same moment could receive the entry, and not every such change is noticed; and the approval window covers only ComplyEaze Bridge, so another Tally connector in the same Claude Desktop that can change entries can do so without it. Read Before you turn on posting first.
Tool calls leave receipts in a log on your computer: the company's Tally identifier, and a fingerprint of what was asked and of what came back, written whether the call succeeds or is refused.
You accept the Terms of Use first. The extension asks you to accept the ComplyEaze Bridge Terms of Use (version 2026-10.1) in its settings, and every tool refuses with
terms_not_accepteduntil you do. (In 0.5.0, after an update from 0.4.2, Claude Desktop may not start the extension: on a Mac with an error that does not mention the Terms, on one Windows computer with no error; #1413.)Open source under Apache-2.0.
Related MCP server: Tally Prime MCP Server
What has been run against a real TallyPrime
Each line below is recorded in the repository or on the linked issue or pull request, unless marked as reported by the owner. Each ran on licensed TallyPrime Silver 7.1 and synthetic companies unless stated. The MCP guide and ADR 0004 hold the full record.
Reads: 27 checks on an unpublished macOS arm64 build (PR #228), recorded in the 6 September 2026 assessment. Some later reads were also run live on development builds, for example the trial balance on a debug build with synthetic companies (#246, whose record does not name the Tally release or licence tier). Not every read has its own recorded live run.
Posting one Journal, on a development build from 22 September 2026 (issue #579), and a Payment, a Contra and two Receipts (one of three entries) with the approval dialog on macOS (PR #600), each read back as posted. These builds predate the release published on 26 September 2026 (version 0.3.0).
Native posts of ten batches on licensed TallyPrime Gold 7.1, in one session on 28 September 2026, on a development build and one client book (the import request was captured for nine of them); their approval step was not recorded (protocol reference).
The published 0.3.0 package on Windows x64, in Claude Desktop (with no paid plan; we make no claim about other plans): reads only, against licensed TallyPrime Gold 7.1 with one client book, on 28 September 2026, in a session separate from the development-build posting above (reported by the owner; no logs were kept).
A candidate build of 0.4.0 on Windows 11, on 1 October 2026 (the build CI produced for the version pull request: the same code as the release apart from a comment in one test file). The maintainer installed it in Claude Desktop with a new Claude account that has no paid plan, against licensed TallyPrime Silver 7.1 holding one synthetic company. With the Terms setting off, a call was refused and nothing was read. With it on,
tally_status,vouchers,validate_masters,purchase_register,stock_summaryandlocal_data_reportanswered. One voucher post was declined in the Windows approval window and nothing was sent; one was approved, and one Journal was posted and then verified byverify_import. The same candidate's macOS build was started and read the company list, and in Claude Desktop on macOS its tools loaded in a chat. This was one run, not a controlled test of each key of the window.A build of 0.4.1 on a Mac, on 2 October 2026. What was run: the package CI built for the version pull request, not the published file. The maintainer installed it in Claude Desktop over an installed 0.4.0, as an upgrade; the Terms setting and the other settings carried over, and the extension's server process started again on its own after the upgrade (its start time was read from the process list).
tally_statusandlist_companiesthen answered against licensed TallyPrime Silver 7.1 holding the lab's own synthetic companies. What was not run: the published file is built again on another runner, and its program file differs from the one tested. We ran both builds without Tally: each reports version 0.4.1, lists 21 tools and gives the same answer totally_status. We have not installed the published file in Claude Desktop.A build of 0.4.2 on a Mac, on 3 October 2026. What was run: the package CI built for the release candidate, not the published file. The maintainer installed it in Claude Desktop on a Mac that had 0.4.1: it did not replace 0.4.1 but installed as a second extension (the author line changed in 0.4.2, and Claude Desktop builds an extension's identity partly from it); the settings did not carry over.
tally_statusandlist_companiesthen answered against licensed TallyPrime Silver 7.1 holding the lab's own companies. What was not run: the published file is built again on another runner, and its program file differs from the one tested. We ran the published Mac file without Tally: it reports version 0.4.2, lists 22 tools with posting off (24 with it on), and refuses a call with the Terms setting off. We have not installed the published file in Claude Desktop, and nobody on our side has installed the Windows package in Claude Desktop on a Windows PC.A build of 0.5.0 on a Mac, on 8 October 2026. What was run: the package CI built in the merge queue for the version pull request, not the published file. The maintainer installed it in Claude Desktop over an installed 0.4.2: it replaced 0.4.2 as an update, with the Tally port, Response redaction and the posting setting as they were; the old Terms setting was gone and the new one had no value. Before the box was ticked, and before any quit, Claude Desktop did not start the extension, and a request failed with a 400 error that did not mention the Terms. After it was ticked and saved the extension started at once and
tally_statusanswered, though the assistant first called a leftover second entry for the same extension, which failed the same way; after Claude Desktop was quit and reopened there was one connector and the company list was returned. What was not run: the published file, quitting and reopening without ticking the box, installing over a release older than 0.4.2, a fresh install, and Windows.A package for 0.5.1 on a Mac, on 8 October 2026. What was run: a package built on that Mac from the Terms-setting change (#1436), with only its version set to 0.5.1; not a published file and not the CI package. The contributor installed it in Claude Desktop 2.26454.2 on macOS 26.6.2 with Tally not running and posting off: as a fresh install; over 0.4.2 (switched on with its Terms accepted; left off and then switched on); over 0.5.0 as an update leaves it and with the Terms ticked; and after 0.4.2 was removed. Claude Desktop started the program as soon as the extension was switched on each time, except once, over a 0.4.2 left switched off, where the assistant had no ComplyEaze Bridge tools until Claude Desktop was quit and reopened. With the Terms off, the call was refused and named the Terms; with them ticked, it reached the Tally check and reported Tally unreachable. A user-level
BRIDGE_TERMS_ACCEPTEDset to true did not change that: the program's own value stayed false. The record is on #1436. What was not run: a read of a live Tally with it, the published file, and Windows.Builds of 0.5.1 on a Windows computer, on 9 October 2026, India time (#1413). One Windows 10 computer (22H2), Claude Desktop 2.26454.2 from the Microsoft Store, TallyPrime Release 7.1 Silver, a company made for the test. What was run: the CI build of commit
d744d25a(an earlier commit than the published file; later commits reworded some tool texts and the notes): a fresh install; an update from 0.4.2 and from 0.5.0 (as an update leaves it, and with the Terms ticked); a user-levelBRIDGE_TERMS_ACCEPTEDset to true; the company list; one bank-statement import file of six vouchers, built under 0.5.0 and under this build and compared, and this build's file imported by hand and read back (the verification found all six, the narrations were read back, and an August trial balance agreed with Tally's own screen; a first build under 0.5.0 into the company, which then held ledgers but no voucher, was refused asempty_book_first_import, so one more ledger and one 1 April voucher were imported into Tally outside ComplyEaze Bridge first, and that voucher is in the trial balance); an unchanged re-import of that file (matched to the six vouchers, none added); and a switched-off extension through two updates (it stayed off, with no tool and no error in the chat; switching it on was enough). Then steps 1 and 2 again on the CI build of the merged commitb91038a9, and step 1 on the published 0.5.1 file (checked against its.sha256file and its build attestation), with Tally closed. The published 0.5.0 file over 0.4.2 was not started on this computer: the chat had no ComplyEaze Bridge tool and showed no error. What was not run: a changed re-import, steps 2 to 11 on the published file, posting, and other Windows versions, Tally editions or Claude Desktop builds. The record is the contributor's reports on #1413.Builds of 0.6.0 on a Windows computer, on 16 October 2026 (#1148). One Windows 10 Home 22H2 computer, Claude Desktop 2.37337.1.0 from the Microsoft Store, TallyPrime 7.1 Silver on port 9001, one new synthetic company. What was run: the CI package of the release pull request (commit
a3b7316947cdf3c5ce46615c8b89e45d538345f3,bridge-tally.mcpbSHA-2566b83ca74377d7ed86a2b524f4d53bd2e9753b3318bfa6634078d5f5645184022,bridge_mcp.exeSHA-256e9780806594e60afabdb83d35bb751f0aeefba708b2b63c33b11452bbf0e5a84) with the one posting setting on: a Journal, a Receipt, a Contra and a Payment posted once each with no voucher number, and one batch of three (a Payment, a Receipt and a Contra) posted after one approval. Every post created what it sent, and every voucher readposted_verifiedin the post's own readback and again inverify_import. The approval window showed in front of a full-screen Tally and of Claude Desktop (one screen, one run), with No as the default, and took keyboard focus (a Down arrow meant for Tally moved the selection inside the window; Enter alone refuses, arrow keys then Enter can reach Yes; a typed letter was not tried). Then a package built by the release workflow's own steps (rehearsal run 38885882661,bridge_mcp.exeSHA-25610e4614f74eab975897834ec1c9750edbe9fc7ad91584b802e5cde57a8180899) was installed over it, kept its port and posting settings (the same version, not an upgrade), and posted one more Journal the same way. The published file (bridge-tally-mcp-v0.6.0-windows-x64.mcpbSHA-2567bf81f08e058fc7ae00ccc51b3dceec10dc50d45dca8477a0438fd9b5a2852ca,bridge_mcp.exeSHA-2561e41e039fbf3daaf6be5a3c8e2f5e0bd1245a745abc5e78349fd83ce678224c1) is neither of those: its exe differs from the rehearsal's in 77 of 26,503,168 bytes, and we have not run it against a live TallyPrime. What was not run, among others: a batch of Journals, a batch of more than 3, a refused or partly landed post, amendments, the review window, an On Account approval, the retired batch variable, the voucher-numbering rows (#724, #1668),voucher_read_costagainst a realvoucherscall, the Store-install proof of the lock (#1584, #1459), a second monitor, the batchheadlineon a live post, the Import menu, the desktop app, Sales invoice posting (not offered in 0.6.0), Gold, macOS, other Windows or Tally releases, and an upgrade from 0.5.1. The record of the pass is in the 0.6.0 entry of the changelog; the comparison with the published file was made from the release assets after the release.The bank-statement path through its fourth step, on a Mac, on 4 and 5 October 2026, with that same CI-built 0.4.2 candidate (installed on 3 October; not the published file), against licensed TallyPrime Silver 7.1 holding the lab's own synthetic companies. The synthetic HDFC-format statement parsed (six rows, its totals matched the figures supplied); the name check found no "Suspense" ledger and building the file was refused, with no file written; after "Suspense" was created in Tally by a separate one-ledger import, outside this tool, a file of six vouchers was built. We have not imported that file or read it back, and no real statement has been run.
Not yet run by us in a controlled test: posting with a published package
against a live TallyPrime; each way of declining in the Windows approval window
(one was tried); the tools answering through Claude Desktop on macOS after the
Terms are accepted (tally_status and list_companies answered on a CI build
of 0.4.1, again on a CI build of 0.4.2 and on one Mac on a CI build of 0.5.0); posting on TallyPrime Education; posting on TallyPrime Gold
with its approval step recorded. Each release package is built and launched,
its tool list checked and a synthetic encrypted bank statement parsed, on
hosted CI runners for Windows x64 and Apple Silicon Mac.
Not in the latest release
Stock quantities of items inside a stock group, and stock reads on books with many masters of any kind; sales, purchase or tax posting; creating masters; bill-wise allocation
TallyPrime Education mode: the trial balance, Profit and Loss, Balance Sheet, the stock summary and the
mastersread are refused; so is a read of vouchers, ledger movement, either register or another date-window read whose window starts or ends on a day other than the 1st, 2nd or 31st; so is an import file or a post with a voucher dated on any other day (posting on Education has not been run)The stock summary on a book with inventory turned off, or on a company split by year when a sibling year's company is loaded at the same time
Deleting or undoing a posted voucher (correct it in Tally)
Reads on very large books can fail or take longer than the assistant waits (#485, #703)
A base currency other than INR. On a book with several currencies: the foreign-currency ledgers and vouchers themselves (they are set aside or withheld, and named), ledger movement, Profit and Loss and Balance Sheet, the purchase and sales registers (each refuses the whole read, with no rows, if one voucher in it names a set-aside ledger), and posting
Tally Cloud Access or any remote Tally host
Intel Macs, and a code-signed installer
Is this for you
It is aimed at a practising accountant or a CA firm that already keeps client books in TallyPrime and wants to ask questions of them, or post entries into them, through an AI assistant such as Claude Desktop.
What it does today
Reads the loaded companies, ledger masters, trial balance, vouchers in a date window, outstanding receivables and payables, and ledger movement.
Checks ledger names before you post. Give it the names from a bank statement or an invoice and it reports which exist in the book and which are near-misses needing your decision. Reading the ledger list first is the single biggest cause of an import being rejected wholesale when it is skipped.
Records what it did. Every tool call Bridge runs — read or write, and whether it succeeds or is refused — appends a receipt to a log on your own machine, identifying the company it touched and fingerprinting what was asked and what came back. Reads keep those fingerprints as evidence alongside. A prepared batch records the local endpoint it was built for, and a native posting is refused if that endpoint has changed since; that is a safety check kept in Bridge's internal import ledger, not a line in the proof report a reviewer opens. A reviewer can read the log rather than take a summary on trust.
Before you turn on posting
Whether writing is on depends on how you installed it. Everything above is reading. When writing is off, the write tools do not merely refuse — they are absent from the tool list entirely, so an assistant cannot see that they exist.
The Claude Desktop extension turns voucher posting off by default. Four known limits in posting remain. Tally aims an import at a company by its name and cannot bind it to a company's GUID. Bridge's last request before the post checks that exactly one loaded company has the target's GUID and name, and that no other loaded company has the same name ignoring case and spacing; otherwise it refuses the post (#607). A company renamed to, or loaded under, the target's name (or one differing only in case or spacing) in the moment after that check could still receive the voucher, if it has the voucher's ledgers. Bridge may flag afterwards that the loaded companies changed, but cannot always say where the voucher went, and cannot prevent it (accepted residual, #574). A ledger renamed and replaced in that same moment means the post can land in the replacement ledger. Bridge marks the result as needing reconciliation when it sees that the ledger now resolves to a different master; a change that leaves the company's master mark unmoved, or is reverted before that check, is not seen, and a regroup in that moment is not detected (#623). And Bridge has no tool to delete or undo a voucher it has posted, so a wrong post must be corrected by hand in Tally. It records the REMOTEID each post sends, but no delete tool exists yet (#579, #582). And the approval window covers only ComplyEaze Bridge: another Tally connector in the same Claude Desktop that can change entries can do so without it. Turning on Allow voucher posting, one voucher or a batch of up to 50 in the extension settings adds
post_import, which posts one saved voucher of those types, or a saved batch of 2 to 50 Journals, or of 2 to 50 Payments, Receipts and Contras; every posting still waits for your approval in a separate Bridge dialog (for a batch, its summary). For a batch there are two more limits: if Tally creates only some vouchers of a batch, Bridge reports which ones it finds in the book and which it does not, and refuses to post the missing ones again (a voucher it does not find may still be in Tally, edited: check each in Tally and do not re-enter it before you check); and a batch of more than 50, or one whose summary does not fit the window, is refused. Leave the setting off unless you accept those risks. Voucher file preparation and bank-statement parsing, which write nothing to Tally, stay available with the setting off. This is a new setting: if you turned posting on in an earlier version, turn it on again.A source build turns writing off by default. Preparing a file needs
BRIDGE_AGENT_ENABLE_IMPORT; posting additionally needsBRIDGE_AGENT_ENABLE_WRITES, which grants both and covers one voucher and a saved batch of 2 to 50.BRIDGE_AGENT_ENABLE_BATCH_POSTis retired: while posting is on and it is still set,post_importrefuses assetting_retired; remove it.A source build also needs
BRIDGE_TERMS_ACCEPTED=true. The extension asks for that as its "I accept" setting; without it every tool refuses.
With writing on:
Prepares vouchers as a local file — Journal, Payment, Receipt and Contra. Bridge writes the file; it does not send it.
Posts one saved Journal, Payment, Receipt or Contra per approval, or a saved batch of 2 to 50 after one approval of its summary, and only after you approve that exact voucher (or that batch's summary) in a dialog on your own machine. The assistant cannot approve it. Bridge then reads the voucher back so you can see what actually landed. You can also import a prepared file through Tally yourself;
verify_importthen reads that back.Posting has limits. It creates no masters, posts no sales, purchase, tax or inventory entries, and never alters or deletes a voucher. A company with more than one currency defined is refused.
A bank line is posted at most once. Bridge sends each bank-statement line to a company at most once from this computer, and will not send it again as a new voucher, even if the post failed, the reply was lost, or the voucher was later changed or deleted in Tally. If Tally does not hold it, enter it in Tally yourself; do not edit the statement to get it past Bridge. It cannot see a post made from another computer or after a reinstall, a hand-typed entry that differs in date, type, ledgers or amount, the same statement downloaded from another place when the posted voucher was since changed, or a hand import of the file Bridge saved. The full rule and its six limits are in the agent guide.
What it does not do
The Tally path uploads nothing to ComplyEaze. Bridge reads it over a local connection and hands it to the assistant you are talking to; nothing in the Tally path sends it to a server of ours.
It will not post anything without a separate, explicit step after the file is prepared.
It is not a Tally replacement, a reporting suite, or a filing tool.
The desktop app
The extension is built from the same source library as the desktop app. Packages up to 0.3.0 contained an unfinished document-upload feature and an AXAL sign-in, which no tool of the extension reached. That code was removed (#914) and releases from 0.4.0 on do not contain it; the only network client in ComplyEaze Bridge's own code connects to Tally on your own computer. No desktop installer is published. See Security and privacy.
Before you use it with client data
One thing to understand before you use it. When you ask an AI assistant for
financial data through Bridge, the assistant's provider sees what it reads,
including company, party and ledger names, amounts, dates, narrations,
references, GSTINs and, when it reads ledger details, PAN, bank account numbers,
IFSC, MSME or Udyam registration numbers, email, phone and address, and, when it
builds a voucher file, that file's local path (which can include your computer
user name). That is a property of using a hosted assistant, not of Bridge.
ComplyEaze Bridge can, before sending, shorten party and ledger names and bank
account numbers to their first two and last two characters (four or fewer become
“…”), or drop narrations (BRIDGE_AGENT_REDACTION takes one value, not both).
Neither hides amounts, company names, PAN, GSTIN, IFSC, MSME or Udyam
registration numbers, contact details or references, or the last four digits of
a bank statement's account number, and a shortened name can still be identified, not least from the GSTIN or PAN sent beside it — figures
always go with the answer. Decide this deliberately for client data.
What it costs
ComplyEaze has not set a price for ComplyEaze Bridge and does not sell licences to it; there is no account with us, subscription or licence key. The code of a release you download stays under the licence it was published with (Apache-2.0 for current releases). We have not decided whether to charge for anything in future.
What you pay or provide today:
TallyPrime: your own licence.
Claude Desktop: Anthropic's plans. On 1 October 2026 we ran a candidate build of 0.4.0 (not the published file) on Windows with a Claude account that had no paid plan, on one synthetic company; we make no claim about other plans or larger books.
Your clients' data: what Claude reads goes to Anthropic, under Anthropic's terms for your plan; through ComplyEaze Bridge, ComplyEaze does not receive it (Privacy Policy, sections 4 to 6).
Your checking: check results in Tally before you rely on them.
Support and updates are not guaranteed (Terms of Use, section 4.4). Our liability is limited as section 14 sets out, including its fallback and exceptions; read it before client work.
Installing it
Before you install, turn on Tally's HTTP gateway. TallyPrime does not
listen for ComplyEaze Bridge by default. In Tally's own connectivity / client-server
configuration settings, set Tally to act as a server ("acts as Both" in
Tally's own words) and note its HTTP gateway port — 9000 by default, but
configurable. To check it is actually on, open http://localhost:9000/status
(substitute your port) in a browser: a running gateway answers with a short
Tally XML response, and a browser that cannot connect means the gateway is
still off — unless Tally is running in a Windows virtual machine on a Mac,
in which case run this check inside that VM, or only once your local
forwarding is working. A Mac browser that cannot connect may mean the
forwarding described below is missing rather than that the gateway is off.
If instead it hangs without answering, Tally may simply be busy behind
another request — wait and retry rather than changing the setting.
The latest published release of the Claude Desktop extension is the one to install. Follow the installation guide to install and configure it. Before you do, know what it is and is not:
Bridge is still being developed. A release may contain errors, so try it on test data first and keep current backups. It is not yet code-signed or notarized, so your operating system may warn before opening it. Each package has a
.sha256file and a provenance record so you can confirm exactly which bytes and which source commit you downloaded.Checked only as far as launching. The release build confirms the package starts and lists its tools. It does not establish that it works against your Tally, or in conversation inside Claude Desktop. What has been run against a real TallyPrime, and on which builds, is listed above; the published 0.6.0 package itself has not been run by us against a live TallyPrime; two other builds of 0.6.0, made by our checks from the same source, were run against TallyPrime 7.1 Silver on one Windows computer (see the 16 October 2026 entry above).
Windows x64 and Apple Silicon Macs only. Intel Macs are not supported.
On a Mac, Tally must run on that same Mac, in a local Windows virtual machine or through approved local forwarding. Bridge only talks to Tally on your own computer, so a separate PC or a Tally elsewhere on your network cannot be reached by typing its address.
It does not update itself. To upgrade, install a newer release from Claude Desktop's Extensions settings and keep the data folder. Release 0.4.2 installed beside an older release instead of replacing it (seen on a Mac; not tried on Windows). A build of 0.5.0 made by our checks (not the published file) replaced 0.4.2 on one Mac and kept its Tally port, Response redaction and posting setting: there, tick the new Terms setting, check the posting setting, then quit and reopen Claude Desktop. Installing over a release older than 0.4.2 was not tried: remove it first. If Settings, Extensions lists two ComplyEaze Bridge entries (as happened when 0.4.2 was installed beside an older release), remove the older entry before you use either, enter your settings in the new one, including Response redaction, which starts at none, tick the new Terms setting, and quit and reopen Claude Desktop.
The Bridge desktop application is a separate program and has no published installer; building it from source is described under Contributor quick start below.
The rest of this file is for people working on Bridge. The repository is self-contained: build and development commands resolve files relative to the clone, not to a developer-specific directory. It holds a Tauri desktop application and the MCPB packaging path for Claude Desktop, with React/TypeScript and Rust components for Tally and local database operations.
First useful result
Install the latest published release of the Claude Desktop extension with the installation guide. For source use, the contributor quick start below builds the desktop app; to run the MCP server from source, follow the source MCP setup.
Before requesting financial data through an MCP client, the client may send the
selected Tally result to its AI provider, including company identity, party or
open-bill details, amounts, dates, narrations, references, GSTINs and, when it
reads ledger details, PAN, bank account numbers, IFSC, MSME or Udyam
registration numbers, email, phone and address, and, when it builds a voucher
file, that file's local path (which can include your computer user name). Source
installations default to BRIDGE_AGENT_REDACTION=none; set it to mask_parties
or drop_narration (one value, not both) before launch when that better fits
the workflow. These settings shorten party and ledger names and bank account
numbers or drop narrations; they do not hide amounts, company names, PAN, GSTIN,
IFSC, MSME or Udyam registration numbers, contact details or references, or the
last four digits of a bank statement's account number. The package installation
settings expose the same choices.
For a first result, run tally_status to check that TallyPrime and its Licensed
or Education mode are observed, then list the loaded companies. Select a
company with exactly one observed INR currency master and request receivables
or payables. In Education mode, explicitly supply an as_of date on day 1, 2,
or 31; an omitted date defaults to today and may be refused. Bridge rechecks
product, mode, dates and currency for the financial read; other or unobserved
products/modes, no currency master, non-INR, or multiple currency masters are
refused.
The desktop also offers local XML draft preparation through Prepare file. It preserves source observations beside editable proposals and saves a local draft for later review.
For contributors, use the setup and development path below.
Supported development hosts
Bridge is intended to build and run on Windows and macOS 12.4 or later. Run platform checks on a native host for each operating system; a successful build on one operating system does not verify the other.
Shared prerequisites:
Node.js 24 (>=24.15.0) and Corepack (
.node-versionpins the CI baseline)the Rust toolchain pinned by
rust-toolchain.tomlPerl 5 with
Locale::Maketext::Simplefor the bundled SQLCipher/OpenSSL buildLLVM/libclang for SQLCipher binding generation (
LIBCLANG_PATHmay be required)the operating-system dependencies listed in the Tauri prerequisites
On Windows, install the Microsoft C++ build tools, WebView2 components, and a
complete Perl distribution such as Strawberry Perl. If another incomplete
perl.exe appears first on PATH, set OPENSSL_SRC_PERL to the complete Perl
executable. Install LLVM as well; if libclang.dll is not discoverable, set
LIBCLANG_PATH to its directory (commonly C:\Program Files\LLVM\bin). On
macOS, install Xcode Command Line Tools. Bridge's macOS bundles require macOS
12.4 or later.
Contributor quick start
Run these commands from the repository root in PowerShell, Command Prompt, or a POSIX-compatible shell:
corepack pnpm install --frozen-lockfile
corepack pnpm exec playwright install chromium webkit
corepack pnpm test
corepack pnpm run build
corepack pnpm run cargo:check
corepack pnpm run tauri:devpnpm test includes Chromium and WebKit evidence-drawer focus suites; installing
the lock-pinned browsers after dependencies is therefore required once for each
developer environment. tauri:dev starts the Vite development server and
desktop application. It does not require a fixed checkout location. The first
Rust build can take several minutes.
For a release build, run corepack pnpm run tauri:build on each target host.
CI-produced bundles are unsigned smoke artifacts only. Do not redistribute a
desktop installer until the signing, notarization, provenance, and rollback
gates in the release runbook are complete.
Platform verification
Before claiming support for a platform, run the following on that platform:
corepack pnpm install --frozen-lockfile
corepack pnpm run build
corepack pnpm run cargo:check
corepack pnpm run tauri:buildAlso manually exercise the affected Tally workflows. Vendor integrations may require host-specific software even though repository paths and project commands are portable.
Integration trust boundaries
Bridge restricts native network and file access even if the renderer is compromised:
Tally connections are loopback-only (
localhost,127.0.0.0/8, or::1). Remote plaintext Tally hosts are intentionally rejected.Showing an export in the file manager accepts only a file ComplyEaze Bridge exported since it started; any other path the renderer sends is refused before anything is launched.
Privacy and safe diagnostics
Do not commit or attach real customer, company, tax, certificate, credential, financial, or document data. Before sharing logs, screenshots, fixtures, or reproduction steps, replace personal and customer data with synthetic values and remove local usernames and absolute paths. See SECURITY.md for private reporting and handling requirements.
Repository map
src/- React UI and API bindingssrc-tauri/- Rust core and Tauri configurationdocs/- architecture, roadmap, and operational guidance.github/- issue and pull-request templates plus CI configuration
Governance
License
Bridge is licensed under the Apache License, Version 2.0.
Attribution notices are provided in NOTICE.
The ComplyEaze logo and icon files are not licensed under Apache-2.0; see
NOTICE and TRADEMARKS.md.
The historical v0.1.0 release remains under the MIT license shipped with
that tag; current development source is version 0.6.0 under Apache-2.0.
Available Tools
26 toolsbalance_sheetARead-only
Return the Balance Sheet for a date range, derived from Tally's native Trial Balance: one line per reserved Balance Sheet primary group (Capital Account, Loans (Liability), Current Liabilities, Suspense A/c, Branch / Divisions, Fixed Assets, Investments, Current Assets, Misc. Expenses (ASSET)), each the signed closing balance at to (a debit negative), and result.profit_and_loss: the Profit & Loss A/c ledger's closing and the carried result (that closing plus every P&L ledger's closing; in a part-year window the year's earlier result sits in that ledger). The top-level lines is null while carried is not established, so a derived line is never shown as the statement. Reads the Trial Balance, the group tree and Tally's own Balance Sheet inside one company, mode and book-extent bracket; requires observed INR currency (a book with more than one currency master is refused) and supported date boundaries. Each line reports amount (sum, present_count, empty_count): the sum is over the amounts Tally returned, and the empty ones it left out are counted. A result is established only if every ledger is classified (a ledger under a user-created primary group, or whose group chain is incomplete, is listed in unclassified, up to 100, with unclassified_total), no Stock-in-Hand ledger carries an amount, and Tally's own Balance Sheet for the window ties line for line to the derived one (balance_sheet_gate). Otherwise it is not_established with a reason (unclassified_ledger_carries_an_amount, closing_stock_not_derivable_from_trial_balance, profit_and_loss_ledger_not_returned, tally_balance_sheet_differs, or for gross and net tally_profit_and_loss_differs); for the two differs reasons, lines names the lines that did not tie. The top-level state is observed only while carried is established, and not_established otherwise with the same reason the nested result carries. A book with stock items is expected to refuse; no inventory book has been measured. A Tally line with an amount the derivation has no counterpart for, such as a heading or a difference in opening balances, refuses rather than being guessed at. Tally's own statements carry no company identity and are bound only by the checks around the read. The gate has been measured over one full year on one book and one month on another; a window spanning more than one financial year is unmeasured. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/destructiveHint annotations, it discloses the gate logic (`balance_sheet_gate`), the full `not_established` reason set, the unclassified-ledger cap and total, the null-`lines`-until-`carried` rule, and the fact that each call appends receipt lines to a local log while writing nothing to Tally. This is unusually rich behavioral disclosure that an agent could not infer from annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is correctly front-loaded, but the body is a single dense paragraph of long sentences mixing derivation rules, gate semantics, refusal reasons, and receipt logging. Much of it is necessary given no output schema, yet the wall-of-text structure hurts scanability and some clauses could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full burden of return-value explanation and does so thoroughly: `lines`, `state`, `result.profit_and_loss`, `carried`, `unclassified`, and the `reason` enumerations. An agent has enough to interpret both success and refusal outcomes correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, which sets the baseline at 3. The description adds a little semantic value (the signed closing-balance-at-`to` convention with debit negative, and the notion of a book-extent bracket), but it does not meaningfully extend what the schema already documents for `from`, `to`, and `company_guid`.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource ('Return the Balance Sheet for a date range') plus the derivation source (Tally's native Trial Balance) and the exact line set. It is immediately distinguishable from siblings like profit_and_loss, trial_balance, and cash_flow without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operating context: a single company/mode/book-extent bracket, observed INR currency required, supported date boundaries, and that a book with stock items is expected to refuse. It does not, however, explicitly route the agent to a sibling (e.g. when trial_balance or profit_and_loss is the better call), so it stops short of full when/when-not/alternatives framing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cash_flowARead-only
Return Tally's own Cash Flow for whole months: its month-wise movement of the cash and bank ledgers, not a cash flow statement under AS 3. The months are returned only after the net total of the whole period has been compared with the trial balance, over the ledgers this check counts as cash and bank (those under Cash-in-Hand and Bank Accounts, a group inside them included; a ledger under a group a user made inside one was not measured), and found equal; otherwise the result is not_established and no month is shown (cash_flow_differs_from_trial_balance; cash_flow_money_group_unmeasured when a Bank OD A/c or Bank OCC A/c ledger has movement; cash_flow_nothing_to_compare when neither the cash and bank ledgers nor Tally's Cash Flow carry an amount for the period). Each month's closing is Tally's closing column for it, not checked month by month, and Tally's debit and credit columns are not returned. A month Tally printed with no amount is returned with an empty closing, which is not zero and does not say the month had no entries. A negative amount is a debit: cash and bank grew. The result's unmeasured_in_this_answer names any credit amount, positive closing or window from March into April it contains (a credit amount was seen tied to the trial balance in live runs on one synthetic book (two windows, one of them with a positive closing), and a window from March into April was not run; no month was compared with Tally's own Cash Flow screen: compare such months with it); two zero nets are not a tie (cash_flow_nothing_to_compare). The window must be whole months, at most twelve, and not start before the book (cash_flow_window_not_month_start, cash_flow_window_not_month_end, cash_flow_window_too_many_months, trial_balance_before_books). A book with several currency masters and Education mode are refused. The report's cost on a large book with cash activity is not known (one year of empty months on a large book answered at once): ask for one month first, and if a call times out do not repeat it. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the last month, which must be a month's last day, so that from to to holds at most twelve whole months (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the first month, which must be the 1st (YYYYMMDD or YYYY-MM-DD). | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare read-only/non-destructive, and the description goes well beyond them: it enumerates the failure modes and their codes, states that no month is shown when the check fails, explains that `closing` is Tally's closing column unchecked month-by-month, that an empty closing is not zero, that a negative amount is a debit, and that each call appends metadata-only receipt lines to a local log while writing nothing to Tally.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded, but the rest is a single dense paragraph with deep parenthetical nesting and long error-code lists, which makes it hard to parse. Most content is relevant, yet details about live runs on a synthetic book and an unrun March-into-April window add bulk with limited decision value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter read tool with no output schema, the description covers return semantics (per-month closing, not_established, empty closing), sign convention, validation conditions, refusal cases, performance caveats, and side effects, leaving little an agent would need to infer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so `from`/`to`/`company_guid` are already documented, but the description adds real constraints beyond the schema: whole months only, at most twelve, must not start before the book's start, plus the specific error codes for violating each rule.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb+resource and scope: Tally's own Cash Flow for whole months, the month-wise movement of cash and bank ledgers, explicitly distinguished from an AS 3 cash flow statement. An agent can separate this from siblings like trial_balance or ledger_movement without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives rich context on when the result is usable (only after the net total ties to the trial balance), when it is refused (multiple currency masters, Education mode), and practical sequencing ('ask for one month first, and if a call times out do not repeat it'). What it lacks is explicit routing to a named alternative tool for the cases where this one fails.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
company_featuresARead-only
Return three settings Tally's company record holds today for one company: cost centres, GST and batch-wise stock (each yes, no or not_reported), and the company's currency symbol. They say nothing about what the books contain or what the settings were during a year: a cost-centre allocation can be stored while the setting reads No. Each of the three settings has been compared with Tally's own F11 screen, on three synthetic books and not on this company; a setting changed inside a sitting has not been measured. Each setting says what it rests on. The currency is the symbol Tally holds (for example the rupee sign), not an ISO code, and it does not say whether foreign currencies are used. A setting Tally did not send is not_reported, never no. Tally's other feature flags are fetched in the same request and are not returned. Nothing this tool returns changes what another tool reads or refuses. Take company_guid from list_companies. This reads the company record and the book extent twice and returns no ledger, voucher, amount or narration. A company in Education mode is refused. Never present a setting as a fact about the books or about a past period. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Far beyond the annotations, it discloses that the settings are not statements about book content or a past period, that each setting reports what it rests on, that it was validated against F11 on three synthetic books and not this company, that an unset value is 'not_reported' never 'no', that it reads the record twice, that Education-mode companies are refused, and that each call appends metadata-only receipt lines to a local log while writing nothing to Tally. These details are consistent with the readOnly/idempotent=false annotations and explain the non-idempotency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and the essential caveats (not_reported semantics, no book content, refusal) are front-loaded, but the single dense paragraph is long and mixes behavioral, validity, logging, and epistemic caveats without visual structure. Every sentence carries some signal, yet the volume makes it harder to scan than necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, yet the description fully characterizes the return values (three yes/no/not_reported settings plus a currency symbol, not an ISO code), what is deliberately not returned, refusal conditions, side effects, and epistemic limits. An agent has everything needed to call it and interpret results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With one parameter and 100% schema description coverage, the schema already carries the parameter's meaning. The description only restates the source ('Take company_guid from list_companies') and adds a validity constraint (Education-mode companies are refused); it adds little syntax or format detail beyond the schema, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb (return) and precisely scopes the resource: three named company-record settings (cost centres, GST, batch-wise stock) plus a currency symbol, with the allowed values. It also implicitly distinguishes itself from siblings like trial_balance or vouchers by stating it returns no ledger, voucher, amount or narration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear prerequisite ('Take company_guid from list_companies') and a when-not rule (a company in Education mode is refused; do not present settings as facts about books or past periods). It does not, however, name a specific alternative tool for agents who actually want book contents or period settings, leaving that routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
egress_logARead-only
Everything the assistant reads from Tally through ComplyEaze Bridge in this chat, amounts included, is sent to the AI provider; redaction can only shorten party and ledger names and bank account numbers or drop narrations, and does not hide amounts, company names, PAN, GSTIN, IFSC, MSME or Udyam registration numbers, contact details or references, or the last four digits of a bank statement's account number (account_last4); under mask_parties a name written inside a narration or reference stays as it is. Never tell the user that no data has left their computer. Shows the receipts ComplyEaze Bridge keeps of its own tool calls, read from its local log file on this computer: tool, time, company, counts and fingerprints, no figures or book content (bounded to the most recent receipts). It does not show what the AI provider received. Use it when the user asks what ComplyEaze Bridge has done, or to show a reviewer which calls ran, on which company and when. Reading the log changes nothing in it; this call's own receipt lines are added after the read, like every call's. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many of the most recent receipt lines to return (each completed call writes two): default 20, at most 256 (or the configured row limit, BRIDGE_AGENT_MAX_ROWS, if lower, which can cap the default too), and fewer when the newest receipt lines do not fit in the log read's size bound. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare read-only and non-destructive, and the description goes well beyond them: reading alters nothing, but "this call's own receipt lines are added after the read," each call appends metadata-only lines, and it "writes nothing to Tally." It also discloses log contents and bounds ("bounded to the most recent receipts"). This is unusually rich behavioral context for a read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a run-on of multiple long clauses, and the core purpose is not front-loaded — the privacy mandate comes first, then scope, then usage, then behavior. There is also redundancy: the metadata-only receipt lines and "writes nothing to Tally" point is stated twice. Content is mostly load-bearing, but the delivery is not tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must convey return shape, which it does (tool, time, company, counts, fingerprints; no figures or book content). It covers scope, exclusions, triggers and side effects. The only gap is that it never mentions the `limit` truncation behavior in prose, but the schema handles that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single `limit` parameter is fully documented in the schema, including defaults, caps and truncation behavior. The description adds no parameter guidance of its own, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
It names a specific verb and resource: "Shows the receipts ComplyEaze Bridge keeps of its own tool calls, read from its local log file on this computer: tool, time, company, counts and fingerprints." That clearly separates it from the accounting siblings (balance_sheet, vouchers, etc.). However, the actual purpose statement is buried behind a long privacy disclosure, so the agent must read past several sentences before learning what the tool is.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit trigger: "Use it when the user asks what ComplyEaze Bridge has done, or to show a reviewer which calls ran, on which company and when." It also draws a scope boundary with "It does not show what the AI provider received," which prevents misuse as a data-exfiltration audit. No named alternative sibling is offered, but the use case is concrete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gst_statusARead-only
Return Tally's own GSTR-1 status of the vouchers of ONE voucher type in a date window, read from the status flags Tally keeps on each voucher. For each voucher it returns the voucher number, date, voucher type, master_id and alter_id, its gst_status (included, uncertain, excluded, not_in_return, all three flags No, which on the lab's Receipts, read before the request fetched the cancelled, optional and post-dated flags, means Tally does not list the voucher, or cancelled, optional or post_dated, decided first from Tally's own cancelled, optional and post-dated flags and never counted as included, uncertain, excluded or not_in_return; such a voucher's item also holds status_flags, what its three status flags read, which is not counted) and whether a person accepted it as it stands (accepted_as_it_stands, Accept As Is), with the window's counts of each. A status is Tally's own flag and not a judgement of ComplyEaze Bridge: it does not say that a voucher is right or wrong, or that a return is ready to file. The reason for a status is not available: Tally shows it on its screen only, and none is returned. Tally keeps the status a voucher was given when it was saved. included also counts a voucher a person accepted as it stands. post_dated is Tally's flag and not a date still ahead: the lab's one post-dated voucher was marked so by hand and dated the day Tally's current date (set with F2) had been set to, and whether Tally lists a cancelled voucher anywhere in the return, or a post-dated one while Tally's current date is before the voucher's date or once it has reached it, is not measured. A total of 0 may mean the type name matched nothing, and each page is a new read, so a voucher saved between two pages can shift the offsets. A voucher whose flags, or whose cancelled, optional or post-dated flag, are absent or not in a form that was measured, or whose deleted flag reads Yes (never seen: the lab's one deleted voucher left the answer), is returned as unread with a code, never as included, and the result is then partial. Limits: one voucher type by its exact name (a type of the same class under another name is not read), at most 93 days, and a book whose voucher mark is above 25,000 is refused. Measured on one synthetic book of TallyPrime 7.1 Silver only, for the unregistered buyer of its Sales invoices; a registered buyer, other releases and Gold are not measured, and excluded has not been observed. Take company_guid from list_companies and the type name from masters. This first reads the book's voucher mark and then the vouchers of the type in the window, and returns no amount, party or narration. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. | |
| voucher_type_name | Yes | The exact name of ONE voucher type in the book, as masters lists it (for example the name of a Sales type). A type of the same class under another name is not read. At most 100 characters, with no double quote, backslash, & < > ' or control character and no space at either end (gst_status_type_name_invalid). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Far beyond the annotations, the description discloses side effects ('appends metadata-only receipt lines ... to ComplyEaze Bridge's local log', 'writes nothing to Tally'), partial-result conditions (unread vouchers, absent flags), non-idempotent page reads where concurrent saves shift offsets, and a 0-total ambiguity. It also clarifies that a status is Tally's own flag, not a judgement by the bridge, and that the reason for a status is never returned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded, but the second sentence is a single ~120-word run-on with parents within parents, and the same caveats (flag semantics, 'included' counting accepted vouchers, post_dated) are restated across multiple sentences. For a tool with this level of nuance the length is defensible, but the structure makes it hard to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity, edge-case-heavy tool with no output schema, the description is unusually complete: it enumerates returned fields, the enum-like status values, flags, counting rules, failure modes, limits and prerequisites. An agent has enough to call it correctly and to interpret 0, partial and unread outcomes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented in the schema; baseline is 3. The description adds meaningful constraint context (exact-type matching, 93-day window, refused books), but the per-parameter mechanics (limit/offset dates) live entirely in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause gives a specific verb and resource: returns Tally's own GSTR-1 status of the vouchers of one voucher type in a date window. It is clearly not the same as a plain voucher listing. However, it never names or contrasts with closest siblings such as tally_status or vouchers, so an agent must infer the boundary between them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied rather than stated: it explains where to source inputs ('Take company_guid from list_companies and the type name from masters') and lists operational constraints (one type by exact name, max 93 days, voucher mark limit). There is no explicit 'use this when / use X instead' guidance against the many sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ledger_mastersARead-only
Return a company's ledger masters, each with its opening balance as of the start of the books (opening_balance, opening_balance_as_of), on a freshly observed supported product and mode. fields=basic (the default) or fields=compliance, which adds paired party-master observations (GSTIN, PAN, MSME, bank, contact and address), each ledger's group ancestry and its gst_duty_head. GSTIN (compliance): party_gstin is the GSTIN in force on party_gstin_as_of (the optional as_of, YYYYMMDD or YYYY-MM-DD such as 20260331, else this computer's date; without fields=compliance, as_of is refused as ledger_masters_as_of_requires_compliance), taken from the ledger's dated registration history, or from the flat GSTIN field only when that history is empty or not returned (an empty flat field names no GSTIN). party_gstin_status: in_force, flat_field, no_gstin_in_force (a history with no GSTIN in force on that date; party_gstin_registration_type says whether that entry is registered), not_reported, or history_unreadable, which fails closed (an undated, misdated, malformed, repeated or contradictory history: party_gstin is null and the flat field unused). party_gstin_flat is always the flat field as read; gstin_sources_disagree is true when it names a GSTIN the in-force entry does not: both are reported, neither is chosen. For another date, such as a transaction's, pass it as as_of or read the dated compliance.gst_registrations. Duty head (compliance): gst_duty_head is recognized (head: cgst, igst, state_tax, sgst_utgst, ut_tax or cess; raw: the spelling Tally returned), unrecognized (raw kept), not_tax_ledger, contradictory or absent. state_tax (raw State Tax) and sgst_utgst (raw SGST/UTGST) are two spellings Tally has returned for a state-side head, kept apart: to sum state tax, include both. Ancestry (compliance): chain (nearest group first, each hop's name and reserved_name), complete (true only if resolved to the reserved account root) and gap (null when complete, else why it stopped: no_parent, group_absent, group_name_repeated, reserved_name_missing, cycle or exhausted). An incomplete chain is never padded or guessed: chain is exactly what was resolved, so check complete before treating it as exhaustive. A reserved_name starting with U+FFFD #4; is a Tally reserved value (written ); U+FFFD#4; Primary is the account root, not a group a user named Primary. Group filter: group filters by group name. group_scope "immediate" (the default) matches only the ledger's own parent and does NOT include ledgers under sub-groups of group; "ancestry" matches anywhere in the resolved chain, the whole subtree (a ledger under Bank OD A/c matches Loans (Liability)), with either fields value, and a gap in a chain never counts as a match. A group filter reads the group collection (one more paired read with fields=basic) and returns group_filter: excluded_subgroup_ledgers (count left out for sitting under a sub-group of group, always 0 under ancestry scope, with group_count and up to 20 of those sub-groups in groups) and unresolved_ancestry_ledgers (ledgers not returned whose chain stops short of group, so whether they belong under it is unknown; counted over the whole book). GST details (compliance, opt-in): include_gst_details (a boolean, default false; with any other fields it is refused as ledger_masters_gst_details_requires_compliance) adds compliance.gst_details to each ledger: observation is not_observed (Tally returned no such list), entries (each dated entry with applicable_from, taxability, source, itc_eligible and states; each state row has state_name, slab_rates_present and rates with duty_head, valuation_type and a rate whose kind is absent, empty, zero or value with raw as sent and decimal; other_content_skipped says content was not read) or unreadable (a defect for this ledger only). absent, empty, zero and value mean different things and are never merged. These are Tally's ledger-level details as sent: HSN/SAC and type of supply are not returned because no capture shows them, the place of supply is in the registration history, and slab rates are only flagged. Measured on one 14-ledger lab book of TallyPrime 7.1 Silver; this was not yet run through this tool on a live Tally. Without the flag every request and result is unchanged and carries no gst_details. The read is admitted at 8,000 bytes a ledger instead of 3,750, a margin over the one capture (a ledger with an empty list 2,138 to 2,704 bytes; one dated entry 5,248 to 5,394; UTF-16 bytes of the ledger's own element), not a measured ratio; a large book may be read in more parts or refused as too large. Large books (compliance): when the master-alteration mark (an upper bound on the ledgers, since every master raises it) puts the estimated response over budget, the ledgers are counted first, then read whole or, if the count does not fit, in parts by parent group; every counted ledger must come back exactly once, or the whole call is refused. Above a mark of 22,857 the count runs in AlterID-span slices of at most 4,000, one GUID-only request each; above 400,000 the call is refused before any ledger read (cause ledger_catalogue_too_large, with size), even for a company with fewer ledgers. Each refusal names its cause: parent_over_budget, parent_partition_too_many_parts, parent_complement_over_budget, ledger_without_parent, parent_name_unsupported (with unsupported_parent_ledgers), parent_partition_duplicate_ledger_identity, the parent_part_* coverage causes, parent_part_response_too_large, ledger_span_slice_over_bound, ledger_span_duplicate_identity, ledger_span_census_empty, ledger_span_slice_malformed, ledger_span_identity_mismatch, ledger_span_slice_response_too_large or ledger_count_catalogue_too_large. A size refusal refuses again on retry; fields=basic still reads the book. For ledger_count_differs (two counts, or a count and the ledgers read, disagree) or ledger_count_company_differs (Tally's own ledger count exceeds the census's), retry once while the book is quiet; for ledger_count_company_invalid (that count's answer was damaged) or ledger_count_company_response_too_large, retry once, then use fields=basic. A counted read reports ledger_count_cross_check.status: matched, company_count_lower, or unavailable (no count in Tally's answer, so no check ran). Currencies (compliance): a book with several Currency masters is read through the base Tally identifies: only plain base-currency ledgers are returned (ledgers_scope base_currency_ledgers_only); ledgers kept in another currency (foreign_currency_ledgers_excluded) and base-currency ledgers whose balances Tally shows in another currency (base_currency_ledgers_mixed_excluded) are named, never read. Paging: offset 0 always reads Tally afresh and holds the read; later pages are served from it while the book extent, ALTMSTID and ALTVCHID included, is unchanged, and each result reports snapshot. Pass the first page's snapshot_id on later pages to be refused as listing_snapshot_changed (cause book_changed_since_first_page or snapshot_not_held) rather than continue from a different read. With fields=compliance, repeat the first page's as_of: a snapshot serves only pages read as of the same date, so a later page without it (or across midnight) reads afresh, or is refused if it names the snapshot; the same holds for include_gst_details: a later page called without include_gst_details reads afresh and returns rows without gst_details (snapshot.reused false), and only a call that names snapshot_id is refused. A change that moves neither mark is not seen, so a later page can be up to 10 minutes old; every screen action measured so far moved one (a regroup, an opening change, a ledger create or delete, a voucher delete, a cancel, a save with no change; protocol reference section 11c.5, one run each). For what parties owe or are owed now, by their open bills, use outstandings instead. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | No | Optional, with fields=compliance only: the day the GSTIN in force is read for (YYYYMMDD or YYYY-MM-DD). Left out, this computer's date. | |
| group | No | Optional: return only the ledgers under this group name; which ones count follows group_scope. | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| fields | No | basic (the default) or compliance, which adds the party-master observations, each ledger's group ancestry and its gst_duty_head; the description says what each holds. | basic |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| group_scope | No | With group: immediate (the default) matches only a ledger's own parent; ancestry matches any group in its resolved chain, the whole subtree. | immediate |
| snapshot_id | No | Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. | |
| include_gst_details | No | Optional boolean, default false, with fields=compliance only (any other fields is refused as ledger_masters_gst_details_requires_compliance): add each ledger's dated GST rate details as compliance.gst_details. They are Tally's ledger-level details as sent, per dated entry and state row; a rate is absent, empty, zero or a value, never merged. HSN/SAC and type of supply are not returned; slab rates are only flagged. Measured on one 14-ledger lab book; not yet run through this tool on a live Tally. The read is admitted at 8,000 bytes a ledger instead of 3,750, a margin over the one capture (a ledger with an empty list 2,138 to 2,704 bytes; one dated entry 5,248 to 5,394; UTF-16 bytes of the ledger's own element), not a measured ratio; a large book may be read in more parts or refused as too large. On later pages repeat `include_gst_details` as well as `as_of`: a later page called without `include_gst_details` reads afresh and returns rows without `gst_details` (`snapshot.reused` false), and only a call that names snapshot_id is refused. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, but the description goes far beyond them: it names every refusal cause, the snapshot paging invariant, the 8,000-bytes-per-ledger admission budget, the retry guidance for count mismatches, and that each call appends metadata-only receipt lines to a local log while writing nothing to Tally. This is unusual behavioral depth for a read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is thousands of words and reads as a specification manual rather than a tool description; the opening intent is front-loaded but is then buried under exhaustive enumeration of refusal codes, byte budgets and snapshot edge cases. Most individual sentences are informative, but the sheer volume violates the conciseness bar and makes the description hard to parse at selection time.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so thoroughly: it explains what fields=basic vs compliance return, the gst_details shapes, the ledger_count_cross_check status, snapshot reporting and the currencies ledger_scope behaviour. Nothing an agent needs to call or interpret this tool appears missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds meaning the schema does not: `as_of` is refused without fields=compliance (ledger_masters_as_of_requires_compliance), `snapshot_id` must be the first page's or the call is refused as listing_snapshot_changed, and `include_gst_details` is refused with any other fields. That is genuine added semantics beyond the field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: return a company's ledger masters with opening balances. It also distinguishes itself from the sibling `outstandings` for party balances, so an agent can route correctly without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use another tool ('for what parties owe or are owed now, by their open bills, use outstandings instead') and lays out fields=basic vs fields=compliance and the group_scope choices. It does not compare against the sibling `masters`, which is the closest alternative, so it falls short of a full when/when-not/alternatives treatment.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ledger_movementARead-only
Return literal-window ledger opening, exact debit/credit movement, closing, and touched-voucher count with a freshly observed supported product/mode and an operation-valid opening boundary. Reads the full voucher window before filtering or pagination; use narrow dates. Dense windows can fail source limits. Requires one observed INR currency master: a book with several Currency masters, none, or one that is not INR is refused before any ledger read. A ledger name resolves only when spelled as in the book or differing from it only in ASCII case and spaces; ledger_match names the ledger read, how (matched: exact, or case_or_spacing, which the answer should mention by naming the ledger read) and any similar_ledgers that differ from it only in case or whitespace. A slow read says so in the result's read_cost: the window is read twice, a planned read and a replay that proves nothing moved, and the block gives both reads' observed seconds, a floor derived from the census gaps (not measured) and whether those two voucher reads together stayed inside the one measured host limit (the two ledger catalogue reads, the company check and the wider read an empty window gets are not in it); it adds no request and refuses nothing. For every ledger's balances from Tally's own Trial Balance, without reading vouchers, use trial_balance instead. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| ledger | No | Optional: one ledger's name, spelled as in the book or differing only in ASCII case and spaces. Left out, every ledger. A name that does not resolve is refused before any voucher is read. | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the read-only/safety profile, and the description adds substantial behavioral context: the INR currency-master precondition and refusal, ledger-name resolution semantics, the double-read read_cost measurement and what it excludes, and the metadata-only receipt logging to a local bridge with nothing written to Tally. This goes well beyond what the annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The return value is front-loaded, which is good, but the read_cost sentence is a ~90-word run-on with nested clauses that is very hard to parse, and several behavioral points (refusals, receipt logging) are stated at length. Most content earns its place, but the presentation is not tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing the return payload (opening, movement, closing, counts, ledger_match, read_cost) and does so. It also covers refusals, pagination interaction, logging side effects, and the alternative tool. Complete for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters including the ledger name-resolution rule. The description mostly repeats that rule and adds detail on the non-parameter ledger_match/similar_ledgers fields, so it does not meaningfully extend parameter meaning beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb and resource set: ledger opening, debit/credit movement, closing, and touched-voucher count over a date window. It also explicitly differentiates from the sibling trial_balance, so an agent can route correctly. The heavy jargon ('literal-window', 'operation-valid opening boundary') slightly obscures the plain purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance ('use narrow dates', reads the full window before filtering) and names the alternative with the selecting condition ('without reading vouchers, use trial_balance instead'). The refusal preconditions (no/several/non-INR currency master) are stated as gating context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_companiesARead-only
Start here. Return observed company tuples (the company_guid every tool that reads a company's books needs) and identity ambiguity flags. If exactly one company is open and the user named no client, use it and say which in your first line; if the user names a client and exactly one open company matches that name, use it and say which; otherwise ask which, offering the list, and never guess a company. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, non-destructive, not open-world), and the description adds non-obvious behavior: every call appends metadata-only receipt lines (tool, company, counts, fingerprints) to a local log, and it writes nothing to Tally. This is exactly the extra context annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with 'Start here' and organized around the routing decision, so the important guidance comes first. It is dense and the trailing logging sentence adds length, but each sentence carries load-bearing information rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, the description must carry both selection logic and return-content expectations, and it does so, including the company_guid contract and ambiguity flags. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing to disambiguate and the baseline is 4. The description instead front-loads what the call returns (tuples with company_guid and ambiguity flags), which is useful but belongs to return semantics rather than parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource ('Return observed company tuples') and explains the payload's role by naming the exact field other tools need (company_guid). 'Start here' explicitly positions it as the entry point, distinguishing it from the many sibling read tools that require a company.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit decision rules: single open company with no named client -> use it; named client matching one open company -> use it; otherwise ask and offer the list. It also states an exclusion ('never guess a company'), leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
local_data_reportARead-only
Reports what ComplyEaze Bridge stores locally, by class, with counts, sizes, the age of the oldest file and the state of its import journal: how many batches were sent or found posted, how many of those are not settled (not_settled_binding_refused: native posts whose binding to their own vouchers was refused, including one Tally rejected in part or whole; they stay not settled for good, their vouchers may or may not be in the book, and the person checks them in Tally. not_settled_no_response, not_settled_binding_refused and not_settled_not_verified do not overlap), and how many have no recorded dispatch and were never verified as posted (no_dispatch_never_verified: this can include a batch imported by hand, which may be in Tally, so never treat it as proof that a batch is absent). Reads ComplyEaze Bridge's own local data folder and the per-user folder of dispatch lease locks (names, sizes and times) and names no file path. A folder, link or journal it could not read or enter is reported as such (incomplete_reason and folders_that_could_not_be_listed, and this call's evidence is partial), never as empty or absent. It covers the folder the MCP server and the desktop Journal flow share; the desktop app's other settings, its mirror database and logs live elsewhere and are not covered. The import journal, the skipped-rows file agent-import-statement-skips.jsonl and the imports folder are ComplyEaze Bridge's memory of what it already sent to Tally and of the statement rows it was told to skip: never suggest deleting them. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses that unreadable folders are reported as incomplete (incomplete_reason, folders_that_could_not_be_listed) and never as empty, defines the non-overlapping not_settled_* states, and warns never to suggest deleting the journal/skips file. It also discloses the per-call receipt-line side effect and that nothing is written to Tally, which is exactly the kind of context readOnlyHint alone cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and information-dense, but delivered as a single sprawling paragraph riddled with nested parentheses ('not_settled_binding_refused: native posts whose binding... including one Tally rejected in part or whole') that make it hard to scan. Almost every clause carries real meaning, but the packaging costs the reader.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, no-output-schema tool this is unusually complete: it enumerates the returned fields (counts, sizes, age, journal state), defines each status value, states coverage boundaries, and describes the partial-evidence failure mode. An agent has everything needed to call it and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the rubric the baseline is 4; there is no parameter syntax the description could add. The description instead spends its budget on the semantics of the returned fields, which is the right allocation here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'Reports what ComplyEaze Bridge stores locally, by class, with counts, sizes, the age of the oldest file and the state of its import journal.' It is instantly distinguishable from the Tally-data siblings (balance_sheet, vouchers, trial_balance) because it inspects Bridge's own local folders and dispatch-lock folder rather than book content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It draws explicit scope boundaries: what is covered (the folder the MCP server and desktop Journal flow share) versus what is not (the desktop app's other settings, mirror database and logs). It also frames correct interpretation ('never treat it as proof that a batch is absent'). What is missing is naming a sibling to use instead when the agent actually wants Tally-side evidence, which is why it falls short of 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mastersARead-only
List a company's masters of one kind: voucher types with the numbering value Tally reports at the type level (see below: it is not their numbering method), active and optional flags and series_numbering (the numbering method, under Automatic its sub-method, and the duplicate setting of the type's series), godowns, units (with decimal places and whether simple), stock groups, cost centres (with their category), cost categories (with three allocation flags), or account groups (groups). Each row of another kind carries name, guid, master_id, alter_id and parent (null where it does not apply or is absent; a parent that is Tally's reserved root is written as U+FFFD #4; Primary, as in the group tree); a groups row carries name, parent and reserved_name only. Voucher types also carry active, optional (true, false or null when Tally did not say) and numbering_method (automatic, manual, default, {"unrecognised": <raw text>} for any other value Tally reports, or null when absent) and series_numbering ({"observation":"observed","method":"automatic"|"manual"|"automatic_manual_override"|{"unrecognised": <raw text>},"duplicates":"prevented"|"not_prevented"}, with "sub_method":"auto_retain"|"auto_renumber"|"absent"|{"unrecognised": <raw text>} under automatic and under no other method, {"observation":"series_count","count":n} when a type has no series or several, and nothing is read from it, or {"observation":"field_invalid","code":...}), read from a second paired read of the voucher-type export and joined to each row by GUID with the name as a second equality, so a type on one side only, or a GUID and name that disagree between the two reads, refuses the whole read (masters_numbering_names_differ for a type in one read only, masters_numbering_identity_differs for a GUID and name that disagree), as do masters_numbering_collection_changed (the numbering read changed between its two reads) and masters_bound_premise_violated (the numbering answer's row count or size), and a moved book is reported as masters_extent_changed in place of a join or premise refusal; units carry decimal_places and simple; cost centres carry category (always present: a centre without one is refused), cost categories allocates_revenue, allocates_non_revenue and affects_stock; cost centres and categories are returned whether or not the company's Cost Centres setting is on (a book with the setting off was read with its centres, and a book with it on with its own), an empty cost-centre list does not say whether the feature is off or none is defined, and an empty cost-category list is refused (masters_cost_categories_empty, on the expectation that the predefined Primary Cost Category always exists), and ComplyEaze Bridge does not return how a voucher was allocated to a cost centre. One kind per call, read inside one company, mode and book-extent bracket: the extent before and after must be equal and each collection is read twice and compared, so a book that changed during the read is refused. Whole reads only. Godowns, units, stock groups, cost centres and cost categories are read only when the book's master-alteration mark times an assumed worst-case row for that kind fits 16 MB (the mark counts the masters of every kind, so a book with few of this kind can be refused), and otherwise refuse before any request with masters_too_large and size (master_alter_id, estimated_bytes, limit_bytes, limit_master_alter_id); that admits marks up to 1,152 for godowns, 1,168 for units, 1,160 for stock groups, 1,037 for cost centres and 1,264 for cost categories. Retrying refuses again. The refusal's size carries limit_master_alter_id, the largest mark this kind is read at. Both stock-heavy client books measured, with marks of about 100,000 and 300,000, refuse godowns, units and stock groups (cost centres and cost categories were not tried on them); how common such marks are across live books is unmeasured. voucher_types and groups have no size check before the read (voucher types keep the policy of ComplyEaze Bridge's other voucher-type read, and their second, numbering read is likewise sent with no size check). After a read of any kind other than groups, each row's length is checked against the assumed worst-case row (masters_row_exceeds_bound), and the row count, the rows' AlterIDs (at or under the mark, none repeated) and the response size (each collection is read twice, and the size check runs after both reads) are checked against the mark and the admitted size; a breach of those three refuses the whole read as masters_bound_premise_violated and returns no partial list, unless the closing extent shows the book moved, which is reported instead (masters_extent_changed). A response ComplyEaze Bridge cannot read refuses at once with a masters_* cause, and a voucher_types answer with no rows refuses as masters_voucher_types_empty, because every company has predefined voucher types. Not returned: alias names, counts and hints (no company NUM* fields), stock items, ledgers (use ledger_masters), and any write. The row shape was captured from one synthetic book on one licensed TallyPrime 7.1 (cost centres: three synthetic books, the third captured in a separate sitting whose own status read recorded TallyPrime 7.1, licence Silver, Education mode off; cost categories: two): the type-level numbering_method it carries is not the voucher type's numbering method: it read None for types a person had set to Automatic and to Manual on the screen, and the method is kept per number series, which series_numbering returns instead, so no value of numbering_method (default, automatic, manual or any other) says how a post is numbered. series_numbering was measured on one synthetic book (TallyPrime 7.1 Silver, Windows): 24 voucher types, each with one series named Default, of which three (Journal Automatic, Payment Manual with duplicates prevented, Receipt Manual with duplicates not prevented) were checked against Tally's screen; Automatic (Manual Override) through this tool (it is mapped from the series text measured on a synthetic book on 13 October 2026), more than one series, Multi-user Auto, a single series not named Default, a voucher type created new and other releases were not measured, an unrecognised method is never manual, and the integrated read, the two requests sent as one tool call, was run live on two synthetic books on 14 October 2026 and returned the numbering set or checked on Tally's screen for six types. sub_method is the series' own NUMBERINGSUBMETHOD (auto_retain is the screen's Retain Original Voucher No., auto_renumber its Renumber Vouchers, absent a series that printed none, and any other text, a blank one included, is returned raw under unrecognised); a Manual series printed Auto Retain too, which is not the numbering in force there, so it is not returned for one. It was measured on a second synthetic book (TallyPrime 7.1 Silver, Windows) and one voucher type, Receipt, set to Renumber Vouchers and back: with it on Renumber Vouchers, numbers already in the book changed, at the switch, when a voucher with an earlier date was entered by hand, and when one was sent by import without a number (the import's answer reported nothing altered and no voucher's AlterID moved); any other wording, a series that prints no sub-method, other voucher types, a batch of several vouchers, Gold, other releases and the same through ComplyEaze Bridge's own post are not measured. A value other than Automatic, Manual or Default is returned raw under unrecognised, not refused. default is Tally's reported value, not evidence that a type numbers automatically. The company's voucher-type count (NUMVOUCHERTYPES) did not equal the rows returned on two books (35 vs 26, 33 vs 24), and on one book equalled the number-series count (inferred to count series, unmeasured), so do not check these rows against it. The completeness of the voucher-type list is unverified: absence from it is not evidence that a voucher type is absent from the book. Under mask_parties, godown, stock-group, cost-centre and cost-category names, their parents and a cost centre's category are masked, because a job-work godown, a supplier-named stock group or a customer-named cost centre can carry a party's name (Tally's reserved root as a parent is left as it is). Voucher-type, unit and account-group names are not masked: they are configuration labels, not counterparties. Education mode is refused. A first page (offset 0) always captures a fresh read and holds it in memory; a later page for the same kind (offset > 0) is served from it while the company's book extent, including ALTVCHID and ALTMSTID, is unchanged, at the cost of one small extent read. Each result reports snapshot (id, master_alter_id, voucher_alter_id, read_at, reused). Pass the first page's snapshot_id on later pages to have the call refused with listing_snapshot_changed (cause book_changed_since_first_page or snapshot_not_held) instead of continuing from a different read. A change that moves neither mark is not seen, so a later page can be up to 10 minutes old after such a change. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Which masters to list, one kind per call: voucher_types, godowns, units, stock_groups, cost_centres, cost_categories or groups (account groups). | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| snapshot_id | No | Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a safe read (readOnlyHint true, destructiveHint false, openWorldHint false), but the description adds extensive behavior beyond them: size pre-checks with kind-specific mark thresholds, the full set of masters_* refusal causes, snapshot reuse/expiry semantics, mask_parties behavior, and local logging. This is far more than the annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first clause, but the body is a single enormous block mixing invocation-critical facts (refusals, masking, pagination) with measurement provenance, unmeasured-case disclaimers and synthetic-book history. Critical details like the snapshot contract are buried far down, and much of the text does not help an agent select or invoke the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a seven-kind listing tool with no output schema, the description carries the full burden and does: it documents per-kind row shapes, refusal conditions, masking rules, pagination and snapshot semantics, and the absence of writes. An agent has everything needed to call it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: how offset interacts with the in-memory first-page snapshot, when snapshot_id causes listing_snapshot_changed, and what each kind value returns. It stops short of exhaustively documenting limit behavior beyond the schema's default note.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'List a company's masters of one kind', then enumerates the seven kinds by name. It also explicitly distinguishes itself from the closest sibling by stating ledgers are not returned and pointing to ledger_masters.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use rules ('One kind per call', 'Whole reads only', education mode refused), states what is not returned (aliases, counts, hints, stock items, ledgers, writes) and names the alternative for ledgers. It also explains the pagination/snapshot contract that governs how calls must be sequenced.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
month_registerARead-only
Return Tally's own month-wise Sales Register or Purchase Register for whole months, read by its report name: one row per month with Tally's debit, credit and closing columns exactly as Tally printed them. The rows are not tied to the vouchers, to the trial balance or to the sales_register and purchase_register tools; on the one synthetic book read, the Sales Register's credit was the month's sales invoices, tax included, and its closing a running total printed only for the months with sales, and the Purchase Register's debit was the month's purchases as a negative amount. The period must be whole months, at most twelve, and must not start before the book does. An empty amount is not zero. The result's limitations say what has not been measured. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the last month, which must be a month's last day, so that from to to holds at most twelve whole months (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the first month, which must be the 1st (YYYYMMDD or YYYY-MM-DD). | |
| kind | Yes | sales (Tally's Sales Register) or purchase (Tally's Purchase Register). | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/destructiveHint annotations, it discloses that each call appends metadata-only receipt lines to a local log and writes nothing to Tally (explaining the non-idempotent hint), warns that an empty amount is not zero, and notes the result carries limitations. This is rich behavioral context the annotations alone do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the core purpose, but the body is a dense run-on of long sentences mixing output semantics, edge cases, and logging behavior. Most content earns its place, yet the structure is hard to parse and could be tightened into clearer discrete statements.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully explains the return shape (one row per month with debit, credit, and closing columns exactly as Tally printed them), the synthetic-book caveats, the limitations note, and the side-effect logging. It is nearly complete for a read tool, though the synthetic-book semantics are complex and could be framed more cleanly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents kind, from, to, and company_guid, including the whole-month and 12-month constraints. The description largely restates those constraints and describes output shape rather than adding new parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (Return) and resource (Tally's own month-wise Sales Register or Purchase Register, read by its report name), and explicitly distinguishes itself from siblings by saying the rows are not tied to the vouchers, trial balance, or the sales_register and purchase_register tools. An agent can tell this apart from the sibling register tools without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete usage constraints (whole months only, at most twelve, must not start before the book does) and implicitly rules out the sibling register tools. It stops short of an explicit 'use this instead of sales_register/purchase_register when...' routing statement, so it is strong but not fully prescriptive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
outstandingsARead-only
Answer what is outstanding: receivable and payable totals from Tally's own paired bills reports, ageing, the top parties and the open bills, on a freshly observed supported product and mode and a date valid for the operation. as_of is optional: left out, it is this computer's date (tally_status today), and the date used is always returned as result.as_of, whatever the state. top ranks parties only; page the bills with offset and limit. open_bills_total counts every open bill in the requested direction, all of which totals and the ageing cover, and open_bills_shown counts the bills on this page (limit is not lowered when the response size shortens the page): when shown is less than total, say so plainly, for example "showing 500 of 1,240 open bills; the totals and the ageing cover all 1,240" (on a later page, the bills from offset + 1; on a partial read, both counts and the sentence cover the base-currency ledgers only, so say so in it), and ask for the next bills with offset set to next_offset. receivable and payable follow the sign of each bill's balance, as Tally's own Bills Receivable and Bills Payable reports scope them, not the type of party: a customer's advance or a credit note raised to a customer appears under payable, and a supplier's advance or a debit note raised to a supplier under receivable, because those reports carry no bill type. That holds for an advance or a note kept as its own bill: an on-account advance goes to the unallocated figure instead, and a credit note set against an open invoice reduces that invoice. Measured on one synthetic book (TallyPrime Silver 7.1). Read a bill's kind as a direction, not as owed by a customer or owed to a supplier. An unallocated amount's direction is the sign of the party's net unallocated balance, so an on-account receipt and an on-account payment on one party net into one figure. A book with several Currency masters is read through the INR base Tally identifies. If it has ledgers kept in another currency (foreign_currency_ledgers_excluded, each with its currency) or base-currency ledgers whose balance Tally shows in another currency (base_currency_ledgers_mixed_excluded, each set aside with all its bills), the state is partial with partial_reason currency_ledgers_excluded and partial_reasons naming the lists that are not empty: figures cover its base-currency ledgers only, under base_currency_ledgers, never a total for the whole book, and both lists are always present, paged like the bills. Each unallocated party carries ledger_bill_wise, opening_balance (the ledger's opening as of the start of the books, with Tally's sign, so a debit opening is negative, never interpreted; absent when Tally sent none, which is unknown, not zero) and a composition: not_bill_wise_ledger (the ledger keeps no bills) or bill_wise_ledger_components_not_separated (what is left on a bill-wise ledger after its named bills: on-account entries, an unallocated opening, notes with no reference and anything else, not told apart). amount is a magnitude and direction says which side; unallocated.totals.by_composition splits the gross, receivable and payable apart, by those two over every party in the requested direction before paging (a row saved without one counts under composition_not_observed). No unallocated figure is labelled on-account. Party detail: with party (a ledger name) and detail, the result also carries a detail object for that party at the same as-of. A ledger name resolves only when spelled as in the book or differing from it only in ASCII case and spaces; the detail's ledger_match names the ledger read, how (matched: exact, or case_or_spacing, which the answer should mention by naming the ledger read) and any similar_ledgers that differ from it only in case or whitespace. Passing detail is the request to read the company's vouchers from the start of the books (or, for a named bill that Tally's bills reports list, from the earliest date they list for it) to as_of; nothing is read for a party detail without it. bill_trail (optionally one reference) lists every allocation of each bill in vouchers that are neither cancelled nor optional, oldest first, with state tied (the signed allocations equal Tally's own balance for that bill, or zero for a bill the report no longer lists), trail_does_not_tie (both numbers shown) or bill_identity_ambiguous (more than one native row or bill date for one reference, or a native row dated differently from the allocations; nothing is merged, and the native dates are shown). Naming a reference starts the read at the earliest date the reports list for it, so allocations dated earlier are not read, and a reference that carries two bill dates over the whole history, and is ambiguous there, can tie when named. The detail's own state is bills_listed, or for an empty list not_bill_wise_ledger or no_named_bill_for_party (no named bill in the vouchers or in Tally's list: a ledger that keeps no bills, one that is not a party's and a party with no bills are not told apart). The vouchers and the bills reports are two reads whose extents are not compared: a voucher posted between them usually shows as trail_does_not_tie, but two changes that compensate, or allocations that net to zero, can still read tied. unadjusted lists the party's on-account, advance and pending note allocations and compares their on-account sum with the party's unallocated amount: tied means the two figures are equal, not that the composition is proven (components that net to zero are not seen); residual_not_explained_by_vouchers gives the difference and whether it equals the ledger's opening balance; no_residual_row_for_party (with residual null) means Tally lists no unallocated amount for the ledger (a zero residual, a ledger that is not a party's and a name that matched no row are not told apart), so nothing is tied; not_bill_wise_ledger lists no rows. Its rows are row_amounts: as_allocated: each amount is the allocation as made, never net of what later allocations adjusted against its reference, so an advance shows what was received, not what is left; what is still open on a reference is Tally's own native_balance beside the row, null when the reports do not list the reference or list it more than once (so no balance is chosen), told apart only by native_rows. Either detail is window_returned_no_vouchers, with nothing tied or listed, when the voucher read returned no voucher (that read is not corroborated). Cost and limits: the detail keeps the party's entries from the whole company's vouchers, so its cost is that of a vouchers read over the same span, which is unmeasured on a large book, and any refusal of that read fails the whole outstandings call. One foreign-currency composite voucher anywhere in the window fails it (voucher_amount_invalid, or bill_allocation_amount_invalid on an allocation). At most 128 data requests are sent (each sent twice, as every read is, with its census and the company marks besides), each holding at most 42 vouchers before anything is measured, so a window of more than 5,376 of the company's vouchers is always refused, and a smaller one may be. The refusals are trail_window_too_large (name a reference that open_bills lists for the party, and the read starts at that bill's date), named_bill_window_too_large (a reference was named already, so nothing narrows it further) and unadjusted_window_too_large (nothing narrows it, so it is not available for that party on that book), each with reads.needed_at_least against reads.allowed; a refusal comes before any data request when the count shows it, otherwise when a measured part does, with window listing any part already read. The detail needs a complete read (detail_requires_a_complete_read, with the read's own partial_reason) and refuses rather than cuts an answer of over 500 allocations: trail_too_large (name a reference) or unadjusted_detail_too_large (nothing narrows it). The limit counts allocations, not bills, so a party with very many opening bills can meet agent_response_too_large instead. For a ledger's master record (its group, opening balance and, with fields=compliance, GSTIN and party details), use ledger_masters instead. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | How many parties to rank by gross exposure (default 25). It ranks parties only; page the bills with offset and limit. | |
| as_of | No | Optional: the day the open bills are read as of (YYYYMMDD or YYYY-MM-DD). Left out, this computer's date, and the date used is returned as result.as_of. | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| party | No | Optional, for detail: a party ledger's name, spelled as in the book or differing only in ASCII case and spaces. A ledger whose own name differs in case or symbols from the spelling its vouchers carry is reached by either; `ledger_match` shows its own name and, when different, `ledger_row_spelling`, the spelling its vouchers carry. The bills are matched on the voucher spelling; what Tally's outstandings reports call such a ledger is not measured, so a detail that finds no bill for a party that has some is not proof it has none. | |
| detail | No | Optional, with party: bill_trail (each bill's allocations) or unadjusted (the party's on-account, advance and pending note allocations). It reads the company's vouchers; the description gives its cost and limits. | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| direction | No | receivable, payable or both (the default). Direction follows the sign of each bill's balance, not the type of party. | both |
| reference | No | Optional, with detail=bill_trail: one bill reference as open_bills lists it; the read then starts at the earliest date the reports list for that bill. | |
| ageing_basis | No | Which date each open bill is aged from: due_date (the default) or bill_date. A bill whose date is after as_of has no age yet. | due_date |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations covering only read-safety, the description carries and discharges the full behavioral burden: it discloses the 128-request/42-voucher ceilings, the 5,376-voucher hard refusal, the named refusal codes, the partial-read semantics (currency_ledgers_excluded), that detail requires a complete read, and that each call appends metadata-only receipt lines locally while writing nothing to Tally.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded well, but the body is an unbroken multi-hundred-word paragraph with no headings, lists or line breaks, mixing call-critical routing rules with rare edge cases. Much of it earns its place given tool complexity, yet the flat blob structure makes it hard for an agent to scan and extract the operative rules.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no output schema, the description is complete: it documents returned fields (result.as_of, open_bills_total/open_bills_shown, next_offset, partial_reason, detail.state, ledger_match, bill_trail/unadjusted outcomes) and the refusal envelope an agent must handle. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the prose adds substantial meaning beyond the schema: the sign-based (not party-type-based) rule for receivable/payable, the netting of unallocated directions, the exact resolution rules for a `party` name, what `reference` does to the read window, and how `top` vs `offset`/`limit` divide the work. This is far more than the schema descriptions convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb and resource: it answers receivable/payable totals, ageing, top parties and open bills from Tally's bills reports. It is clearly distinguished as a bills-reports tool rather than a ledger tool. It stops short of contrasting itself with the many other financial-report siblings (trial_balance, ledger_movement, statement_tie_out), so the differentiation is only partial.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names exactly one alternative ('for a ledger's master record ... use ledger_masters instead') and gives detailed conditions for the `party`/`detail`/`reference` modes. However, it never says when to prefer this tool over the other receivable-adjacent siblings, and no exclusions for the top-level totals/ageing path are stated beyond cost limits.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profit_and_lossARead-only
Return the Profit and Loss for a date range, derived from Tally's native Trial Balance: one line per reserved P&L primary group (Sales Accounts, Direct Incomes, Purchase Accounts, Direct Expenses, Indirect Incomes, Indirect Expenses), each the window's signed debit plus credit movement (a debit negative), with gross_result and net_result (a profit positive). The top-level lines is null while net_result is not established, so a derived line is never shown as the statement. Reads the Trial Balance, the group tree and Tally's own Balance Sheet inside one company, mode and book-extent bracket; requires observed INR currency (a book with more than one currency master is refused) and supported date boundaries. Each line reports amount (sum, present_count, empty_count): the sum is over the amounts Tally returned, and the empty ones it left out are counted. A result is established only if every ledger is classified (a ledger under a user-created primary group, or whose group chain is incomplete, is listed in unclassified, up to 100, with unclassified_total), no Stock-in-Hand ledger carries an amount, and Tally's own Balance Sheet for the window ties line for line to the derived one (balance_sheet_gate). Otherwise it is not_established with a reason (unclassified_ledger_carries_an_amount, closing_stock_not_derivable_from_trial_balance, profit_and_loss_ledger_not_returned, tally_balance_sheet_differs, or for gross and net tally_profit_and_loss_differs); for the two differs reasons, lines names the lines that did not tie. The top-level state is observed only while both gross_result and net_result are established, and not_established otherwise with the same reason the nested result carries (the weaker result decides). A book with stock items is expected to refuse; no inventory book has been measured. A Tally line with an amount the derivation has no counterpart for, such as a heading or a difference in opening balances, refuses rather than being guessed at. Tally's own statements carry no company identity and are bound only by the checks around the read. The gate has been measured over one full year on one book and one month on another; a window spanning more than one financial year is unmeasured. Tally's own Profit and Loss is read too and compared by display name in tie_out (matched, matched_empty_as_zero, differs or not_compared). Gross and net are also refused as tally_profit_and_loss_differs unless it ties: no line differs, no derived line is missing from it, and no line of its with an amount is uncompared, except its Cost of Sales : heading while that equals the derived Purchase Accounts plus Direct Expenses exactly (observed once, on one book). A stock line refuses. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the read-only/idempotency profile, and the description adds substantial context beyond that: it appends metadata-only receipt lines to a local log (explaining the idempotentHint=false), refuses on multi-currency masters, unclassified ledgers, Stock-in-Hand amounts, and Balance Sheet mismatches, and enumerates each `reason`. It discloses what gets written where ('writes nothing to Tally') and the exact gating logic.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and derivation are correctly front-loaded, but the description is a very long wall of text that buries key facts. Sentences such as how far the gate has been measured ('one full year on one book and one month on another') add length without helping an agent invoke the tool correctly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so thoroughly: it documents `lines`, `gross_result`, `net_result`, `state`, `tie_out`, `unclassified`/`unclassified_total`, `balance_sheet_gate` and the `reason` enum. For a tool this complex it leaves an agent well equipped to interpret the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the three parameters (company_guid, from, to) are fully documented by the schema itself; the baseline is 3. The description adds little per-parameter syntax, and its mention of 'mode and book-extent bracket' refers to concepts not exposed as parameters, which does not enrich parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Return the Profit and Loss for a date range'), then pins down exactly what each output line is (one line per reserved P&L primary group derived from the Trial Balance) and how gross/net are computed. This clearly separates it from siblings like balance_sheet, trial_balance and cash_flow, which an agent can distinguish without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied — you call it to get a derived P&L — and the description notes it reads/refuses rather than pointing to alternatives ('a book with stock items is expected to refuse'). It never says when to prefer trial_balance, balance_sheet or statement_tie_out, nor when to avoid this tool, so the when-to-use guidance is only inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
purchase_registerARead-only
Read-only: a register of what the books record, not a GST return. It does not decide input tax credit eligibility or blocked credit, matches nothing against GSTR-2B or any portal, checks no GSTIN (party_gstin is returned only when the voucher carries one), returns reference_date only when the voucher carries one, as Tally sent it (reference likewise; measured on one synthetic book, on one Purchase), does not classify an item invoice's purchase as taxable (has_taxable_entry is false when no entry sits on a Purchase Accounts ledger), and never sums tax across heads or vouchers. It does not treat reverse-charge journals, imports (IGST paid at customs) or input service distribution specially: a voucher that touches a Duties & Taxes ledger is listed by the rule below and nothing more. A GST duty head does not say whether a ledger is input or output, and a Debit Note can be a purchase return or a debit note issued to a customer: each row carries party_group (the voucher party's predefined group, for example Sundry Creditors or Sundry Debtors, when it resolves) and the tool does not guess which it is. It inherits the compliance read's refusals (an INR base currency is required; a book too large to list is refused; see ledger_masters) and refuses with register_master_mark_unavailable when Tally does not report the master-alteration mark. Each page re-reads the masters and the window, so rows can shift between pages. Return the Purchase and Debit Note vouchers of a date window that touch a ledger under Duties & Taxes, with the tax each entry carries taken only from the GST duty head recorded on that ledger's master -- never from a ledger name and never from an amount. Reads the full voucher window before pagination (use narrow dates) and the ledger masters twice, before and after it. Per row: tax_in_books lists each entry on a ledger whose head ComplyEaze Bridge recognises as {ledger, head, raw_head, amount}; duties_taxes_entries_without_gst_head lists entries on Duties & Taxes ledgers that carry no GST head and never assigns them one: observation not_tax_ledger is a ledger whose own tax type is not GST (usually TDS or another payable), absent is a ledger with no head whose tax type is GST or was not reported, which may be a GST ledger whose head is missing (tax_type says which); duties_taxes_entries_with_unrecognised_head lists entries whose head is not in the recognised vocabulary or contradicts the ledger's tax type, with the raw spelling and its observation; entries_on_ledgers_with_unresolved_group lists entries on ledgers whose group chain could not be resolved; taxable_entries are entries on Purchase Accounts ledgers only (a GST purchase booked to a fixed-asset or expense ledger has has_taxable_entry false); party_entries are the voucher party's own; other_entries is everything else (round-off included) with no role inferred. status is the first that applies of head_conflict, has_unrecognised_head, has_unresolved_group, has_entries_without_gst_head, has_other_entries, complete. The response state follows the rule vouchers uses: complete only when every voucher read was checked against a separate count of the window (a census, which ComplyEaze Bridge sends for every book that has held a voucher, however few), otherwise partial with reason nonempty_window_unqualified and the rows still returned; an empty window is complete when its corroboration read confirms it. A row's status is separate: it says whether every entry the voucher touches classified, and the state does not change it. Amounts are as the books state them (negative is a debit), never re-signed and never summed across heads; there is no input-credit or direction field. reference, party_gstin, is_invoice, post_dated follow vouchers: absent means not observed, and cancelled, optional and post_dated vouchers are returned flagged, not excluded. Every other voucher type that touches Duties & Taxes (Sales, Journal, Payment and so on) is listed apart in other_voucher_types_touching_duties_taxes, not in items: whether it belongs in a return is the CA's call. A voucher with no resolved class is listed under unclassified_voucher_type; a voucher that touches only unplaceable ledgers under vouchers_with_unplaced_ledgers; a Purchase or Debit Note voucher with no entry on a Duties & Taxes ledger under purchase_vouchers_without_duties_taxes_entry (exempt or unregistered purchases, tax booked to a ledger filed elsewhere, or a cancelled voucher). A cancelled voucher is listed there with cancelled true whether or not it was taxed, because the cancelled vouchers measured came back from Tally with no ledger entries; a cancelled voucher that keeps its entries is not measured. Rows are in items (paged by offset and limit like vouchers); each has has_taxable_entry, false when no entry sits on a Purchase Accounts ledger (an item invoice may hold it in an inventory allocation). The side lists carry exact counts (total) and at most 100 items (listed); every ledger name in the response is masked like vouchers masks it. A voucher that names a ledger the masters do not list, a master or voucher that changed while the window was read, or a ledger set aside for its currency, refuses (ledger_snapshot_drifted, voucher_window_changed_during_read, register_ledger_currency_excluded) and releases no rows; a row dated outside the window refuses as window_not_honoured, or as voucher_window_part_not_admitted when the window was counted. A sgst_utgst head is a state-side head that a consumer summing state tax must include alongside state_tax. Not measured: a REFERENCEDATE on a sale, item invoices whose purchase ledger sits in an inventory allocation, and books with several currencies. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Far exceeds the annotations. It discloses pagination instability ('each page re-reads the masters and the window, so rows can shift'), the pre-pagination full-window read, local metadata-only receipt logging, that it writes nothing to Tally, and a full catalogue of refusal codes. Consistent with idempotentHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A very long wall of text that front-loads a list of negations and buries the actual purpose in the middle. Many individual clauses carry real behavioral content, but the organization makes the definition hard to scan and the lede is lost.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with no output schema, the description fully documents the return surface: items, side lists with counts, per-row status, and top-level state semantics. An agent has what it needs to interpret results and errors.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by tying from/to to the 'use narrow dates' advice and confirming limit/offset paging behaves like `vouchers`. Most remaining prose concerns output fields rather than input parameters, so it does not go far beyond baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The core purpose is specific verb+resource: 'Return the Purchase and Debit Note vouchers of a date window that touch a ledger under Duties & Taxes.' It clearly distinguishes itself from a GST return and from run-of-the-mill voucher listing. However, this statement is buried after two paragraphs of negative framing, so an agent must read deep before the actual purpose is stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Strong context on when-not: it explicitly says it does not decide input tax credit eligibility, does not match GSTR-2B, and does not classify a return. It also advises 'use narrow dates' and defers to 'ledger_masters' for refusals. It does not name sibling alternatives (e.g. sales_register) by condition, so it stops just short of an explicit when-vs-which routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_evidenceARead-only
Everything the assistant reads from Tally through ComplyEaze Bridge in this chat, amounts included, is sent to the AI provider; redaction can only shorten party and ledger names and bank account numbers or drop narrations, and does not hide amounts, company names, PAN, GSTIN, IFSC, MSME or Udyam registration numbers, contact details or references, or the last four digits of a bank statement's account number (account_last4); under mask_parties a name written inside a narration or reference stays as it is. Never tell the user that no data has left their computer. Shows ComplyEaze Bridge's own recent reads since it started, kept in memory on this computer: request and response fingerprints, byte counts and state, no figures or book content (bounded: the newest limit records). It does not show what the AI provider received. Use it to check which reads ComplyEaze Bridge made since it started, with their fingerprints and byte counts. It reads memory only; this call's own record is added to memory after the read, and its receipt lines go to the local log, like every call's. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many of the newest in-memory records to return: default 20, at most 256 (or the configured row limit, BRIDGE_AGENT_MAX_ROWS, if lower, which can cap the default too). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, but the description earns credit by explaining the surprising idempotentHint=false: it reads memory only, this call's own record is appended after the read, and each call writes metadata-only receipt lines to the local log, with nothing written to Tally. That is real disclosure beyond the annotations. It stops short of describing the exact return shape or the receipt log's location.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is severely bloated and back-loaded: a lengthy redaction/privacy paragraph leads, pushing the actual purpose to the middle. The log-writing behavior is stated twice ('its receipt lines go to the local log, like every call's' then 'Each call appends metadata-only receipt lines…'), and much of the opening paragraph concerns general chat egress rather than this tool's function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden and does convey what comes back: request and response fingerprints, byte counts, and state, bounded to the newest `limit` records. It also clarifies the memory-only, non-Tally-write nature. Minor gaps remain around ordering, timestamps, and whether records include failed reads.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% – the single `limit` parameter is fully documented in the schema itself, including the default of 20, the 256 ceiling, and the BRIDGE_AGENT_MAX_ROWS cap. The description only restates this as '(bounded: the newest `limit` records),' adding no syntax or format detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The operative sentence names a specific verb and resource: it 'Shows ComplyEaze Bridge's own recent reads since it started, kept in memory on this computer: request and response fingerprints, byte counts and state.' It also draws a boundary against the egress_log sibling ('It does not show what the AI provider received'). However, this core purpose is buried after a long privacy preamble, diluting the first-read signal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is stated once and clearly: 'Use it to check which reads ComplyEaze Bridge made since it started, with their fingerprints and byte counts,' and the exclusion 'It does not show what the AI provider received' implicitly points to egress_log. But there is no explicit when-not guidance or sibling name, and the odd instruction 'Never tell the user that no data has left their computer' is a behavioral directive rather than scoping guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sales_registerARead-only
Read-only: a register of what the books record, not a GST return. It does not decide the place of supply, the tax rate, whether tax is payable or which part of a return a sale belongs in, matches nothing against any portal, checks no GSTIN (party_gstin is returned only when the voucher carries one), returns reference_date only when the voucher carries one, as Tally sent it (reference likewise; measured on one synthetic book, on one Purchase and not on a sale), and never sums tax across heads or vouchers. It does not treat exports, sales under reverse charge or advances specially: a voucher that touches a Duties & Taxes ledger is listed by the rule below and nothing more. A GST duty head does not say whether a ledger is input or output, and a Credit Note can be a sales return or a credit note issued to a supplier: each row carries party_group (the voucher party's predefined group, for example Sundry Debtors or Sundry Creditors, when it resolves) and the tool does not guess which it is. A Debit Note, including one issued to a customer, is not a sales row: it is listed apart by identity and ledger names, with no amount. It inherits the compliance read's refusals (an INR base currency is required; a book too large to list is refused; see ledger_masters) and refuses with register_master_mark_unavailable when Tally does not report the master-alteration mark. Each page re-reads the masters and the window, so rows can shift between pages. Return the Sales and Credit Note vouchers of a date window that touch a ledger under Duties & Taxes, with the tax each entry carries taken only from the GST duty head recorded on that ledger's master -- never from a ledger name and never from an amount. Reads the full voucher window before pagination (use narrow dates) and the ledger masters twice, before and after it. Per row: tax_in_books lists each entry on a ledger whose head ComplyEaze Bridge recognises as {ledger, head, raw_head, amount}; duties_taxes_entries_without_gst_head lists entries on Duties & Taxes ledgers that carry no GST head and never assigns them one: observation not_tax_ledger is a ledger whose own tax type is not GST (usually TDS or another payable), absent is a ledger with no head whose tax type is GST or was not reported, which may be a GST ledger whose head is missing (tax_type says which); duties_taxes_entries_with_unrecognised_head lists entries whose head is not in the recognised vocabulary or contradicts the ledger's tax type, with the raw spelling and its observation; entries_on_ledgers_with_unresolved_group lists entries on ledgers whose group chain could not be resolved; taxable_entries are entries on Sales Accounts ledgers only (a sale booked to another ledger, or whose sales ledger sits in an inventory allocation, has has_taxable_entry false); party_entries are the voucher party's own; other_entries is everything else (round-off included) with no role inferred. status is the first that applies of head_conflict, has_unrecognised_head, has_unresolved_group, has_entries_without_gst_head, has_other_entries, complete. The response state follows the rule vouchers uses: complete only when every voucher read was checked against a separate count of the window (a census, which ComplyEaze Bridge sends for every book that has held a voucher, however few), otherwise partial with reason nonempty_window_unqualified and the rows still returned; an empty window is complete when its corroboration read confirms it. A row's status is separate: it says whether every entry the voucher touches classified, and the state does not change it. Amounts are as the books state them (negative is a debit), never re-signed and never summed across heads; there is no input-credit or direction field. reference, party_gstin, is_invoice, post_dated follow vouchers: absent means not observed, and cancelled, optional and post_dated vouchers are returned flagged, not excluded. Every other voucher type that touches Duties & Taxes (Purchase, Journal, Payment and so on) is listed apart in other_voucher_types_touching_duties_taxes, not in items: whether it belongs in a return is the CA's call. A voucher with no resolved class is listed under unclassified_voucher_type; a voucher that touches only unplaceable ledgers under vouchers_with_unplaced_ledgers; a Sales or Credit Note voucher with no entry on a Duties & Taxes ledger under sales_vouchers_without_duties_taxes_entry (listed by identity only; the tool does not say why such a voucher carries no tax entry). A cancelled sale that Tally returns with no ledger entries is listed there too, with cancelled true; no cancelled sale has been read, so whether one keeps its entries is not measured. Rows are in items (paged by offset and limit like vouchers); each has has_taxable_entry, false when no entry sits on a Sales Accounts ledger (a sale typed on Tally's screen, or an item invoice of another shape than the imported one that was measured, may hold the sales ledger in an inventory allocation instead; not measured). The side lists carry exact counts (total) and at most 100 items (listed); every ledger name in the response is masked like vouchers masks it. A voucher that names a ledger the masters do not list, a master or voucher that changed while the window was read, or a ledger set aside for its currency, refuses (ledger_snapshot_drifted, voucher_window_changed_during_read, register_ledger_currency_excluded) and releases no rows; a row dated outside the window refuses as window_not_honoured, or as voucher_window_part_not_admitted when the window was counted. A sgst_utgst head is a state-side head that a consumer summing state tax must include alongside state_tax. Measured so far: sales_register was run against a live Tally on two synthetic companies. On the first, once per day, for one taxed Sales item invoice and one untaxed one: the taxed sale came back as one row with its CGST and SGST/UTGST heads taken from the ledger masters and its sales ledger as the taxable entry, and the untaxed one (read once by an earlier build; its voucher window is committed, its masters and the tool's answer are not) was counted under sales_vouchers_without_duties_taxes_entry. On the second, which has 44 ledgers, for one Credit Note in voucher view booked on account: one row, with its CGST and state-tax heads and its sales ledger as the taxable entry. One Sales accounting voucher (not an invoice) was also classified, in tests, against the ledger masters of the purchase register's lab book. A Credit Note is returned as a row with its signs reversed as Tally sends them: the tool neither nets nor flips, so a caller that sums tax over a window must add signed amounts. The measured Credit Note of 1,000.00 with 90.00 CGST and 90.00 State Tax came back with the sales entry -1000.00, each tax entry -90.00 and the party entry 1180.00, where a Sales row has the sales and tax entries positive and the party entry negative. The state-side tax head is state_tax (raw State Tax) on one measured book and sgst_utgst (raw SGST/UTGST) on another; both are recognised heads for the same side of the tax, so a caller must not look for one of them only. The cost of a call varies by book: 102 requests on a book with 8 ledgers and one currency (96 were recorded before a small book was counted, plus the six the count adds; not measured since), 118 on one with 44 ledgers and two currencies, which adds base-currency reads; the result does not report the cost. Not shown by any run: an invoice-view Credit Note; an inter-state (IGST) line; a cancelled or optional sales voucher; an unrecognised or missing duty head on a sale; more than one voucher in a window; paging; a company with a registration; a tax that Tally computes itself; a sale typed on Tally's screen; accounting-invoice mode; a post-dated sale; a REFERENCE or a populated PARTYGSTIN on a sale; a REFERENCEDATE on a sale; and a ledger or voucher kept in a currency other than the book's base. A row of such a kind is returned, not withheld, and carries not_measured_live naming why (invoice_view_credit_note, inter_state_line, sales_ledger_not_an_entry, cancelled, optional, post_dated, party_gstin_present, reference_present) only where the row itself shows the kind. Kinds a row cannot show are never marked and are not vouched for: a sale typed on Tally's screen in voucher view, a tax Tally computed itself, a duty head no sales capture has (such as cess), an invoice of another shape than the one run (for example several goods lines), and a ledger or voucher kept in a currency other than the book's base; an unmarked row is not a measured one in those respects. A row is marked inter_state_line only when a tax entry's ledger master carries a recognised IGST head; an IGST ledger with no head, or an unrecognised head, is listed under the without-head or unrecognised list and the status is not complete. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover only the safety profile (readOnlyHint, idempotentHint=false, openWorldHint=false), and the description adds far more: pagination instability ('each page re-reads the masters and the window, so rows can shift between pages'), the full refusal vocabulary (`register_master_mark_unavailable`, `ledger_snapshot_drifted`, `voucher_window_changed_during_read`, `window_not_honoured`), base-currency and book-size refusals, per-call cost, and that it writes nothing to Tally but appends metadata-only receipts locally. Nothing here contradicts the annotations, and it explains why idempotence does not hold.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly a thousand-plus words, with the core operational definition not appearing until after three paragraphs of negative scoping ('does not decide… does not treat… does not guess…'). Much of the measured/not-measured and refusal detail is legitimately tool-specific, but the ordering buries the purpose and the repetition of exclusions is costly to an agent parsing it under context pressure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity, no-output-schema tool with 5 parameters, the description covers everything an agent needs: row fields and their meaning, the `status` precedence ladder, `state` semantics, side lists with counts and 100-item caps, name masking, per-voucher-type routing (other_voucher_types_touching_duties_taxes, unclassified_voucher_type, sales_vouchers_without_duties_taxes_entry), refusal codes, and which cases are unmeasured (`not_measured_live`).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description earns extra credit by adding operational semantics the schema lacks: it urges narrow date windows because the full voucher window is read before pagination, and it notes offset/limit paging behaves like `vouchers` with rows possibly shifting between pages. It does not restate the date pattern or limit/offset defaults, leaving those to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Buried mid-description but unambiguous: 'Return the Sales and Credit Note vouchers of a date window that touch a ledger under Duties & Taxes.' It names its verb, resource, and scope, and explicitly walls itself off from siblings ('not a GST return', behaves like `vouchers`, inherits refusals from `ledger_masters`), so an agent can distinguish it from `purchase_register` or `vouchers` without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description supplies strong context for when the tool applies (GST-relevant sales/Credit Note rows touching Duties & Taxes) and extensive when-not framing (does not decide place of supply, tax rate, payability, return placement; other voucher types are listed apart and 'whether it belongs in a return is the CA's call'). It points to references like `ledger_masters` and the `vouchers` behaviour it follows, but never states a direct use-this-instead-of-that routing to a sibling tool, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statement_tie_outARead-only
Tie the bank ledger in Tally to the bank statement already parsed by parse_bank_statement, at the start and at the end of the statement's own dates, or of the whole calendar months it was parsed for. Read-only: it writes nothing to Tally and never posts. Its check of the import journal takes the shared import-admission lock for a moment, so a build or post at the same time can be refused as lock-busy, and it can be refused by theirs; call again. It reads the proposals file named by proposals_id and proposals_sha256 (as build_import_xml does) and the book's ledger list three times: at the window's first date, at the day after its last date, and at the first date again, which catches a change dated before the window or an edit to the ledger itself (its opening balance, name or removal) made during the read (a voucher dated inside the window and posted during the read moves only the end figure and is not caught). No ledger is read when the file alone answers (window_not_recorded, window_narrower_than_statement, window_not_whole_calendar_months, window_beyond_statement_rows) or the window starts before the company's books begin (window_precedes_books_from). It reads no vouchers, and each ledger-list read has the same deadline and size limits as ledger_movement's. The proposals file is not bound to a company: pass the company_guid of the company the statement belongs to, because a different company that has a ledger of the same name is read just as readily. The window is the whole statement, from its first to its last row date, at the balances you supplied. A file parsed with from or to that left rows out is compared over those dates only if they are whole calendar months (from the 1st to a month's last day) within the statement's rows; the opening and closing are then worked out from the statement's own rows, so a gap together with the book's figure gives the statement's balance at the month edge. Any other window is not_established: window_not_whole_calendar_months, or window_beyond_statement_rows when a month starts before the statement's first row or ends after its last. So is a narrowed file written before parse_bank_statement recorded a window's balances (window_narrower_than_statement), and one written before it recorded the statement's dates (window_not_recorded); parse the statement again. The result carries the stage, the two dates, rows_without_voucher, three figures, a fixed reading and the company block. opening_gap is the book at the start of the window's first date less the statement's balance then; closing_gap is the book at the end of its last date less the statement's balance then, where stage before_build adds what this file's vouchers would put into the bank ledger (where the book would stand once the file is imported) and stage after_post is the book as it stands now; change_in_window is closing_gap less opening_gap. All three are in the statement's sign: positive means the book shows more money in the bank than the statement does. The book's own balances are not returned, but a gap plus the statement's balance at that date (for the whole statement, the balance you supplied) gives the book's balance, so they are derivable from the result. For whole calendar months the reverse also holds: the book's figure less a gap gives the statement's balance at the month edge, and change_in_window with the book's movement gives the statement's net over those months. These are totals per calendar month, never a part of a month except the part-months at the statement's own start and end, whose net a month edge's balance gives together with the opening and closing you supplied; but a month in which every other row's amount is already known (one row alone, or one row beside open cash lines, whose amounts parse_bank_statement returns) gives that row's amount. Each figure has a state: tied (exactly zero), differs, or not_established with a reason (window_not_recorded, window_narrower_than_statement, window_not_whole_calendar_months, window_beyond_statement_rows, window_precedes_books_from, bank_ledger_not_in_book, book_changed_during_read; for before_build also rows_without_voucher, when some rows of the statement have no voucher in the file because a cash line is unanswered or a row is skipped, and file_already_partly_posted, when the import journal already holds a row of this file, either of which leaves closing_gap and change_in_window not established). A gap does not say why: uncleared cheques and deposits in transit, a missing entry, a repeated entry and the wrong bank ledger look alike here, and the reading says so and prescribes no remedy. It checks the bank ledger only; a wrong party or expense ledger is not caught. Use it after parse_bank_statement and before build_import_xml with stage before_build, and again with stage after_post after a post or an import by hand. Requires one observed INR currency master, as ledger_movement does. Not yet proved against a live book. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| stage | Yes | before_build: the closing gap counts this file's vouchers as if they were already in the book. after_post: the book as it stands now, for after any of the file's vouchers has been imported, by anyone. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. | |
| proposals_id | Yes | The proposals_id parse_bank_statement returned for the statement. | |
| proposals_sha256 | Yes | The sha256 parse_bank_statement returned for that proposals file; the call is refused (proposals_changed) if the file no longer has it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint/destructiveHint/idempotentHint, but the description goes far beyond them: it discloses the import-admission lock and lock-busy refusal, the triple ledger-list read and what change it does and does not catch, per-read deadlines matching ledger_movement, the local receipt-line logging, that it writes nothing to Tally, and that it is 'not yet proved against a live book'. The idempotentHint=false is consistent with the locking and log-append behavior described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is dense and largely load-bearing given the tool's complexity, but it is delivered as one undifferentiated wall of text with run-on sentences and no front-loading of structure. The full list of not_established reasons is repeated twice, and window_not_whole_calendar_months appears three times, which violates 'every sentence earns its place'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so: it enumerates the result fields (stage, two dates, rows_without_voucher, three figures, a fixed reading, company block) and defines opening_gap, closing_gap and change_in_window including sign convention and derivation of the book's balance. Error/reason codes and the limits of what a gap proves are all covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: why company_guid matters ('The proposals file is not bound to a company... a different company that has a ledger of the same name is read just as readily'), what proposals_id/sha256 bind to (refused as proposals_changed if stale), and how stage changes the closing figure. It does not explain window parameters (which come from the proposals file, not this schema), so it stops short of 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause gives a specific verb and resource ('Tie the bank ledger in Tally to the bank statement'), names the sibling that produces its input (parse_bank_statement), and implicitly distinguishes it from build_import_xml and ledger_movement by naming them as adjacent tools. An agent can tell this is a bank reconciliation check without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states explicitly: 'Use it after parse_bank_statement and before build_import_xml with stage before_build, and again with stage after_post after a post or an import by hand.' It also names the exclusion (checks the bank ledger only; a wrong party or expense ledger is not caught) and the prerequisites (one observed INR currency master, as ledger_movement does).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stock_summaryARead-only
Return the stock summary: the closing stock value per stock item as of a date, with the total of those values checked against Tally's own Stock Summary, and whether inventory is integrated with the accounts. The top-level state is one of three. value_total_matched: the items are returned, and their closing values add up to the sum of the top-level lines of Tally's own Stock Summary; only that total was compared, so value_total_matched can stand beside partial true when some items have no closing value. no_stock_items: Tally's own stock item count is 0, the item list is empty and the Stock Summary is empty; items is an empty list. not_established: no item is returned (items is null), reason says why and remediation says what to do next: tally_stock_summary_differs (the report has a total the items do not add up to), tally_stock_summary_shows_no_value (the items carry a value and the report has no amount; an empty report is not told apart from one Tally did not render) or stock_values_not_comparable (nothing could be compared). Such a result carries unchecked_comparison in place of tie_out, for investigation only: neither side is a stock value or a total, the items' side adds only the closing values present, and the closing-value total of a matched read is the only thing this tool checks. A not_established result is not held for paging, and it replaces any earlier read of the same date. A closing quantity is returned only where Tally's own plain Stock Summary shows the same item by name with the same quantity, unit and amount (closing.quantity.state agreed, with amount and unit); every other item says why not (none_sent, unread, inside_stock_group, report_has_no_line, report_name_not_unique, report_differs). In the captures the report listed only what sits directly under the root, so an item inside a stock group is taken to have no line and no quantity is returned for it (inside_stock_group); totals.closing_quantity_unread_count counts quantities that could not be read (a compound unit, or a unit with a space), which do not refuse the read. checks says per field what is checked, checked_per_item or not_checked: the closing-value total is checked; the closing quantity is checked item by item; each value on its own, the names, parents and base units, and whether the date was honoured are not. as_of (YYYYMMDD or YYYY-MM-DD) must be a 31 March, not before the book's start or after today. The only period measured is the period ending 31 March 2026; other years' 31 March are admitted but unmeasured, and any other date is refused as stock_summary_as_of_not_measured before any request. The period runs from 1 April (or the book's start, if later) to as_of. Each item carries name, guid, parent, base_unit and closing; closing holds value exactly as Tally sends it, and quantity (a state, with amount and unit when it is agreed). Empty is not zero: an empty closing value is returned as null and counted in totals.empty_closing_value_count, and a value sent as 0.00 is a value. Signs are kept, as in the trial balance: a negative value is a debit, which is stock held, and Tally's own Stock Summary screen shows it as a positive value (measured on one synthetic company, licensed TallyPrime 7.1 Silver). value_sum adds the values with their signs, so stock held gives a negative sum, and totals.value_sum_signs is always as_sent_negative_is_debit; value_sum is written at the scale of the values it adds, and is null with partial true whenever any item's closing value is empty. The opening quantity and value are read but not returned, because their as-at date is unmeasured. inventory reports integrated, inventory_on and batchwise as yes, no or unknown (unknown does not refuse), and basis states what Tally reported (ISINTEGRATED); how the books use these values (as closing stock, or against a Stock-in-Hand ledger) is not measured. An item valued at zero or with no value adds nothing to either total, so only Tally's own stock item count vouches for it; that count followed the one delete measured (one synthetic company, one sample), which is not proof of a complete list (checks.item_list_complete is not_checked). item_count_cross_check reports rows, tally_count and status: items are returned only when the two are equal. Otherwise the read is refused as stock_summary_item_count_differs (both numbers under counts); a count Tally did not give refuses as stock_summary_read_failed with cause stock_item_count_unavailable, and a Stock Summary this Tally does not recognise with cause stock_report_unknown. items (1 to 50 GUIDs, each once) filters what is returned from the held read; a GUID not found is listed under items_not_found, not refused, and totals, tie_out and item_count_cross_check still cover the whole book. The inventory flags, the stock items and the Stock Summary are each read twice inside one company, mode and book-extent bracket, or the read is refused. A book whose inventory is off is refused as stock_not_enabled, Education mode is refused, and a company split by year, whose sibling companies share the GUID, is refused (stock_summary_read_failed, cause company_flags_not_one_row). Small books only: the items are read whole only when the master-alteration mark (it counts masters of every kind) times an assumed worst-case row fits 16,000,000 bytes, a mark of at most 874; a larger book is refused before any item request as stock_summary_too_large, with size, and retrying refuses again. Typical stock-heavy client books refuse today. A row count or response size past what was admitted refuses as stock_summary_bound_premise_violated, or stock_summary_extent_changed if the book moved. Limits: company totals only, with no godown or batch split and no rates. The row shape and the tie were measured on one synthetic book on one licensed TallyPrime 7.1 (the tie also once on a client book); other releases, dates and books are not measured. An item's name and parent are masked under mask_parties, because stock names can carry a customer's or supplier's name (Tally's reserved root as a parent is left as it is); guid is not masked and is what items filters on. A first page (offset 0) always reads afresh and holds the read; a later page for the same date is served from it while the book extent, including ALTVCHID and ALTMSTID, is unchanged, and each result reports snapshot. Pass the first page's snapshot_id on later pages to have the call refused as listing_snapshot_changed instead of continuing from a different read (cause book_changed_since_first_page, or snapshot_not_held for an id not held). A change that moves neither mark is not seen, so a later page can be up to 10 minutes old after such a change. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | Yes | The last day of the stock period, a 31 March (YYYYMMDD or YYYY-MM-DD). The period runs from 1 April, or the book's start if later. | |
| items | No | Optional: 1 to 50 stock item GUIDs, each once, to return only those items. A GUID not found is listed under items_not_found; the totals still cover the whole book. | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| snapshot_id | No | Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint/destructiveHint already covering the safety profile, the description adds far more: does not write to Tally, appends metadata-only receipt lines to a local log, masks item names and parents under mask_parties, staleness of up to 10 minutes on later pages, and the full set of refusal codes with causes. The non-idempotent nature (fresh read on offset 0, snapshot-served later pages) is disclosed and consistent with idempotentHint=false. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The return-value description is front-loaded, but the body is an undifferentiated wall of run-on sentences with no headings or grouping, running to hundreds of words. Much is redundant with the schema, and critical facts are buried mid-paragraph. Adequately sized only because the tool is complex; structurally poor.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the full return-shape burden, and it does so exhaustively: the three `state` values, `checks` per-field coverage, item field shape (`name`, `guid`, `parent`, `base_unit`, `closing`), signs convention, `value_sum` scale, totals counters, and every refusal cause. Nothing an agent needs to interpret or invoke the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description genuinely adds meaning: `as_of` constraints (31 March, within book start and today, unmeasured-year behavior), `items` semantics (not-found GUIDs listed, totals/tie_out still cover the whole book), and `snapshot_id` refusal behavior (`listing_snapshot_changed`, `snapshot_not_held`). These go beyond the schema text rather than repeating it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first clause states a specific verb and resource — 'Return the stock summary: the closing stock value per stock item as of a date' — with the tie-out and inventory-integration checks named up front. An agent can tell this is a per-item closing-stock read rather than a trial balance or generic ledger read. It never names a sibling tool explicitly to differentiate itself, so it lands at 4 rather than 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Strong conditional guidance: `as_of` must be a 31 March not before book start or after today, only the period ending 31 March 2026 is measured, Education mode and inventory-off books are refused, and small books only (mark <= 874) are admitted. These effectively define when the tool may be used, and paging guidance (pass the first page's snapshot_id) is given. It stops short of naming an alternative tool to use instead when refused, so not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tally_statusARead-only
Return loopback endpoint status and observed loaded-company identity tuples. Every ComplyEaze Bridge process on this computer (the desktop app and each AI client) sends to one Tally port one request at a time. Any tool that reads may therefore refuse, having sent nothing: tally_endpoint_busy when another ComplyEaze Bridge window or AI client held the port for longer than this call's bounded wait (about 10 seconds in all per call); it carries retry_after_s, and the same call is safe to repeat after that many seconds. post_import can be refused the same way, but only repeat it when the refusal says attempt_recorded is false; once an attempt is recorded, follow the refusal's next_step (verify_import) and never call post_import again. tally_endpoint_lock_unavailable when ComplyEaze Bridge could not open its local coordination file. today is this computer's calendar date (YYYYMMDD), the date outstandings uses when as_of is left out, and ledger_masters with fields=compliance for party_gstin. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: single-request-at-a-time concurrency across all Bridge processes, a ~10 second bounded per-call wait, the tally_endpoint_busy and tally_endpoint_lock_unavailable failure modes, the retry_after_s field, and the metadata-only local receipt log with an explicit 'writes nothing to Tally' guarantee. This is exactly the behavioral context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose well, but the body is a dense run-on spanning error codes, retry rules, and a `today` explanation that mostly concerns outstandings and ledger_masters rather than this tool. The date discussion is scope creep on a zero-parameter status probe and dilutes the core message.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-param read-only probe with no output schema, the description covers failure modes, retry policy, and side effects (local receipt log, no Tally writes) adequately. It never describes the shape of the returned status/identity tuple, which is the one remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4; the description instead documents the derived `today` value (this computer's calendar date, YYYYMMDD) that other tools consume. That is useful context but is not parameter semantics for this tool itself, so it stays at baseline rather than exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Return loopback endpoint status and observed loaded-company identity tuples.' An agent can tell this is a health/status probe distinct from the data-reading siblings, though the phrasing is jargon-heavy and no sibling is named as an alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the contention model clearly and when refusals occur (another ComplyEaze Bridge process holding the port), plus what to do: retry after retry_after_s for reads, and for post_import only when attempt_recorded is false, otherwise follow verify_import. It does not explicitly frame which situations should trigger calling this tool first, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
trial_balanceARead-only
Return native ledger-wise Trial Balance for a date range, using Tally's TBAL fields without scanning vouchers. Requires an INR base currency and supported date boundaries. A book with several Currency masters is read through the base Tally identifies: only its plain base-currency ledgers are returned, with ledgers_scope base_currency_ledgers_only, the ledgers kept in another currency named under foreign_currency_ledgers_excluded, and the base-currency ledgers whose balances Tally shows in another currency named under base_currency_ledgers_mixed_excluded; totals then cover those plain ledgers only (totals_scope) and are not expected to balance. Preserves empty amounts; paired source stability is not voucher-level reconciliation. Pagination limits output only. A first page (offset 0) always captures a fresh report and holds it in memory; a later page for the same period (offset > 0) is served from it while the company's book extent, including ALTVCHID and ALTMSTID, is unchanged, at the cost of one small extent read. Each result reports snapshot (id, master_alter_id, voucher_alter_id, read_at, reused). Pass the first page's snapshot_id on later pages to have the call refused with listing_snapshot_changed (cause book_changed_since_first_page or snapshot_not_held) instead of continuing from a different report. A change that moves neither mark is not seen. A voucher delete, a cancel, a save with no change and a master change made in Tally's own screens each moved a mark when measured (protocol reference section 11c.5, one run each), but a change that moves neither can leave a later page up to 10 minutes old. For one ledger's movement counted from the window's vouchers, with how many vouchers touched it, use ledger_movement instead. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| snapshot_id | No | Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say read-only/non-destructive; the description goes well beyond them by disclosing the snapshot caching model, the refusal path ('listing_snapshot_changed' with its two causes), the up-to-10-minute staleness window, the exact ledger scoping rules (base_currency_ledgers_only, foreign_currency_ledgers_excluded, base_currency_ledgers_mixed_excluded) and that totals are not expected to balance. It also honestly discloses a side effect not visible in annotations: metadata-only receipt lines appended to a local log, while writing nothing to Tally.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is correctly front-loaded in sentence one, but the remainder is a single dense run-on paragraph with nested clauses and marginal detail ('a save with no change and a master change made in Tally's own screens each moved a mark when measured (protocol reference section 11c.5, one run each)'). Almost every sentence carries relevant information, but bullet points or paragraph breaks would make the snapshot protocol far easier to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does a good job: it names the 'snapshot' fields (id, master_alter_id, voucher_alter_id, read_at, reused), the totals scope, and the row scoping. The detailed ledger row shape and the receipt-line format are not described, but the omissions are minor for a report endpoint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics the schema lacks: snapshot_id must be the first page's id and is only meaningful on later pages, and its effect (refusal rather than silent continuation from a different report) is spelled out. It also explains the offset/limit pagination contract (a fresh report is captured at offset 0 and reused for later pages).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Return native ledger-wise Trial Balance for a date range') and adds the mechanism ('using Tally's TBAL fields without scanning vouchers'), which distinguishes it from voucher-scanning siblings. It also explicitly names the adjacent tool it is not (ledger_movement), so an agent can separate the two without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives prerequisites ('Requires an INR base currency and supported date boundaries') and an explicit redirect with its selecting condition ('For one ledger's movement counted from the window's vouchers... use ledger_movement instead'). It does not, however, address close sibling reports such as balance_sheet, profit_and_loss or statement_tie_out, so routing for the wider report family is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_mastersARead-only
Bind 1–100 nonblank ledger names (at most 1024 characters each) against the live catalogue. An identifier embedded in a master name is matched before the name itself. match_state is exact, identifier, near_miss or missing; folded names remain near_miss candidates because this catalogue has no qualified scope to bind them. Only exact is admitted by build_import_xml, and a bound row alone carries exact_live_spelling. A near-miss is never resolved: it returns candidates with the rule that surfaced each, bounded to 25 names and 8192 UTF-8 bytes per requested name, with candidate_count, candidate_count_is_lower_bound and truncation reported. When candidate_count_is_lower_bound is true, the count is a conservative lower bound and must be shown as at least that many candidates. There is no ranking and no score. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| ledgers | Yes | 1 to 100 ledger names to bind against the live catalogue, each spelled as it will be written into a voucher. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the read-only/idempotency profile, but the description adds non-obvious behavior: each call appends metadata-only receipt lines to a local log (tool, company, counts, fingerprints, no book content) while writing nothing to Tally. It also discloses candidate bounds (25 names, 8192 bytes), truncation reporting, and that a near-miss is never auto-resolved — all beyond what the annotations state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and scope are front-loaded, and virtually every sentence carries substantive semantics about matching or returns rather than filler. The trade-off is a dense, run-on block without structure, which burdens parsing but not length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description does the heavy lifting by enumerating match_state values, the exact_live_spelling-only-on-bound-rows rule, and candidate_count/truncation reporting. It is thorough on semantics and side effects, though it doesn't describe the overall response shape (e.g. per-name result entries) or error behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already documents both parameters, including the minLength/maxLength/pattern constraints that the description restates. The description adds only incremental meaning (identifier precedence inside a name, spelling-as-written), so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ('Bind 1–100 nonblank ledger names against the live catalogue') and covers scope (count, per-name length). An agent can immediately tell this apart from sibling readers like masters or ledger_masters, since this validates names rather than listing them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It situates the tool in a workflow by noting that only 'exact' is admitted by build_import_xml and that folded names remain near_miss because there is no qualified scope to bind them, which tells the agent when a near_miss is acceptable versus blocking. It gives clear contextual usage but never names an alternative tool or an explicit when-not condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_importA
Read back a manually imported local batch and write Proof-of-Post files. This never dispatches import XML to Tally. The result gives verification_status, counts, every voucher that is not posted_verified (unverified_vouchers; for a native post a voucher may be bound_not_in_window, book_rolled_back or sent_not_attributed, never absence, with post_span_binding naming how the post was attributed and a plain summary to give the person first; a book restored from a backup and then keyed past the post's voucher mark before this check is not seen as rolled back, and Tally then gives vouchers keyed again the post's MasterIDs, GUIDs and numbers, so a bound voucher can read posted_verified while being one keyed by hand with the same content: measured once, bridge#1050. In plain words: after a restore, a native voucher keyed again with the same content before any check can read verified, and no identifier a read returns tells the two apart (measured once on TallyPrime 7.1 Silver, with Tally's security off), so after restoring a backup over a company, check its posted vouchers in Tally), duplicates, unrelated_duplicates_in_window and ambiguous_within_batch in full, never cut to fit. Only the posted_verified vouchers are paged, as items from offset out of verified_total; when the response cap shortens them it sets truncated and next_offset. To read further pages, call again with proof_sha256 set to the returned proof.sha256 and offset set to next_offset: those pages come from the persisted proof and never read Tally again. The call is refused with verification_proof_changed if a newer verification has since become the batch's current proof, with verification_proof_altered if the saved proof no longer matches its recorded SHA-256, and with verification_too_large_to_report if the parts never cut do not fit the response cap. The first page also carries a transfers section for the company, in the shape build_import_xml returns: the bank rows skipped as carried by another account's Contra that are not yet paired with a verified Contra, by bridge_txn_id and date. It is computed after the verdict is saved and changes no verdict; transfers.state not_established means it could not be computed (for example another process holds the import folder) or was cut to fit the response, not that nothing is open. A later page never carries it. Every verification's full proof is kept on disk; none is replaced. Reads the batch's date window from Tally, then adds new proof files for the batch beside every earlier one and a status record naming them current, and may also add a verified baseline, a masters-check record and, for a native post, the binding of its vouchers to the Tally vouchers its post created, in ComplyEaze Bridge's local folder on this computer, replacing and deleting nothing there (paging an existing proof only reads it); writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| batch_id | Yes | The batch_id build_import_xml returned for the saved batch. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. | |
| proof_sha256 | No | On a later page only: the proof.sha256 the first page returned, so the page is served from that saved proof without reading Tally again. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite thin annotations (readOnlyHint=false, destructiveHint=false), the description discloses the full behavioral profile: named refusal codes (verification_proof_changed, verification_proof_altered, verification_too_large_to_report), the persistence model ('every verification's full proof is kept on disk; none is replaced'), the exact write target, and the guarantee that it 'replaces and deletes nothing' and 'writes nothing to Tally.' This is far beyond what the annotations convey and is consistent with them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence is well front-loaded, but the rest collapses into a single sprawling run-on paragraph with deeply nested parentheticals (the bridge#1050 aside, the restore caveat, the transfers digression) that are hard to parse. The valuable content is present but poorly structured, and several clauses repeat the same 'measured once' caveat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, stateful, side-effecting tool with no output schema, the description covers return fields, pagination, refusal conditions, the transfers section, and every filesystem side effect. An agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value beyond the individual schema fields by explaining the cross-parameter contract for paging (proof_sha256 must be the returned proof.sha256, offset must be next_offset) and the fact that such pages 'never read Tally again.'
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening states a specific verb and resource ('Read back a manually imported local batch and write Proof-of-Post files') and immediately delimits scope with 'This never dispatches import XML to Tally,' which separates it from the build_import_xml sibling it names later. An agent can identify the tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear operational routing: how to page ('call again with proof_sha256 set to the returned proof.sha256 and offset set to next_offset'), when the call is refused, and that only the first page carries the transfers section. It does not explicitly say when to prefer this over related read/validation siblings, so it falls short of naming alternatives and exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
voucher_presenceARead-only
Answer which of 1–500 proposed vouchers are already in the book. presence is present, possibly_present or absent, and only present names a book voucher. A nonempty window is read as complete only when its rows were checked voucher for voucher against a count ComplyEaze Bridge made of the window first, as vouchers labels it; ComplyEaze Bridge makes that count for every book that has held a voucher, however few, so a small book can read complete too. A nonempty window not counted is partial with reason nonempty_window_unqualified. An empty window is complete only when a read widened by a day on each side is also empty and the company has no vouchers (company_has_no_vouchers); it is otherwise partial, with empty_uncorroborated when the widened read is also empty but the company has vouchers, and empty_window_wider_read_nonempty when the widened read found rows on the neighbouring days, which cannot count the window. present and possibly_present never need a complete window and are produced either way, but absent means absent from the whole window and is only ever produced from one proven complete — a proposal that would otherwise be absent from a merely partial window instead comes back possibly_present with reason window_not_proven_complete. The conditional decision basis can use a voucher number on a voucher type you declare manual — unique on both sides, within an observed voucher type, and never onto a cancelled or optional voucher; or, for a voucher ComplyEaze Bridge wrote into a file a person imported by hand, the narration marker derived from the supplied batch_id and bridge_txn_id together. A native post (post_import) writes no marker, so this tool cannot identify its vouchers: one edited or re-dated in Tally can read absent here. Check a natively posted batch with verify_import, which finds its vouchers by the GUIDs its post created once its binding is made, before posting any of them again. It neither accepts nor reads client remote identifiers. Supplying only one narration identity component is an error. The marker reaches only the current writer identity scheme; older-scheme ComplyEaze Bridge writes stay unidentified rather than matched. Date, party and amount only ever produce candidates, with the rule that surfaced each and no ranking or score. Every voucher type a proposal names needs a declared numbering method; under automatic Tally discards the supplied number, so nothing can be decided from it. absent means absent from this window, so cover the dates the book could hold. A proposal comes back absent only when the window is proven complete, nothing in it resembles the proposal, a voucher type declared manual carries its voucher number, and the party was supplied and could be compared completely; a proposal with no party (a Journal has none), no manual number, or a party whose comparison was cut short comes back possibly_present with a reason such as party_not_supplied, manual_number_not_supplied or party_not_decidable, however complete the window is. Reads the full window before comparing; dense windows can fail source limits. Party names bind through the same rules as validate_masters. A reported difference on a present voucher is a finding for a person, not a work item: correcting a voucher by Alter or Cancel silently creates a duplicate instead (§9.7), and no ComplyEaze Bridge path can correct a voucher it did not write. This never dispatches import XML to Tally. To list the vouchers of a date window, use vouchers instead. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| vouchers | Yes | 1 to 500 proposed vouchers to look for in the book; the description says what decides present, possibly_present and absent. | |
| numbering | Yes | One entry per voucher type the proposals name, with its numbering method as the person confirms it for the series used, not the numbering_method of the masters tool: manual, automatic or unknown. Under automatic, Tally discards a supplied number, so nothing is decided from it. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/non-destructive/closed-world, but the description adds substantial context beyond them: it writes nothing to Tally yet appends metadata-only receipt lines to a local log, dense windows can fail source limits, it does not accept client remote identifiers, and it never dispatches import XML. These are behavioral facts the annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded, and most sentences carry genuine decision-bearing information, but the description is a ~450-word run-on block that mixes presence semantics, marker identity, error reasons, and caveats without sub-structure. It is dense enough to impede parsing even if little is truly redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, high-parameter tool with no output schema, the description carries the full burden and does so: it enumerates the `presence` values, the `complete`/`partial` window conditions, every reason code, and the failure modes. An agent has enough to call it and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema baseline is 3, but the description adds real meaning: it explains that `numbering` must be declared `manual` for a voucher number to decide anything, that `automatic` makes Tally discard the number, and that `batch_id`+`bridge_txn_id` together derive the narration marker (one alone is an error). This goes beyond the schema's field-level text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource ('Answer which of 1–500 proposed vouchers are already in the book'), and the closing sentence names the sibling it is not ('To list the vouchers of a date window, use vouchers instead'). An agent can distinguish it from `vouchers` and `verify_import` without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly routes the agent: use `vouchers` to list a date window, and use `verify_import` for natively posted batches ('Check a natively posted batch with verify_import'). It also states the preconditions for each decision outcome, so when-to-use and when-not-to-use are both covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
voucher_read_costBRead-only
Say, before a call, the most census reads one call of vouchers, ledger_movement or verify_import will send on this company (a read can be refused before its census ends), and the least time a call that is not refused earlier spends on the gaps between them. The census follows the company's voucher mark, not the window: this figure is for one call, a narrower window does not lower it, and reading N days in N calls pays it N times. It is as of this call's own read of the mark; the next call reads the mark again. It reads the company's identity and then its marks (one paired read with an identity check on either side), the opening every windowed call makes, and sends no census and no voucher request. The count and the floor are derived from the mark and the gate's rules, not measured on this book, and the floor leaves out every data part. No estimate is made: measured is constant text, whole calls recorded in the protocol reference with their census reads, data parts, host, date and confidence, each marked as not a bound. Nothing is refused on this figure; the one refusal it can state is the one the read itself makes (voucher_window_book_too_large). Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| company_guid | Yes | The company's company_guid, as list_companies returns it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that it reads company identity and marks with an identity check, that the read itself can be refused (`voucher_window_book_too_large`), that the figure is derived not measured, and that each call appends metadata-only receipt lines to a local log while writing nothing to Tally. That is rich, useful behavioral detail complementing the readOnly/idempotent hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense block that is far longer than the operation warrants and is not front-loaded: the core answer (it returns a max read count and a floor) competes with tangents about `measured`, protocol references, and logging. Sentences do not earn their place, given the odd phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does try to sketch return values (count, floor, `measured`), and annotations carry the safety profile. But the sketch is opaque enough that an agent cannot confidently predict the response shape for a low-complexity single-param tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter, and the schema already documents it fully (100% coverage, with its own description). The prose adds no format or lookup detail for company_guid, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description does state what the tool returns: the maximum census reads and the minimum gap-time a call of `vouchers`, `ledger_movement` or `verify_import` will incur, i.e. a cost estimator. But it is buried under undefined jargon ('census', 'marks', 'gate') and never names the tool's function cleanly, so an agent must reconstruct the purpose from scattered clauses.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies the when ('Say, before a call...'), and clarifies that it is per-call and that narrower windows do not reduce the figure, which is genuine context. It does not name when to prefer this over a sibling or what action to take with the number.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vouchersARead-only
Return literal-window voucher evidence with curated metadata and redaction. Reads the full source window before selectors and output pagination; limit does not reduce Tally work. A complete window is held in memory for its later pages: a page after the first (offset above 0) is served from that read, with one marks read instead of the whole window, while the company's two marks (vouchers and masters) are unchanged, and its result carries snapshot (id, master_alter_id, voucher_alter_id, read_at, reused). Pass the first page's snapshot_id on later pages to have the call refused with listing_snapshot_changed (cause book_changed_since_first_page or snapshot_not_held) instead of continuing from a different read. Without it, a later page whose window is no longer held or whose book moved reads the window again, and rows can shift between pages. A partial window is not held. A later page is served only for the same question: the same dates (a date is the same however it is written), the same voucher-type selector, search and grouping, and the ledger argument exactly as typed on the first page (a differently spelled ledger is a different question and reads the whole window again). Without snapshot_id, a page whose held window found the book moved reads afresh and carries earlier_snapshot (offsets_do_not_continue true): start again from offset 0. snapshot_id is read on later pages only. Only a page whose snapshot.reused is true continues the earlier pages: a later page with reused false or no snapshot is a fresh read whose offsets may not continue them. A change that moves neither mark is not seen; not established: whether a company feature or configuration change that alters export content moves a mark, whether a restored copy of the company with the same marks is told apart, and whether a remote writer's save shows in the marks at once. So a held page can be up to ten minutes old after its read finished; a first page is always read fresh. Use narrow dates; dense windows are unqualified and can fail source limits. state is complete only when the window's rows were checked voucher for voucher against a count ComplyEaze Bridge made of the window first, or the window was empty, a read widened by a day on each side was also empty, and the company has no vouchers (reason company_has_no_vouchers); otherwise it is partial, with reason nonempty_window_unqualified when rows were not counted, empty_uncorroborated when an empty window's widened read is also empty but the company has vouchers, and empty_window_wider_read_nonempty when the widened read found rows on the neighbouring days (the window's own read found nothing and those rows cannot count it, so an empty window beside a busy day cannot reach complete today). ComplyEaze Bridge makes that count for every book that has held a voucher, however few, so nonempty_window_unqualified is expected only when the company's mark reads zero while the window holds rows. Selectors apply after the window is labelled, so a zero from a complete window is a checked zero. A voucher created, altered or deleted between the count and the read refuses with voucher_window_part_not_admitted, cause part_census_mismatch; call again. Each item carries cancelled and optional (always booleans; a source that omits or cannot assert either fails the whole read rather than guess). post_dated behaves differently: Tally asserts it on every voucher when the fetch list asks for it, and the key is left out only when a source does not report it (one old capture did, taken before the tag was asked for), so it is boolean only when Tally asserted Yes/No and is absent from the item when Tally did not report it. Absent is not evidence of false — it means ‘Tally did not say’, not ‘Tally said no’, and a caller must branch on key presence, not on falsiness, before treating a voucher as not post-dated. Neither this tool's listing nor voucher_presence filters out post-dated (or optional/cancelled) vouchers; the caller decides what a non-posting or unobserved status means for its own computation. (A summarise_by call is the exception: it sets aside cancelled, optional and entry-less vouchers and counts them, and sums post-dated ones with a count.) reference, is_invoice and party_gstin follow the same absent-means-not-observed convention as post_dated: each key is present only when Tally reported a non-empty value for it, and its absence must not be read as false or as an empty string. is_invoice is a boolean exactly like post_dated; reference and party_gstin are non-empty strings when present. A captured book with no GSTIN recorded against a party's ledger has shown party_gstin absent on every voucher for that party, which is not evidence Tally cannot report one. Filter by voucher type with at most one of: voucher_class (a reserved class such as Purchase, matched however the book has renamed its types, and including their child types, by Tally's own class functions), voucher_type_guid (exactly one type; a GUID that is not this company's is refused as voucher_type_guid_foreign), or voucher_type (one display name, matched ignoring ASCII case as Tally does). Voucher-type names are editable in Tally, so a display name that is a class name, or the reserved name of any type in scope, is refused as voucher_type_ambiguous whenever the types of that name are not exactly the types of that class or reserving that name; the types involved are listed in candidates (bounded to a quarter of the response budget, with candidates_total and candidates_truncated). Use voucher_class or voucher_type_guid instead. That check sees only the vouchers in scope: the window read, after any ledger filter. A type with no voucher in scope is not seen, and when nothing is in scope nothing is ambiguous. When a voucher_type name selects no voucher, one more read lists the book's voucher types: a name no type carries is refused as unknown_voucher_type, with the name as requested and every type in candidates, nearest name first (bounded as above); a name some type carries keeps its zero. A filtered result carries voucher_types: the types included and every type in_scope (name, GUID, own reserved name, class and row count), and each item carries voucher_type_guid, voucher_type_reserved_name and voucher_class (null outside the measured classes). A row whose type Tally cannot resolve, or whose class answers contradict each other or its reserved name, refuses the whole read. A voucher whose amount Tally stored as a foreign-currency composite (-$ 100.00 @ I₹ 86/$ = -I₹ 8600.00) is withheld, not read: it still passes every date, ledger and type check, and is then listed in withheld_vouchers (GUID, date, type, number and cause foreign_currency_amount_unparsed, up to 100) with an exact withheld_total, the same on every page. items and total then exclude it, state is partial with reason vouchers_withheld, and coverage says so; the voucher_types row counts still include it, and the listing is also bounded to a quarter of the response budget. Any other amount Tally did not return as a plain decimal still refuses the whole read, as does a composite whose foreign and base amounts differ in sign while the foreign amount is not zero. A ledger name resolves only when spelled as in the book or differing from it only in ASCII case and spaces; ledger_match names the ledger read, how (matched: exact, or case_or_spacing, which the answer should mention by naming the ledger read) and any similar_ledgers that differ from it only in case or whitespace. Search: voucher_number and reference (each matched whole, ignoring ASCII case and surrounding spaces), narration_contains (a phrase of at least 3 characters, matched ignoring letter case, accent composition and runs of spaces) and amount (a plain unsigned decimal, matched against the absolute value of any ledger entry of a voucher, so it finds an invoice total and a tax line alike) keep only the vouchers that satisfy every criterion given. The search runs last, on the labelled window, so a zero from a complete window is a checked zero; each item then carries matched (which criteria held and, for an amount, the positions in amounts that equalled it). A blank, over-long or invalid criterion is refused (search_criterion_empty, search_criterion_too_long, search_narration_too_short, search_amount_invalid), and a narration phrase is refused as search_narration_redacted where narrations are withheld from the assistant. suspense_tagged (true, only with ledger) keeps the vouchers of that ledger whose narration ends in a suspense tag ComplyEaze Bridge writes and says which in matched.suspense_tag; it classifies by the narration text, so the same text typed by hand matches and a narration edited after the tag is not listed: also read the ledger without it. It is refused as search_suspense_tagged_needs_ledger without ledger and as search_narration_redacted where narrations are withheld. A voucher withheld for a foreign-currency amount is never dropped by an amount search, since its amounts cannot be compared: it stays in withheld_vouchers and the result stays partial. A held window is reused only for the same search, and only for the same listing or summary: a listing and a summary of one question hold separate windows. voucher_types counts are taken before the search, so with a search they do not add up to total. Summaries: summarise_by (ledger, month, voucher_type, group or primary_group) returns buckets instead of items, over the same window and the same selectors and search; offset and limit then page the buckets. Each bucket has group (a ledger name, a YYYY-MM month, a voucher type name or a group name), vouchers (an exact count, each voucher once), debit (zero or negative, as ledger_movement reports it), credit, net (debit plus credit) and voucher_refs (up to 5 vouchers by date, type, number and GUID; voucher_refs_complete says whether that is all of them; a vouchers listing without summarise_by, narrowed with the existing selectors, lists the rest). Debit and credit follow each entry's sign (a zero amount stays on the side Tally flagged it). A ledger bucket adds the entries on that ledger of the vouchers the window, selectors and search selected: with a ledger, type or search given, a counter-ledger's bucket holds only its entries on those vouchers, not that ledger's whole movement. A month or type bucket adds all the entries of its vouchers (debits and credits then equal in size), or only the selected ledger's entries when ledger is given. entries_counted says which: all_entries or selected_ledger. A group or primary_group bucket adds the entries of the ledgers under that group (every entry of the selected vouchers, also when ledger is given). A group bucket holds only the ledgers directly under that group, as the ledger master shows it (a ledger directly under the root is under Primary, with reserved_name null), so a predefined group whose ledgers sit in sub-groups has no bucket or a small one: its whole figure, descendants included, is in subtree_totals (each group on any bucket's chain with covers, depth, vouchers, debit, credit and net over everything under it, never to be added to a bucket of the same group, whose own covers says it holds only the ledgers directly under it, largest movement first, at most 60, with subtree_totals_total exact and subtree_totals_complete; they overlap, so they do not add up to totals). A group bucket carries reserved_name (empty for a group the book's user made), chain (every group from it up to the one under the root, nearest first, each with name and reserved_name) and primary_group. A primary_group bucket holds every ledger under the group directly under the root and is keyed by its reserved name, so a renamed predefined group stays one bucket and shows its current name in group (a group the book's user made there is keyed by its name). Each has members (the ledgers in it with their own debit and credit, largest movement first, at most 10), members_total (exact) and members_complete; a group bucket cannot be narrowed with a selector, so trace its vouchers through a member ledger with ledger. Group names are shown as the book has them (a group may be named after a party); member ledger names are masked when parties are masked. The groups are the book's masters read now, not the grouping in force on each voucher's date: each ledger's group chain is read before the window and again after it and must be the same, or the call refuses (group_snapshot_drifted, or ledger_snapshot_drifted if the set of ledgers changed). A ledger that the ledger list does not hold, or whose group chain cannot be walked, refuses the whole summary (summary_group_unresolved, with cause no_parent, group_absent, group_name_repeated, reserved_name_missing, cycle, exhausted, top_group_not_under_root or ledger_not_in_catalogue; ledger names the ledger that could not be placed, the group is not named, and no_parent also covers a parent group Tally returned that ComplyEaze Bridge will not carry). By construction a group summary adds 30 requests to the window read, with or without ledger (a paired, identity-bracketed read is 6 requests: the company's marks to size the ledger list first, then the ledger list and the group list before the window and again after it); in one live run each call took 64 requests (34 for the window and 30 for the group modes, as counted from the code); a book of thousands of ledgers was not measured: a book whose master-alteration mark is above 11,983 is refused first (summary_group_book_too_large; the limit is provisional and computed, not measured: 16 MiB, a size chosen here and not verified, over the compliance ledger read's estimate of 1,400 bytes a ledger, which that read measured at 1,104 (a book of 1,989 ledgers) and 1,221 (a real book of about 9,500) on its own list without balances, and this list read 1,175 bytes a ledger in one live run (51,698 bytes for a book of 44 ledgers; a small book, so the figure is not a basis to raise the limit); the mark is an upper bound on ledgers, so a smaller book may be refused, and the limit is about half of what the transport's own rule admits for the same list), a real book's group buckets may need several pages (use offset), and on a large book ledger totals are cheaper with trial_balance. Group summaries were checked once against a live TallyPrime 7.1 on one synthetic book of 67 vouchers: each bucket equalled the ledger buckets added up by the trial balance's own parent column and the call took 64 requests; a large book, a group renamed or moved while a window is read and a held later page were not run live. Each bucket has position, its place in the whole ordering (labels of ledgers can read alike when parties are masked, and a masked label cannot be passed back as ledger); to list a month bucket's rest, narrow from and to to that month. totals is the debit and credit the buckets add up to, vouchers_summarised the vouchers behind them, and excluded_from_buckets the cancelled, optional and entry-less vouchers left out (counted, not hidden). Post-dated vouchers are summed, not set aside: post_dated_included counts those Tally flagged Yes and post_dated_flag_absent those with no flag at all (the read asks for the flag and Tally asserts it on every voucher, so that is expected to be 0; only when it is not does a zero in the first prove nothing); a voucher type that does not post (a memorandum, a reversing journal, a sales or purchase order, a delivery or receipt note), if the book uses it and Tally exports it with ledger entries, is not told apart and is summed too: basis says so in the result. Checked once against a live TallyPrime 7.1 on a synthetic book of 67 vouchers (a year, 44 ledgers, a debug build of master at 4c30f3f9f): every ledger, month and voucher-type bucket equalled the sums over the listed vouchers, the 30 ledger buckets equalled trial_balance for the same year, each search returned what the same criterion selects from the listing, and a later page came from the held window in 10 small requests. Not covered: a memorandum, a reversing journal, a voucher withheld for a foreign-currency amount, mask_parties, withheld narrations, an item invoice with stock lines, paging of a summary past one page, ledger name resolution, another TallyPrime edition or release, Windows, a large book. Cost, from that one run: a plain read took 34 requests, about 7 s and about 6 MB from Tally; each ledger, month or voucher_type summary or search call reads the window again at the same cost, and ledger adds 12 requests there, four of them reads of the whole ledger list (a group summary adds 30 with or without ledger, below); for a month or more on a large book read ledger totals with trial_balance (it has no month or voucher-type grouping and no search; the same year's trial_balance took 34 requests and 2.5 s on that book; one day of vouchers took minutes on the largest book measured, a voucher mark of about a million). Bucket debit, credit, net and totals are plain decimals with trailing zeros dropped (1000, -87900.5); an item's amounts keep the two places Tally sent (1000.00). Withheld vouchers are not in any bucket and the result is partial. A voucher whose entries do not balance refuses the whole summary (voucher_entries_unbalanced). Buckets are ordered by the larger movement first (ledger, type, group, primary_group), ties in movement keeping the order in which the bucket was first counted in the window, or by month. A held window serves a later page of buckets as it serves a later page of vouchers. Each ledger entry's bill_allocations carries reference, bill_type and amount; where Tally sends them it also carries bill_date (YYYYMMDD, the original bill's date for an Agst Ref) and credit_period (a value and a unit of days, weeks or months, or unit unrecognised with its text when the text cannot be read); an allocation Tally sent neither for has neither. To ask whether vouchers you mean to post are already in the book, use voucher_presence instead. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The last day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| from | Yes | The first day of the date range, included (YYYYMMDD or YYYY-MM-DD). | |
| limit | No | The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise). | |
| amount | No | Optional: an unsigned decimal such as 1180.50; only vouchers with a ledger entry of exactly this amount (debit or credit). Each item says which entries matched. | |
| ledger | No | Optional: only vouchers with an entry on this ledger, spelled as in the book or differing only in ASCII case and spaces. A ledger whose own name differs in case or symbols from the spelling its vouchers carry is reached by either; `ledger_match` shows its own name and, when different, `ledger_row_spelling`, the spelling its vouchers carry. | |
| offset | No | How many rows to skip before this page: 0, the default, is the first page. | |
| reference | No | Optional: only vouchers whose reference is exactly this, ignoring ASCII case and surrounding spaces. A voucher with no reference never matches. | |
| snapshot_id | No | Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read. | |
| company_guid | Yes | The company's company_guid, as list_companies returns it. | |
| summarise_by | No | Optional: ledger, month, voucher_type, group or primary_group. The result then holds buckets of debit, credit and voucher counts instead of the vouchers, over the same window, selectors and search; offset and limit page the buckets. group and primary_group sum each ledger under its group as the book has it now (see the description). | |
| voucher_type | No | Optional, at most one of the three: one voucher type's display name, matched ignoring ASCII case. A name that could mean more than one class or type is refused (voucher_type_ambiguous). | |
| voucher_class | No | Optional, at most one of voucher_class, voucher_type_guid and voucher_type: a reserved class, matched however the book has renamed its types, child types included. | |
| voucher_number | No | Optional: only vouchers with exactly this voucher number, ignoring ASCII case and surrounding spaces. Numbers repeat across voucher types, so more than one voucher can match. | |
| suspense_tagged | No | Optional, true only, and only together with `ledger` (the suspense ledger): keep the vouchers on that ledger whose narration ends in a suspense tag ComplyEaze Bridge writes ("Bridge: purpose not confirmed; reclassify", or "UNIDENTIFIED - reallocate from" followed by the name of one of the voucher's own ledgers), allowing one trailing [BRIDGE:...] marker after it. Each item says which tag in `matched.suspense_tag`. This classifies by the narration text: it does not prove ComplyEaze Bridge wrote the voucher (the same text typed by hand matches), and a voucher on the ledger whose narration was edited after the tag is NOT listed, so also read the ledger without this filter and treat every voucher left over as still in suspense. Refused without `ledger` and where narrations are withheld from the assistant. | |
| voucher_type_guid | No | Optional, at most one of the three: exactly one voucher type, by its GUID. Another company's GUID is refused (voucher_type_guid_foreign). | |
| narration_contains | No | Optional: only vouchers whose narration contains this phrase (at least 3 characters), ignoring letter case, accent composition and runs of spaces. Refused where narrations are withheld from the assistant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare read-only/non-destructive, but the description discloses far more: snapshot holding and reuse, pages up to ten minutes stale, refusals (listing_snapshot_changed, snapshot_not_held, part_census_mismatch, group_snapshot_drifted), foreign-currency withholding, and an explicit statement that the call writes nothing to Tally and only appends metadata-only receipt lines locally. This is well beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is an unformatted wall of several thousand words with no headings or bullets, mixing essential contract (snapshot rules, refusals, selector semantics) with internal engineering notes (a debug build hash, byte-per-ledger estimates, the provenance of a 16 MiB limit, a single live-run request count). The purpose is front-loaded, but most passages do not earn their place in a tool description an agent must parse on every call.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 16-parameter tool with pagination, snapshot semantics, five summary modes, withholding and numerous refusal codes, the description is more than complete: it covers the window model, selector interactions, summary bucket accounting, subtree_totals, search behavior and error causes. No output schema exists, so coverage of return structure is necessary and is provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all 16 parameters (baseline 3). The description adds genuine semantics on top: ledger name resolution rules, voucher_type ambiguity and the candidate listing, the absent-means-not-observed convention for post_dated/reference/party_gstin/is_invoice, and the meaning of snapshot_id on later pages. It is richer than the schema alone, though much of the same text is duplicated in the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening states a specific verb and resource ("Return literal-window voucher evidence with curated metadata and redaction") and the body makes clear it lists vouchers and can instead return summaries via summarise_by. It explicitly distinguishes itself from voucher_presence and trial_balance. The phrase "literal-window voucher evidence" is dense jargon that a first-time reader must decode, which keeps this just below a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It routes the agent explicitly: use voucher_presence to check whether vouchers are already posted, use trial_balance for ledger totals on large books, use voucher_class or voucher_type_guid instead of voucher_type when ambiguity is possible, and read the ledger without suspense_tagged as a cross-check. It also states when-not (dense windows are unqualified and can fail source limits; narrow dates advised). Nothing about tool selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
voucher_schemaARead-only
Return the fail-closed local voucher-file schema; no Tally request is sent. Each call appends metadata-only receipt lines (tool, company, counts, request and response fingerprints; no book content) to ComplyEaze Bridge's local log on this computer; it writes nothing to Tally.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=false, and destructiveHint=false. The description adds valuable context beyond annotations by detailing that each call appends metadata-only receipt lines to a local log, specifies what data is logged, and confirms no writes to Tally. It does not violate any annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loads the purpose, and includes relevant behavioral details without unnecessary verbosity. It is appropriately sized for a zero-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, no parameters, and no output schema, the description provides sufficient information about what it returns and its side effects. There is no output schema, so the description covers the essential return behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters, the baseline is 4. The description does not need to explain any parameters, and it appropriately focuses on the tool's behavior rather than parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a fail-closed local voucher-file schema and explicitly says no Tally request is sent. It distinguishes itself from siblings like vouchers or voucher_presence by emphasizing the local schema-return behavior, though it does not name any specific sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use this tool versus alternatives. It implies usage by stating it returns a schema and writes a local receipt, but provides no conditions, prerequisites, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.4.4- Added
month_register
21 tool updates
v0.4.3- Changed
balance_sheet3 fields changed- added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / from / descriptionAdded value: +"The first day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - added
Input schema / properties / to / descriptionAdded value: +"The last day of the date range, included (YYYYMMDD or YYYY-MM-DD)."
- Added
cash_flow - Added
company_features - Changed
egress_log1 field changed- added
Input schema / properties / limit / descriptionAdded value: +"How many of the most recent receipt lines to return (each completed call writes two): default 20, at most 256 (or the configured row limit, BRIDGE_AGENT_MAX_ROWS, if lower, which can cap the default too), and fewer when the newest receipt lines do not fit in the log read's size bound."
- Added
gst_status - Changed
ledger_masters10 fields changed- added
Input schema / properties / as_of / descriptionAdded value: +"Optional, with fields=compliance only: the day the GSTIN in force is read for (YYYYMMDD or YYYY-MM-DD). Left out, this computer's date." - added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / fields / descriptionAdded value: +"basic (the default) or compliance, which adds the party-master observations, each ledger's group ancestry and its gst_duty_head; the description says what each holds." - added
Input schema / properties / group / descriptionAdded value: +"Optional: return only the ledgers under this group name; which ones count follows group_scope." - added
Input schema / properties / group_scope / descriptionAdded value: +"With group: immediate (the default) matches only a ledger's own parent; ancestry matches any group in its resolved chain, the whole subtree." - added
Input schema / properties / include_gst_detailsAdded value: +{ + "default": false, + "description": "Optional boolean, default false, with fields=compliance only (any other fields is refused as ledger_masters_gst_details_requires_compliance): add each ledger's dated GST rate details as compliance.gst_details. They are Tally's ledger-level details as sent, per dated entry and state row; a rate is absent, empty, zero or a value, never merged. HSN/SAC and type of supply are not returned; slab rates are only flagged. Measured on one 14-ledger lab book; not yet run through this tool on a live Tally. The read is admitted at 8,000 bytes a ledger instead of 3,750, a margin over the one capture (a ledger with an empty list 2,138 to 2,704 bytes; one dated entry 5,248 to 5,394; UTF-16 bytes of the ledger's own element), not a measured ratio; a large book may be read in more parts or refused as too large. On later pages repeat `include_gst_details` as well as `as_of`: a later page called without `include_gst_details` reads afresh and returns rows without `gst_details` (`snapshot.reused` false), and only a call that names snapshot_id is refused.", + "type": "boolean" +} - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / snapshot_id / descriptionAdded value: +"Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read."
- Changed
ledger_movement7 fields changed- added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / from / descriptionAdded value: +"The first day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - added
Input schema / properties / ledger / descriptionAdded value: +"Optional: one ledger's name, spelled as in the book or differing only in ASCII case and spaces. Left out, every ledger. A name that does not resolve is refused before any voucher is read." - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / to / descriptionAdded value: +"The last day of the date range, included (YYYYMMDD or YYYY-MM-DD)."
- Changed
masters7 fields changed- added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / kind / descriptionAdded value: +"Which masters to list, one kind per call: voucher_types, godowns, units, stock_groups, cost_centres, cost_categories or groups (account groups)." - changed
Input schema / properties / kind / enumPrevious value: -[ - "voucher_types", - "godowns", - "units", - "stock_groups", - "groups" -]New value: +[ + "voucher_types", + "godowns", + "units", + "stock_groups", + "cost_centres", + "cost_categories", + "groups" +] - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / snapshot_id / descriptionAdded value: +"Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read."
- Changed
outstandings11 fields changed- added
Input schema / properties / ageing_basis / descriptionAdded value: +"Which date each open bill is aged from: due_date (the default) or bill_date. A bill whose date is after as_of has no age yet." - added
Input schema / properties / as_of / descriptionAdded value: +"Optional: the day the open bills are read as of (YYYYMMDD or YYYY-MM-DD). Left out, this computer's date, and the date used is returned as result.as_of." - added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / detail / descriptionAdded value: +"Optional, with party: bill_trail (each bill's allocations) or unadjusted (the party's on-account, advance and pending note allocations). It reads the company's vouchers; the description gives its cost and limits." - added
Input schema / properties / direction / descriptionAdded value: +"receivable, payable or both (the default). Direction follows the sign of each bill's balance, not the type of party." - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / party / descriptionAdded value: +"Optional, for detail: a party ledger's name, spelled as in the book or differing only in ASCII case and spaces. A ledger whose own name differs in case or symbols from the spelling its vouchers carry is reached by either; `ledger_match` shows its own name and, when different, `ledger_row_spelling`, the spelling its vouchers carry. The bills are matched on the voucher spelling; what Tally's outstandings reports call such a ledger is not measured, so a detail that finds no bill for a party that has some is not proof it has none." - added
Input schema / properties / reference / descriptionAdded value: +"Optional, with detail=bill_trail: one bill reference as open_bills lists it; the read then starts at the earliest date the reports list for that bill." - added
Input schema / properties / top / descriptionAdded value: +"How many parties to rank by gross exposure (default 25). It ranks parties only; page the bills with offset and limit."
- Changed
profit_and_loss3 fields changed- added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / from / descriptionAdded value: +"The first day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - added
Input schema / properties / to / descriptionAdded value: +"The last day of the date range, included (YYYYMMDD or YYYY-MM-DD)."
- Changed
purchase_register6 fields changed- added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / from / descriptionAdded value: +"The first day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / to / descriptionAdded value: +"The last day of the date range, included (YYYYMMDD or YYYY-MM-DD)."
- Changed
read_evidence1 field changed- added
Input schema / properties / limit / descriptionAdded value: +"How many of the newest in-memory records to return: default 20, at most 256 (or the configured row limit, BRIDGE_AGENT_MAX_ROWS, if lower, which can cap the default too)."
- Changed
sales_register6 fields changed- added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / from / descriptionAdded value: +"The first day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / to / descriptionAdded value: +"The last day of the date range, included (YYYYMMDD or YYYY-MM-DD)."
- Added
statement_tie_out - Changed
stock_summary7 fields changed- added
Input schema / properties / as_of / descriptionAdded value: +"The last day of the stock period, a 31 March (YYYYMMDD or YYYY-MM-DD). The period runs from 1 April, or the book's start if later." - added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / items / descriptionAdded value: +"Optional: 1 to 50 stock item GUIDs, each once, to return only those items. A GUID not found is listed under items_not_found; the totals still cover the whole book." - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / snapshot_id / descriptionAdded value: +"Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read."
- Changed
trial_balance7 fields changed- added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / from / descriptionAdded value: +"The first day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / snapshot_id / descriptionAdded value: +"Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read." - added
Input schema / properties / to / descriptionAdded value: +"The last day of the date range, included (YYYYMMDD or YYYY-MM-DD)."
- Changed
validate_masters2 fields changed- added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / ledgers / descriptionAdded value: +"1 to 100 ledger names to bind against the live catalogue, each spelled as it will be written into a voucher."
- Changed
verify_import4 fields changed- added
Input schema / properties / batch_id / descriptionAdded value: +"The batch_id build_import_xml returned for the saved batch." - added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / proof_sha256 / descriptionAdded value: +"On a later page only: the proof.sha256 the first page returned, so the page is served from that saved proof without reading Tally again."
- Changed
voucher_presence8 fields changed- added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / from / descriptionAdded value: +"The first day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / numbering / descriptionAdded value: +"One entry per voucher type the proposals name, with its numbering method as the person confirms it for the series used, not the numbering_method of the masters tool: manual, automatic or unknown. Under automatic, Tally discards a supplied number, so nothing is decided from it." - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / to / descriptionAdded value: +"The last day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - added
Input schema / properties / vouchers / descriptionAdded value: +"1 to 500 proposed vouchers to look for in the book; the description says what decides present, possibly_present and absent."
- Added
voucher_read_cost - Changed
vouchers17 fields changed- added
Input schema / properties / amountAdded value: +{ + "description": "Optional: an unsigned decimal such as 1180.50; only vouchers with a ledger entry of exactly this amount (debit or credit). Each item says which entries matched.", + "maxLength": 256, + "minLength": 1, + "type": "string" +} - added
Input schema / properties / company_guid / descriptionAdded value: +"The company's company_guid, as list_companies returns it." - added
Input schema / properties / from / descriptionAdded value: +"The first day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - added
Input schema / properties / ledger / descriptionAdded value: +"Optional: only vouchers with an entry on this ledger, spelled as in the book or differing only in ASCII case and spaces. A ledger whose own name differs in case or symbols from the spelling its vouchers carry is reached by either; `ledger_match` shows its own name and, when different, `ledger_row_spelling`, the spelling its vouchers carry." - removed
Input schema / properties / limit / defaultRemoved value: -500 - added
Input schema / properties / limit / descriptionAdded value: +"The most rows to return on this page. The default and the maximum are this server's row limit (500 unless it is configured otherwise)." - added
Input schema / properties / narration_containsAdded value: +{ + "description": "Optional: only vouchers whose narration contains this phrase (at least 3 characters), ignoring letter case, accent composition and runs of spaces. Refused where narrations are withheld from the assistant.", + "maxLength": 256, + "minLength": 1, + "type": "string" +} - added
Input schema / properties / offset / descriptionAdded value: +"How many rows to skip before this page: 0, the default, is the first page." - added
Input schema / properties / referenceAdded value: +{ + "description": "Optional: only vouchers whose reference is exactly this, ignoring ASCII case and surrounding spaces. A voucher with no reference never matches.", + "maxLength": 256, + "minLength": 1, + "type": "string" +} - added
Input schema / properties / snapshot_id / descriptionAdded value: +"Optional, on a later page only: the first page's snapshot_id, so the call is refused (listing_snapshot_changed) rather than continuing from a different read." - added
Input schema / properties / summarise_byAdded value: +{ + "description": "Optional: ledger, month, voucher_type, group or primary_group. The result then holds buckets of debit, credit and voucher counts instead of the vouchers, over the same window, selectors and search; offset and limit page the buckets. group and primary_group sum each ledger under its group as the book has it now (see the description).", + "enum": [ + "ledger", + "month", + "voucher_type", + "group", + "primary_group" + ], + "type": "string" +} - added
Input schema / properties / suspense_taggedAdded value: +{ + "description": "Optional, true only, and only together with `ledger` (the suspense ledger): keep the vouchers on that ledger whose narration ends in a suspense tag ComplyEaze Bridge writes (\"Bridge: purpose not confirmed; reclassify\", or \"UNIDENTIFIED - reallocate from\" followed by the name of one of the voucher's own ledgers), allowing one trailing [BRIDGE:...] marker after it. Each item says which tag in `matched.suspense_tag`. This classifies by the narration text: it does not prove ComplyEaze Bridge wrote the voucher (the same text typed by hand matches), and a voucher on the ledger whose narration was edited after the tag is NOT listed, so also read the ledger without this filter and treat every voucher left over as still in suspense. Refused without `ledger` and where narrations are withheld from the assistant.", + "enum": [ + true + ], + "type": "boolean" +} - added
Input schema / properties / to / descriptionAdded value: +"The last day of the date range, included (YYYYMMDD or YYYY-MM-DD)." - added
Input schema / properties / voucher_class / descriptionAdded value: +"Optional, at most one of voucher_class, voucher_type_guid and voucher_type: a reserved class, matched however the book has renamed its types, child types included." - added
Input schema / properties / voucher_numberAdded value: +{ + "description": "Optional: only vouchers with exactly this voucher number, ignoring ASCII case and surrounding spaces. Numbers repeat across voucher types, so more than one voucher can match.", + "maxLength": 256, + "minLength": 1, + "type": "string" +} - added
Input schema / properties / voucher_type / descriptionAdded value: +"Optional, at most one of the three: one voucher type's display name, matched ignoring ASCII case. A name that could mean more than one class or type is refused (voucher_type_ambiguous)." - added
Input schema / properties / voucher_type_guid / descriptionAdded value: +"Optional, at most one of the three: exactly one voucher type, by its GUID. Another company's GUID is refused (voucher_type_guid_foreign)."
1 tool update
v0.4.2- Changed
vouchers1 field changed- added
Input schema / properties / snapshot_idAdded value: +{ + "maxLength": 128, + "minLength": 1, + "type": "string" +}
20 tool updates
v0.4.1- First observed
balance_sheet - First observed
egress_log - First observed
ledger_masters - First observed
ledger_movement - First observed
list_companies - First observed
local_data_report - First observed
masters - First observed
outstandings - First observed
profit_and_loss - First observed
purchase_register - First observed
read_evidence - First observed
sales_register - First observed
stock_summary - First observed
tally_status - First observed
trial_balance - First observed
validate_masters - First observed
verify_import - First observed
voucher_presence - First observed
voucher_schema - First observed
vouchers
TDQS
Scored across 26 tools
Most tools have clearly distinct resource+action scopes and the long descriptions explicitly cross-reference alternatives (trial_balance vs ledger_movement, vouchers vs voucher_presence, registers vs month_register). However, several pairs are conceptually close (month_register vs sales_register/purchase_register, egress_log vs read_evidence, balance_sheet/profit_and_loss vs cash_flow), and the sheer description length makes misselection plausible for an agent.
All 26 names are snake_case with a predictable noun or noun-phrase style, so the surface reads consistently. Minor deviation: a few tools use verb_noun (list_companies, verify_import, validate_masters) while the rest are nouns, but readability and pattern remain intact.
26 tools is at the heavy end and just past the 16-25 borderline band, and a few look like near-duplicates (two read-log tools, a Tally-native month register alongside the derived sales/purchase registers, a cost-estimator tool). The domain (TallyPrime books, GST, inventory, imports) is genuinely broad, so most tools earn their place, but the set feels slightly oversized.
There are significant gaps: the tool set references build_import_xml, post_import and parse_bank_statement as existing operations, yet none are present, leaving the import/post/statement workflow without its key steps. Core read coverage (financial statements, ledgers, vouchers, masters, GST, inventory, diagnostics) is otherwise thorough, with no write/Create path by design.
Maintenance
Related MCP Connectors
AI for Tally Prime and Tally ERP 9. Hosted MCP server to ask your accounts in any language.
Query your books, company data, business health, and ship invoices from your AI assistant.
Connect QuickBooks to ChatGPT, Claude & Grok. Record bills, invoices, journal entries. Run reports.
QuickBooks Online in Claude and ChatGPT: 221 tools, full ledger, multi-company, Canada + US, FR/EN.
Related MCP Servers
- FlicenseAqualityDmaintenanceEnables natural language interaction with TallyPrime accounting software via Claude AI, allowing querying reports, creating vouchers, and managing ledgers without manual navigation.17-
- AlicenseNot gradedqualityBmaintenanceEnables Large Language Models to access and query Tally Prime ERP data, including financial reports, masters, and inventory summaries, via the Model Context Protocol.97MIT
- AlicenseNot gradedqualityDmaintenanceConnects Tally Prime ERP data to AI assistants via MCP, enabling natural language queries for financial reports, stock summaries, and ledger balances.MIT
- AlicenseNot gradedqualityAmaintenanceBridges Tally Prime ERP with AI assistants, enabling querying financial reports, managing masters, creating vouchers, and analyzing GST data through natural language.AGPL 3.0