MCP Server for Wave
Complete access to Wave Accounting from AI assistants: read everything, and optionally create, update, delete, and email records with write tools enabled. The server exposes 74 tools (30 read-only, 44 write) covering the full Wave API. Write operations require setting WAVE_ALLOW_WRITES=1.
Business & Settings: List businesses, set default, view branding (logo/accent color).
Reference Data: List countries, currencies, provinces; view account types/subtypes.
Chart of Accounts: View accounts with balances; [Write] create, rename, archive.
Customers: List, view details/balances; [Write] create, update, delete.
Vendors: List and view details (read-only in Wave's API).
Products & Services: List, view details; [Write] create, update, archive.
Sales Taxes: List taxes with rate history; [Write] create, update, archive.
Invoices: List/filter; [Write] create, clone, approve, send, mark sent, delete, record/update/delete payments, send receipts.
Estimates: List/filter; [Write] create, clone, approve, send, mark sent/accepted, reset acceptance, send acceptance emails, generate PDF, convert to invoice, delete; record/update/delete deposit payments, send deposit receipts.
Bookkeeping: [Write] Create single or bulk money transactions (expenses, income, transfers), deposit transactions (e.g., processor payouts), expense from receipt (category matching), income from payment.
Grounding Resources: Read-only JSON views of businesses, accounts, customers, vendors, products, sales taxes, account taxonomy.
Auth & Safety: Check auth status; all writes guarded by WAVE_ALLOW_WRITES=1; smart error messages for unbalanced transactions and unknown categories.
Click on "Install 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., "@MCP Server for WaveCreate an invoice for Acme Corp with 10 hours of consul"
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 gives small businesses free accounting and invoicing, and a GraphQL API that covers nearly all of it. This server puts that entire API in front of an AI assistant: invoices and payments, estimates and deposits, customers, vendors, products, sales taxes, the chart of accounts, and double-entry bookkeeping.
Every query is verified against Wave's live schema in CI, and the tools that change or send anything stay hidden until you turn them on.
Why This Exists
Bookkeeping is mostly translation. You have a receipt, a bank line, an email promising to pay next week, and none of it is in the shape your books want. The work is not hard, it is just constant, and it is exactly the kind of task worth handing to an assistant that can hold the whole picture at once.
Doing that well needs more than a few convenience endpoints. An assistant that can list invoices but not record the payment, or draft an estimate but not convert it, forces you back into the web app halfway through every task. So this server covers the API completely: all 42 mutations, all 11 root queries, every sub-resource on a business. If Wave's API can do it, a tool here does it.
Two decisions shape the rest:
Writes are off by default. Wave has genuinely irreversible operations.
Sending an invoice emails a real customer. Deleting one is permanent. A default
install exposes 30 read-only tools; the other 44 appear only when you set
WAVE_ALLOW_WRITES=1. Reading your books should not require trusting a model
with your outbox.
Errors explain themselves. Wave rejects an unbalanced transaction without telling you which figure is wrong. This server compares the anchor against the line items first and reports the difference. A category word that matches no account produces the list of real account names rather than a silent guess at the first one.
Related MCP server: Wave MCP Server
Quick Start
{
"mcpServers": {
"wave-mcp-server": {
"command": "npx",
"args": ["-y", "@oliverames/mcp-server-for-wave@latest"],
"env": {
"WAVE_ACCESS_TOKEN": "your_token_here"
}
}
}
}Then ask for your businesses and set one as the default:
List my Wave businesses and set the first one as the default.Get a token
Create an application and generate an access token in the Wave developer portal. Wave's tokens expire, so expect to refresh it periodically, or use the hosted connector which handles refresh for you.
Install as a plugin
The repo doubles as a single-plugin marketplace for hosts that support them:
/plugin marketplace add oliverames/wave-mcp-server
/plugin install wave-mcp-serverInstall in Codex
codex mcp add wave-mcp-server \
--env WAVE_ACCESS_TOKEN=your_token_here \
-- npx -y @oliverames/mcp-server-for-wave@latestVerify with codex mcp list. Startup takes about 0.2s, well inside Codex's
10-second startup_timeout_sec, and the retry budget is capped below its
60-second tool_timeout_sec so a slow API surfaces Wave's real error rather
than a client timeout.
Enable write tools
"env": {
"WAVE_ACCESS_TOKEN": "your_token_here",
"WAVE_ALLOW_WRITES": "1"
}This registers the 44 tools that create, change, delete, or email records. Without it they are not advertised at all, so a model cannot call one by guessing its name.
Docker
docker build -t wave-mcp-server .
docker run --rm -i -e WAVE_ACCESS_TOKEN=your_token_here wave-mcp-serverThe -i matters: the server speaks JSON-RPC on stdin and stdout.
1Password token lookup
Rather than pasting a token into a config file, point the server at a secret
reference and it will shell out to the op CLI on startup:
"env": { "WAVE_OP_PATH": "op://Development/Wave/credential" }WAVE_ACCESS_TOKEN_FILE works the same way for a file on disk.
What You Can Do
Bill a customer end to end
Create an invoice for Acme Corp with 10 hours of consulting at $150/hour,
due in 30 days. Approve it and email it to billing@acme.com.Quote, then convert
Create an estimate for the website redesign package with a 25% deposit,
send it, and convert it to an invoice once they accept.Record a receipt
Log a $45.99 expense from Office Depot on 2026-03-15 for office supplies,
paid from Business Checking.Split a transaction
Record a $100 withdrawal from checking: $60 to fuel and $40 to meals.Reconcile a processor payout
A Stripe payout of $97 landed in checking: $100 of consulting income
less a $3 processing fee.Chase what is owed
Show me every unpaid invoice over $500, sorted by amount due, and which
customers carry the largest overdue balances.Tools Reference
Names are prefixed wave_ so they do not collide with other MCP servers.
Tools marked W require WAVE_ALLOW_WRITES=1.
Businesses and reference data
Tool | Purpose |
| List reachable businesses |
| Full business detail |
| Set the session default |
| Accent color and logo |
| How credentials resolved, and what is gated. Makes no API call |
| Account the token belongs to |
| Application that issued the token |
| Supported currencies |
| Countries and their provinces |
| One province or state |
| The five top-level account types |
| Subtypes, which |
Chart of accounts
Tool | Purpose |
| Accounts with balances |
| Add an account |
| Rename or renumber |
| Hide from pickers, keep history |
Customers, vendors, products, taxes
Tool | Purpose |
| Customers with balances |
| Manage customers |
| Vendors (read-only in Wave's API) |
| Products and services |
| Manage products |
| Taxes and rate history |
| Manage taxes |
Invoices and payments
Tool | Purpose |
| Invoices with items and payments |
| Build invoices |
| Move a draft into the books |
| Emails the customer |
| Record delivery made outside Wave |
| Permanent |
| One payment |
| Record payments |
| Emails the customer |
Estimates and deposits
Tool | Purpose |
| Estimates with history and deposits |
| Build estimates |
| Approve a draft |
| Emails the customer |
| Record offline delivery and acceptance |
| Undo an acceptance |
| Emails the customer |
| Render a PDF |
| Turn an accepted estimate into an invoice |
| Permanent |
| One deposit payment |
| Record deposits |
| Emails the customer |
Bookkeeping
Tool | Purpose |
| One expense, income, or transfer |
| Bulk import, applied atomically |
| A payout whose net differs from gross |
| Expense, account matched from a category word |
| Income, account matched from a category word |
Resources
Read-only JSON views for grounding context. Everything here is also reachable through a tool, so hosts that ignore resources lose nothing.
wave://businesses • wave://accounts • wave://customers •
wave://vendors • wave://products • wave://sales-taxes •
wave://account-taxonomy • wave://health
How Transactions Work
Wave is double-entry, so wave_create_money_transaction has two sides:
The anchor is the account money physically moved through, a bank account or credit card, with a direction of
DEPOSITorWITHDRAWAL.The line items are the categories it is attributed to. Their amounts must total the anchor amount.
A $50 office-supplies expense paid from checking is one anchor (checking,
WITHDRAWAL, 50.00) and one line item (Office Supplies, 50.00). A split is
the same anchor with more line items.
Every transaction carries an external_id. Wave deduplicates on it, so passing
a stable value of your own makes retries safe; one is generated when you omit
it.
Environment Variables
Variable | Required | Default | Description |
| Yes | (none) | OAuth2 bearer token from the Wave developer portal |
| No | (none) | Default business, so tools can omit |
| No | off | Set to |
| No | (none) | Read the token from a file instead |
| No | (none) | Read the token from 1Password, e.g. |
| No |
| Per-request timeout |
| No |
| Total time for one call including retries |
| No |
| Reject responses above this size |
| No |
| Retries on 429 and 5xx |
| No | off | Read only the environment, not agent config files |
| No |
|
|
| No | off | Send a W3C |
Credentials resolve in order: environment, then the host agent's own config
file, then WAVE_ACCESS_TOKEN_FILE, then 1Password. Reading the agent config
matters because MCP clients launch this server as a subprocess, so a value in
claude_desktop_config.json or ~/.codex/config.toml reaches it only if the
user wired it through by hand.
Amount Handling
Money is sent to Wave as strings, not floats, so 0.1 + 0.2 cannot become
0.30000000000000004 on the way to your ledger. Balance checks compare minor
units as integers for the same reason.
One exception, and it is Wave's: moneyDepositTransactionCreate types its
amounts as Float rather than Decimal, so wave_create_deposit_transaction
sends numbers there because the API accepts nothing else.
Wave API Limitations
These are constraints in Wave's API, not gaps here. Each was confirmed against the live schema.
Transactions cannot be read back. Wave creates money transactions but exposes no query to list them; there is no
transactionsconnection onBusiness. Review them in the web app.Vendors are read-only. The schema has no
vendorCreate,vendorPatch, orvendorDelete.Money transactions cannot reference a vendor.
wave_create_expense_from_receiptrecords the name in the description.wave_patch_estimatedemands fields you are not changing. Wave marks seven of them required on the patch input; read the estimate first and pass its current values back.wave_patch_accountneeds the account's currentsequenceas an optimistic-concurrency check.Line items must reference a product. No free-text lines.
wave_create_deposit_transactionreturns no ID.Bills, receipts, payroll, and reports have no API.
No file attachments. Receipt images cannot be uploaded.
Rate limits are tight, roughly two concurrent requests.
Un-archiving is web-app only.
Hosted Connector
A Cloudflare Worker serves the same tools over OAuth instead of a shared token.
The hosted connector publishes the Wave connector artwork as an SVG favicon, a conventional ICO, Apple touch, and explicit 8-bit PNG favicons from 16 through 256 pixels. The page head advertises the SVG first with the ICO as its alternate, because icon resolvers take the first usable declaration; the remaining sizes stay served for other consumers. The ICO carries a single 32px frame, since a six-frame uncompressed ICO reached 370 KB and resolvers skipped it rather than decode it. MCP initialization also advertises the versioned 256px URL for clients that support server icon metadata. Users authorize against their own Wave account, tokens are encrypted before storage, and write access is chosen at authorization time so a read-only connection cannot be escalated later.
The deployment at https://wave.amesvt.com/mcp is private: an owner
allowlist restricts it to one Wave account, and any other account is refused
before a token is stored. Deploy your own copy from worker/ to use it.
See worker/README.md for setup and the security model.
Architecture
index.js Single-file server: client, 74 tools, 8 resources
createWaveServer() Factory over injected credentials, shared by
the stdio process and the hosted Worker
scripts/
smoke-validate-graphql.mjs Schema-check every query against live Wave
smoke-list-tools.mjs Start over stdio and enumerate what is advertised
smoke-packed-install.mjs Pack, install, and launch the way npx does
sync-plugin-metadata.mjs Propagate the version to every host manifest
check-release-consistency Fail the build when anything disagrees
build-mcpb.mjs Desktop bundle
worker/ Hosted OAuth connector
test/unit.test.mjs 58 tests, no networkThe tool layer lives in one file on purpose. It is imported unchanged by the Worker, so the hosted and local servers cannot drift apart.
Verification without credentials
Wave validates a GraphQL document and coerces its variables before it checks
authentication. An UNAUTHENTICATED response therefore means the query is
correct, while GRAPHQL_VALIDATION_FAILED means it is not.
CI exploits that to schema-check all 64 documents on every push with no token at all, which catches a field Wave renames before a user does.
Building
npm install
npm test # 58 unit tests, no network
npm run smoke:list-tools # start over stdio, enumerate tools
npm run smoke:packed # pack, install, and launch via the bin symlink
npm run smoke:schema # validate every query against live Wave
npm run release:check # version parity across 8 manifests
npm run build:mcpb # desktop bundleContributions welcome. See CONTRIBUTING.md.
Not Affiliated With Wave
An independent project, not affiliated with, endorsed by, or sponsored by Wave Financial Inc. Wave Financial Inc. owns the Wave name, logo, and marks; the icon above is theirs and is used only to identify the service this server connects to. Originally forked from vinnividivicci/wave_mcp, then rewritten.
Available Tools
30 toolswave_auth_statusWave: Auth StatusARead-onlyIdempotent
Report how this server resolved its Wave credentials and whether write tools are enabled. Makes no Wave API request, so it works even when the token is missing or expired -- use it first when other tools report authentication problems.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| next_step | No | |
| token_source | Yes | |
| lookup_errors | Yes | |
| detected_agent | Yes | |
| writes_enabled | Yes | |
| has_credentials | Yes | |
| sources_checked | Yes | |
| registered_tools | Yes | |
| write_tools_hidden | Yes | |
| default_business_id | Yes | |
| config_fallback_disabled | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, openWorldHint, idempotentHint, and non-destructive behavior. The description adds valuable behavioral context beyond those annotations: it makes no Wave API request and functions even with a missing or expired token. This tells an agent the tool's failure modes and network behavior, which annotations alone do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, each earning its place: the first defines what the tool reports, and the second explains its network-free behavior and primary use case. It is front-loaded with the core purpose and contains no filler, repetition, or schema duplication.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter diagnostic tool with a rich output schema, the description covers everything an agent needs: what it reports, that it does not make an API request, that it tolerates auth failures, and when to use it. The presence of an output schema means return-value details need not be restated in the description.
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?
This tool has zero parameters and the schema coverage is complete, so there are no parameter semantics for the description to clarify. The 0-parameter baseline of 4 applies because there is no information gap to fill; the description correctly avoids inventing parameter guidance where none exists.
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+resource pair: 'Report how this server resolved its Wave credentials and whether write tools are enabled.' This clearly distinguishes the tool from all data-access siblings like wave_list_invoices or wave_get_account by framing it as a diagnostic status tool. The phrase 'Makes no Wave API request' further differentiates it from every sibling that performs API calls.
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 provides an explicit usage directive: 'use it first when other tools report authentication problems.' It also explains why this tool is the right first choice by noting it works even when the token is missing or expired. This is direct, actionable guidance for when to invoke the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_accountWave: Get AccountARead-onlyIdempotent
Get one account by ID, including its current balance.
| Name | Required | Description | Default |
|---|---|---|---|
| account_id | Yes | The Wave account ID. | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and no destruction. The description adds that it returns the current balance, providing minor extra context beyond 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?
Single sentence containing all essential information, no unnecessary words, front-loaded with verb and resource.
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 read-only tool with full schema coverage and clear annotations, the description is complete: it states what it does and that it includes balance.
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 all 3 parameters. The description adds no additional parameter 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 clearly states the action (Get), resource (account), and key detail (includes current balance). It distinguishes from sibling wave_list_accounts.
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 explicit guidance on when to use this tool versus alternatives like wave_list_accounts. No when-not-to-use or prerequisite information.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_businessWave: Get BusinessARead-onlyIdempotent
Get full detail for one business: currency, address, type, and settings.
| Name | Required | Description | Default |
|---|---|---|---|
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the description reinforces that this is a safe read operation. It adds value by listing the specific fields returned (currency, address, type, settings), which is helpful beyond the annotations. No contradictions.
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 sentence that is front-loaded with the main purpose. It is concise and contains no unnecessary words. Every part 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?
Given no output schema, the description adequately lists the fields returned (currency, address, type, settings), providing sufficient context for an agent to understand what to expect. The tool has 0 required parameters and is a simple read operation, making the description complete for its complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (both parameters have descriptions). The description adds no new parameter information; it only mentions returned fields. With high schema coverage, the baseline is 3, and the description does not significantly enhance parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('get full detail') and the resource ('one business'), listing specific fields (currency, address, type, settings). This distinguishes it from sibling tools like wave_list_businesses (list all) and wave_set_default_business (set default).
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 usage when needing details of a specific business, but it does not explicitly state when to use this tool versus alternatives (e.g., wave_list_businesses for listing all businesses) or provide exclusion criteria. With many sibling tools, more explicit guidance would be beneficial.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_countryWave: Get CountryARead-onlyIdempotent
Get one country and its provinces or states. Use this to find the province codes that address fields expect.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | ISO 3166-1 alpha-2 code such as "US", "CA", or "GB". | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare read-only, idempotent, non-destructive. Description adds context about returning provinces and province codes, which complements annotations without contradicting.
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 with zero waste. Primary purpose and key use case stated upfront. Efficient and clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given low complexity (2 params, no output schema), description fully covers what the tool does and why to use it. Return format not mentioned but not critical for this tool type.
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 both parameters. Description does not add additional semantic value beyond schema, so baseline score 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?
Description clearly states verb 'Get', resource 'one country and its provinces or states', and specific use case 'find the province codes that address fields expect'. Distinguishes from sibling tools like wave_list_countries and wave_get_province.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (to find province codes for addresses), implying usage context. Lacks explicit exclusions or alternatives, but sufficiently guides selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_currencyWave: Get CurrencyARead-onlyIdempotent
Get one currency by ISO 4217 code.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Currency code such as "USD", "CAD", or "EUR". | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, etc. Description adds no additional behavioral context beyond what 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?
Single sentence that is front-loaded and to the point. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple parameter set and comprehensive annotations, the description sufficiently covers the tool's purpose and use case.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The tool description adds no extra 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?
Clearly states verb 'Get', resource 'one currency', and method 'by ISO 4217 code'. Distinguishes from sibling 'wave_list_currencies' which would list multiple.
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 explicit when/when-not or alternative usage guidance. However, the purpose is self-explanatory for a simple get-by-code operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_customerWave: Get CustomerARead-onlyIdempotent
Get one customer by ID, including address and shipping details.
| Name | Required | Description | Default |
|---|---|---|---|
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| customer_id | Yes | The Wave customer ID. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so agent knows it's safe. Description adds that the response includes address and shipping details, which is useful context. However, no behavioral traits like error handling or permissions are mentioned.
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?
Single sentence that is front-loaded with the key action and resource, no extraneous words.
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?
No output schema, but description mentions included details (address, shipping). For a simple get tool with complete schema and annotations, it is fairly complete. Minor gap: does not mention the response_format parameter or business_id default 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 coverage is 100% with descriptions for all three parameters. Description adds no additional parameter meaning beyond the schema, so 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?
Description clearly states 'Get one customer by ID, including address and shipping details.' Verb 'Get' and resource 'customer' are specific. Distinguishes from siblings like wave_list_customers and wave_get_vendor.
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?
Description implies when to use (when needing a single customer by ID) but lacks explicit guidance on when not to use or comparison to alternatives like wave_list_customers. No exclusions or context provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_estimateWave: Get EstimateARead-onlyIdempotent
Get one estimate in full: line items, deposits, and acceptance history.
| Name | Required | Description | Default |
|---|---|---|---|
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| estimate_id | Yes | The Wave estimate ID. | |
| include_history | No | Include the acceptance and rejection audit trail. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
| include_attachments | No | Include attached files. | |
| include_deposit_payments | No | Include deposit payments recorded against it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the agent knows it's a safe read operation. The description adds concrete details on what is returned (line items, deposits, acceptance history), which provides useful behavioral context beyond the annotations. No contradictions.
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 sentence that is front-loaded with the purpose and scope. Every word is necessary and no extraneous information 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?
Given the tool has 6 parameters (most with defaults), no output schema, and clear annotations, the description adequately explains the tool's function. It covers the key elements returned. The missing return format details are covered by the schema's response_format parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 6 parameters. The description mentions 'line items, deposits, and acceptance history,' which aligns with parameters like include_history, include_attachments, include_deposit_payments, but does not add new meaning beyond the schema. Baseline score 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 explicitly states the action ('Get'), the resource ('one estimate'), and the scope ('in full: line items, deposits, and acceptance history'). It clearly distinguishes from siblings like wave_list_estimates (list) and wave_get_estimate_payment (payment-specific).
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 usage for retrieving full details of a single estimate, but does not explicitly provide when to use this tool versus alternatives (e.g., wave_list_estimates for listing, wave_get_estimate_payment for payment info). No when-not-to-use or selection criteria are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_estimate_paymentWave: Get Estimate PaymentARead-onlyIdempotent
Get one estimate deposit payment by ID. To see every deposit on an estimate, call wave_get_estimate with include_deposit_payments=true.
| Name | Required | Description | Default |
|---|---|---|---|
| payment_id | Yes | The Wave estimate payment ID. | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
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. The description adds the context that this tool retrieves a single payment and provides a relationship to the listing tool, but does not disclose additional behavioral details like required permissions or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long, with the first sentence clearly stating the action and the second providing a relevant usage pointer. No unnecessary words or redundancy.
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 read-only tool with annotations covering safety and idempotency, the description is sufficient. It explains the core function and provides a sibling reference. However, it does not mention the return format or any side effects, which would be useful but are partially covered by the response_format parameter description.
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 each parameter, so baseline is 3. The description does not add extra meaning beyond the schema; it only mentions getting a payment by ID, which is already captured by the payment_id 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 uses a specific verb ('Get') and resource ('estimate deposit payment') and immediately distinguishes from the sibling tool wave_get_estimate by stating that this tool gets a single payment by ID, while wave_get_estimate with a parameter gets all deposits.
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 explicitly provides an alternative for seeing all deposits on an estimate, guiding the agent to use wave_get_estimate with include_deposit_payments=true. It does not include explicit when-not scenarios, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_invoiceWave: Get InvoiceARead-onlyIdempotent
Get one invoice in full: line items, taxes, discounts, and payments.
| Name | Required | Description | Default |
|---|---|---|---|
| invoice_id | Yes | The Wave invoice ID. | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is clear. The description adds value by specifying the return contents (line items, taxes, discounts, payments), Beyond annotations, it does not disclose rate limits or authorization needs, but those are common for read tools.
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, well-formed sentence that is front-loaded with the main action and resources. Every word is meaningful, and there is no wasted text.
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?
The description covers the tool's purpose and return content adequately. With no output schema, the description clarifies what the returned invoice includes. It does not mention error handling or edge cases, but for a simple getter with rich annotations, it is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema provides parameter names and types. The description adds context: for `response_format`, it clarifies 'compact human-readable summary' vs 'complete record'; for `business_id`, it explains defaulting behavior. This goes beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get one invoice in full: line items, taxes, discounts, and payments.' It specifies the verb 'Get', the resource 'invoice', and the scope 'in full' with included details. This distinguishes it from sibling tools like wave_list_invoices which likely return a list without full details.
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 does not explicitly provide when to use this tool vs alternatives. It implies use when full invoice details are needed, but there is no mention of when not to use or alternative tools. The context is clear but lacks exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_invoice_estimate_settingsWave: Get Invoice Estimate SettingsARead-onlyIdempotent
Get the branding applied to invoices and estimates: accent color and logo.
| Name | Required | Description | Default |
|---|---|---|---|
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds no additional behavioral context beyond stating that it retrieves branding settings. It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence of 14 words, front-loaded with the verb 'Get.' Every word is purposeful, with no unnecessary detail.
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 read-only tool with two optional parameters and no output schema, the description adequately explains the core purpose and mentions the key output fields (accent color and logo). It could be slightly more complete by noting the dependency on the session business, but that is covered in 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?
Schema description coverage is 100%, so the schema already documents both parameters. The description mentions 'accent color and logo,' which helps explain the output but does not add meaning to the input parameters 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 uses the specific verb 'Get' and clearly identifies the resource as 'branding applied to invoices and estimates: accent color and logo.' It distinguishes this tool from siblings like wave_get_invoice and wave_get_estimate, which deal with individual records, by focusing on global branding settings.
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 does not provide any guidance on when to use this tool versus alternatives, nor does it mention when not to use it or suggest any prerequisites. The single sentence offers no usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_invoice_paymentWave: Get Invoice PaymentARead-onlyIdempotent
Get one invoice payment by ID. To see every payment on an invoice, call wave_get_invoice instead: it returns them all.
| Name | Required | Description | Default |
|---|---|---|---|
| payment_id | Yes | The Wave invoice payment ID. | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds no further behavioral detail, which is adequate for a simple get 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?
Two compact sentences with the primary action front-loaded; every word 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?
Given full schema coverage, annotations, and the simple nature of a get-by-id tool, the description is 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 baseline is 3. The description does not add additional parameter 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 clearly states the verb 'Get', the resource 'one invoice payment by ID', and distinguishes from the sibling tool 'wave_get_invoice' which returns all payments.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use this tool vs the sibling: 'To see every payment on an invoice, call wave_get_invoice instead: it returns them all.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_oauth_applicationWave: Get Oauth ApplicationARead-onlyIdempotent
Get the OAuth application that issued the current access token.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds the nuance that it retrieves the application tied to the current access token, which is slightly beyond the annotations (which already declare readOnlyHint, idempotentHint, etc.). However, it does not disclose any additional behavioral traits like rate limits or response size.
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 directly states the tool's purpose. It is front-loaded and contains no unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema, the description could be improved by hinting at what fields are returned. However, for a simple retrieval tool with good annotations and parameter schema, the current description is nearly 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 100% (the single parameter 'response_format' is fully described in the schema). The tool description adds no further meaning beyond the schema, so a baseline score 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 clearly states the verb (Get), the resource (OAuth application), and the scope (issued the current access token). This distinguishes it from sibling tools, none of which mention OAuth applications.
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 (when you need information about the OAuth application associated with the current token) but does not explicitly state when not to use it or suggest alternatives. Sibling tools like wave_auth_status might offer related functionality, but no guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_productWave: Get ProductARead-onlyIdempotent
Get one product by ID, including its accounts and default sales taxes.
| Name | Required | Description | Default |
|---|---|---|---|
| product_id | Yes | The Wave product ID. | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false. The description adds value by disclosing that the response includes accounts and default sales taxes, which is beyond the schema. No contradictions.
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, clear sentence that immediately conveys the core purpose and key details. No superfluous words; highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description covers the essential behavior (get by ID, included associations). Schema and annotations fill remaining gaps. Missing explicit mention of optional business_id default is minor and covered by 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?
Schema description coverage is 100% for all three parameters; the description adds no additional information about parameter meaning or usage beyond what the schema provides. Baseline score 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 clearly states the tool retrieves one product by ID and specifies included data (accounts and default sales taxes). This distinguishes it from sibling tools like wave_list_products (which lists products) and aligns with the 'get' naming convention.
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 explicit guidance on when to use or when not to use. The purpose is implicit: use when you need a specific product by ID. However, it does not mention alternatives (e.g., wave_list_products for listing) or provide exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_provinceWave: Get ProvinceARead-onlyIdempotent
Get one province or state by its code.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Province code, typically country-qualified, e.g. "CA-ON" or "US-NY". | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and open-world hints. The description adds 'get one province or state by its code,' which aligns but does not provide additional behavioral context beyond what the annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that conveys the core functionality without excessive detail. Front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description is adequate. It covers the primary purpose and parameter semantics. However, it does not explain the output format or error behavior (e.g., what happens if the code is invalid), which could be helpful for completeness.
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 covers both parameters with descriptions, and the description adds a concrete example for the 'code' parameter ('CA-ON' or 'US-NY'), which clarifies the expected format 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 clearly states the action ('get') and the resource ('one province or state by its code'), using a specific verb. It distinguishes from sibling tools like wave_get_country or wave_list_provinces.
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 provides no guidance on when to use this tool versus alternatives (e.g., wave_list_countries for all countries, wave_get_country for country details). The agent must infer from the tool 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_sales_taxWave: Get Sales TaxARead-onlyIdempotent
Get one sales tax by ID, including its full rate history.
| Name | Required | Description | Default |
|---|---|---|---|
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| sales_tax_id | Yes | The Wave sales tax ID. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds that it returns the full rate history, providing additional behavioral context beyond 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 description is a single concise sentence that is front-loaded and contains no unnecessary words.
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 read-by-ID tool with readOnlyHint=true and idempotentHint=true, the description is complete: it covers what the tool does and what it includes (rate history). No output schema is needed given the description's clarity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add parameter-level meaning beyond what the schema already provides (e.g., business_id default, sales_tax_id as ID, response_format enum).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (Get one sales tax by ID) and the scope (including full rate history). It distinguishes from list siblings like wave_list_sales_taxes.
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 from the tool name and description (when you have a specific ID), but there is no explicit guidance on when to use this versus alternatives (e.g., list tools) or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_userWave: Get UserARead-onlyIdempotent
Get the Wave user account that owns the current access token. Useful for confirming which account a token authenticates as.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, openWorldHint, idempotentHint, destructiveHint. Description adds no further behavioral context beyond confirming it's a read operation. Adequate but not enhanced.
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 fluff, front-loaded with purpose. Every word 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 simple tool with 0 required params and no output schema, the description is fully adequate. Use case is clearly stated.
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% for the single parameter (response_format). Description does not add additional meaning beyond what the schema provides, so baseline of 3.
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?
Clearly states the verb 'Get' and resource 'Wave user account that owns the current access token'. Distinguishes from sibling tools like wave_auth_status by specifying it returns user account details.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'useful for confirming which account a token authenticates as', indicating when to use. Does not mention when not to use or alternatives, but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_get_vendorWave: Get VendorARead-onlyIdempotent
Get one vendor by ID, including address and shipping details.
| Name | Required | Description | Default |
|---|---|---|---|
| vendor_id | Yes | The Wave vendor ID. | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the tool's safety is clear. The description adds value by mentioning that address and shipping details are included in the response, but does not elaborate on other behavioral traits.
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, front-loaded sentence of 11 words with no wasted words. It efficiently conveys the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (3 parameters, no output schema), the description adequately covers the returned fields (address and shipping details). However, it does not mention the response_format parameter or the default Markdown output, which are minor 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 each parameter has a description. The tool description itself does not add any additional meaning beyond what the schema already provides, so baseline score 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 clearly states the verb ('Get'), the resource ('vendor'), and the scope ('by ID, including address and shipping details'). This distinguishes it from sibling tool wave_list_vendors which retrieves multiple vendors.
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 usage when a single vendor is needed, but does not explicitly state when to use this tool versus alternatives (e.g., wave_list_vendors). No exclusions or context are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_accountsWave: List AccountsARead-onlyIdempotent
List the chart of accounts, with balances. Filter by type to find the account a transaction needs: EXPENSE for expense categories, INCOME for revenue, ASSET with subtype CASH_AND_BANK for bank accounts, LIABILITY with subtype CREDIT_CARD for cards.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number for offset pagination. | |
| types | No | Filter by type: ASSET, LIABILITY, EQUITY, INCOME, EXPENSE. | |
| subtypes | No | Filter by subtype, e.g. ["CASH_AND_BANK", "CREDIT_CARD"]. | |
| fetch_all | No | Walk every page instead of returning just one. Slower, but complete. | |
| page_size | No | Records per page (1-200). | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| is_archived | No | Filter to archived (true) or active (false) accounts. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
| excluded_subtypes | No | Subtypes to omit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate read-only, idempotent, non-destructive behavior, which is consistent. The description adds transparency by mentioning balances in output, pagination parameters, and default business behavior. No contradictions.
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 extremely concise—two sentences front-loading the core function and then providing filtering examples. No unnecessary words.
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?
Despite 9 parameters and no output schema, the description covers the main return content (list with balances) and key behaviors (pagination, filtering). It is sufficient for an agent to understand and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for all 9 parameters. The description adds practical guidance by showing how to filter for specific account categories, going beyond the schema. This extra value justifies a score above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists the chart of accounts with balances. It distinguishes from siblings like wave_get_account by focusing on listing and filtering, and provides specific type examples, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on when to use this tool—to find accounts for transactions based on type/subtype. It includes concrete examples but does not explicitly state when not to use it or mention alternatives, though siblings imply them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_account_subtypesWave: List Account SubtypesARead-onlyIdempotent
List account subtypes -- the value wave_create_account needs. Every account belongs to a subtype (CASH_AND_BANK, EXPENSE, INCOME, ...), which in turn determines its type. Some subtypes are system-created and cannot be used for new accounts.
| Name | Required | Description | Default |
|---|---|---|---|
| account_type | No | Filter to one type: ASSET, LIABILITY, EQUITY, INCOME, EXPENSE. | |
| creatable_only | No | Exclude system-created subtypes unavailable to new accounts. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds useful behavioral context: subtypes determine type and some are system-created, which explains why filtering may be needed. No contradictions.
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 extremely concise with two sentences. The first sentence front-loads the core purpose, and the second adds critical context about hierarchy and system-created subtypes. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (3 optional params, no output schema, rich annotations), the description is sufficiently complete. It explains the purpose and a key constraint (system-created subtypes). Lacks explicit mention of output fields, but the response_format parameter covers output presentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by explaining that the subtype values are needed for wave_create_account and that creatable_only filters system-created ones, providing rationale beyond the schema's parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists account subtypes and explicitly connects them to wave_create_account, establishing a specific verb-resource relationship. It distinguishes from siblings like wave_list_account_types by defining subtypes as the detailed classification that determines the type.
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 indicates usage context (needed for create_account) and notes that some subtypes are system-created, implying when to use creatable_only filter. However, it does not explicitly contrast with alternatives like wave_list_account_types or state 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_list_account_typesWave: List Account TypesARead-onlyIdempotent
List the five top-level account types in Wave's chart of accounts: ASSET, LIABILITY, EQUITY, INCOME, and EXPENSE, each with its normal balance.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint, idempotentHint, and no destructiveness. The description adds value by specifying that the output includes the normal balance for each account type, which is beyond what 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?
Description is a single concise sentence that front-loads the key information. No extraneous words or repetition.
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 list tool with strong annotations and no output schema, the description provides all necessary context: what it lists, the exact set of items, and that each has its normal balance. No critical 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%, so baseline is 3. The description does not add any information about the response_format parameter, but the schema already fully documents it with enum and 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 explicitly states it lists the five top-level account types (ASSET, LIABILITY, EQUITY, INCOME, EXPENSE) with their normal balance. This clearly identifies the resource and scope, distinguishing it from sibling tool wave_list_account_subtypes.
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 explicit guidance on when to use this tool versus alternatives. The description implies its use for top-level types, but does not contrast with siblings like wave_list_account_subtypes or wave_list_accounts. Usage context is implied but not elaborated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_businessesWave: List BusinessesARead-onlyIdempotent
List the Wave businesses this access token can reach. Start here: every other tool needs a business ID. Pass one to wave_set_default_business so later calls can omit it.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number for offset pagination. | |
| fetch_all | No | Walk every page instead of returning just one. Slower, but complete. | |
| page_size | No | Records per page (1-200). | |
| is_archived | No | Filter to archived (true) or active (false) businesses. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, destructiveHint. The description adds no behavioral details beyond what annotations provide, but it does not contradict them. It could mention that results may span pages (implied by pagination params) or that the token restricts visibility, but it is adequate.
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 concise sentences that front-load the core purpose and critical usage guidance. No unnecessary words, every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Description lacks mention of output format (markdown vs. json) and pagination behavior, which are documented in the schema but not in the description. Given the tool's role as entry point and the presence of rich annotations, the description is adequate but could be more complete by summarizing key parameters and return options.
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 all 5 parameters. The description adds no additional parameter information beyond the schema. Baseline score of 3 is appropriate given that the schema already provides sufficient 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?
Explicitly states the action (list businesses) and resource (Wave businesses accessible by token). Clearly distinguishes it as the entry point for obtaining business IDs needed by all other tools, which separates it from 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?
Explicitly says 'Start here' and explains that every other tool needs a business ID, with a specific instruction to pass one to wave_set_default_business. This gives clear when-to-use and when-to-use-next guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_countriesWave: List CountriesARead-onlyIdempotent
List the countries Wave supports, with each one's default currency.
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | Case-insensitive filter on country code or name. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, so the description adds no additional behavioral context (e.g., pagination, data freshness). It merely restates the function.
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, clear sentence with no unnecessary information. The purpose is front-loaded and directly stated.
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 list operation with comprehensive annotations and schema, the description is sufficient. It could mention if results are limited or paginated, but the openWorldHint implies completeness.
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 tool description does not add meaning beyond the schema's parameter descriptions. The description is adequate but does not compensate for any gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists supported countries and their default currency, which is specific and distinct from sibling tools like wave_get_country (single country) and wave_list_currencies (currencies only).
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 explicit guidance on when to use this tool versus alternatives. While the purpose is clear, there is no mention of exclusions or context, leaving the agent to infer usage 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_list_currenciesWave: List CurrenciesARead-onlyIdempotent
List the currency codes Wave supports. Wave supports about 160 currencies, so pass search to narrow the list.
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | Case-insensitive filter on code or name, e.g. "CAD" or "dollar". | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds minimal behavioral context (data size ~160 currencies, search narrowing), but does not disclose pagination, rate limits, or response structure, which are expected for a list 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?
The description is extremely concise—two sentences with no filler. The first sentence immediately states the core purpose, and the second provides actionable context about data volume and search usage. Every sentence is essential.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of a list-all task and strong annotation coverage, the description sufficiently sets expectations. It hints at returned data (code/name via search filter) but omits explicit return structure for the two output formats, which is a minor gap for a tool without an output 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?
Schema coverage is 100%, so parameters are already well-defined. The description reinforces the search parameter's purpose ('narrow the list') but does not add new meaning beyond what the schema provides. Baseline score 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 clearly states the tool lists supported currency codes. The verb 'list' and resource 'currency codes' are unambiguous. It differentiates from sibling tools like wave_get_currency (which retrieves a single currency) by focusing on enumeration.
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 contextually advises using the search parameter to narrow results, implying efficient usage for large datasets. However, it does not explicitly compare to alternatives like wave_get_currency for single-currency lookups, missing a clear when-not-to-use guide.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_customersWave: List CustomersARead-onlyIdempotent
List customers, with each one's outstanding and overdue balance. Wave can filter by exact email only; name_contains is applied by this server after fetching, so combine it with fetch_all=true when searching a large customer list.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number for offset pagination. | |
| sort | No | NAME_ASC, NAME_DESC, CREATED_AT_ASC/DESC, MODIFIED_AT_ASC/DESC. Defaults to NAME_ASC. | |
| No | Exact email match, applied by Wave. | ||
| fetch_all | No | Walk every page instead of returning just one. Slower, but complete. | |
| page_size | No | Records per page (1-200). | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| name_contains | No | Case-insensitive substring match on name, applied locally. | |
| modified_after | No | ISO 8601 timestamp; only customers changed after it. | |
| modified_before | No | ISO 8601 timestamp; only customers changed before it. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnly, idempotent, and non-destructive. The description adds valuable behavioral details: local filtering for name_contains, pagination with fetch_all, and sorting options, without contradicting 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?
Two concise, front-loaded sentences that first state the core purpose, then provide critical usage nuance. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description covers the key return aspect (balances). It also addresses pagination, filtering, sorting, and output format. While it could mention default behavior for missing parameters, it is sufficiently complete for a list tool with rich schema descriptions.
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 all 10 parameters. The description adds extra context beyond the schema, such as the interaction between name_contains and fetch_all, and the exact email matching, which helps the agent choose correct parameter combinations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists customers with outstanding and overdue balances. It distinguishes from sibling tools by detailing specific filtering behaviors (email exact, name_contains local) and pagination nuances.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on when to use fetch_all=true with name_contains for large lists, and implies that email is an exact filter. It does not explicitly list alternatives but provides enough context for proper usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_estimatesWave: List EstimatesBRead-onlyIdempotent
List estimates (quotes), filtered by status, customer, or date range.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number for offset pagination. | |
| sort | No | A single value such as "ESTIMATE_DATE_DESC" or "TOTAL_DESC". Defaults to ESTIMATE_DATE_DESC. | |
| status | No | DRAFT, SENT, VIEWED, ACCEPTED, APPROVED, CONVERTED, EXPIRED, REJECTED, ACTIVE, PAID, PARTIAL, UNPAID. | |
| currency | No | Currency code, e.g. "USD". | |
| fetch_all | No | Walk every page instead of returning just one. Slower, but complete. | |
| page_size | No | Records per page (1-200). | |
| amount_due | No | Exact outstanding amount match. | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| customer_id | No | Only estimates for this customer. | |
| modified_after | No | ISO 8601 timestamp; only estimates changed after it. | |
| estimate_number | No | Exact estimate number match. | |
| modified_before | No | ISO 8601 timestamp; only estimates changed before it. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
| estimate_date_end | No | Latest estimate date, YYYY-MM-DD. | |
| estimate_date_start | No | Earliest estimate date, YYYY-MM-DD. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and non-destructive. Description adds filter and pagination context but does not disclose behavioral traits beyond annotations, so a 3 is appropriate.
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?
Single sentence, efficient and to the point. Could be slightly more structured (e.g., front-loading core purpose) but otherwise concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 15 parameters fully described in schema and good annotations, the description is adequate but lacks details on pagination, sorting, or output format. Still complete enough for a filtered-list 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?
With 100% schema description coverage, the description adds minimal meaning beyond a summary of filtering options. It does not elaborate on parameter relationships or nuances, meeting the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'list' and resource 'estimates (quotes)', and specifies filtering by status, customer, or date range. It distinguishes itself from sibling tools like wave_list_invoices by focusing on estimates.
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 guidance on when to use this tool vs alternatives (e.g., wave_get_estimate for a single estimate). No exclusions or context on when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_invoicesWave: List InvoicesARead-onlyIdempotent
List invoices, filtered by status, customer, date range, or amount due. To find unpaid invoices use status "UNPAID"; "OVERDUE" narrows that to ones past their due date.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number for offset pagination. | |
| sort | No | e.g. ["INVOICE_DATE_DESC"], ["AMOUNT_DUE_DESC"], ["CUSTOMER_NAME_ASC"]. Defaults to INVOICE_DATE_DESC. | |
| status | No | DRAFT, SAVED, UNPAID, SENT, VIEWED, PARTIAL, PAID, OVERDUE, OVERPAID. | |
| currency | No | Currency code, e.g. "USD". | |
| fetch_all | No | Walk every page instead of returning just one. Slower, but complete. | |
| page_size | No | Records per page (1-200). | |
| amount_due | No | Exact outstanding amount match, e.g. "250.00". | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| customer_id | No | Only invoices for this customer. | |
| invoice_number | No | Substring match applied by Wave: 12 also matches 112 and 120. | |
| modified_after | No | ISO 8601 timestamp; only invoices changed after it. | |
| modified_before | No | ISO 8601 timestamp; only invoices changed before it. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
| invoice_date_end | No | Latest invoice date, YYYY-MM-DD. | |
| invoice_date_start | No | Earliest invoice date, YYYY-MM-DD. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds value by clarifying status semantics (UNPAID vs OVERDUE), which is a behavioral nuance beyond the raw schema. However, it does not disclose pagination behavior, return format, or that results are a list (though the name implies it). With annotations carrying the safety burden, the description adds modest behavioral context, warranting a 3.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with zero waste. The core purpose ('List invoices...') is front-loaded, followed by a concise, high-value elaboration on the most common use case (unpaid vs overdue). Every word earns its place; no redundant or filler text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 15 parameters, no output schema, and annotations covering read-only safety, the description focuses on the most pivotal filtering scenario (unpaid vs overdue invoices) which is the primary reason an agent would call this tool. It does not mention pagination or response_format, but those are documented in the schema. For a list tool with rich schema and annotations, the description addresses the key decision point sufficiently. A 5 would require explicating pagination or return structure, but the schema mitigates that 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%, so all 15 parameters are already documented. The description adds meaningful semantics specifically for the status parameter, explaining the difference between UNPAID and OVERDUE in the context of finding unpaid invoices—information not in the schema. This extra guidance elevates it above the baseline 3 for fully-covered schemas.
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 ('List') and resource ('invoices') with applicable filters (status, customer, date range, amount due). The verb distinguishes it from the sibling wave_get_invoice which retrieves a single invoice, and the filter list clearly signals this is a collection operation. 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?
The description gives explicit, actionable guidance for the status parameter: 'To find unpaid invoices use status "UNPAID"; "OVERDUE" narrows that to ones past their due date.' This tells the agent exactly how to approach a common task. It does not explicitly state when to use this tool versus wave_get_invoice, but the verb distinction makes that implied. No exclusions or alternatives are mentioned, so it falls short of a perfect score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_productsWave: List ProductsARead-onlyIdempotent
List products and services. Invoice and estimate line items must reference a product, so this is the usual first step when building either one.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number for offset pagination. | |
| sort | No | NAME_ASC, NAME_DESC, CREATED_AT_ASC/DESC, MODIFIED_AT_ASC/DESC. Defaults to NAME_ASC. | |
| is_sold | No | Only products sold to customers. | |
| fetch_all | No | Walk every page instead of returning just one. Slower, but complete. | |
| is_bought | No | Only products bought from vendors. | |
| page_size | No | Records per page (1-200). | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| is_archived | No | Filter to archived (true) or active (false) products. | |
| name_contains | No | Case-insensitive substring match on name, applied locally. | |
| modified_after | No | ISO 8601 timestamp; only products changed after it. | |
| modified_before | No | ISO 8601 timestamp; only products changed before it. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. Description adds no further behavioral traits (e.g., pagination details are in schema). Meets baseline but adds no extra value beyond 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?
Two focused sentences, front-loaded with purpose and context. No wasted words.
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?
Sufficient for a listing tool with 12 documented parameters and clear annotations. Lacks explanation of output format behavior, but schema covers response_format and fetch_all.
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 baseline is 3. Description does not elaborate on parameter meanings beyond what 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?
Clearly states the tool lists products/services and explains its role as a first step for invoices/estimates, distinguishing it from single-resource tools like wave_get_product.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says it's the usual first step for building invoices/estimates, providing strong contextual guidance. Does not explicitly mention alternatives for single products, but context signals include wave_get_product.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_sales_taxesWave: List Sales TaxesARead-onlyIdempotent
List sales taxes, with their current rate and rate history.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number for offset pagination. | |
| fetch_all | No | Walk every page instead of returning just one. Slower, but complete. | |
| page_size | No | Records per page (1-200). | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| is_archived | No | Filter to archived (true) or active (false) taxes. | |
| modified_after | No | ISO 8601 timestamp; only taxes changed after it. | |
| modified_before | No | ISO 8601 timestamp; only taxes changed before it. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
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 clear. The description adds value by noting that results include rate history, but doesn't disclose behavioral traits beyond what 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 a single, well-structured sentence that is front-loaded and concise, with no wasted words. It could be slightly more detailed but is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 8 parameters with full schema coverage, annotations providing safety info, and no output schema, the description is complete enough—it specifies what data is returned (current rate and rate history). Minor gaps in usage context prevent 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 description coverage is 100%, and the description does not add additional meaning beyond what is already in the schema. Baseline score 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 clearly states the action (list) and the resource (sales taxes) with specifics about what data is returned (current rate and rate history), distinguishing it from other tools like wave_get_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?
The description provides no guidance on when to use this tool versus alternatives, nor does it mention any prerequisites or exclusions. Context from sibling tools is not sufficient to fill this gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_list_vendorsWave: List VendorsARead-onlyIdempotent
List vendors -- the suppliers a business buys from. Vendors are read-only in Wave's API: they can be listed and read but not created, changed, or deleted. Wave filters by exact email only; name_contains is applied locally, so pair it with fetch_all=true on a long vendor list.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number for offset pagination. | |
| No | Exact email match, applied by Wave. | ||
| fetch_all | No | Walk every page instead of returning just one. Slower, but complete. | |
| page_size | No | Records per page (1-200). | |
| business_id | No | Business to operate on. Defaults to the session business set by wave_set_default_business. | |
| name_contains | No | Case-insensitive substring match on name, applied locally. | |
| modified_after | No | ISO 8601 timestamp; only vendors changed after it. | |
| modified_before | No | ISO 8601 timestamp; only vendors changed before it. | |
| response_format | No | Output format: "markdown" for a compact human-readable summary, "json" for the complete record. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds value beyond annotations by explaining local filtering of name_contains and the need for fetch_all. Describes response_format option. No contradictions with annotations (readOnlyHint, idempotentHint).
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?
Description is concise (2-3 sentences), front-loaded with purpose, then key behavioral notes. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, description covers key behavioral aspects (pagination, local filtering, response format). Could mention default page size, but schema handles that. Essentially complete for use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline 3. Description adds meaning: clarifies that email is exact match applied by Wave, name_contains is local, and advises pairing with fetch_all. Also mentions response_format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists vendors (suppliers a business buys from). It distinguishes from sibling tools like wave_get_vendor (single vendor retrieval) and other list tools for different entities.
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 context on when to use (listing vendors) and notes read-only nature. Gives specific guidance on filtering: email is exact match, name_contains is local and requires fetch_all. Could explicitly mention not to use for creating/modifying vendors, but implied by read-only.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wave_set_default_businessWave: Set Default BusinessAIdempotent
Set the business that later tool calls use when none is given. This is session state on the running server, not a change in Wave. Set WAVE_BUSINESS_ID in the environment to make it persist across restarts.
| Name | Required | Description | Default |
|---|---|---|---|
| business_id | Yes | The Wave business ID to make the default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond annotations by explaining it's session state on the server, not a change in Wave, and how to persist across restarts. Annotations (idempotentHint=true, destructiveHint=false) are consistent and enhanced by the description.
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 action, no unnecessary words. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema, the description fully covers purpose, effect, scope (session vs persistent), and persistence method. No 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 coverage is 100% for the single parameter, and its description in the schema already states it's the ID to make the default. The tool description adds no further semantics beyond what the schema provides, so baseline score 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 clearly states the tool sets the default business for subsequent tool calls, using the verb 'Set' and specifying the resource 'default business'. It distinguishes itself from siblings as the only tool for configuring this context.
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 indicates when this tool is used: to set a default business for later calls when none is given. It also mentions persistence via environment variable, providing clear context. No explicit when-not-to-use, but it's implied it's optional if business_id is always provided.
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. Dates show when Glama detected each change.
2 tool updates
v1.0.6- Changed
wave_auth_status1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "config_fallback_disabled": { + "type": "boolean" + }, + "default_business_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "detected_agent": { + "type": "string" + }, + "has_credentials": { + "type": "boolean" + }, + "lookup_errors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "next_step": { + "type": "string" + }, + "registered_tools": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "sources_checked": { + "items": { + "additionalProperties": false, + "properties": { + "found": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "id", + "label", + "path", + "found" + ], + "type": "object" + }, + "type": "array" + }, + "token_source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "write_tools_hidden": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "writes_enabled": { + "type": "boolean" + } + }, + "required": [ + "has_credentials", + "token_source", + "writes_enabled", + "default_business_id", + "detected_agent", + "config_fallback_disabled", + "sources_checked", + "lookup_errors", + "registered_tools", + "write_tools_hidden" + ], + "type": "object" +}
- Changed
wave_list_invoices1 field changed- changed
Input schema / properties / invoice_number / descriptionPrevious value: -"Exact invoice number match."New value: +"Substring match applied by Wave: 12 also matches 112 and 120."
30 tool updates
v1.0.2- First observed
wave_auth_status - First observed
wave_get_account - First observed
wave_get_business - First observed
wave_get_country - First observed
wave_get_currency - 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_estimate_settings - First observed
wave_get_invoice_payment - First observed
wave_get_oauth_application - First observed
wave_get_product - First observed
wave_get_province - First observed
wave_get_sales_tax - First observed
wave_get_user - First observed
wave_get_vendor - First observed
wave_list_account_subtypes - First observed
wave_list_account_types - First observed
wave_list_accounts - First observed
wave_list_businesses - First observed
wave_list_countries - First observed
wave_list_currencies - First observed
wave_list_customers - First observed
wave_list_estimates - First observed
wave_list_invoices - First observed
wave_list_products - First observed
wave_list_sales_taxes - First observed
wave_list_vendors - First observed
wave_set_default_business
TDQS
Every tool targets a distinct resource/action pair, with standard list/get pairs and clear separation between account types, subtypes, and accounts. Auth-related tools (OAuth app, user, auth status) each have a unique purpose and are not easily confused.
Almost all tools follow the wave_<verb>_<noun> pattern with list_/get_ prefixes. The only outlier is wave_auth_status, which lacks a verb, but the convention is otherwise highly consistent.
At 30 tools, this exceeds the 25+ threshold for a heavy tool set. Many list/get pairs cover peripheral reference data such as currencies, countries, provinces, and OAuth application details, making the surface feel bloated.
The server is almost entirely read-only, with no create/update/delete tools for invoices, estimates, customers, products, or accounts. This is a significant gap, and wave_list_account_subtypes even references a wave_create_account tool that does not exist.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Invoicing you drive by talking to your AI: log time, raise invoices and track what's owed via MCP.
Let AI agents query data and act across all your business apps via MCP.
Connect your AI to your Well financial data - invoices, companies, contacts.
Connect Exact Online to your AI assistant via MCP. Manage Exact Online with natural language.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceThis MCP server enables AI assistants like Claude to perform Wave Accounting bookkeeping tasks—such as drafting invoices, managing customers, recording payments, and looking up financial data—through natural language commands.2MIT
- FlicenseNot gradedqualityDmaintenanceComprehensive MCP server for Wave Accounting, providing 45+ tools across invoicing, customers, products, transactions, bills, estimates, taxes, and financial reporting, plus 17 pre-built UI workflows.4-
- AlicenseAqualityDmaintenanceEnables Wave invoicing operations including listing invoices, retrieving details, and generating branded PDFs directly from AI assistants.521ISC
- FlicenseAqualityFmaintenanceMCP server for Wave accounting that provides tools for managing chart of accounts, invoices, customers, vendors, products, and reports via the Wave GraphQL API.6-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/oliverames/wave-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server