Wave MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Wave MCPshow my overdue invoices and total amount due"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Wave MCP
A Model Context Protocol server for Wave accounting. It covers the whole public Wave GraphQL API (every query and every non-deprecated mutation), reads and edits transactions through the API Wave's own web app uses, adds payment listings and derived financial reports, and keeps responses small enough that a model can page through real books without flooding its context.
Not affiliated with Wave Financial. Writes change real books and some tools email real customers. Transaction reads and edits use Wave's unofficial web-app API, which Wave can change at any time.
What it can do
Area | Read | Write |
Businesses, user, reference data | context, list/get businesses, currencies, countries/provinces, account types/subtypes | — |
Customers | list (filters + search), get | create, update, delete |
Vendors | list (filters + search), get | Wave API has no vendor writes |
Products & services | list, get | create, update, archive |
Chart of accounts | list with balances, get | create, update (auto sequence), archive |
Sales taxes | list, get with rate history | create, update rates, archive |
Invoices | list (all Wave filters), get with items/payments | create, update, clone, approve, mark sent, email, delete |
Invoice payments | get, list (see below) | record, update, delete, email receipt |
Estimates | list, get with deposits/history | create, update, clone, approve, mark sent/accepted, reset acceptance, convert to invoice, PDF, email, delete |
Estimate deposits | get, list | record, update, delete, email receipt |
Transactions (live) | list/search (date, text, bank account, categories, uncategorized, source; cursor pages), get with every line, tax and sequence | create (public API, single or 50 in bulk); edit date, description, notes, reviewed, account, amount, category, vendor/customer, split lines, sales tax; delete. Web-app API, see Transactions |
Transactions (snapshot) |
| — |
Payments received |
| — |
Reports |
| — |
Anything else |
| — |
72 tools, 3 resources (wave://guide, wave://limitations, wave://schema)
and 3 prompts (month_end_review, chase_overdue_invoices, record_expense).
Every tool, parameter and default is listed in docs/TOOLS.md,
which is generated from the server.
Reports
Wave's public API has no report endpoints, so wave_run_report derives them
and every result states its basis:
Report | Source | Period |
| current account balances | as of now only |
| invoices (invoiced) + invoice payments (paid) | any date range |
| invoice line items | any date range |
| tax on invoice lines (collected only) | any date range |
| invoices by status, overdue | any date range |
| open invoices, bucketed by days past due | as of today |
| a customer's outstanding (or dated) invoices and payments | as of today / range |
Multi-currency totals are converted with each invoice's exchange rate and also reported per original currency.
Transactions (web-app API)
Wave's public API can create transactions but not read, edit or delete them.
wave_list_transactions, wave_get_transaction, wave_update_transaction and
wave_delete_transaction use gql.waveapps.com/graphql/internal, the API
behind next.waveapps.com, with the same operations the web app sends. It is
unofficial: Wave can change it without notice, and it only accepts a
browser session token (see wave-mcp login below), not API tokens.
Edits read the transaction first and send its
sequence(Wave's optimistic lock), so a change made meanwhile in the web app is never overwritten; passexpectedSequenceto pin the version you showed the user.Fields Wave marks as not editable (bank-feed, reconciled, payment or payroll transactions) are refused before anything is sent.
Line amounts include sales tax and must add up to the total; this is checked locally.
salesTaxon a line recalculates tax through Wave's own calculator (omitamount), sets it, or removes it ([]). Wave recalculates taxes it computed itself when an amount changes and keeps manually set ones; the tool warns when that happens.Delete is Wave's soft delete (the web app's Delete).
dryRunshows the exact patch without saving.Journal entries (
journalEntry: true) have no bank side: edit their lines, withsideon new lines; debits must equal credits.Verified live on 2026-11-08:
Walked every transaction of two real businesses (over 1,300 in all), cursor page by cursor page. Each one came back exactly once, in order, and every bank balance rebuilt from them matched Wave's to the cent.
Every filter agreed with the full walk.
Edits were tested on throwaway transactions: header fields, review status, recategorize, amount, split/merge lines, journal lines, tax recalculation/manual/removal, stale sequence and delete.
Wave quirks found while testing, and how the tools handle them:
Quirk | Handling |
Wave's cursors repeat rows when sorting by creation date | Only date sorts are offered |
A page can exceed the response cap | The tool returns fewer rows and points |
| Described in the tool |
Search also matches line descriptions | Described in the tool |
One invalid transaction in a bulk create crashes Wave's server, unnamed | Sides are checked against each account's normal balance before sending |
Customer delete is soft: the record stays readable by ID |
|
What Wave's public API cannot do
Verified against live introspection (see wave://limitations):
No transaction reads or edits (only creates). The tools above fill the gap through the web-app API; the Data Export import is the offline route.
No native reports; account balances have no as-of date. Cash flow, general ledger, aged payables and purchases by vendor cannot be produced.
No bills, bill payments, journal entries, receipts, payroll or bank feeds.
Vendors are read-only; no un-archive; no attachment uploads.
Invoice/estimate lines must reference a product.
Related MCP server: MCP Server for Wave
Install
Node.js 20 or later. Agents get two things on top of the server:
the
wave-accountingskill (skills/wave-accounting/SKILL.md), which covers first steps, sign-in, the tools and the safety rules;the sign-in command, which the server puts into its connector description,
wave_get_context(auth.signIn) and every auth error, with this machine's real path and host name.
pi / Phosphor: one command
pi install git:github.com/agustinsacco/wave-mcppi installs the npm dependencies. The package's extension registers the
wave MCP server for every session (codemode exposure, which keeps the 72
tool schemas out of the context until a script uses them), and the skill joins
every session's skill index. Phosphor can also install it from Settings →
Skills & extensions. Until someone signs in, each new session shows:
Wave is not signed in on <host>. In a terminal there, run: node <package>/bin/wave-mcp.js loginA wave entry in mcp.json takes precedence over the package's registration.
Claude Code and other clients: setup
git clone https://github.com/agustinsacco/wave-mcp && cd wave-mcp && npm install
node bin/wave-mcp.js setupsetup looks for pi and Claude Code, shows each change and asks first:
pi:
pi install <this folder>.Claude Code:
claude mcp add --scope user wave …, plus a link at~/.claude/skills/wave-accounting.
It then runs login and check. Re-running it skips whatever is already set
up, and --yes accepts every step without asking. For other clients (Claude
Desktop, Cursor, …) it prints the config entry to add:
{ "mcpServers": { "wave": { "command": "node", "args": ["/path/to/wave-mcp/bin/wave-mcp.js"] } } }Clients without skills can read the same guide from the wave://guide
resource. Credentials and imported ledgers stay on the machine that runs the
server (~/.config/wave-mcp, ~/.local/share/wave-mcp), so sign in on each
machine where it runs.
Sign in
Credentials live outside the repository in
~/.config/wave-mcp/credentials.env (override with WAVE_CREDENTIALS_FILE),
mode 600. Never put them in MCP config arguments, source or chat. See
credentials.env.example.
Easiest: wave-mcp login (one paste, enables every tool).
node bin/wave-mcp.js loginOpen https://next.waveapps.com and sign in.
DevTools (F12) → Network → type
graphqlin the filter (reload if empty).Right-click a
gql.waveapps.comrequest (namedinternal) → Copy → Copy as cURL (bash, cmd, fetch and PowerShell copies all work).Paste at the hidden prompt.
Only the authorization: Bearer token is kept (cookies and everything else
are discarded) and it is never printed. login asks Wave what kind of token
it is: a web session is saved as WAVE_SESSION_TOKEN (live transactions, and
the public API too when no API token is stored); a full access token pasted
the same way is saved as WAVE_ACCESS_TOKEN. A web session ends when you sign
out of Wave or it times out; tools then say to run login again. logout
forgets it. Piped input works too: wave-mcp login < request.txt.
Option A: full access token (does not expire; works without Wave Pro). In the developer portal → Manage applications → your app → Full access tokens → Create token:
WAVE_ACCESS_TOKEN=...It reaches every business in your Wave account. Use it for personal use and development only.
Option B: OAuth 2 (auto-refreshing, scoped; needs Wave Pro on the business).
Register http://localhost:8765/callback as a redirect URI on the app, then:
WAVE_CLIENT_ID=...
WAVE_CLIENT_SECRET=...
WAVE_REDIRECT_URI=http://localhost:8765/callbacknode bin/wave-mcp.js auth # full scopes
node bin/wave-mcp.js auth --read-only
node bin/wave-mcp.js check # verify, list businessesauth prints the authorization URL. If your browser is on another machine,
approve there and paste the URL the browser was redirected to (the page itself
may not load). Tokens are written back to the credentials file.
Token lifecycle: the access token refreshes two minutes before expiry and once more if Wave rejects it. Wave rotates refresh tokens, so refreshes run under a cross-process file lock with a re-read. Several MCP processes (one per agent lane) can therefore share one file without invalidating each other. Writes are atomic (temp file, fsync, rename, chmod 600).
Configuration
Variable | Default | Meaning |
| auto | Default business. Otherwise the token's business, or the only non-personal one |
| off | Register only read tools |
| all | Comma list: |
|
| Where imported ledgers are stored (mode 600) |
| 60000 | Hard cap per tool result (trailing list items are dropped, with a note) |
| 5000 | Max records a report or search walks |
| 120000 | Cache for scans and reference data; any write clears it |
| 2 | Concurrent Wave requests (Wave's limits are tight) |
| 30000 / 3 | Per request |
| info |
|
| 127.0.0.1 / 8787 / /mcp | HTTP transport |
| loopback | Host/Origin allow-list for HTTP |
| — | Bearer token for HTTP (credentials file); required off loopback |
Use it
Ask things like "which invoices are overdue?", "recategorize last month's
Uber rides to Travel", "what did I sell by product this quarter?" or "split
this transaction between Meals and Office". The prompts give ready-made
versions: month_end_review (month), chase_overdue_invoices and
record_expense.
Streamable HTTP (one server for several clients)
node bin/wave-mcp.js serve --http # http://127.0.0.1:8787/mcp
WAVE_MCP_HTTP_HOST=100.x.y.z WAVE_MCP_ALLOWED_HOSTS=myhost,100.x.y.z node bin/wave-mcp.js serve --httpOff loopback the server refuses to start without WAVE_MCP_HTTP_TOKEN, and
clients send Authorization: Bearer <token>
(pi mcp add wave --url http://myhost:8787/mcp --bearer-token-env-var WAVE_MCP_HTTP_TOKEN).
Host and Origin headers are validated against DNS rebinding. GET /healthz
reports liveness.
Response design
Pagination everywhere. Wave lists use
page/pageSize(default 20, max 100; 25 fordetail: "full"invoices/estimates). Reports and payments useoffset/limit. Every response sayshasMoreand givesnextPage/nextOffset.Summary by default.
detail: "summary"returns key fields and clips long text;get_*tools return everything.Compact JSON. Nulls, empty strings and empty lists are dropped, and
{code}/{value}wrappers are collapsed ("currency": "CAD"). Money is a decimal string.A hard budget. Results above
WAVE_MCP_MAX_RESPONSE_CHARSare trimmed, never silently.Totals cover all rows even when only a page of rows is returned.
Errors are tool results (
isError: true) whose text names the fix: Wave'sinputErrorswith paths, missing IDs, unbalanced transactions with both figures, auth problems with the command to run.
MCP practices followed
Official TypeScript SDK v2 (
@modelcontextprotocol/server), spec 2026-07-28, serving 2025-era clients from the same factory over stdio and Streamable HTTP.Zod input schemas with per-field descriptions and bounds; arguments are validated before handlers run.
Tool annotations on every tool:
readOnlyHint,destructiveHint(update/delete/archive/send),idempotentHint, andopenWorldHint(email sends).Server
instructions, resources for the guide, schema and limitations, and user-invoked prompts.stdout carries only JSON-RPC; logs go to stderr with secrets redacted.
Read-only mode and toolsets for least privilege; no tool accepts or reveals credentials.
Mutations are never retried after an ambiguous network failure (no duplicate writes); rate limits and 5xx on reads back off and retry.
Security
Writes change real books, and
wave_send_*tools email real customers. The skill tells agents to confirm recipients and amounts first.WAVE_MCP_READ_ONLY=1registers only read tools.Credentials live only in the mode-600 credentials file on the machine that runs the server. They are never in MCP arguments, logs or tool results.
loginandsecrets setread them with echo off.Agents are told never to ask for a token, cookie or curl command in the chat, and never to run
loginthemselves.The web-app API is unofficial and needs your browser session, so treat that token like your Wave password. Signing out of Wave ends it.
HTTP binds to loopback unless a bearer token is set.
Development
npm test # unit + end-to-end over both transports (no network)
npm run test:contract # live: every query/mutation document and the inputs the
# write tools build are sent to Wave with an invalid
# token. Wave validates before it authenticates, so
# this proves they are accepted, with nothing read or written
npm run smoke # live, with your credentials: every read tool and report
npm run smoke -- --writes # plus a reversible create/update/delete round trip (test business!)
npm run docs # regenerate docs/TOOLS.md (a test fails when it is out of date)
npm run schema:update # detect upstream schema drift (exit 1 on breaking changes)
npm run inspect # MCP InspectorThe end-to-end tests run a fake Wave built from the real schema snapshot
(schema/wave.graphql), so every document is parsed, validated and executed
exactly as Wave would. The web-app API refuses introspection, so its tests use
a stateful fake (test/helpers/fake-internal.js) that reproduces the
behaviours observed live: sequence locking, JSON-encoded input errors, soft
delete and calculated vs manual sales tax.
Related
questrade-mcp, a read-only MCP server for Questrade, works the same way: it installs the same way, signs in the same way, and has the same CLI and response design.
License
MIT
Available Tools
72 toolswave_approve_estimateApprove estimateAIdempotent
Approve a draft estimate so it can be sent. Does not email it.
| Name | Required | Description | Default |
|---|---|---|---|
| estimateId | Yes | Estimate ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true and destructiveHint=false, so the description's marginal job is the side-effect profile — and it delivers the key fact that no email is dispatched. It still omits what happens on failure (invalid ID, non-draft state) and what the mutated estimate looks like afterward.
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?
Two short sentences, front-loaded with the action and immediately followed by the most likely point of confusion (that it does not send an email). No 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?
For a one-parameter mutation with annotations covering safety and idempotency and no output schema, the description supplies everything an agent needs to pick and call it correctly: the action, the state prerequisite, and the absence of an email side effect.
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 single estimateId parameter is 100% documented in the schema, so the description owes nothing extra there and provides nothing extra. Baseline 3 applies for a high-coverage schema with one parameter.
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 ('Approve a draft estimate') plus the resulting state transition ('so it can be sent'). The clause 'Does not email it' separates it from the sibling send tools (wave_send_estimate, wave_send_estimate_acceptance_email) without naming 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?
Implicitly tells the agent to use this when a draft needs to become sendable, and rules out emailing as its effect. It does not name the alternative tool to call for sending, nor state the precondition explicitly as a requirement (what happens if the estimate isn't a draft).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_approve_invoiceApprove invoiceAIdempotent
Approve a draft invoice, which posts it to the books (status SAVED). Does not email it.
| Name | Required | Description | Default |
|---|---|---|---|
| invoiceId | Yes | Invoice ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false), the description discloses the resulting state (SAVED) and the accounting consequence of posting to the books, which is exactly the context a mutation tool needs. It does not cover failure behavior for non-draft invoices or whether the approval can be reversed.
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?
Two sentences, no filler, with the effective state change front-loaded and the negative scope (no email) placed last. Every clause 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?
For a single-parameter mutation with annotations and no output schema, this covers what the tool does and what state it leaves behind. The only real gap is preconditions and error behavior for invoices that are not in draft.
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 (invoiceId) exists and schema description coverage is 100%, so the schema already carries the semantics. The description adds nothing about the identifier's origin or constraints, 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?
States a specific verb and resource ("Approve a draft invoice") plus the concrete effect ("posts it to the books (status SAVED)"). The closing clause "Does not email it" separates it from wave_send_invoice and wave_mark_invoice_sent without needing to open either 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 word "draft" implicitly scopes when this applies, and "Does not email it" steers the agent away from conflating this with sending. It stops short of naming siblings explicitly (e.g. use wave_send_invoice to deliver it) or stating what happens on a non-draft invoice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_archive_accountArchive accountADestructiveIdempotent
Archive an account (hide it while keeping its history). Wave refuses for system accounts and accounts with a balance. No un-archive through the API.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Account ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is known. The description adds context annotations cannot carry: the two server-side refusal conditions and the fact that the action is irreversible through the API ('No un-archive'). That is precisely the risk information an agent needs before calling a destructive 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?
Three short sentences, no filler: the operation's effect first, then the refusal conditions, then the irreversibility warning. Each sentence carries information an agent would otherwise have to discover by failing the 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 one-parameter destructive mutation with no output schema, effect, preconditions and irreversibility are all covered. A minor gap remains around what happens to linked transactions/reports after archiving, but nothing required to 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?
There is a single required parameter with 100% schema description coverage, so the schema already documents 'Account ID'. The description adds no further meaning about the id (format, where to obtain it), which is the baseline 3 when the schema does the work.
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 and then glosses the operation's semantics: 'hide it while keeping its history.' That gloss is what distinguishes archive from delete, and the resource word distinguishes it from the sibling wave_archive_product and wave_archive_sales_tax.
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-not conditions — Wave refuses for system accounts and accounts with a balance — which is exactly the guidance an agent needs before attempting the call. It stops short of naming a sibling alternative (e.g. wave_update_account for making an account inactive-by-other-means), so it is not a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_archive_productArchive product or serviceADestructiveIdempotent
Archive a product/service so it can no longer be added to new invoices. Past invoices keep it. The API cannot un-archive (web app only).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Product ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered. The description earns credit beyond that by disclosing two non-obvious behaviors: past invoices retain the product, and the archive is irreversible through the API. It doesn't say what happens to existing recurring or draft invoices, which is the remaining gap.
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?
Three short sentences, zero filler, and the primary effect is front-loaded before the edge cases. Each sentence contributes a distinct fact: effect, invoice history, irreversibility.
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 one-parameter destructive mutation with no output schema and safety already covered by annotations, the description covers effect, historical scope, and reversibility. Only secondary consequences (recurring invoices, estimates referencing the product) are left implicit.
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?
There is one required parameter at 100% schema coverage, and the schema already labels it "Product ID". The description adds no meaning about the id (for example, whether it accepts an internal ID versus a display name), 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?
"Archive a product/service" gives a specific verb and resource, and the qualifier "so it can no longer be added to new invoices" states the observable effect. The agent can distinguish this from wave_update_product or wave_list_products by the archive semantics, though no sibling is named explicitly.
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 implies the use case (retiring a product from future invoices) but never states when to prefer this over wave_update_product or how it relates to other product tools. The one routing fact given -- un-archiving is web-app only -- is about recovery, not tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_archive_sales_taxArchive sales taxADestructiveIdempotent
Archive a sales tax so it can no longer be applied. No un-archive through the API.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Sales tax ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description still earns credit for spelling out the semantic consequence — the tax can no longer be applied — and for explicitly stating there is no API path to undo it, which goes beyond the hints. It doesn't say what happens to historical invoices/transactions already using the tax.
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?
Two short sentences, the effect front-loaded and the irreversibility constraint immediately after. No padding, nothing redundant with the title.
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 one-parameter, no-output-schema mutation, the description covers the effect and irreversibility, which are the essentials. The notable remaining gap is whether already-issued invoices keep referencing the tax, which matters for a destructive operation.
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% for the single 'id' parameter, so the schema fully documents the input. The description adds no meaning about the ID format or what a bad/missing ID returns, so 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?
States a specific verb ('Archive') and resource ('sales tax') and adds the consequence ('can no longer be applied'), so the agent knows the operation's effect. It doesn't contrast with sibling archive tools (archive_product, archive_account), but the name plus description makes the target resource unambiguous.
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 phrase 'No un-archive through the API' signals a when-to-use caution by flagging irreversibility, which is real guidance. However, it never names an alternative (e.g., update_sales_tax to modify rather than retire a tax) or states prerequisites such as whether the tax must be unused first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_clone_estimateClone estimateB
Copy an estimate into a new draft.
| Name | Required | Description | Default |
|---|---|---|---|
| estimateId | Yes | Estimate ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false and openWorldHint=false, so the safety profile is covered. The description adds one genuinely new fact beyond annotations – the copy lands as a draft – but says nothing about what is carried over (line items, customer, dates), whether a new ID is issued, or that the source is untouched, and idempotency/non-idempotency implications of repeated calls are unaddressed.
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 front-loaded sentence with zero filler, which is appropriate for a one-parameter clone. It is efficient but so terse that a brief clause on what is copied or what is returned would have been nearly free to include.
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 simple one-param clone with annotations carrying the safety profile, the definition is minimally sufficient to call correctly. However, with no output schema the description is the only place an agent could learn what comes back (new estimate ID? draft object?) or which fields are carried over, and it provides neither.
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% with a single parameter documented as 'Estimate ID', so the schema carries parameter meaning. The description only implies that this ID is the source estimate to be copied; it adds no format, prefix, or sourcing detail.
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 (copy/clone) and resource (estimate) and states the outcome state ('a new draft'), which separates it from wave_create_estimate and wave_convert_estimate_to_invoice. It does not explicitly name the closest sibling (wave_clone_invoice) or contrast the two, but the purpose is unambiguous.
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 only implied by the word 'copy' – an agent can infer 'use this when you want a duplicate rather than a fresh estimate', but nothing states when NOT to use it (e.g. converting vs cloning) or that the source estimate is left unchanged. No alternatives are named despite several adjacent estimate tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_clone_invoiceClone invoiceA
Copy an invoice into a new draft.
| Name | Required | Description | Default |
|---|---|---|---|
| invoiceId | Yes | Invoice ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is non-read-only, non-destructive, and non-idempotent. The description usefully adds that the result is a 'new draft,' implying the source invoice remains unchanged, but it does not say what fields are copied, whether the draft is editable or sendable, or that repeated calls may create multiple drafts.
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 single short sentence that front-loads the action and states the outcome. There is no filler or redundant wording.
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 one-parameter clone operation, the essential call mechanics are covered by the schema and annotations, and 'new draft' communicates the output state. However, an agent choosing among many invoice tools receives no information about what is copied or how this differs from wave_create_invoice, leaving a meaningful selection 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?
There is only one parameter, and its schema description covers 100% of the field, including type and required status. The description does not add selection guidance or formatting detail for invoiceId, so it meets the baseline without adding meaning beyond 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 description uses a specific verb ('Copy') and resource ('invoice') and states the resulting state ('new draft'), so the core action is clear. It does not differentiate from nearby tools such as wave_create_invoice or wave_clone_estimate, so tool selection still relies partly on the name.
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 phrase 'into a new draft' implies this is for duplicating an existing invoice rather than creating one from scratch. However, there is no explicit when-to-use, when-not-to-use, prerequisite, or named alternative such as wave_create_invoice or wave_clone_estimate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_convert_estimate_to_invoiceConvert estimate to invoiceA
Create an invoice from an estimate (deposits paid carry over). Returns the new invoiceId.
| Name | Required | Description | Default |
|---|---|---|---|
| estimateId | Yes | Estimate ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-read-only, non-idempotent, non-destructive behavior, and the description adds genuinely useful context beyond them: deposits paid carry over to the new invoice, and the new invoiceId is returned. It stops short of saying whether the source estimate is modified or left intact, and does not warn that repeated calls will create duplicate invoices.
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?
Two short clauses, both load-bearing, with the transformation rule and the return value front-loaded. Nothing is wasted.
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 one-parameter conversion tool with annotations covering the safety profile and no output schema, the description supplies the essential side effect (deposit carryover) and the return shape. Only the fate of the source estimate and duplicate-call risk are left unstated.
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?
There is a single parameter with 100% schema description coverage, so the schema already carries the burden. The description adds no format, source, or constraint detail about estimateId, making the baseline 3 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?
States a specific verb and resource ('Create an invoice from an estimate') plus the key transformation rule (deposits carry over). This clearly distinguishes it from generic siblings like wave_create_invoice and wave_clone_invoice without needing to name 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?
The conversion framing implies when to use it — when an estimate should become an invoice — but there is no explicit when-not guidance versus wave_create_invoice or wave_clone_estimate, and no prerequisites such as estimate status requirements.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_create_accountCreate accountA
Add an account to the chart of accounts. The subtype decides its type (see wave_get_reference kind=account_subtypes).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| subtype | Yes | ||
| currency | No | Defaults to the business currency | |
| displayId | No | Your account number/code | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is consistent with the annotations: 'Add' aligns with readOnlyHint=false and destructiveHint=false. It adds the useful behavioral detail that subtype determines account type, but it does not elaborate on permissions, validation, duplicate handling, or other mutation consequences beyond what the annotations already say.
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?
Two short sentences with no filler, front-loaded with the action and followed by the key subtype dependency. Nothing is wasted.
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 six-parameter create tool with no output schema, the definition covers the core action and the most important subtype relationship. It remains thin on mutation behavior, return expectations, duplicate constraints, and business-context requirements, leaving meaningful gaps for an agent invoking it.
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 only 50%, so the description should compensate more than it does. It adds meaningful semantics for subtype by explaining that it decides the account type and pointing to wave_get_reference, but it says nothing about name, description, duplicate naming, or the other optional parameters beyond what the schema already provides.
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 states a specific verb and resource: 'Add an account to the chart of accounts.' That distinguishes creation from sibling tools such as wave_update_account and wave_archive_account, though it does not explicitly name those alternatives.
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 by 'Add an account', and the pointer to wave_get_reference for subtype selection gives practical setup guidance. However, it does not say when to create versus update, archive, or list accounts, nor does it state prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_create_customerCreate customerC
Create a customer. Only name is required.
| Name | Required | Description | Default |
|---|---|---|---|
| fax | No | ||
| name | Yes | Customer or company name | |
| No | |||
| phone | No | ||
| mobile | No | ||
| address | No | Postal address | |
| website | No | ||
| currency | No | Default invoicing currency for this customer | |
| lastName | No | ||
| tollFree | No | ||
| displayId | No | Your own account number for the customer | |
| firstName | No | ||
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| internalNotes | No | ||
| shippingDetails | No | Shipping contact and address |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false, destructiveHint=false and openWorldHint=false, so the safety profile is covered. Beyond that the description adds nothing: it does not say whether duplicates are rejected, whether email/currency are validated, or what the call returns. For a write tool with 15 parameters this is thin.
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?
Two short sentences, front-loaded with the action. Nothing is padded, but the second sentence earns little since it duplicates the required field already encoded in the schema.
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 15 parameters, nested address and shippingDetails objects, no output schema, and only 40% schema description coverage, the description leaves most of the tool's contract undocumented. An agent cannot tell what identity fields to prefer (name vs firstName/lastName), how businessId defaults, or what comes back after creation.
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 only 40%, so the schema does not document fax, phone, mobile, website, firstName, lastName, internalNotes, or shippingDetails on its own. The description compensates with the single phrase "only name is required," which merely restates the schema's required array and leaves the other 14 parameters unexplained.
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 states a specific verb and resource ("Create a customer"), which is unambiguous against siblings like wave_update_customer, wave_delete_customer, or wave_create_invoice. It stops short of any sibling routing (e.g. when to reuse wave_update_customer instead), so it stays 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?
"Only name is required" is a parameter fact, not usage guidance. There is no statement of when to use this versus wave_get_customer, wave_list_customers, wave_update_customer, or the generic wave_graphql_query, and no mention of duplicate-detection or preconditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_create_estimateCreate estimateB
Create a draft estimate (quote). Each line needs a product and a unitPrice. Optionally ask for a deposit. Nothing is emailed.
| Name | Required | Description | Default |
|---|---|---|---|
| memo | No | Notes shown to the customer | |
| items | Yes | ||
| title | No | ||
| footer | No | ||
| dueDate | No | Expiry date | |
| subhead | No | ||
| currency | No | ISO 4217 currency code, e.g. CAD or USD | |
| hideName | No | ||
| hideUnit | No | ||
| poNumber | No | ||
| discounts | No | ||
| hidePrice | No | ||
| itemTitle | No | ||
| unitTitle | No | ||
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| customerId | Yes | ||
| hideAmount | No | ||
| priceTitle | No | ||
| amountTitle | No | ||
| depositUnit | No | ||
| depositValue | No | Deposit size in depositUnit. Wave documents AMOUNT values in cents | |
| estimateDate | No | Date, YYYY-MM-DD | |
| exchangeRate | No | Business currency per document currency (foreign-currency documents only) | |
| depositStatus | No | Whether the customer can or must pay a deposit | |
| estimateNumber | No | ||
| hideDescription | No | ||
| disableAmexPayments | No | ||
| disableBankPayments | No | ||
| disableCreditCardPayments | No | ||
| dontCarryOverNotesToInvoice | No | ||
| requireTermsOfServiceAgreement | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful context beyond that: the record is created in draft state and no email is dispatched, which an agent could not infer from annotations alone.
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?
Four short sentences, front-loaded with the core action and result state. No filler, though the deposit sentence is vague about which parameters it maps to.
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 31-parameter mutation tool with low schema description coverage and no output schema, the description is far too thin. An agent gets no guidance on currency/exchangeRate interplay, discount scale verification, businessId defaulting, or what the created draft returns.
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 only 26% across 31 parameters, so the description carries a heavy compensation burden and does not meet it. It restates the two required line fields (already in the schema's required array) and mentions an optional deposit, but says nothing about currency, exchangeRate, discounts, businessId defaulting, or the many hide*/title* layout flags.
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 ('Create a draft estimate (quote)') and clarifies the creation result is a draft. 'Nothing is emailed' implicitly separates it from wave_send_estimate, though no sibling is named explicitly.
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 only implied: 'draft' and 'Nothing is emailed' hint that this is the pre-send creation step versus wave_send_estimate or wave_create_invoice. No explicit when-to-use, prerequisites, or named alternative is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_create_invoiceCreate invoiceA
Create an invoice for a customer. Created as DRAFT unless status=SAVED (approved). Number, dates, title and notes default to the business's invoice settings. Taxes default per product; pass taxIds:[] for none. Nothing is emailed.
| Name | Required | Description | Default |
|---|---|---|---|
| memo | No | Notes shown to the customer | |
| items | Yes | ||
| title | No | ||
| footer | No | ||
| status | No | ||
| dueDate | No | Date, YYYY-MM-DD | |
| subhead | No | ||
| currency | No | ISO 4217 currency code, e.g. CAD or USD | |
| hideName | No | ||
| hideUnit | No | ||
| poNumber | No | ||
| discounts | No | ||
| hidePrice | No | ||
| itemTitle | No | ||
| unitTitle | No | ||
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| customerId | Yes | ||
| hideAmount | No | ||
| priceTitle | No | ||
| amountTitle | No | ||
| invoiceDate | No | Date, YYYY-MM-DD | |
| exchangeRate | No | Business currency per document currency (foreign-currency documents only) | |
| invoiceNumber | No | ||
| hideDescription | No | ||
| disableAmexPayments | No | ||
| disableBankPayments | No | ||
| disableCreditCardPayments | No | ||
| requireTermsOfServiceAgreement | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses important behavior: default DRAFT status, defaulting of invoice number/dates/title/notes from business settings, per-product tax defaults, and that no email is sent. It does not cover return shape or permission requirements, but it adds substantial context for a mutation 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 four short sentences with no wasted wording. It front-loads the core action and follows with the most decision-relevant defaults and side effects.
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 28-parameter creation tool, the description covers the key behavioral facts an agent needs: draft versus saved state, tax defaults, defaulted invoice fields, and no email. The richer schema fills in many parameter details, though the description could say more about the created object's return.
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 low at 21%, so the description must compensate. It adds meaning for status, tax handling, and several defaulted fields, but it leaves many of the 28 parameters, such as discounts, currency, exchange rate, and the hide/disable flags, unexplained.
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 states a specific verb and resource: create an invoice for a customer. It also distinguishes the operation from sending by explicitly saying nothing is emailed, so an agent can tell it apart from wave_send_invoice and wave_mark_invoice_sent.
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 context for use: the invoice is created as DRAFT unless status=SAVED, and nothing is emailed. It does not explicitly name alternatives such as wave_send_invoice or wave_approve_invoice, but the intended usage is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_create_productCreate product or serviceA
Create a product or service. Give it an incomeAccountId to sell it on invoices, an expenseAccountId to buy it, or both.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| unitPrice | Yes | Price per unit, major currency units | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| description | No | ||
| incomeAccountId | No | Makes it sellable. Account subtype must be INCOME, DISCOUNTS or OTHER_INCOME | |
| expenseAccountId | No | Makes it buyable. Account subtype must be EXPENSE, COST_OF_GOODS_SOLD, PAYMENT_PROCESSING_FEES or PAYROLL_EXPENSES | |
| defaultSalesTaxIds | No | Sales taxes applied by default on invoice lines |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false and openWorldHint=false, so the agent knows this is a non-destructive local write. The description adds that providing account IDs changes downstream behavior (sellable on invoice lines), which is genuine context. But it is silent on the practical consequences of idempotentHint=false — that repeated calls may create duplicates — and on what is returned or what errors arise from mismatched account subtypes.
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?
Two tight sentences with zero filler, and the core action is front-loaded before the optional configuration detail. Every clause earns its place by telling the agent something about how the account IDs affect the created item.
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 7-parameter creation tool with no output schema, the description covers the what and the sellable/buyable configuration but omits the return payload (presumably a product ID) and any note about duplicate creation given idempotentHint=false. It is adequate to make the call, but a meaningful mutation tool warrants slightly more.
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 71%, so the schema already documents unitPrice, businessId, incomeAccountId, expenseAccountId and defaultSalesTaxIds with meaningful detail. The description largely restates the income/expense account meaning already present in the property descriptions and adds no format or constraint detail beyond that. A baseline 3 is appropriate given the schema does most of the work, with three undocumented fields (name, description, defaultSalesTaxIds semantics) left thin.
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 opens with a specific verb and resource ('Create a product or service'), which is immediately distinguishable from siblings like wave_update_product, wave_archive_product and wave_list_products. It does not name those alternatives explicitly, but the create verb alone is unambiguous.
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 explains the configuration choice well: supply incomeAccountId to make the item sellable, expenseAccountId to make it buyable, or both. However, it never says when to prefer this over alternatives (e.g., creating an account first via wave_create_account, or checking for an existing product with wave_list_products) nor what prerequisites must be resolved before calling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_create_sales_taxCreate sales taxB
Create a sales tax. abbreviation must be unique in the business (max 10 characters).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| rate | Yes | Rate as a fraction: 0.13 means 13% | |
| taxNumber | No | Registration number from the tax authority | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| isCompound | No | Calculated on top of other taxes | |
| description | No | ||
| abbreviation | Yes | ||
| isRecoverable | No | Tax paid on purchases can be deducted | |
| showTaxNumberOnInvoices | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a non-readonly, non-idempotent mutation. The description adds a useful behavioral constraint: abbreviation must be unique within the business. However, it does not explain duplicate-handling behavior, permission requirements, or what happens on success beyond creating the tax.
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 appropriately brief and front-loaded, stating the core action first and the key constraint second. The max-length mention slightly duplicates the schema, but the uniqueness detail is a valuable addition and no sentence is wasted.
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 9-parameter mutation tool with no output schema, the description is minimally adequate. It covers the primary action and one important validation rule, but lacks detail on error behavior, required permissions, and expected response or created-tax lifecycle.
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 56%, with useful descriptions for rate, businessId, taxNumber, isCompound, and isRecoverable. The description only adds the abbreviation uniqueness rule and repeats the max length constraint. It does not compensate for undocumented parameters such as name, description, and showTaxNumberOnInvoices.
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 states a specific verb and resource: 'Create a sales tax.' This clearly distinguishes it from sibling tools like wave_list_sales_taxes, wave_get_sales_tax, wave_update_sales_tax, and wave_archive_sales_tax. It does not explicitly name those siblings, but the CRUD distinction is unambiguous from the name and description.
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 guidance on when to use this tool versus alternatives, no prerequisites, and no exclusions. The only usage-related detail is the abbreviation uniqueness constraint, which is a validation rule rather than selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_create_transactionCreate money transactionA
Record a bank/credit-card transaction and categorize it, as if entered in Wave's Transactions page. Expense paid by card: anchor {accountId: card, direction: WITHDRAWAL}, line {accountId: expense category, balance: INCREASE}. Sale deposited to bank: anchor {bank, DEPOSIT}, line {income account, INCREASE}. Split across several lines; they must total the anchor. Keep the returned id: wave_get_transaction / wave_list_transactions read it back. Use dryRun=true to validate without writing. Wave does not document de-duplication by externalId: if a call timed out, check the Wave web app before retrying.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Date, YYYY-MM-DD | |
| notes | No | ||
| anchor | Yes | Bank/card side of the transaction | |
| dryRun | No | ||
| lineItems | Yes | How the amount is categorized; must add up to the anchor amount | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| externalId | No | Your reference for idempotent imports; a UUID is generated when omitted | |
| description | Yes | Shown in Wave's transaction list, e.g. the payee |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that Wave does not document de-duplication by externalId, advising a check of the web app after a timeout rather than blind retry, and telling the agent to retain the returned id for later reads. These are exactly the operational risks (duplicate writes, lost ids) an agent needs before calling a non-idempotent create.
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?
Every sentence carries weight: the two patterns, the balancing rule, the id-retention note, the dryRun escape hatch, and the dedupe caution. It is front-loaded with the modeling rules and telegraphic without becoming ambiguous.
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 an 8-parameter nested create with no output schema, the description covers the hard parts: double-entry construction, balancing, validation, and duplicate risk. Minor gaps remain around tax line handling and the customerId/notes fields, which the schema alone must carry.
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 75%, and the description still adds real meaning: it explains the anchor/line relationship, maps direction DEPOSIT/WITHDRAWAL to money in/out through concrete examples, and shows which account types go in the anchor vs. the lines. It leaves taxes, customerId, and the businessId default 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?
The description gives a specific verb and resource: 'Record a bank/credit-card transaction and categorize it,' and anchors it to the familiar Wave Transactions page. It differentiates from the read path (wave_get_transaction / wave_list_transactions) but never mentions the bulk sibling wave_create_transactions, so an agent cannot fully disambiguate single vs. batch creation from this text alone.
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?
Provides two concrete worked patterns (expense paid by card vs. sale deposited to bank), the rule that line items must total the anchor, and an explicit validate-without-writing path via dryRun=true. It does not state when to prefer this over wave_create_transactions or wave_import_ledger, which is the main remaining routing gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_create_transactionsCreate money transactions in bulkA
Create up to 50 money transactions in one request (same shape as wave_create_transaction). Every transaction is checked first (amounts balance; debit and credit sides make sense for the accounts); nothing is sent if any fails. Wave applies the batch as one request and reports input errors by path (transactions.N...).
| Name | Required | Description | Default |
|---|---|---|---|
| dryRun | No | ||
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| transactions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the safety profile (not read-only, not destructive, not idempotent, closed-world), while the description adds real behavior: all-or-nothing validation ('nothing is sent if any fails'), the checks performed, and path-based error reporting (transactions.N...). It omits the dryRun flag's effect and does not address idempotency/retry behavior, which matters for a non-idempotent batch write.
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?
Three sentences, front-loaded with the batch limit and the sibling reference; nothing is filler. Parenthetical asides ('same shape as ...', 'transactions.N...') add value rather than noise, though the middle clause is slightly compressed.
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 mutation tool with a large nested schema and no output schema, the description covers atomicity, validation and error shape well. The notable residual gaps are what a successful response contains (created IDs, externalIds?) and how dryRun changes the outcome, both of which an agent would want before calling.
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 low (33%), so the description needs to carry weight; it contributes the 50-item cap and a shape pointer to wave_create_transaction, but leaves the top-level dryRun flag completely unexplained in both schema and description. The nested transaction fields are well documented in the schema, so the gap is mostly at the top level.
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 ('Create ... money transactions'), quantifies scope ('up to 50 ... in one request') and anchors to the sibling ('same shape as wave_create_transaction'), so the agent can immediately distinguish it from the single-transaction tool.
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 bulk-vs-single distinction is clear from the 50-item cap and the 'same shape as wave_create_transaction' pointer, which implies this tool is for batches. It stops short of an explicit routing rule ('use wave_create_transaction for a single entry') or any statement of when not to use bulk.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_delete_customerDelete customerADestructiveIdempotent
Delete a customer. Wave removes it from lists, but the record stays readable by ID (wave_get_customer shows deleted: true); there is no undelete through the API.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Customer ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety bar is partly covered. The description goes well beyond them by disclosing the exact post-condition: removal from lists, continued readability by ID via wave_get_customer with deleted: true, and the absence of any undelete path.
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?
Two tight sentences, front-loaded with the action and then the critical consequence. Every clause earns its place, including the pointer to wave_get_customer and the no-undelete warning.
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 one-parameter delete with full annotation coverage and no output schema, the description supplies exactly the missing pieces: what actually happens to the record and that the action is irreversible through the API. Nothing an agent needs before invoking it is absent.
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?
There is a single required parameter (id) and schema description coverage is 100%, so the schema already documents it as 'Customer ID'. The description adds nothing about the identifier's format or source, which is acceptable at this 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?
Names a specific verb (delete) and resource (customer) and immediately clarifies the semantics: a soft delete that removes it from lists while keeping the record retrievable by ID. An agent can distinguish this from wave_update_customer or wave_get_customer without reading 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 by the destructive nature and the note that there is no undelete, which is a useful warning. However, the description never explicitly says when to choose deletion versus updating the record, nor does it route the agent to any alternative (e.g., if it only wants to hide a customer from lists).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_delete_estimateDelete estimateBDestructiveIdempotent
Permanently delete an estimate.
| Name | Required | Description | Default |
|---|---|---|---|
| estimateId | Yes | Estimate ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered. The word 'Permanently' reinforces irreversibility but adds little beyond the annotation; nothing is said about side effects on linked invoices, payments, or permissions. That is adequate but thin for a destructive operation.
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?
One short, front-loaded sentence with no redundant wording; the destructive nature is stated immediately. Nothing in it is 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?
For a simple one-parameter tool with a full annotation set and no output schema, the description is minimally sufficient to call it. However, a destructive estimate operation would benefit from noting constraints such as acceptance/conversion state or cascading effects, which are absent.
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?
There is a single parameter with 100% schema description coverage, so the schema already carries the semantic load. The description adds no format, sourcing, or validation hints beyond what the schema states.
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 states a specific verb and resource ('Permanently delete an estimate'), which lets an agent distinguish it from sibling deletion tools such as wave_delete_estimate_payment and wave_delete_invoice. It does not explicitly name those siblings or state scope limits, so it falls short of 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?
There is no when-to-use guidance, no prerequisites (e.g., whether an accepted or converted estimate can be deleted), and no pointer to alternatives like wave_update_estimate or archive-style operations. The agent must infer everything about timing from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_delete_estimate_paymentDelete estimate depositCDestructiveIdempotent
Delete a recorded estimate deposit payment.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Estimate payment ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is fully covered by structured data. The description adds almost nothing beyond that: it does not say whether the deposit's associated transaction is also removed, whether the estimate balance is recalculated, or whether the deletion is reversible.
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 short sentence that is front-loaded with the action and has no filler or redundancy. It is efficient but borders on under-specification rather than tight communication.
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 destructive mutation with no output schema, the description should explain the consequences of deletion and the relationship to the parent estimate and underlying transaction. It says only that the payment is deleted, leaving the agent to guess at side effects before performing an irreversible operation.
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 a single parameter at 100% schema description coverage ('Estimate payment ID'), the schema already carries the meaning, so the baseline of 3 applies. The description contributes no additional detail about ID format, source, or whether an estimate-scoped ID is accepted.
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 uses a specific verb and resource ('Delete a recorded estimate deposit payment'), which is far clearer than a tautology. However, it does not distinguish this tool from close siblings such as wave_delete_estimate (removes the whole estimate) or wave_update_estimate_deposit / wave_record_estimate_deposit, so an agent must infer the boundary from names alone.
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 when-to-use or when-not-to-use guidance, no prerequisite that the payment must already be retrieved via wave_get_estimate_payment, and no pointer to the alternative of updating rather than deleting. The only implied guidance is the word 'recorded', which hints at a precondition but never states it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_delete_invoiceDelete invoiceBDestructiveIdempotent
Permanently delete an invoice.
| Name | Required | Description | Default |
|---|---|---|---|
| invoiceId | Yes | Invoice ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is largely covered. The word 'Permanently' usefully reinforces irreversibility, but the description says nothing about effects on linked records such as payments or whether deletion fails when an invoice has payments attached.
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?
One short sentence, front-loaded with the verb and resource, with no filler or repetition. Its brevity is close to under-specification but nothing written is wasted.
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 destructive, single-parameter mutation with no output schema, the safety hints are supplied by annotations, so the description need not explain return values. However, an irreversible delete should say what happens to dependent data and what errors are possible, and that is absent.
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?
There is a single parameter with 100% schema description coverage, so the schema itself documents invoiceId. The description adds no semantics about format, source of the ID, or whether IDs come from wave_list_invoices or wave_get_invoice, which is the baseline expectation when the schema is complete.
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 uses a specific verb ('delete') plus a specific resource ('invoice'), which clearly separates it from siblings like wave_delete_customer, wave_delete_estimate, or wave_delete_invoice_payment. The adverb 'Permanently' adds a meaningful qualifier about the nature of the operation, though there is no explicit contrast with wave_update_invoice or any void/archive 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?
There is no when-to-use guidance, no prerequisites, and no named alternative among the many invoice siblings (update, clone, send). An agent must infer entirely from the name that this is the removal path rather than an update or reversal path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_delete_invoice_paymentDelete invoice paymentADestructiveIdempotent
Delete a recorded invoice payment; the invoice becomes unpaid by that amount.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Invoice payment ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered. The description contributes real added context beyond that: it states the downstream consequence that the invoice is reduced back to unpaid by that amount, which helps an agent predict side effects. It stops short of saying whether the deletion is reversible, whether the invoice's status/history is recalculated, or what happens to linked transaction records.
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 front-loaded sentence states the action and then the effect, with no boilerplate or repetition. Every clause earns its place; nothing could be removed without losing information.
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 one-parameter destructive tool with full annotation coverage and no output schema, the definition supplies the action, the target, and the accounting consequence — enough for correct invocation. The remaining gap is procedural context (irreversibility, permissions, how to obtain a valid payment ID) that an agent might want before firing a destructive call.
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?
There is a single required parameter and schema description coverage is 100%, with the schema already labeling it "Invoice payment ID". The description adds no format, sourcing guidance (e.g., obtain via wave_get_invoice_payment or wave_list_payments), or validation notes, 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 pairs the specific verb "delete" with the specific resource "recorded invoice payment" and adds the resulting state change. It is unambiguous, though it never explicitly contrasts with wave_delete_estimate_payment or wave_update_invoice_payment; the distinction is carried mainly by the tool name rather than the description.
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 only implied: the word "recorded" hints that this removes an existing payment rather than a pending one, but there is no statement of when to delete versus correcting via wave_update_invoice_payment, nor any prerequisite (e.g., payment must exist, be unapplied). An agent must infer the selection criteria from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_delete_transactionDelete transactionADestructiveIdempotent
Delete a transaction, as the web app's Delete does. Changes the books and account balances: confirm with the user first. Wave refuses for transactions that must be removed at their source (e.g. invoice payments, payroll). Uses Wave's web-app API (unofficial), which needs a web session: if it is missing or expired, the user runs node /app/bin/wave-mcp.js login in a terminal on f32f40788a38.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| expectedSequence | No | Fail if the transaction changed since you read it |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, but the description adds material context the agent would otherwise not have: the delete mutates books and account balances, it requires human confirmation, it is rejected for source-owned records, and it depends on an unofficial web-app API whose session can expire with a concrete remediation command. That is exactly the beyond-annotation disclosure this dimension rewards.
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 the action and the destructive warning, then the failure modes, then the auth remedy — a sensible order with little wasted wording. The embedded container hostname and login command are verbose but actionable; the sentence could be tightened without losing meaning.
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 should cover behavior and side effects, and it does: mutation of books and balances, rejection paths, and auth prerequisites. The only real omission is what a successful call yields (no returned record, for instance), which an agent deleting an entity would reasonably want to know.
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 67%: businessId and expectedSequence are documented in the schema, while id is a bare string but self-evident. The description contributes nothing about expectedSequence, an optimistic-concurrency guard whose purpose (failing when the transaction changed since it was read) is worth reinforcing for a destructive call. Baseline 3 fits since the schema does most of the work.
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 ("Delete a transaction") and pins the semantics to the web app's own Delete behavior. An agent can immediately distinguish it from the many read/update siblings such as wave_get_transaction and wave_update_transaction 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 clear context: confirm with the user first, and expect a refusal for transactions that must be removed at their source (invoice payments, payroll). It also tells the agent what to do when the web session is missing or expired. It stops short of naming an alternative action for the refused cases (for example reversing via wave_update_transaction or deleting the source record instead), leaving that to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_generate_estimate_pdfGenerate estimate PDFBIdempotent
Generate (or regenerate) the estimate PDF and return its URL.
| Name | Required | Description | Default |
|---|---|---|---|
| estimateId | Yes | Estimate ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=false, idempotentHint=true, destructiveHint=false, openWorldHint=false). The description adds value by disclosing the 'regenerate' idempotent-ish behavior and the URL return value, which is meaningful given there is no output schema. It does not say whether the PDF is persisted or overwritten, whether generation is synchronous, or what permissions/state the estimate must be in.
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?
One short sentence with the action and result front-loaded and zero wasted wording. It is efficient, though borderline terse for a tool that mutates state (creates a PDF artifact).
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 one-parameter tool with full schema coverage and no output schema, naming the returned URL is the key missing piece and it is present. However, prerequisites and side effects of PDF generation are not addressed, leaving gaps for an agent deciding when the call will succeed.
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?
There is a single required parameter with 100% schema description coverage, so the schema already documents estimateId. The description adds no syntax, format, or example for the ID, 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?
States a specific verb ('Generate (or regenerate)') and a specific resource ('the estimate PDF'), and adds the useful detail that a URL is returned. It is clearly distinct from siblings such as wave_get_estimate or wave_send_estimate, though it does not explicitly name a boundary against any of 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?
The parenthetical '(or regenerate)' implies usage: call it when a PDF is needed for an existing estimate, including when one already exists. There is no explicit when-not guidance, no prerequisites (e.g., estimate must exist and be non-deleted), and no alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_accountGet accountBRead-onlyIdempotent
One account with type, subtype, normal balance, current balance (account and business currency) and its sequence number.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Account ID | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false, so safety is fully covered. The description's valuable addition is disclosing the return payload shape (dual-currency balances, sequence number), which matters because there is no output schema. It stops short of noting error behavior for a missing id.
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 compact sentence with zero filler, and the most informative fields are front-loaded. The fragmentary noun-phrase construction is slightly less clear than a verb-led sentence would be.
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 two-parameter read-only resource fetcher with rich annotations and a fully described schema, the only thing the structured fields cannot supply is the shape of the returned account, and the description covers exactly that. Nothing an agent needs in order 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?
Schema description coverage is 100% and the schema already explains that businessId defaults to what wave_get_context reports. The description adds no parameter-level 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 is a noun phrase enumerating the fields of the returned object (type, subtype, normal balance, balances, sequence number) rather than stating a verb+resource action. Combined with the name wave_get_account the intent is inferable, but the text itself never says 'retrieves a single account by ID' and makes no reference to the adjacent wave_list_accounts tool.
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 guidance on when to use this versus wave_list_accounts or wave_get_reference, no mention of what happens when the id is unknown, and no note about the businessId default. The agent must infer the single-vs-list distinction from tool names alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_businessGet businessBRead-onlyIdempotent
Full details of one business: address, contact info, currency, timezone, whether Wave can email invoices for it, and invoice/estimate branding.
| Name | Required | Description | Default |
|---|---|---|---|
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and closed-world, so the safety profile is fully covered. The description's contribution is naming the payload fields, which is genuinely useful because there is no output schema, but it says nothing about failure modes (invalid or inaccessible businessId) or whether the default resolves silently.
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?
One front-loaded sentence with a colon-delimited field list; every element carries information for an agent with no output schema. Slightly dense as a fragment, but nothing is wasted.
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?
A simple single-record read with rich annotations and a fully documented parameter; the field enumeration compensates well for the absent output schema. Only the default-resolution behavior and error handling are left implicit, which is minor for this tool class.
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 single parameter already documents that businessId defaults to whatever wave_get_context reports. The description adds no meaning beyond that — no guidance on when to omit versus pass explicitly — so 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?
States a specific verb and resource ('Full details of one business') and enumerates the returned facets — address, contact info, currency, timezone, invoice-email capability, branding. That makes it clearly a single-record fetch rather than a list, though it never explicitly contrasts itself with wave_list_businesses.
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?
No when-to-use guidance at all: nothing about calling this before invoice/estimate creation to obtain branding defaults, and nothing about the fallback to the context business. The only hint of the default behavior lives in the schema, not the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_contextGet Wave connection contextARead-onlyIdempotent
Start here. Returns the signed-in Wave user, how credentials are configured, the businesses this credential reaches, which one is the default, whether writes are enabled, and what the public API cannot do. Works without credentials and then explains how to set them up.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/non-destructive, and the description adds genuinely new behavior: it succeeds with no credentials at all and then acts as a setup guide, and it reports whether writes are enabled and what the public API cannot do. That is capability and failure-mode disclosure an agent cannot get from the 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?
Three short sentences with the highest-value instruction ('Start here') front-loaded, followed by the return inventory and the no-credentials fallback. Every clause earns its place; nothing is repeated from the title.
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 explaining return values and does so by enumerating each field group. It also covers the authenticating and unauthenticated cases, which is the full decision surface for a zero-argument bootstrap 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?
There are zero parameters, so the baseline is 4. Nothing in the description needs to explain inputs, and it correctly devotes its space to return contents instead.
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-and-resource pattern (returns connection context) and enumerates the exact contents: signed-in user, credential configuration, reachable businesses, default business, write enablement, and API limitations. The opening 'Start here' positions it clearly against the CRUD siblings like wave_get_business and wave_list_businesses.
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?
'Start here' is an explicit ordering instruction that tells the agent to call this before other wave_* tools. It also states the unauthenticated path ('works without credentials and then explains how to set them up'). It does not explicitly say when to call wave_list_businesses or wave_get_business instead, so it stops short of full alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_customerGet customerARead-onlyIdempotent
One customer with address, shipping details, notes and outstanding/overdue amounts. Deleted customers are still returned by ID, marked deleted: true.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Customer ID | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already establish read-only, idempotent, non-destructive behavior. The description adds valuable context beyond that by disclosing that deleted customers are still returned and flagged with deleted: true, although it does not cover not-found behavior or permission requirements.
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 tight sentences with no filler. The included fields are front-loaded, followed by the important deleted-customer behavior.
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 simple single-customer lookup with two fully documented parameters and no output schema, the description supplies enough information about returned content and deleted records. Only edge-case behavior such as not-found handling is left implicit.
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 explains both the id and businessId parameters. The description reinforces ID-based retrieval but adds no additional syntax or meaning beyond what the schema provides.
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 states that this returns one customer and enumerates the content included: address, shipping details, notes, and outstanding/overdue amounts. This clearly distinguishes it from a broader list operation, though it does not explicitly name wave_list_customers as the 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?
The description implies retrieval by ID because it mentions deleted customers still being returned by ID, but it gives no explicit guidance on when to use this versus wave_list_customers or wave_get_context. No prerequisites or exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_estimateGet estimateBRead-onlyIdempotent
One estimate with items, taxes, discounts, deposit settings and payments, acceptance history and attachments.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Estimate ID | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered by structured data. The description contributes the payload scope, which is useful because there is no output schema, but it says nothing about not-found handling, permissions, or whether the response is trimmed for large estimates.
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 front-loaded sentence with no filler; every noun phrase names a returned component. It is a sentence fragment lacking a verb, but the information density is high and nothing needs trimming.
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 simple two-parameter read tool, the annotations cover safety, the schema covers inputs, and the description covers the returned payload in the absence of an output schema. The only real gap is the lack of pointer to wave_list_estimates for discovering an ID.
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%: 'id' is documented as the Estimate ID and 'businessId' explicitly states it defaults to the value wave_get_context reports. The description adds no additional meaning about either parameter, 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 identifies the resource ('One estimate') and enumerates the contents included in the payload (items, taxes, discounts, deposit settings, payments, acceptance history, attachments), which implicitly conveys a single-record fetch. The word 'One' distinguishes it from wave_list_estimates, though the verb itself is never stated explicitly.
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 when-to-use guidance, no mention of the natural alternative (wave_list_estimates to find an ID first), and no statement of preconditions or error behavior. Retrieval context is only weakly implied by the singular noun phrase.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_estimate_paymentGet estimate deposit paymentBRead-onlyIdempotent
One estimate deposit payment (or refund/void) with its estimate.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Estimate payment ID | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and closed-world scope, so the safety profile is fully covered by structured data. The description adds only the useful detail that the response bundles the parent estimate and that the record may be a payment, refund, or void — modest value beyond annotations, with no info on pagination, errors, or auth.
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 a single short fragment with no wasted words, but it is under-written rather than concise — the parenthetical '(or refund/void)' is the only elaboration, and the missing verb makes it read as a title rather than a definition.
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 simple two-parameter read tool with complete annotations and full schema coverage, the minimum an agent needs is a clear verb and the return shape; the return shape is partially conveyed ('with its estimate') but the verb is absent and no output schema exists to compensate. Adequate but thin.
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 both parameters are documented, including that businessId defaults to the value from wave_get_context, so the schema carries the semantics. The description adds nothing about the id format or prefix, but with a fully documented two-parameter schema the baseline of 3 is comfortably met.
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 phrase names the resource ('one estimate deposit payment') and hints at the return shape ('with its estimate'), but it is a noun fragment with no verb, so the action (fetch) is only inferable from the title and sibling naming convention. It does at least distinguish itself from payment-mutating siblings like wave_record_estimate_deposit and wave_delete_estimate_payment.
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 when-to-use guidance at all: no mention of when to call this versus wave_list_payments or wave_get_estimate, and no prerequisites. The agent must infer usage entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_invoiceGet invoiceCRead-onlyIdempotent
One invoice with line items, taxes, discounts, payments, reminders, PDF and customer view links.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Invoice ID | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and closed-world scope, so the safety profile is covered. The description's list of returned components (line items, taxes, discounts, payments, reminders, PDF and customer view links) adds genuine value since no output schema exists, but it says nothing about behavior on an unknown or unauthorized ID, or whether any invoice state is excluded.
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 short sentence with zero filler, but it is not front-loaded with an action verb, so the agent reads a payload list before understanding the operation. Slightly expanded to "Retrieve one invoice by ID; returns…" it would be both concise and scannable.
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 two-parameter read tool with rich annotations, this is close to adequate, and listing the returned components compensates in part for the absent output schema. However, the description never states the input contract (single invoice ID) or the failure mode, leaving meaningful gaps for an agent deciding between this and wave_list_invoices.
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 schema itself documents both parameters including the businessId default note pointing at wave_get_context. The description adds no meaning about the id parameter or the businessId fallback, so 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 is a noun-phrase fragment — "One invoice with line items, taxes, discounts, payments, reminders, PDF and customer view links" — with no verb; the retrieval action comes only from the title "Get invoice" and the tool name. It does implicitly distinguish itself from wave_list_invoices via "One invoice," but it never states explicitly that it fetches a single invoice by ID.
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 when-to-use guidance, no mention of alternatives such as wave_list_invoices for browsing or wave_update_invoice/wave_delete_invoice for mutation, and no prerequisites or error conditions. The agent must infer usage entirely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_invoice_paymentGet invoice paymentCRead-onlyIdempotent
One invoice payment with account, method, currency details and processor info.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Invoice payment ID | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered. The description's only added behavior is the shape of the returned record (account, method, currency, processor), which is useful since no output schema exists, but it says nothing about not-found handling or scoping.
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 compact sentence with no filler, and the most useful information (the returned record's contents) comes first. It is telegraphic rather than polished, but nothing is wasted.
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 simple two-parameter read with no output schema, the description at least signals what fields come back, which partially compensates for the missing return definition. It still omits error behavior and any routing context relative to the many payment-related siblings, so it is only minimally complete.
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 both the required invoice payment id and the optional businessId default are already documented in the schema. The description adds no syntax, format, or sourcing guidance beyond that, which is the expected baseline when the schema does the work.
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 identifies the resource (one invoice payment) and enumerates the data it carries (account, method, currency, processor info), so the intent is inferable. However, it is a noun phrase with no explicit retrieval verb, and it does not distinguish this from nearby siblings such as wave_list_payments or wave_get_estimate_payment, leaving the agent to rely on the tool name.
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 when-to-use guidance at all: nothing says to call this when you have a payment ID, nor that wave_list_payments should be used to discover IDs first. No exclusions or alternatives are named despite a crowded sibling set of payment and invoice tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_ledger_transactionGet ledger transactionARead-onlyIdempotent
One transaction from the imported ledger with every journal line (account, debit, credit, line description, sales tax). IDs come from wave_list_ledger_transactions.
| Name | Required | Description | Default |
|---|---|---|---|
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| transactionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and closed-world scope, so safety is covered. The description adds value beyond that by disclosing the response shape (all journal lines with account, debit, credit, description, sales tax), which matters because there is no output schema. It does not mention pagination or behavior when a transaction ID is absent.
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?
Two short sentences with no waste. The returned content is front-loaded and the parameter-sourcing note follows immediately, which is the right order for an agent deciding whether to call it.
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 two-parameter read tool with no output schema, the description covers the essential missing pieces: what a record contains and where the required ID comes from. The businessId default is already handled in the schema, so nothing critical is absent, though a note on error behavior for unknown IDs would round it out.
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 only 50%: businessId is documented in the schema, but transactionId has no description there. The description compensates by stating that IDs come from wave_list_ledger_transactions, effectively explaining the origin and format of the one undocumented required parameter.
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 resource and scope: a single transaction from the *imported ledger*, plus an enumeration of the journal-line fields returned. That distinguishes it reasonably from wave_get_transaction and wave_list_ledger_transactions, though it never explicitly contrasts itself with wave_get_transaction, which is the nearest ambiguous 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?
It gives a concrete sourcing rule — 'IDs come from wave_list_ledger_transactions' — which tells the agent how to obtain the required parameter. However, there is no when-to-use/when-not guidance relative to wave_get_transaction or wave_list_ledger_transactions, so the agent must infer that this is the detail-fetch following a list call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_productGet product or serviceBRead-onlyIdempotent
One product/service with its accounts and default sales taxes.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Product ID | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the bar is lower, but the description still adds genuine context by disclosing that the response is hydrated with related accounts and default sales taxes. It does not state behavior for a missing or archived ID, but for a simple read that is a minor gap.
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 a single front-loaded clause with no wasted wording, which is good. The trade-off is that it is so compressed that it reads as a fragment and omits the retrieval verb and any operational qualifiers.
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 two-parameter read tool with full schema coverage and complete annotations, this is close to adequate, and no output schema means return values needn't be detailed. What is missing is what happens on a nonexistent/archived product and what 'accounts' refers to, which an agent would need when interpreting 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?
With 100% schema description coverage, the schema already documents both 'id' and 'businessId' including the default-to-context fallback, so the baseline is 3. The description adds no further meaning about whether the ID accepts a product key, a numeric ID, or a reference.
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 identifies the resource ('One product/service') and hints at the expanded payload ('with its accounts and default sales taxes'), and the singular 'One' implicitly contrasts with wave_list_products. However, it is a noun phrase rather than a verb+resource statement, so the retrieval action is only inferred from the name.
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 when-to-use or when-not-to-use guidance and no mention of the sibling alternatives (wave_list_products, wave_update_product, wave_archive_product). The singular framing is the only cue that this is a single-record lookup rather than a list operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_referenceGet reference dataARead-onlyIdempotent
Reference data needed to fill other tools' inputs: currencies, countries, one country with its provinces/states (kind=country, code=CA), a province by code, account types, and account subtypes (needed by wave_create_account). Lists are paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | Required for kind=country (e.g. CA) and kind=province (e.g. CA-ON) | |
| kind | Yes | ||
| page | No | 1-based; use nextPage | |
| search | No | Case-insensitive filter on code or name | |
| pageSize | No | Items per page (max 250) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is covered structurally. The description adds that lists are paginated, but that is also visible in the page/pageSize parameters, and it does not say what a country lookup returns in shape terms or whether an invalid code errors versus returns empty.
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?
Two sentences, front-loaded with the purpose and then the enumeration of kinds, with the pagination note trailing. The mid-sentence parentheticals make it dense but every clause carries information; no filler or restatement of the title.
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 five parameters, one enum and no output schema, the description covers the full kind vocabulary, the dependency between kind and code, and pagination behavior. The main residual gap is return shape per kind, but for a read-only lookup tool backed by an 80%-documented schema this is close to complete.
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 80%, so the baseline is 3; the description earns an uplift by clarifying that kind=country returns one country together with its provinces/states and that kind=province resolves a single province by code. That adds interpretive value about what the code parameter selects, beyond the schema's terse 'Required for kind=country'.
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-resource pair (get reference data) and then enumerates exactly which datasets are available: currencies, countries, country-with-provinces, province, account types and account subtypes. It also distinguishes itself from the account-related siblings by framing subtypes as inputs to wave_create_account rather than as account records.
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 the intended usage context plainly — reference data needed to fill other tools' inputs — and explicitly ties account_subtypes to wave_create_account, which tells the agent when to reach for this instead of a list/CRUD sibling. It stops short of naming alternatives or exclusions (e.g. 'do not use for listing actual accounts; use wave_list_accounts').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_sales_taxGet sales taxCRead-onlyIdempotent
One sales tax with its full dated rate history.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Sales tax ID | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and closed-world scope, so the safety profile is covered. The description's one contribution beyond that is disclosing the shape of the response ('full dated rate history'), which is valuable given there is no output schema, but it says nothing about error behavior for missing or archived tax IDs.
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 a single short sentence fragment with zero filler, and the salient detail (rate history) is front-loaded. Economy is good, though the terseness borders on under-specification rather than disciplined brevity.
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 simple two-parameter read tool with full schema coverage and strong annotations, the description covers the essentials at a minimum-viable level. The lack of an output schema is partly offset by the mention of dated rate history, but nothing explains failure modes or how this differs operationally from listing taxes.
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 the sales tax ID and the businessId default (falling back to the value from wave_get_context). The description adds no parameter meaning beyond this, 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 phrase 'One sales tax with its full dated rate history' identifies the resource as a single sales tax record rather than a list, which implicitly separates it from wave_list_sales_taxes, and it adds that rate history is included. However, it is a bare noun phrase with no verb, so the retrieval action is only inferable from the tool name and title rather than 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?
There is no when-to-use guidance, no mention of the wave_list_sales_taxes alternative for enumerating taxes, and no statement that an ID is required to fetch a single record. The agent must infer the lookup workflow entirely from the name and schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_transactionGet transactionARead-onlyIdempotent
One transaction with every line: bank/card side (anchor), category lines with order numbers, amounts, sales tax, vendor/customer, tags, review status, its current sequence, and which fields Wave allows editing. Uses Wave's web-app API (unofficial), which needs a web session: if it is missing or expired, the user runs node /app/bin/wave-mcp.js login in a terminal on f32f40788a38.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Transaction ID from wave_list_transactions | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive, open-world behavior. The description adds meaningful context beyond them: the unofficial web-app API dependency and the exact remediation if the session is missing or expired, plus the editable-field and review-status return content. It does not cover error handling beyond authentication.
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?
Two sentences, purpose first and auth remediation second. The long enumeration in the first sentence is dense but necessary because there is no output schema; no 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?
For a read-only get-by-id tool with no output schema, the description covers the returned transaction structure and the session prerequisite. The schema handles parameter details, so no material context 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%, with descriptions for id and businessId; the description adds no additional parameter meaning such as format, defaults, or lookup behavior. Baseline 3 applies because the schema carries 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 states this returns a single transaction with its full set of lines and metadata, which is a specific resource and scope. It implicitly contrasts with wave_list_transactions by saying 'One transaction,' but it does not explicitly name that sibling or clarify its distinction from ledger transaction retrieval.
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 provides an authentication prerequisite (web session, login command) but no explicit when-to-use or when-not-to-use guidance versus wave_list_transactions or wave_get_ledger_transaction. Retrieval of one transaction by ID is implied by the description and schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_vendorGet vendorCRead-onlyIdempotent
One vendor with address and contact details.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Vendor ID | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is fully covered. The description's only added behavior is the return content hint (address and contact details), which is real value given no output schema, but it says nothing about error behavior for an unknown ID.
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 short phrase with zero filler and the payload information up front. It is efficient, though it is a sentence fragment rather than a structured statement of action and result.
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 two-parameter read-only getter with full schema coverage and rich annotations, the description is minimally adequate: it tells the agent what comes back. It omits what happens with an invalid or missing ID and does not point at wave_list_vendors for lookup-by-name, leaving small but real gaps.
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 both parameters (id, businessId) are documented in the schema, including the default-resolution note for businessId. The description adds no parameter meaning beyond that, 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?
"One vendor with address and contact details" conveys the resource (a single vendor) and the payload shape (address, contact details), but it is a noun fragment with no verb and never names the sibling it contrasts with, such as wave_list_vendors. An agent can infer retrieval from the title, but the description itself does not do the work.
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 when-to-use guidance and no routing to alternatives: nothing says to use wave_list_vendors when the ID is unknown or wave_get_context to resolve the default businessId. The singular "one vendor" only implicitly distinguishes it from the list tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_graphql_queryRun a read-only GraphQL queryARead-onlyIdempotent
Escape hatch for reads the other tools do not shape the way you need: run one GraphQL query (never a mutation) against Wave's public API and get the raw data. Select only the fields you need, and always pass page/pageSize on connections. Schema: the wave://schema resource. Example: query($id: ID!){ business(id:$id){ customers(page:1,pageSize:5){ edges{ node{ id name } } } } }
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | A single GraphQL query document | |
| variables | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false; the description reinforces this with "never a mutation", which is the key safety signal for a free-form query tool. It adds real context beyond the annotations (raw unshaped return data, the wave://schema resource, pagination requirement, worked example), but says nothing about query size limits, depth/complexity caps, or error behavior when a query is malformed.
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 the decision-relevant framing, then constraints, then schema pointer and example — a sensible ordering with no filler sentences. The opening clause is slightly convoluted ("reads the other tools do not shape the way you need"), but every sentence carries usable information.
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 two-parameter escape hatch with no output schema, the description covers what an agent needs: read-only scope, what comes back (raw data), where the API schema lives, and a concrete call shape. Missing only operational guardrails such as the query length limit and failure modes, which is why it is not a 5.
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 50%: only `query` is documented in the schema, and `variables` has no description at all. The description compensates meaningfully by showing a parameterized query document (`query($id: ID!){...}`), which implies how variables bind, and by pointing to wave://schema for field selection. It still omits the 20000-character cap on `query` and any statement about how `variables` is passed.
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 ("run one GraphQL query ... against Wave's public API") plus the explicit scope boundary "never a mutation". The framing as an "escape hatch for reads the other tools do not shape" immediately distinguishes it from the ~70 shape-specific sibling tools (wave_list_customers, wave_get_invoice, etc.).
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 a clear selection rule: use this only when the purpose-built tools do not shape reads the way you need, and never for mutations. It also supplies two mandatory invocation practices (select only needed fields; always pass page/pageSize on connections) that an agent would otherwise get wrong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_import_ledgerImport transactions from a Wave Data ExportADestructiveIdempotent
Load the full transaction journal from Wave's Data Export so transactions can be listed and date-range reports run. Wave's public API cannot read transactions; this is the supported way to get them. Get the file: Wave → Settings → Data Export → Accounting (CSV) → Export; Wave emails a download link (valid 24 hours). Pass the path of the downloaded .zip (or the accounting .csv inside it) on the machine running this server. Replaces any earlier import for the business. Nothing is sent to Wave; the ledger is stored locally (mode 600).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to the Data Export .zip or its accounting .csv | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations: it discloses that an earlier import for the business is replaced (concretely explaining destructiveHint=true), that nothing is sent to Wave (reinforcing openWorldHint=false and clarifying the network/auth posture), and that the ledger is stored locally with mode 600 permissions. These are exactly the side-effect and data-safety facts an agent needs before invoking a destructive write.
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?
Five dense, front-loaded sentences: what it does, why it exists, how to get the file, what to pass, and what the side effects are. No filler, and the destructive caveat lands before an agent would act.
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 two-parameter destructive import with no output schema, this covers acquisition, argument form, scope, and side effects. The only gap is the result: nothing about what is reported back (transaction count, validation failures on a malformed CSV), which an agent would want after a replace-the-ledger operation.
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 earns above that by clarifying that the path must resolve on the machine running the server and that either the .zip or the inner accounting .csv is acceptable. It says nothing about businessId, but the schema already documents that default fully.
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 ("Load the full transaction journal from Wave's Data Export") plus the downstream purpose (listing and date-range reports), and explains why this path exists at all ("Wave's public API cannot read transactions"), which cleanly separates it from wave_list_transactions and wave_list_ledger_transactions. An agent can pick this 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?
Gives explicit trigger conditions and even operational steps to obtain the input (Settings → Data Export → Accounting CSV → emailed 24h link). The routing statement that this is the supported ingestion path is a strong when-to-use signal, but there is no explicit "when not to use" — e.g. no note that manually created transactions already live locally and don't require an import.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_accountsList chart of accountsARead-onlyIdempotent
List the chart of accounts with current balances. Find transaction accounts with filters: bank accounts are types=[ASSET] subtypes=[CASH_AND_BANK]; credit cards subtypes=[CREDIT_CARD]; expense categories types=[EXPENSE]; income categories types=[INCOME].
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| types | No | ||
| detail | No | summary: key fields, long text clipped. full: every field and line items | summary |
| search | No | Case-insensitive substring match on name, displayId, description (scans the full list; use filters when you can) | |
| pageSize | No | Items per page (max 100) | |
| subtypes | No | ||
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| isArchived | No | Default false (active only) | |
| excludedSubtypes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered structurally. The description adds that returned accounts carry current balances, which is useful behavioral context, but says nothing about pagination behavior, how archived accounts are handled, or what the focused default (isArchived false, detail=summary) implies for output volume.
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?
Two sentences, front-loaded with the purpose before the filter recipes, and no filler. The semicolon-separated recipe list is dense but each clause corresponds to a distinct lookup the agent may need.
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 9-parameter list tool with no output schema, the description covers the conceptual core (what the list contains, how to filter for the common cases) while the schema documents the plumbing (page/pageSize/nextPage, detail, search, isArchived). Minor residual gap: the description never mentions paging or the summary-vs-full output distinction, which matters for a paginated read.
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 schema documents parameters at roughly 67% coverage, listing enum values without explaining what they mean in business terms. The description bridges that gap by mapping real-world concepts (bank account, credit card, expense category, income category) onto specific types/subtypes combinations, which is meaning the enum list alone cannot 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 description opens with a specific verb and resource — "List the chart of accounts with current balances" — so the agent knows exactly what is returned (account records plus balances). It does not, however, distinguish itself from nearby siblings such as wave_get_account or wave_list_ledger_accounts, which an agent could plausibly confuse it with.
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 practical guidance via concrete filter recipes: bank accounts are types=[ASSET] subtypes=[CASH_AND_BANK], credit cards subtypes=[CREDIT_CARD], expense types=[EXPENSE], income types=[INCOME]. This tells the agent how to accomplish common lookups, but there is no explicit when-not-to-use or pointer to alternative tools for account lookup.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_businessesList businessesARead-onlyIdempotent
List the Wave businesses this credential can access (paginated).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| pageSize | No | Items per page (max 50) | |
| isArchived | No | true = only archived, false = only active, omit = both |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered elsewhere. The description adds two facts beyond that: results are paginated and scoped to the credential's accessible businesses. It does not say whether archived businesses appear by default or what a business record contains.
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 sentence with no filler; scope and pagination are both front-loaded. Nothing in it could be removed without losing information.
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-required-parameter list tool with rich annotations, a fully documented schema, and no output schema, this is nearly sufficient. The one remaining gap is that the default inclusion of archived businesses is only discoverable by reading the isArchived schema entry, not the description itself.
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 all three parameters (page, pageSize, isArchived) carry their own inline descriptions, including the default-both behavior for isArchived. The description adds no parameter-specific meaning 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?
States a specific verb and resource ("List the Wave businesses") and adds the scope constraint that results are limited to what the credential can access. It does not name the sibling wave_get_business or explain the list-vs-get relationship, so differentiation is left to inference.
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 only implied: the credential-scoped listing suggests this is the entry point for discovering business IDs before calling wave_get_business, but no when-to-use or when-not-to-use condition is stated. No alternative tool is named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_customersList customersARead-onlyIdempotent
List customers with their outstanding and overdue balances. Filter by exact email, archive state or modification time; use search for a name substring.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| sort | No | Default CREATED_AT_DESC | |
| No | Exact email match | ||
| detail | No | summary: key fields, long text clipped. full: every field and line items | summary |
| search | No | Case-insensitive substring match on name, email, displayId, firstName, lastName (scans the full list; use filters when you can) | |
| pageSize | No | Items per page (max 100) | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| isArchived | No | ||
| modifiedAtAfter | No | Only records modified after this time (ISO 8601) | |
| modifiedAtBefore | No | Only records modified before this time (ISO 8601) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and closed-world, so the safety profile is covered. The description adds real behavioral content beyond that: the response includes outstanding and overdue balances, exact-match semantics for email, and the notable performance trait that search scans the full list while filters do not.
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?
Two sentences, front-loaded with purpose and return content, followed immediately by filter guidance. Every clause carries information and nothing is repeated.
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 read tool with no output schema, the description covers purpose, returned data and filter strategy adequately, and the schema handles the rest. A small gap remains: the summary-vs-full detail tradeoff and pagination are only implied via schema, and the default business resolution is not hinted at.
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 90%, so nearly every parameter is already documented, and most of the description's parameter text (exact email, archive state, modification time) restates the schema. The one marginal addition is steering agents to search for name substrings, but it does not explain detail, sort, or pagination semantics beyond 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 description states a specific verb and resource ('List customers') and adds what the listing surfaces ('outstanding and overdue balances'), which is useful since there is no output schema. It does not explicitly distinguish itself from wave_get_customer or other list siblings, but the list-vs-get distinction is implicit in the name.
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 guidance on which filters to use ('exact email, archive state or modification time') and warns to prefer search only for name substrings, which is a genuine usage nuance. However, there is no explicit when-to-use-this-vs-alternative guidance naming wave_get_customer for single-record lookups or wave_list_invoices for related data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_estimatesList estimatesARead-onlyIdempotent
List estimates (quotes) with totals, deposit state and status. detail="full" adds line items, deposit payments and acceptance history (pages of at most 25).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| sort | No | Default CREATED_AT_DESC | |
| detail | No | summary: key fields, long text clipped. full: every field and line items | summary |
| status | No | ||
| currency | No | ISO 4217 currency code, e.g. CAD or USD | |
| pageSize | No | Items per page (max 100) | |
| amountDue | No | ||
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| customerId | No | ||
| estimateNumber | No | ||
| estimateDateEnd | No | Date, YYYY-MM-DD | |
| modifiedAtAfter | No | ISO 8601 date-time, e.g. 2026-01-31T00:00:00Z | |
| modifiedAtBefore | No | ISO 8601 date-time, e.g. 2026-01-31T00:00:00Z | |
| estimateDateStart | No | Date, YYYY-MM-DD |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), so the description's job is to add operational detail — and it does, disclosing that detail="full" expands into line items, deposit payments and acceptance history, and that full results page at a maximum of 25. That page cap is non-obvious and not derivable from the schema, which advertises pageSize up to 100.
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?
Two dense sentences, front-loaded with the primary purpose and with zero filler. The trailing parenthetical "(pages of at most 25)" is slightly ambiguous about whether it caps pages, items per page, or line items, which costs a point.
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 14-parameter list tool with no output schema, the description covers the return-shape question reasonably well but leaves filtering and sorting behavior entirely to the schema. An agent still has to open the schema to learn that filters exist and how pagination interacts with detail mode.
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 71%, setting a baseline of 3. The description does add real meaning for the detail switch (what "full" actually returns) and the 25-item full-mode page ceiling, but it says nothing about the many filters (status, currency, customerId, estimate date range, amountDue, sort) that an agent must learn from the schema alone.
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 ("List estimates") and disambiguates the vocabulary by equating estimates with quotes, then names the fields surfaced (totals, deposit state, status). It is clearly the collection-level reader versus wave_get_estimate, though it never names that sibling explicitly.
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 only implied: an agent can infer this is for browsing/filtering estimates rather than fetching one by ID or mutating one. There is no explicit when-to-use or when-not-to-use guidance relative to wave_get_estimate, wave_list_invoices, or the estimate mutation siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_invoicesList invoicesARead-onlyIdempotent
List invoices with totals, amount due and status. Filter by status, customer, invoice date range, modification time, number, currency or the estimate they came from (sourceId). detail="full" adds line items and payments (pages of at most 25).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| sort | No | Default CREATED_AT_DESC | |
| detail | No | summary: key fields, long text clipped. full: every field and line items | summary |
| status | No | ||
| currency | No | ISO 4217 currency code, e.g. CAD or USD | |
| pageSize | No | Items per page (max 100) | |
| sourceId | No | Estimate or recurring invoice the invoice was created from | |
| amountDue | No | Exact amount due | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| customerId | No | ||
| invoiceNumber | No | ||
| invoiceDateEnd | No | Date, YYYY-MM-DD | |
| modifiedAtAfter | No | ISO 8601 date-time, e.g. 2026-01-31T00:00:00Z | |
| invoiceDateStart | No | Date, YYYY-MM-DD | |
| modifiedAtBefore | No | ISO 8601 date-time, e.g. 2026-01-31T00:00:00Z |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, so the safety profile is covered. The description still adds real behavioral context beyond the structured fields: detail="full" expands to line items and payments and caps pages at 25, a constraint that is not expressed in the schema's pageSize maximum of 100. It does not discuss rate limits or result ordering beyond what the schema declares.
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?
Two sentences, no filler, with the returned fields front-loaded and the filters grouped into a single enumeration. The one behavioral caveat (page size under full detail) is placed where it is needed, right after the parameter it modifies.
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 15-parameter list tool with no output schema and no required parameters, the description gives enough to select filters and understand the summary-vs-full tradeoff, and annotations handle safety. The remaining gap is that a few filters (amountDue, sort) are never mentioned, though the schema documents them.
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 80%, so the schema already carries most parameter meaning and the baseline is 3. The description adds a little — the parenthetical gloss on sourceId's origin and the 25-item page cap under full detail — but leaves amountDue, sort, businessId, page and pageSize entirely to the schema. Adequate rather than additive.
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 ("List invoices") and immediately names the fields returned (totals, amount due, status), which cleanly distinguishes it from single-invoice readers like wave_get_invoice in the sibling set. It stops short of explicitly naming the sibling it is not, which keeps it 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?
The filter inventory implicitly tells the agent this is the tool for querying invoices by status/customer/date/number/currency/source, and the note that detail="full" adds line items and restricts pages to 25 hints at when to accept the extra cost. There is no explicit when-to-use vs. when-not guidance and no pointer to wave_get_invoice for single-record retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_ledger_accountsList ledger accountsARead-onlyIdempotent
Accounts that appear in the imported ledger, with their type, where the type came from (Wave chart of accounts or export labels) and line counts. Use the names or IDs to filter wave_list_ledger_transactions and account_transactions reports.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| pageSize | No | Items per page (max 200) | |
| businessId | No | Business ID; defaults to the one wave_get_context reports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false, so the safety profile is fully covered. The description adds useful payload context (type derivation source and line counts) that helps the agent judge whether the result is worth fetching. It says nothing about pagination behavior, empty-ledger cases, or ordering, which the schema only partially covers via the 'use nextPage' note on the page parameter.
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?
Two sentences, both front-loaded with the payload description first and the practical follow-up second; nothing is padded. Minor deduction: 'account_transactions reports' is an opaque reference — no tool by that name appears in the sibling list, so the phrase costs a little clarity without a resolvable target.
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 return values and does so adequately (type, provenance, line counts). Combined with the schema's pagination documentation and the annotations' safety profile, an agent has what it needs to call the tool correctly. Only the relationship to wave_list_accounts remains unstated.
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?
All three parameters (page, pageSize, businessId) have full schema descriptions at 100% coverage, so the baseline of 3 applies. The description adds no parameter-level meaning — it does not say, for example, how pageSize interacts with the line counts or what the businessId default means in a multi-business context beyond what the schema already states.
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 resource (accounts appearing in the imported ledger) plus the returned content: type, type provenance (Wave chart of accounts vs. export labels), and line counts. That is more than a restatement of the name. It stops short of explicitly distinguishing itself from the sibling wave_list_accounts, leaving the agent to infer the ledger-vs-chart-of-accounts split from the phrase 'imported ledger'.
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 second sentence gives downstream guidance — reuse the returned names or IDs as filters for wave_list_ledger_transactions and account_transactions reports — which is genuine workflow context. However, there is no statement of when to call this tool versus wave_list_accounts, and no prerequisites or exclusions, so call-selection is still implied rather than specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_ledger_transactionsList ledger transactionsARead-onlyIdempotent
List and search transactions from an imported Data Export snapshot (wave_import_ledger). For live data use wave_list_transactions; this works offline and includes invoices, bills and journal entries: bank and card transactions, expenses, invoices, bills, payments, transfers and journal entries. Filter by date range, account (ID or name), text, customer, vendor, amount, direction or uncategorized only. Newest first by default. Each row has the amount on the bank/card account (or the journal total), the categories used, and the transaction ID for wave_get_ledger_transaction.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| sort | No | date_desc | |
| query | No | Text in descriptions, notes, customer, vendor, invoice/bill number or account name | |
| vendor | No | ||
| account | No | Only transactions touching this account, by name (exact, else contains) | |
| endDate | No | Date, YYYY-MM-DD | |
| customer | No | ||
| pageSize | No | Items per page (max 100) | |
| accountId | No | Only transactions touching this account (Wave account ID) | |
| direction | No | any | |
| maxAmount | No | ||
| minAmount | No | ||
| startDate | No | Date, YYYY-MM-DD | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| uncategorizedOnly | No | Only transactions using Uncategorized Income/Expense |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and non-destructive, so safety is covered; the description adds context those annotations cannot: it works offline against an imported snapshot, results are newest-first by default, and each row carries the bank/card amount (or journal total), its categories, and the transaction ID. It does not restate pagination or cursor mechanics, but nothing here contradicts the 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 offline/live distinction is front-loaded and every sentence carries content rather than filler. The paragraph of filters is denser than ideal but stays scannable and wastes little space.
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 15 optional parameters and no output schema, the description takes on the return-value burden by describing the row shape and the follow-up call for details. Combined with the data-source caveat and default ordering, 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 60% across 15 parameters, so the description must compensate and largely does by grouping the filter dimensions (date range, account by ID or name, text, customer, vendor, amount, direction, uncategorized only) and clarifying that account accepts a name or an ID. It stops short of explaining the direction or sort enum values and leaves vendor/customer/amount params to bare schema names.
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 (list and search ledger transactions) plus the exact data source: an imported Data Export snapshot via wave_import_ledger. It explicitly distinguishes itself from wave_list_transactions (live data) and enumerates the record types included, so an agent can separate it from every sibling 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?
Gives an explicit alternative and the condition that selects it: use wave_list_transactions for live data, this one for offline snapshots. It also names wave_get_ledger_transaction for drilling into a single row, covering both the when and the next step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_paymentsList payments receivedARead-onlyIdempotent
List money received: invoice payments and estimate deposits, newest first, with totals. These are the only transaction records Wave's public API can read; bank/card transactions, expenses and money transactions created through the API cannot be listed. Filter by payment date range and customer.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | all | |
| sort | No | date_desc | |
| limit | No | Rows to return | |
| offset | No | Rows to skip; use nextOffset | |
| endDate | No | Latest payment date (inclusive) | |
| startDate | No | Earliest payment date (inclusive) | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| customerId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent, non-destructive, closed-world behavior, so the description's job is to add context — and it does, disclosing the default newest-first ordering, that totals are included, and the hard API scope limit on which transaction records are readable. It does not mention pagination behavior beyond the schema's offset field, which keeps it from a 5.
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?
Three tight sentences, front-loaded with what is returned before the scope limitations and filters. No filler, though the scope-limitation sentence is dense and could have been split for scanability.
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 an 8-parameter read tool with no output schema, the description covers what is returned ('with totals'), ordering, and the filter surface, which is enough to call it correctly. The main gap is the absence of any note on pagination/nextOffset behavior or a pointer to the sibling for non-payment transactions.
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 63%, and the description compensates by explaining that filtering is by payment date range and customer, and by mapping the undescribed 'kind' enum values to plain language ('invoice payments and estimate deposits'). It adds little about sort, limit or offset, but those are already documented 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 description names a specific verb and resource ('List money received: invoice payments and estimate deposits'), enumerates the exact record kinds returned, and states ordering and totals. It also distinguishes itself from other transaction-reading siblings by declaring that bank/card transactions, expenses and API-created money transactions cannot be listed.
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 conditions for use (invoice payments and estimate deposits only) and explicit exclusions for what this tool will not return, which steers the agent away from misusing it. It stops short of naming the sibling tool to use for the excluded transaction types (e.g. wave_list_transactions), so the routing is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_productsList products and servicesARead-onlyIdempotent
List products/services (the items invoice and estimate lines must reference), with price, income/expense accounts and default sales taxes. Active only unless isArchived=true.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| sort | No | Default CREATED_AT_DESC | |
| detail | No | summary: key fields, long text clipped. full: every field and line items | summary |
| isSold | No | Only items sold (have an income account) | |
| search | No | Case-insensitive substring match on name, description (scans the full list; use filters when you can) | |
| isBought | No | Only items bought (have an expense account) | |
| pageSize | No | Items per page (max 100) | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| isArchived | No | Default false (active only) | |
| modifiedAtAfter | No | Only records modified after this time | |
| modifiedAtBefore | No | Only records modified before this time |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the description's added value is the default filtering behavior: archived records are excluded unless isArchived=true. That is a genuinely useful disclosure an agent could otherwise get wrong. It stops short of describing paging/response behavior, which matters for a list 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?
Two sentences, zero filler, with the resource identified first and the archived-visibility caveat front-loaded at the end where it is easy to scan. Nothing is repeated unnecessarily.
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 an 11-parameter read tool with no output schema, the description covers purpose, key returned fields, and the archived default, but leaves the response shape and pagination contract (page/nextPage, pageSize cap) to the schema alone. It is adequate but not fully self-sufficient for an agent that must page through 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 description coverage is 100%, so every parameter including isArchived, detail, search, and the modifiedAt bounds is already documented in structured data. The description only restates the isArchived default and the returned field categories; it adds no new meaning about parameter interplay (e.g. how search interacts with paging) beyond 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?
"List products/services" is a specific verb+resource, and the parenthetical explains the domain role (the items invoice and estimate lines must reference) plus the fields returned (price, income/expense accounts, default sales taxes). It is clearly distinct from wave_get_product / wave_create_product / wave_update_product by name and verb, though it never names a sibling to route against.
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 rather than stated: the agent learns this is the catalog of items that invoice/estimate lines must reference, which suggests when to call it, and the archived default is flagged. There is no explicit when-to-use vs. alternatives (e.g. wave_get_product for a single item), no mention of when search/paging is preferred over a full scan.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_sales_taxesList sales taxesARead-onlyIdempotent
List sales taxes with current rate (as a fraction: 0.13 = 13%). detail="full" adds the dated rate history.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| detail | No | summary: key fields, long text clipped. full: every field and line items | summary |
| search | No | Case-insensitive substring match on name, abbreviation (scans the full list; use filters when you can) | |
| pageSize | No | Items per page (max 100) | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| isArchived | No | Default false (active only) | |
| modifiedAtAfter | No | Only records modified after this time | |
| modifiedAtBefore | No | Only records modified before this time |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is covered. The description adds resource-specific behavior (rate as a fraction, full detail returns dated history), but says nothing about pagination, pageSize limits, or what the summary mode clips — gaps an agent may care about.
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?
Two short sentences, zero filler, with the most consequential clarification (rate format) placed first and the non-default detail mode second. Nothing is repeated from the schema or annotations.
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 an 8-parameter read-only list tool with full schema descriptions and no output schema, the description covers the resource-specific quirks well. Remaining omissions (pagination flow, default business scoping) are already handled by the schema, so nothing essential is missing, though a note about large-list paging would strengthen it.
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 goes beyond the schema by explaining that detail="full" specifically yields the dated rate history for this resource, which the generic schema text does not convey. Rate-fraction notation also adds interpretive meaning the schema lacks.
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 ("List sales taxes") and immediately clarifies the rate representation (0.13 = 13%), which is the key ambiguity for this resource. It does not explicitly distinguish itself from the sibling wave_get_sales_tax or wave_list_sales_taxes filters, so it stops short of 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?
Usage is only implied: the description hints that detail="full" is the way to get history, but never says when to prefer that over wave_get_sales_tax or how to combine it with the search/filter parameters. There are no explicit when-not conditions or named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_transactionsList transactionsARead-onlyIdempotent
List and search the business's transactions as Wave's Transactions page shows them: bank and card transactions, expenses, deposits, transfers, bill and invoice payments. Live data. Filter by date range, text in the description, bank/card account (accountId), category accounts (categoryIds) or uncategorizedOnly. Cursor pagination: pass nextCursor back as cursor. Each row has the amount, direction, bank/card account, category (or categories when split), vendor, sales tax and review status. IDs work with wave_get_transaction, wave_update_transaction and wave_delete_transaction. Uses Wave's web-app API (unofficial), which needs a web session: if it is missing or expired, the user runs node /app/bin/wave-mcp.js login in a terminal on f32f40788a38.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | By transaction date | date_desc |
| cursor | No | nextCursor from the previous page | |
| detail | No | summary: key fields, long text clipped. full: every field and line items | summary |
| search | No | Text in the transaction description or a line description (case-insensitive) | |
| source | No | Where it came from: MANUAL = statement upload; PLAID/YODLEE/CASHEDGE = bank connection; GENERIC_EXTERNAL_API = API (wave_create_transaction); RECEIPT/RECEIPT_CAPTURE = receipts. Entries typed into Wave have no source | |
| endDate | No | Latest transaction date (inclusive) | |
| pageSize | No | Rows per page (max 100) | |
| accountId | No | Account register: transactions with any line on this account, usually a bank or card account; includes journal entries that touch it (wave_list_accounts) | |
| startDate | No | Earliest transaction date (inclusive) | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| categoryIds | No | Only transactions with a line in one of these category accounts | |
| transactionIds | No | ||
| uncategorizedOnly | No | Only transactions still in Uncategorized Income/Expense |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Well beyond the annotations, it discloses that data is live, explains cursor pagination semantics (pass nextCursor back as cursor), describes the shape of each returned row, and — most importantly — warns that the underlying web-app API is unofficial and requires a web session, with the exact remediation command if it is expired. That auth/expiry behavior is not derivable 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?
A single front-loaded paragraph that leads with purpose, then filters, then pagination, then return shape, then auth caveat — a sensible priority order with no filler. It is dense and long, but nearly every clause carries operational information; the login-path sentence is the only part that feels environment-specific rather than tool-semantic.
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 13-parameter, no-output-schema tool, the description compensates by summarizing the returned row fields (amount, direction, account, category/split categories, vendor, sales tax, review status) and explaining pagination and auth failure handling. An agent can call this correctly and recover from the most likely failure mode without extra discovery.
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 92% schema description coverage the schema already documents nearly every parameter (including enums for sort, detail, source). The description only restates the main filters and the cursor convention, and adds nothing about transactionIds, sort, detail, pageSize or businessId defaults. 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?
Opens with a specific verb+resource ("List and search the business's transactions") and immediately bounds the resource by enumerating what counts as a transaction: bank/card transactions, expenses, deposits, transfers, bill and invoice payments. This is far more precise than the bare tool name and lets an agent distinguish it from ledger or report tools.
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 filter conditions (date range, description text, accountId, categoryIds, uncategorizedOnly) and points to wave_list_accounts for obtaining accountId and to wave_get_transaction/update/delete for follow-up on the returned IDs. It does not state when to prefer this over wave_list_ledger_transactions or wave_run_report, so the sibling differentiation is incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_vendorsList vendorsARead-onlyIdempotent
List vendors (suppliers). Wave's API cannot create, change or delete vendors, and bills are not exposed.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based; use nextPage | |
| No | Exact email match | ||
| detail | No | summary: key fields, long text clipped. full: every field and line items | summary |
| search | No | Case-insensitive substring match on name, email, displayId, firstName, lastName (scans the full list; use filters when you can) | |
| pageSize | No | Items per page (max 100) | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| modifiedAtAfter | No | Only records modified after this time (ISO 8601) | |
| modifiedAtBefore | No | Only records modified before this time (ISO 8601) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds a genuine scope boundary (vendor data is read-only in Wave's API, bills unavailable), which is useful context beyond the annotations, but says nothing about pagination or result volume.
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?
Two short sentences with zero filler; the core purpose is front-loaded and the API limitation follows immediately. Nothing could be removed without losing information.
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 an eight-parameter read-only listing tool whose schema fully documents all inputs and whose annotations cover safety, the description supplies the one non-obvious thing the schema cannot: that write operations and bills simply do not exist in this API. Return shape is not described, but no output schema exists, so that is a minor residual 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?
Schema description coverage is 100%, with every parameter including page, pageSize, search, detail, and the modifiedAt filters documented in the schema itself. The description adds no 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?
States a specific verb and resource ('List vendors') and adds the synonym '(suppliers)', which helps the agent match a user's wording. It does not explicitly contrast with wave_get_vendor, but the list-vs-single distinction is implicit in the verb.
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?
Provides clear negative guidance — no create/update/delete of vendors and bills are not exposed — which stops the agent from hunting for nonexistent sibling tools. It stops short of naming alternatives or stating what to use instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_mark_estimate_acceptedMark estimate acceptedCIdempotent
Record that the customer accepted the estimate.
| Name | Required | Description | Default |
|---|---|---|---|
| estimateId | Yes | Estimate ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=true and openWorldHint=false, so the safety profile is covered. The description adds essentially nothing beyond that: it does not say what the write changes downstream, whether any notification or invoice state is affected, or what happens if the estimate was already accepted (the idempotent hint implies a no-op, but the text never confirms it).
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?
One short, front-loaded sentence with zero filler or repetition. Its brevity is appropriate, though it leaves useful context unstated rather than being over-long.
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 one-parameter state-transition tool with rich annotations and no output schema, the definition is minimally adequate. It still leaves the agent guessing about required estimate state, error conditions, and any side effects of the acceptance write.
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?
There is a single required parameter with 100% schema coverage, so the schema already documents estimateId fully; baseline 3 applies. The description adds no format, source, or lookup hint (e.g., where to obtain the estimate ID) beyond 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 description gives a clear verb ('Record') and resource ('the estimate') plus the domain fact being recorded (customer acceptance), so the action is unambiguous. It does not, however, distinguish itself from nearby siblings such as wave_approve_estimate or wave_reset_estimate_acceptance, which an agent could easily confuse with this state transition.
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 guidance on when to call this versus wave_approve_estimate, wave_reset_estimate_acceptance, or wave_send_estimate_acceptance_email. The description also omits any precondition, such as whether the estimate must be in a sent/pending state first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_mark_estimate_sentMark estimate as sentAIdempotent
Record that an estimate was sent outside Wave (no email goes out).
| Name | Required | Description | Default |
|---|---|---|---|
| sentAt | No | ISO 8601 date-time, e.g. 2026-01-31T00:00:00Z | |
| estimateId | Yes | Estimate ID | |
| sendMethod | No | MARKED_SENT |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare the mutation is non-destructive and idempotent, so the lower bar applies; the description still earns credit by disclosing the non-obvious behavior that no email is dispatched. It does not say what fields change (e.g., sentAt) or whether the send method influences later estimate 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?
One short sentence, front-loaded with the action and immediately qualified by the key behavioral fact. Nothing is wasted or buried.
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 simple mutation with no output schema and reasonable annotation coverage, the definition is adequate, but it omits notable details such as how sentAt behaves when omitted and the presence of a 'WAVE' option in sendMethod that sits oddly with 'outside Wave'.
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 67%, with estimateId and sentAt documented inline, so the baseline is 3. The description adds no meaning about sentAt defaults or which sendMethod values are appropriate when Wave itself was the channel, leaving the enum values to speak for themselves.
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 ('Record that an estimate was sent') and adds the constraint 'outside Wave', which implicitly distinguishes it from wave_send_estimate and wave_send_estimate_acceptance_email. It stops short of naming the sibling it differs from, but an agent can still infer the distinction from the parenthetical.
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?
'Outside Wave' hints at the condition for use, but there is no explicit when-to-use/when-not guidance and no named alternative such as wave_send_estimate for cases where Wave should actually deliver the estimate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_mark_invoice_sentMark invoice as sentAIdempotent
Record that an invoice was sent outside Wave (no email goes out).
| Name | Required | Description | Default |
|---|---|---|---|
| sentAt | No | ISO 8601 date-time, e.g. 2026-01-31T00:00:00Z | |
| invoiceId | Yes | Invoice ID | |
| sendMethod | No | MARKED_SENT |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the operation non-read-only, idempotent, non-destructive, and closed-world. The description adds important behavioral context beyond them: this records a sent state without triggering any email delivery, which is exactly the side-effect distinction an agent needs.
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 definition is a single compact sentence with the core action front-loaded. Every clause earns its place by clarifying the operation and its key non-email behavior.
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 simple, non-destructive, idempotent mutation with no output schema, the description covers the essential behavior and prevents confusion with email sending. Minor gaps remain around sentAt and sendMethod semantics, but these are mostly handled by the schema.
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 schema has moderate description coverage at 67%, with invoiceId and sentAt documented and sendMethod represented by a self-explanatory enum. The description adds no parameter-level meaning, so the schema does most of the work and the baseline of 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 description states a specific verb and resource: recording that an invoice was sent. The parenthetical 'no email goes out' distinguishes it from the sibling email-sending tool wave_send_invoice, so an agent can identify the correct operation 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 usage context: this is for invoices sent outside Wave, and it explicitly notes that no email is sent. It does not name wave_send_invoice as the alternative, but the 'outside Wave' condition effectively implies when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_record_estimate_depositRecord estimate depositB
Record a deposit received outside Wave against an estimate. paymentAccountId is where the money went (a CASH_AND_BANK account).
| Name | Required | Description | Default |
|---|---|---|---|
| memo | No | ||
| amount | Yes | Positive amount, at most 2 decimals | |
| estimateId | Yes | Estimate ID | |
| paymentDate | Yes | Date, YYYY-MM-DD | |
| paymentMethod | Yes | ||
| paymentAccountId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare this is a non-read-only, non-destructive, non-idempotent, closed-world mutation, so the safety profile is covered. The description adds that the deposit is external to Wave and that paymentAccountId must be a CASH_AND_BANK account, which is useful constraint context, but it says nothing about what happens to the estimate's balance or status, or that retries can create duplicates.
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?
Two short sentences, front-loaded with the action and resource, with the account constraint placed second. No filler, though the parenthetical '(a CASH_AND_BANK account)' is slightly bare and could be phrased more explicitly.
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 six-parameter mutation with no output schema, the description covers the core intent and the key account-type constraint. It is still thin on effects (estimate status/balance changes), on what a successful call returns, and on whether memo is optional, which an agent would want before calling.
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 50%, so several parameters are undocumented in the schema. The description compensates for paymentAccountId by explaining it is the destination account and must be of type CASH_AND_BANK, which is genuinely useful, but memo and the paymentMethod enum get no added meaning beyond 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 description states a specific verb and resource ('Record a deposit ... against an estimate') plus a scope qualifier ('received outside Wave') that separates it from invoice-payment and deposit-update siblings. It stops short of naming the sibling tools it should be preferred over, but an agent can still tell what it does 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?
'Received outside Wave' implies the use case (manual recording of an off-platform payment), which is real guidance but only implicit. There is no explicit when-not guidance or reference to alternatives such as wave_record_invoice_payment or wave_update_estimate_deposit, so the agent has to infer routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_record_invoice_paymentRecord invoice paymentA
Record a payment received outside Wave against an invoice (cash, cheque, bank transfer...). paymentAccountId is the account the money went into (usually types=[ASSET] subtypes=[CASH_AND_BANK]). The invoice must be approved, not a draft.
| Name | Required | Description | Default |
|---|---|---|---|
| memo | No | ||
| amount | Yes | Positive amount, at most 2 decimals | |
| invoiceId | Yes | Invoice ID | |
| paymentDate | Yes | Date, YYYY-MM-DD | |
| exchangeRate | No | Payment-account currency per invoice currency; 1 when they match | |
| paymentMethod | Yes | ||
| paymentAccountId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, non-destructive mutation, and the description adds genuine context beyond them: the approved-invoice prerequisite and the account-selection hint. However, the annotations mark idempotentHint=false, and the description never warns that calling it twice creates a duplicate payment, nor does it say whether a recorded payment can be corrected or reversed (via wave_update_invoice_payment / wave_delete_invoice_payment).
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?
Three short sentences: what it does, how to pick the account, and the precondition. No filler, and the purpose is front-loaded ahead of the constraint.
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 7-parameter mutation with no output schema, the description covers purpose, account selection, and the approval precondition, but leaves the agent without any statement of what comes back (a payment id usable with wave_get_invoice_payment / wave_send_invoice_payment_receipt?) or how multi-currency exchangeRate behaves in practice. Adequate to call, not complete enough to be confident about 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?
With schema coverage at 57%, the description compensates for the biggest undocumented parameter: paymentAccountId is explained as the account the money landed in, with concrete guidance (types=[ASSET] subtypes=[CASH_AND_BANK]). The listed payment methods (cash, cheque, bank transfer) also map onto the paymentMethod enum. It adds nothing for memo, amount, or exchangeRate, but those are already documented 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?
"Record a payment received outside Wave against an invoice" states a specific verb (record) plus resource (invoice payment) and scopes it to off-platform payments, which separates it from the estimate-deposit and online-payment siblings. It stops short of naming an alternative tool outright, but the resource is unambiguous.
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 phrase "received outside Wave" tells the agent when this is the right tool, and "The invoice must be approved, not a draft" is an explicit precondition that prevents a common failure. There is no explicit when-not guidance (e.g., for already-recorded or externally-synced payments) or pointer to wave_update_invoice_payment when a payment was entered incorrectly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_reset_estimate_acceptanceReset estimate acceptanceBIdempotent
Undo the customer's acceptance so the estimate can be changed or re-accepted.
| Name | Required | Description | Default |
|---|---|---|---|
| estimateId | Yes | Estimate ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, idempotent, non-destructive mutation, so the safety bar is partly covered. The description adds that the operation reverses a prior customer acceptance, but says nothing about what state the estimate returns to, whether acceptance metadata (signature, timestamp, recorded deposits) is discarded, or what permissions are required.
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?
One short sentence with the action front-loaded and the rationale trailing; nothing is padded. Slightly more structure (e.g., an explicit state-transition note) could be added without bloat.
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 one-parameter state-reversal mutation with no output schema, the definition covers what it does but omits the resulting estimate status and any side effects on related records (deposits, converted invoices), which are the details an agent most needs before calling it.
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 there is a single required estimateId that the schema already documents, so the baseline is 3. The description adds no meaning about the identifier's format, provenance, or what happens if the estimate was never accepted.
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+resource: undo the customer's acceptance of an estimate. It also hints at the follow-on capability (change or re-accept the estimate), which distinguishes it from wave_mark_estimate_accepted and wave_update_estimate without naming them explicitly.
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 purpose clause implies when to reach for it (when an accepted estimate must be edited or re-accepted), but there is no explicit when-not guidance, no mention of prerequisites, and no named alternative such as wave_update_estimate for estimates that were never accepted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_run_reportRun a financial reportARead-onlyIdempotent
Financial reports computed by this server (Wave's API has no report endpoint). Rows are paginated with limit/offset; totals always cover every row. From the imported ledger (wave_import_ledger; any period, default year to date; balance-sheet style reports as of endDate): profit_and_loss, balance_sheet, cash_flow, trial_balance, account_balances, account_transactions/general_ledger (filter with account or accountId), sales_tax (sales and purchases), aged_payables, purchases_by_vendor. Without a ledger, profit_and_loss, balance_sheet, trial_balance and account_balances fall back to current account balances from the API (as of now only), and sales_tax to invoices. Live from invoices (invoice date range): income_by_customer, sales_by_product, invoice_summary; as of today: aged_receivables; customer_statement needs customerId. Not possible: tax_line, payroll_wage_tax, payroll_benefits_deductions.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Rows to return | |
| offset | No | Rows to skip; use nextOffset | |
| report | Yes | ||
| source | No | auto: imported ledger when available for this report, else the live API | auto |
| account | No | account_transactions: account name (exact, else contains) | |
| endDate | No | Period end; also the as-of date for balance_sheet, trial_balance, account_balances, aged_payables | |
| accountId | No | account_transactions: Wave account ID | |
| startDate | No | Date, YYYY-MM-DD | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| customerId | No | Required for customer_statement; filters invoice-based reports | |
| fiscalYearStart | No | balance_sheet: fiscal year start MM-DD, splits retained earnings from current-year profit | 01-01 |
| outstandingOnly | No | customer_statement: only invoices with an amount due | |
| includeZeroBalances | No | account_balances: include accounts with a zero balance | |
| includeArchivedAccounts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, it discloses server-side computation, lack of a Wave report endpoint, limit/offset pagination with totals covering all rows, source fallbacks, as-of date semantics, and unavailable reports. These are meaningful behavioral constraints not present in annotation or schema 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 description is dense and front-loaded, covering purpose, pagination, source rules, report availability, and unsupported reports without filler. The semicolon-heavy single paragraph could be more scannable, but the length is justified by 18 report types and 14 parameters.
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 report tool with no output schema, it explains data sources, report availability, date semantics, pagination, and unsupported requests. It does not describe response fields per report, but given the breadth that is a reasonable gap rather than a blocking omission.
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 high at 86%, so the baseline is 3; the description still adds report-specific meaning such as account/accountId for account_transactions, customerId for customer_statement, endDate as the as-of date for balance-style reports, and source/report availability. It does not explain every parameter, but it substantially supplements 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 sentence states this tool computes financial reports server-side because Wave's API has no report endpoint, and it enumerates the supported report types. That is a specific verb/resource plus scope, distinguishing it from sibling CRUD and data-source tools such as wave_import_ledger.
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 maps each report family to its source (imported ledger vs live invoices/API), names wave_import_ledger, explains fallback behavior when no ledger exists, and flags unsupported reports. It stops short of explicit 'use this instead of X' guidance for every alternative, but the conditions are clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_send_estimateEmail estimateADestructive
Email an estimate through Wave to real recipients. Irreversible: confirm recipients first. The estimate must be approved.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient email addresses | |
| message | No | ||
| subject | No | ||
| ccMyself | No | ||
| attachPDF | No | ||
| estimateId | Yes | Estimate ID | |
| fromAddress | No | ||
| hideGrandTotal | No | ||
| includeAttachments | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, openWorldHint=true and non-idempotent, so the safety profile is partly covered. The description still adds genuine value beyond them: that the send reaches external real recipients, that it is irreversible, and that the estimate must be approved first. It omits what happens on partial failure or whether a resend is blocked.
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?
Three short sentences with the action and the irreversible warning front-loaded; nothing is buried. 'Through Wave' is the only near-filler phrase.
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 destructive, externally-visible send the description covers the critical risk and precondition, and no output schema means returns need not be explained. However, with 7 of 9 parameters undocumented and no explanation of how subject/message/attachment options affect the email, the definition is not fully complete for a call 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 only 22% across 9 parameters; seven of them (message, subject, ccMyself, attachPDF, fromAddress, hideGrandTotal, includeAttachments) are undocumented in both schema and description. The description adds no meaning about recipient limits, subject/message behavior, or attachment toggles, so it does not compensate for the coverage gap.
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?
Specific verb ('Email') plus resource ('an estimate') plus the external-effect scope ('to real recipients'). It does not explicitly separate itself from nearby siblings such as wave_send_estimate_acceptance_email or wave_generate_estimate_pdf, so an agent must infer the distinction.
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?
Provides a real prerequisite ('The estimate must be approved') and a pre-call caution ('confirm recipients first'), which tells the agent when the call is valid. It stops short of naming alternatives or stating when not to use it (e.g., use the acceptance-email tool for a different flow).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_send_estimate_acceptance_emailEmail estimate acceptance confirmationADestructive
Email the customer the confirmation that their estimate acceptance was recorded. Irreversible.
| Name | Required | Description | Default |
|---|---|---|---|
| estimateId | Yes | Estimate ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true, idempotentHint=false, openWorldHint=true, and readOnlyHint=false. The description usefully adds that the action is irreversible and that an email goes to the customer, but it does not explain duplicate-send behavior, required state, or any authorization constraints 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 description is two short sentences and front-loads the primary action. Every phrase contributes to identifying the operation or its irreversibility, with no unnecessary wording.
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 one-parameter mutation with rich annotations, the definition covers the core action and irreversibility. However, it omits the prerequisite that acceptance must already be recorded and does not clarify sequencing relative to wave_mark_estimate_accepted or duplicate-send 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 single estimateId parameter is documented as 'Estimate ID.' The description adds no additional meaning about the parameter, such as whether it must reference an already-accepted estimate, so the schema 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 states a specific verb and resource: emailing the customer a confirmation that their estimate acceptance was recorded. It is clearer than the tool name alone, but it does not distinguish itself from related siblings such as wave_mark_estimate_accepted or wave_send_estimate.
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 phrase 'their estimate acceptance was recorded' implies this should be used after acceptance is recorded, but there is no explicit prerequisite, sequencing guidance, or note about when not to use it. Alternatives such as wave_send_estimate or wave_mark_estimate_accepted are not referenced.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_send_estimate_deposit_receiptEmail deposit receiptBDestructive
Email a receipt for an estimate deposit to real recipients. Irreversible.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient email addresses | |
| message | No | ||
| subject | No | ||
| ccMyself | No | ||
| attachPdf | No | ||
| estimateId | Yes | Estimate ID | |
| fromAddress | No | ||
| estimatePaymentId | Yes | Estimate payment ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, openWorldHint=true, and idempotentHint=false, so the safety profile is largely covered. 'Irreversible' restates destructiveHint rather than extending it, though 'to real recipients' adds a small note that the email actually leaves the system. Nothing is said about rate limits, delivery failure behavior, or sender identity.
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?
Two short sentences, front-loaded with the action and ending with the risk. There is no wasted wording, though the terseness borders on under-specification for an 8-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?
For a destructive, outbound-email tool with 8 parameters, no output schema, and low schema coverage, the description is thin — it omits what happens on success/failure and how optional parameters alter the message. Annotations carry the safety story, which keeps this from being inadequate, but an agent still lacks context on parameter effects.
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 only 38%, and the description adds no meaning for any of the 8 parameters. Optional fields with real ambiguity — attachPdf, ccMyself, subject, message, fromAddress — are undocumented in both schema and description. The description does not compensate for the coverage gap.
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 states a specific verb and resource: email a receipt for an estimate deposit. That distinguishes it from wave_send_invoice_payment_receipt and other send tools in the sibling list. It does not, however, name or differentiate against the closest siblings (wave_send_estimate, wave_send_estimate_acceptance_email) explicitly.
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 when-to-use guidance beyond the implicit 'this sends a deposit receipt.' It never states prerequisites such as the deposit needing to be recorded first, nor does it route the agent to alternatives like wave_send_invoice_payment_receipt or wave_record_estimate_deposit. 'Irreversible' warns of consequence but does not guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_send_invoiceEmail invoiceADestructive
Email an invoice through Wave to real recipients. Irreversible: confirm recipients first. Requires email sending enabled for the business (wave_get_business emailSendEnabled).
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient email addresses | |
| message | No | ||
| subject | No | ||
| ccMyself | No | ||
| attachPDF | No | ||
| invoiceId | Yes | Invoice ID | |
| fromAddress | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already flag destructiveHint=true, openWorldHint=true and non-idempotence, but the description adds genuinely new context beyond them: the action is irreversible, recipients should be confirmed beforehand, and the call will fail unless emailSendEnabled is true on the business. It doesn't mention rate limits, whether sending changes the invoice status, or what happens on partial success with multiple recipients.
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?
Three short sentences, front-loaded with the action and the irreversibility warning before the prerequisite. The parenthetical "(wave_get_business emailSendEnabled)" is efficient but slightly telegraphic; no filler is present.
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 destructive, open-world send operation with no output schema, the description covers the safety narrative and one prerequisite well. However, five of seven parameters remain unexplained and the agent is not told what the tool returns or whether the invoice's sent status changes, leaving a real gap for a 7-parameter mutation.
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 7 parameters and only 29% schema description coverage, the description needed to compensate and instead says nothing about `message`, `subject`, `ccMyself`, `attachPDF` (which defaults to true) or `fromAddress`. Only the recipient concept is gestured at via "real recipients"; the optional email-shaping parameters are undocumented in both places.
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?
"Email an invoice through Wave to real recipients" gives a specific verb (email) and resource (invoice), and the phrase "real recipients" distinguishes it from the nearby mark-sent-style tools that only change status. It stops short of naming the sibling alternative (e.g., wave_mark_invoice_sent) explicitly, so the differentiation is implied rather than 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?
It supplies a clear precondition (email sending must be enabled for the business) and an operational instruction (confirm recipients first) that an agent can act on before calling. It does not say when to prefer this over wave_mark_invoice_sent, so the alternative-routing guidance is incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_send_invoice_payment_receiptEmail payment receiptBDestructive
Email a receipt for an invoice payment to real recipients. Irreversible.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient email addresses | |
| message | No | ||
| subject | No | ||
| ccMyself | No | ||
| attachPdf | No | ||
| invoiceId | Yes | Invoice ID | |
| fromAddress | No | ||
| invoicePaymentId | Yes | Invoice payment ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, openWorldHint=true and idempotentHint=false, so the 'Irreversible' sentence largely restates structured data. 'Real recipients' does add that external email is actually dispatched, but there is no mention of who the mail comes from, whether attachments default on, or rate/recipient-count limits despite maxItems=20.
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?
Two short, front-loaded sentences with no filler. The only questionable element is the vague 'real recipients' qualifier, which is terse but under-explained rather than wasted.
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?
An eight-parameter, irreversible outbound-email mutation with no output schema needs more than a one-line summary: which payment/invoice pair is required, whether a PDF attachment is included by default, and what happens on failure are all absent. As written an agent knows the gist but not enough to invoke it confidently.
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 only 38%; five of eight parameters (message, subject, ccMyself, attachPdf, fromAddress) have no schema description at all. The tool description says nothing about any parameter, so it fails to compensate for the coverage gap on a fairly rich parameter set.
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 ('Email a receipt for an invoice payment'), which is distinguishable from wave_send_invoice and wave_send_estimate_deposit_receipt by the resource named. It does not explicitly contrast with those siblings, so it stops short of 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?
'Irreversible' implies a use-with-caution condition, but there is no explicit when-to-use versus wave_send_invoice or wave_get_invoice_payment, and no prerequisites such as requiring a recorded payment first. The phrase 'real recipients' gestures at a test-vs-production distinction without explaining it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_update_accountUpdate accountADestructiveIdempotent
Rename an account or change its description/number. Wave requires the account's current sequence (optimistic locking); it is read automatically when omitted. Pass null for description/displayId to clear them.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Account ID | |
| name | No | ||
| sequence | No | Current sequence from wave_get_account; fetched when omitted | |
| displayId | No | ||
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=false, destructiveHint=true, idempotentHint=true, openWorldHint=false), so the description's added value is the optimistic-locking requirement and the fact that the sequence is auto-read when omitted — genuinely useful behavior not in the annotations. The null-clearing rule also signals that clearing a field is a destructive act, which supports the destructiveHint. It does not explain what happens to omitted fields (partial vs. full replacement), leaving one behavioral gap.
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?
Three short sentences: the primary capability first, then the locking constraint, then the null-clearing rule. Nothing is redundant with the schema and no sentence is 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?
For a destructive, idempotent mutation with no output schema, the description covers the two things an agent would otherwise get wrong: concurrency handling and how to clear optional fields. The remaining gap is whether unspecified fields are preserved, which matters for a partial update on a destructive 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?
Schema coverage is only 50%, so the description must compensate, and it does for the highest-risk semantics: passing null to description/displayId clears them, a detail absent from the schema. It also reinforces 'rename' as the effect of the name parameter and explains the sequence auto-fetch. businessId is left to the schema alone and the name/displayId distinction could be sharper, so it is not a full 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 description states a concrete verb-and-resource pair — rename an account or change its description/number — which is clearly distinct from wave_create_account, wave_archive_account, and wave_get_account. It stops short of explicitly naming those siblings as alternatives, so the differentiation is implied rather than 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?
Usage is only implied: updating an existing account (as opposed to creating or archiving one). There is no explicit when-to-use, no prerequisites section, and no statement of when to prefer wave_get_account first or when to use the archive path instead. The one operational hint — sequence is fetched automatically when omitted — helps execution but is not routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_update_customerUpdate customerADestructiveIdempotent
Change fields on a customer. Only the fields you pass are changed; nested address/shipping objects replace the existing ones.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Customer ID | |
| fax | No | ||
| name | No | ||
| No | |||
| phone | No | ||
| mobile | No | ||
| address | No | Postal address | |
| website | No | ||
| currency | No | Default invoicing currency for this customer | |
| lastName | No | ||
| tollFree | No | ||
| displayId | No | Your own account number for the customer | |
| firstName | No | ||
| internalNotes | No | ||
| shippingDetails | No | Shipping contact and address |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare mutation, idempotency, and destructiveness. The description adds important behavior beyond them: only supplied fields change, while nested address/shipping objects replace existing objects, which is a meaningful mutation nuance.
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 compact sentences with no wasted wording. The partial-update rule is front-loaded, and the nested-replacement caveat follows immediately.
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 15-parameter mutation with no output schema, the description covers the key partial-update and nested-replacement behavior but omits required-ID semantics, permission implications, and what happens when invalid fields are supplied. It is adequate but not complete.
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 only 33%, so the description must compensate for many undocumented parameters. It usefully explains nested-object replacement semantics, but it does not clarify the required id or the many flat customer fields beyond what their names imply.
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 states a specific verb and resource: "Change fields on a customer." It is clearly distinct from create, get, delete, or list customer tools, though it does not explicitly name those siblings.
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 implies when to use the tool by explaining partial field updates and nested object replacement. However, it does not state prerequisites, when not to use it, or how to choose it over create/delete alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_update_estimateUpdate estimateADestructiveIdempotent
Change an estimate. Wave's patch requires customer, status, title, dates, currency and exchange rate; any you omit are copied from the current estimate. Passing items replaces every line.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Estimate ID | |
| memo | No | Notes shown to the customer | |
| items | No | ||
| title | No | ||
| footer | No | ||
| status | No | ||
| dueDate | No | Date, YYYY-MM-DD | |
| subhead | No | ||
| currency | No | ISO 4217 currency code, e.g. CAD or USD | |
| hideName | No | ||
| hideUnit | No | ||
| poNumber | No | ||
| discounts | No | ||
| hidePrice | No | ||
| itemTitle | No | ||
| unitTitle | No | ||
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| customerId | No | ||
| hideAmount | No | ||
| priceTitle | No | ||
| amountTitle | No | ||
| depositUnit | No | ||
| depositValue | No | Deposit size in depositUnit. Wave documents AMOUNT values in cents | |
| estimateDate | No | Date, YYYY-MM-DD | |
| exchangeRate | No | Business currency per document currency (foreign-currency documents only) | |
| depositStatus | No | Whether the customer can or must pay a deposit | |
| estimateNumber | No | ||
| hideDescription | No | ||
| disableAmexPayments | No | ||
| disableBankPayments | No | ||
| disableCreditCardPayments | No | ||
| dontCarryOverNotesToInvoice | No | ||
| requireTermsOfServiceAgreement | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, but the description adds real context beyond them: Wave's underlying patch requires customer, status, title, dates, currency and exchange rate, and this tool backfills omitted ones from the current estimate. The warning that 'Passing items replaces every line' is the key destructive side effect and is not derivable from the annotations alone.
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?
Two tight sentences, front-loaded with the purpose and then the two highest-value behavioral caveats (fill-forward defaults, destructive item replacement). Nothing is wasted, though a little more structure (e.g., separating the destructive warning) would improve scanability.
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 33-parameter destructive mutation with no output schema and low schema coverage, the description covers only the minimum viable surface. It says nothing about permissions, what happens to an estimate already sent/accepted, whether acceptance state resets, or limits beyond the items-array note, all of which matter when mutating an estimate.
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 only 27% across 33 parameters, so the description must compensate, and it partially does by explaining the fill-forward behavior for customer/status/title/dates/currency/exchangeRate and the replace-all semantics of items. However, the bulk of parameters (hiding flags, subhead, footer, itemTitle, payment disablers, deposit fields) receive no additional meaning from the description, leaving much of the surface undocumented in both places.
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 opens with a specific verb+resource ('Change an estimate') and immediately characterizes the operation as a patch rather than a full replace, which lets an agent distinguish it from wave_create_estimate and wave_clone_estimate. It does not explicitly differentiate from wave_update_estimate_deposit, which is the closest ambiguity among siblings.
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 rather than stated: 'Change an estimate' plus the note that omitted fields are copied from the current estimate tells the agent this is an incremental partial update. There is no explicit when-to-use/when-not-to-use framing and no mention of sibling alternatives such as the deposit-specific updater, so an agent must infer routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_update_estimate_depositUpdate estimate depositCDestructiveIdempotent
Change a manually recorded estimate deposit.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Estimate payment ID | |
| memo | No | ||
| amount | No | Positive amount, at most 2 decimals | |
| estimateId | Yes | Estimate ID | |
| paymentDate | No | Date, YYYY-MM-DD | |
| paymentMethod | No | ||
| paymentAccountId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered. Beyond that, the description does not disclose the critical behavioral question for this mutation — whether omitted fields (memo, amount, paymentDate, paymentMethod, paymentAccountId) are preserved or cleared — nor any permission or side-effect context. The 'manually recorded' qualifier is the only added behavioral constraint.
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 single sentence is front-loaded and free of waste, which is structurally clean. However, at this length the brevity reads as under-specification rather than disciplined conciseness for a 7-parameter destructive mutation.
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 destructive, multi-field update with no output schema and only 57% schema coverage, one sentence leaves out partial-vs-full update semantics, field-level effects, and error conditions. An agent could invoke it but could easily clear fields it intended to leave untouched.
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 57%, leaving id, memo, paymentMethod, and paymentAccountId partially or entirely undocumented, and the description compensates for none of it. It adds no meaning about which parameters are editable, what happens to paymentAccountId, or how amount formatting is handled beyond the schema's own pattern.
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 states a specific verb ('Change') and resource ('estimate deposit') and adds a meaningful scope qualifier ('manually recorded'), so an agent knows this modifies an existing deposit record rather than creating or deleting one. It does not name near-neighbors such as wave_record_estimate_deposit or wave_update_estimate_payment, so sibling differentiation is left to inference.
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 when-to-use guidance, no prerequisites, and no statement of when this tool should be avoided in favor of wave_record_estimate_deposit or wave_delete_estimate_payment. The only implied guidance comes from the word 'Change' and the 'manually recorded' qualifier.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_update_invoiceUpdate invoiceBDestructiveIdempotent
Change an invoice. Passing items replaces every line; omit items to keep them. Wave may refuse changes to paid invoices.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Invoice ID | |
| memo | No | Notes shown to the customer | |
| items | No | ||
| title | No | ||
| footer | No | ||
| status | No | ||
| dueDate | No | Date, YYYY-MM-DD | |
| subhead | No | ||
| currency | No | ISO 4217 currency code, e.g. CAD or USD | |
| hideName | No | ||
| hideUnit | No | ||
| poNumber | No | ||
| discounts | No | ||
| hidePrice | No | ||
| itemTitle | No | ||
| unitTitle | No | ||
| customerId | No | ||
| hideAmount | No | ||
| priceTitle | No | ||
| amountTitle | No | ||
| invoiceDate | No | Date, YYYY-MM-DD | |
| exchangeRate | No | Business currency per document currency (foreign-currency documents only) | |
| invoiceNumber | No | ||
| hideDescription | No | ||
| disableAmexPayments | No | ||
| disableBankPayments | No | ||
| disableCreditCardPayments | No | ||
| requireTermsOfServiceAgreement | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered structurally. The description adds real value beyond that by disclosing the destructive replacement semantics of items and the fact that paid invoices may be rejected. It still omits what happens to unmentioned fields, whether partial updates are atomic, and how refusals surface, which matters for a 28-param mutation.
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?
Three short sentences, front-loaded with the core action, and each sentence carries a distinct decision-relevant fact. No filler, no restatement of the title.
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 destructive 28-parameter mutation with no output schema and thin schema documentation, the description is too terse. It covers the items-replacement hazard and the paid-invoice restriction, but leaves an agent without guidance on field-level update semantics, required permissions, or what a successful response contains.
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 only 21% across 28 parameters, so the description carries a heavy burden it does not fully meet. It does add meaning the schema cannot express on its own: that items is a full-replacement list rather than a merge. The other 27 parameters, including status, currency, exchangeRate, and the various hide* toggles, get no guidance in the description.
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 and resource ("Change an invoice"), so the agent knows it mutates an existing invoice rather than creating or reading one. It does not, however, distinguish itself explicitly from siblings like wave_create_invoice, wave_clone_invoice, or wave_approve_invoice, which also touch invoice state.
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 usage for editing an existing invoice and gives one concrete conditional rule (pass items to replace lines, omit to preserve them), which is genuinely decision-guiding. There is no explicit statement of when this tool is preferred over wave_create_invoice or wave_clone_invoice, and no prerequisites such as needing the invoice ID from wave_list_invoices.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_update_invoice_paymentUpdate invoice paymentCDestructiveIdempotent
Change a manually recorded invoice payment.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Invoice payment ID | |
| memo | No | ||
| amount | No | Positive amount, at most 2 decimals | |
| paymentDate | No | Date, YYYY-MM-DD | |
| exchangeRate | No | ||
| paymentMethod | No | ||
| paymentAccountId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=true and openWorldHint=false, so the safety profile is covered. The description adds only the "manually recorded" scope note and says nothing about whether this is a partial update, which fields can be cleared, whether amount changes are allowed, or what side effects occur on the parent invoice.
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 six-word sentence with no filler and the resource front-loaded, which is structurally clean. However, this is brevity through omission rather than economy — the same length could have carried one clause about update semantics or editability limits.
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?
This is a destructive mutation on a financial record with seven parameters, 43% schema coverage and no output schema. For that complexity the description is inadequate: it does not state whether updates are partial, whether the tool can change the linked account or method, or what an agent should expect on success.
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 only 43%: id, amount and paymentDate are documented inline, but memo, exchangeRate, paymentMethod and paymentAccountId carry no meaning anywhere. The description does not compensate by explaining partial-update semantics (only id is required), the exchange-rate implication for foreign-currency payments, or how paymentAccountId relates to paymentMethod.
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?
"Change a manually recorded invoice payment" gives a specific verb (change), a specific resource (invoice payment), and a scope qualifier (manually recorded) that separates it from wave_record_invoice_payment and wave_delete_invoice_payment. It is clear but does not explicitly name a sibling as the alternative, so it stops short of 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?
There is no explicit when-to-use guidance and no mention of alternatives such as record/delete payment tools. The phrase "manually recorded" implicitly signals that processor-synced payments may not be editable, but the agent must infer that constraint rather than being told.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_update_productUpdate product or serviceBDestructiveIdempotent
Change a product/service. defaultSalesTaxIds replaces the whole list.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Product ID | |
| name | No | ||
| unitPrice | No | ||
| description | No | ||
| incomeAccountId | No | Makes it sellable. Account subtype must be INCOME, DISCOUNTS or OTHER_INCOME | |
| expenseAccountId | No | Makes it buyable. Account subtype must be EXPENSE, COST_OF_GOODS_SOLD, PAYMENT_PROCESSING_FEES or PAYROLL_EXPENSES | |
| defaultSalesTaxIds | No | Sales taxes applied by default on invoice lines |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, and the description adds meaningful context with the note that `defaultSalesTaxIds` replaces the entire list rather than appending. However, it never states the core mutation semantic an agent most needs: whether omitted fields are left untouched (partial update) or cleared, nor what a destructive update here actually overwrites.
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?
Two short sentences with no filler; the replacement warning is placed immediately after the purpose statement where it will be read. Only minor weakness is that the first sentence is terse to the point of near-vagueness.
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 7-parameter destructive mutation with no output schema, the definition covers the purpose and one dangerous parameter but omits partial-vs-full update semantics and whether the updated product is returned. It is adequate to invoke, not adequate to invoke confidently.
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 only 57%, and the description compensates for exactly the riskiest field by explaining that `defaultSalesTaxIds` is a full replacement. It adds nothing for `name`, `unitPrice`, or `description`, which are undocumented in both places, so the compensation is partial.
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?
"Change a product/service" names a specific verb and resource, and the required `id` makes clear it operates on an existing record rather than creating one. It is distinguishable from wave_create_product and wave_archive_product by implication, though those siblings are never named.
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 guidance on when to use this tool versus wave_create_product, wave_archive_product, or wave_get_product, and no prerequisites or preconditions are stated. The agent must infer that this is the edit path for an already-existing product.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_update_sales_taxUpdate sales taxADestructiveIdempotent
Change a sales tax. To change the rate, pass rates with an effective date; rates replaces the dated rate list, so include existing entries you want to keep (see wave_get_sales_tax).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Sales tax ID | |
| name | No | ||
| rates | No | ||
| taxNumber | No | ||
| description | No | ||
| abbreviation | No | ||
| showTaxNumberOnInvoices | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, but the description adds the non-obvious reason why: 'rates replaces the dated rate list' so existing entries must be re-included or they are lost. That is exactly the behavioral context an agent needs before a destructive write and is not derivable from the schema. It stops short of stating whether the other fields are partial-patch or full-replace semantics.
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?
Two sentences, no filler. The core operation is front-loaded and the destructive replacement warning follows immediately, with the pointer to wave_get_sales_tax attached at the exact point of relevance.
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 destructive mutation with no output schema and only 14% schema coverage across seven parameters, the description covers the single biggest hazard (rate-list replacement) but leaves the remaining optional fields and the partial-vs-full update question unaddressed. Adequate for the critical path, incomplete overall.
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 only 14%, so the description must carry weight, and it does explain 'rates' replacement semantics and its effective-date requirement better than the schema does. But name, taxNumber, description, abbreviation, and showTaxNumberOnInvoices receive no mention anywhere, leaving five of seven parameters semantically bare.
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 opens with a specific verb and resource ('Change a sales tax'), and the follow-on sentence narrows it to rate edits, which distinguishes it from wave_create_sales_tax and wave_archive_sales_tax by implication. It does not explicitly state that only the supplied fields are modified versus a full replace, but the core purpose is immediately legible.
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 one solid conditional rule: to change the rate, pass 'rates' with an effective date. It also routes the agent to wave_get_sales_tax for reading the current dated list. However, there is no guidance on when to use this versus wave_archive_sales_tax or wave_create_sales_tax, nor on which of the other six fields are safe to update.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_update_transactionEdit transactionADestructiveIdempotent
Edit a transaction as in the Wave web app: date, description, notes, reviewed (verified), bank/card account, total amount, category, vendor or customer, or the full set of split lines. Journal entries (journalEntry: true) have no bank side: edit their lines, keeping debits equal to credits. Single-category transactions: use categoryId / vendorId / customerId / amount / salesTax directly. Split transactions: pass lines (every line to keep, with order from wave_get_transaction; omit order to add a line; lines left out are removed). Line amounts include sales tax and must add up to the amount. Reads the transaction first and sends its current sequence, so it never overwrites a newer edit. dryRun=true shows the change without saving. Confirm with the user before changing amounts or accounts. Uses Wave's web-app API (unofficial), which needs a web session: if it is missing or expired, the user runs node /app/bin/wave-mcp.js login in a terminal on f32f40788a38.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Transaction ID | |
| date | No | Date, YYYY-MM-DD | |
| lines | No | ||
| notes | No | Notes; empty string clears them | |
| amount | No | New total; for split transactions also pass lines | |
| dryRun | No | ||
| salesTax | No | Replace the sales taxes on this line ([] removes them). Line amounts include tax. Omitted: unchanged; Wave recalculates taxes it calculated itself when the amount changes, but keeps manually set ones | |
| vendorId | No | Vendor ID; null clears it | |
| verified | No | Mark as reviewed (true) or not reviewed (false) | |
| accountId | No | Move it to another bank/card account | |
| businessId | No | Business ID; defaults to the one wave_get_context reports | |
| categoryId | No | New category account (single-category transactions) | |
| customerId | No | Customer ID; null clears it | |
| description | No | ||
| lineDescription | No | Description on the category line (single-category transactions) | |
| expectedSequence | No | Fail instead of editing if the transaction changed since you read it (sequence from wave_get_transaction) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true; the description goes beyond them with the optimistic-concurrency behavior (reads first and sends the current sequence, so it never overwrites a newer edit), the destructive detail that unlisted lines are removed, and the web-session auth requirement including the exact recovery command. It does not describe the response payload, but the concurrency and removal semantics are the material behavioral facts.
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 the purpose and then walks through the three transaction shapes efficiently; nearly every sentence carries an actionable constraint. It is a dense single paragraph that would scan better as short bullets, and the environment-specific login line is verbose, but nothing 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 16-parameter destructive mutation with no output schema, the description covers the gaps that matter: authentication/session recovery, concurrency safety, dry-run preview, confirmation policy, line-removal semantics, and the journal-entry balancing invariant. An agent could call this correctly without further research.
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 81% schema coverage the schema already documents most fields, but the description adds cross-parameter meaning the schema cannot: which parameter bundle applies to single-category vs split vs journal-entry transactions, that line amounts include sales tax and must sum to the total, and that omitting `order` adds a line. A few parameters (businessId, verified, expectedSequence) get no elaboration beyond the schema, so it falls short of a 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?
Opens with a specific verb+resource ('Edit a transaction as in the Wave web app') and enumerates exactly what is editable (date, description, notes, reviewed, account, amount, category, vendor/customer, split lines). It is trivially distinguishable from wave_create_transaction and wave_delete_transaction 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?
Gives explicit mode routing: single-category transactions use categoryId/vendorId/customerId/amount/salesTax, split transactions pass `lines`, and journal entries have no bank side and must keep debits equal to credits. It also names alternatives and preconditions (use wave_get_transaction for line order, dryRun to preview, confirm with the user before changing amounts or accounts).
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.
72 tool updates
v1.0.0- First observed
wave_approve_estimate - First observed
wave_approve_invoice - First observed
wave_archive_account - First observed
wave_archive_product - First observed
wave_archive_sales_tax - First observed
wave_clone_estimate - First observed
wave_clone_invoice - First observed
wave_convert_estimate_to_invoice - First observed
wave_create_account - First observed
wave_create_customer - First observed
wave_create_estimate - First observed
wave_create_invoice - First observed
wave_create_product - First observed
wave_create_sales_tax - First observed
wave_create_transaction - First observed
wave_create_transactions - First observed
wave_delete_customer - First observed
wave_delete_estimate - First observed
wave_delete_estimate_payment - First observed
wave_delete_invoice - First observed
wave_delete_invoice_payment - First observed
wave_delete_transaction - First observed
wave_generate_estimate_pdf - First observed
wave_get_account - First observed
wave_get_business - First observed
wave_get_context - First observed
wave_get_customer - First observed
wave_get_estimate - First observed
wave_get_estimate_payment - First observed
wave_get_invoice - First observed
wave_get_invoice_payment - First observed
wave_get_ledger_transaction - First observed
wave_get_product - First observed
wave_get_reference - First observed
wave_get_sales_tax - First observed
wave_get_transaction - First observed
wave_get_vendor - First observed
wave_graphql_query - First observed
wave_import_ledger - First observed
wave_list_accounts - First observed
wave_list_businesses - First observed
wave_list_customers - First observed
wave_list_estimates - First observed
wave_list_invoices - First observed
wave_list_ledger_accounts - First observed
wave_list_ledger_transactions - First observed
wave_list_payments - First observed
wave_list_products - First observed
wave_list_sales_taxes - First observed
wave_list_transactions - First observed
wave_list_vendors - First observed
wave_mark_estimate_accepted - First observed
wave_mark_estimate_sent - First observed
wave_mark_invoice_sent - First observed
wave_record_estimate_deposit - First observed
wave_record_invoice_payment - First observed
wave_reset_estimate_acceptance - First observed
wave_run_report - First observed
wave_send_estimate - First observed
wave_send_estimate_acceptance_email - First observed
wave_send_estimate_deposit_receipt - First observed
wave_send_invoice - First observed
wave_send_invoice_payment_receipt - First observed
wave_update_account - First observed
wave_update_customer - First observed
wave_update_estimate - First observed
wave_update_estimate_deposit - First observed
wave_update_invoice - First observed
wave_update_invoice_payment - First observed
wave_update_product - First observed
wave_update_sales_tax - First observed
wave_update_transaction
TDQS
Scored across 72 tools
Resources are generally separable (customer/product/account/tax/invoice/estimate), but the set contains many near-parallel or easily confused pairs: wave_list_transactions vs wave_list_ledger_transactions, wave_get_transaction vs wave_get_ledger_transaction, wave_create_transaction vs wave_create_transactions, wave_send_invoice vs wave_mark_invoice_sent, and wave_list_payments vs the transaction listers. The long descriptions do resolve most conflicts (live web-app data vs imported Data Export snapshot), but an agent must read carefully to avoid picking the wrong twin, and wave_graphql_query overlaps with most read tools.
Names follow a steady wave_verb_noun pattern with a shared verb vocabulary (list/get/create/update/delete/archive/approve/send/mark), and the invoice/estimate/transaction families mirror each other predictably. Minor deviations exist: wave_create_transactions (plural batch) next to wave_create_transaction, 'record' vs 'create' for payments/deposits, and one-off verbs like run_report, import_ledger, graphql_query.
72 tools is far beyond a comfortable surface for an agent, even for a broad accounting domain. Much of the bulk comes from duplicated CRUD families (live transaction API, imported-ledger reader, and parallel invoice/estimate payment lifecycles), which inflates the count without adding distinct capability.
Coverage is unusually thorough: customers, products, accounts, sales taxes, invoices, estimates, invoice payments, estimate deposits, transactions, ledger import, and a large report suite, each with read/create/update/delete-or-archive paths. Remaining gaps (vendor writes, bills, un-archive, payroll reports) are explicitly documented as Wave API limitations rather than omissions, and escape hatches (wave_graphql_query, ledger import) cover the rest.
Maintenance
Related MCP Connectors
Connect QuickBooks Online to AI agents with secure read or write access across multiple companies.
Connect Claude or Cursor to books, invoices, bills, payroll, and sealed closes.
Read-only access to a Median customer's ledger, financial reports and transactions. OAuth sign-in.
Query your books, company data, business health, and ship invoices from your AI assistant.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceFinancial data infrastructure for AI agents. Connect to a startup's books to read live P&L and bank balances, review and reclassify transactions, manage the chart of accounts, and connect banking sources.-
- AlicenseAqualityFmaintenanceProvides complete MCP access to Wave Accounting, enabling AI assistants to manage invoices, payments, customers, and bookkeeping via natural language.30106 npmMIT
- AlicenseAqualityCmaintenanceEnables agents to operate QuickBooks Online for a bookkeeping tenant, including company profile, employee listing, salary updates, and dry-run payroll previews without submitting actual pay.6MIT
- AlicenseBqualityAmaintenanceEnables AI assistants to query and manage self-hosted accounting data—invoices, balances, and books—through natural language, with read-only tools by default and optional scoped write operations.3025 PyPI1AGPL 3.0