Skip to main content
Glama
oliverames

MCP Server for Wave

by oliverames

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

Claude and Codex plugin packages remain in this repository for distribution through a separately managed marketplace. The repository no longer supplies root catalogs that appear automatically when the project opens. For direct use, register the MCP server as shown below.

Install in Codex

codex mcp add wave-mcp-server \
  --env WAVE_ACCESS_TOKEN=your_token_here \
  -- npx -y @oliverames/mcp-server-for-wave@latest

Verify 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-server

The -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

wave_list_businesses

List reachable businesses

wave_get_business

Full business detail

wave_set_default_business

Set the session default

wave_get_invoice_estimate_settings

Accent color and logo

wave_auth_status

How credentials resolved, and what is gated. Makes no API call

wave_get_user

Account the token belongs to

wave_get_oauth_application

Application that issued the token

wave_list_currencies / wave_get_currency

Supported currencies

wave_list_countries / wave_get_country

Countries and their provinces

wave_get_province

One province or state

wave_list_account_types

The five top-level account types

wave_list_account_subtypes

Subtypes, which wave_create_account requires

Chart of accounts

Tool

Purpose

wave_list_accounts / wave_get_account

Accounts with balances

wave_create_account W

Add an account

wave_patch_account W

Rename or renumber

wave_archive_account W

Hide from pickers, keep history

Customers, vendors, products, taxes

Tool

Purpose

wave_list_customers / wave_get_customer

Customers with balances

wave_create_customer / wave_patch_customer / wave_delete_customer W

Manage customers

wave_list_vendors / wave_get_vendor

Vendors (read-only in Wave's API)

wave_list_products / wave_get_product

Products and services

wave_create_product / wave_patch_product / wave_archive_product W

Manage products

wave_list_sales_taxes / wave_get_sales_tax

Taxes and rate history

wave_create_sales_tax / wave_patch_sales_tax / wave_archive_sales_tax W

Manage taxes

Invoices and payments

Tool

Purpose

wave_list_invoices / wave_get_invoice

Invoices with items and payments

wave_create_invoice / wave_patch_invoice / wave_clone_invoice W

Build invoices

wave_approve_invoice W

Move a draft into the books

wave_send_invoice W

Emails the customer

wave_mark_invoice_sent W

Record delivery made outside Wave

wave_delete_invoice W

Permanent

wave_get_invoice_payment

One payment

wave_create_invoice_payment / wave_patch_invoice_payment / wave_delete_invoice_payment W

Record payments

wave_send_invoice_payment_receipt W

Emails the customer

Estimates and deposits

Tool

Purpose

wave_list_estimates / wave_get_estimate

Estimates with history and deposits

wave_create_estimate / wave_patch_estimate / wave_clone_estimate W

Build estimates

wave_approve_estimate W

Approve a draft

wave_send_estimate W

Emails the customer

wave_mark_estimate_sent / wave_mark_estimate_accepted W

Record offline delivery and acceptance

wave_reset_estimate_acceptance W

Undo an acceptance

wave_send_estimate_acceptance_email W

Emails the customer

wave_generate_estimate_pdf W

Render a PDF

wave_convert_estimate_to_invoice W

Turn an accepted estimate into an invoice

wave_delete_estimate W

Permanent

wave_get_estimate_payment

One deposit payment

wave_create_estimate_deposit_payment / wave_update_estimate_deposit_payment / wave_delete_estimate_payment W

Record deposits

wave_send_estimate_deposit_receipt W

Emails the customer

Bookkeeping

Tool

Purpose

wave_create_money_transaction W

One expense, income, or transfer

wave_create_money_transactions W

Bulk import, applied atomically

wave_create_deposit_transaction W

A payout whose net differs from gross

wave_create_expense_from_receipt W

Expense, account matched from a category word

wave_create_income_from_payment W

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 DEPOSIT or WITHDRAWAL.

  • 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

WAVE_ACCESS_TOKEN

Yes

(none)

OAuth2 bearer token from the Wave developer portal

WAVE_BUSINESS_ID

No

(none)

Default business, so tools can omit business_id. The base64 id or the bare business UUID

WAVE_ALLOW_WRITES

No

off

Set to 1 to register the 44 tools that change or send data

WAVE_ACCESS_TOKEN_FILE

No

(none)

Read the token from a file instead

WAVE_OP_PATH

No

(none)

Read the token from 1Password, e.g. op://Vault/Item/credential

WAVE_TIMEOUT_MS

No

20000

Per-request timeout

WAVE_TOTAL_BUDGET_MS

No

50000

Total time for one call including retries

WAVE_MAX_RESPONSE_BYTES

No

8388608

Reject responses above this size

WAVE_HTTP_RETRIES

No

2

Retries on 429 and 5xx

WAVE_DISABLE_AGENT_CONFIG_FALLBACK

No

off

Read only the environment, not agent config files

WAVE_LOG_LEVEL

No

info

debug, info, warn, error, or silent. JSON lines on stderr

WAVE_TRACING_ENABLED

No

off

Send a W3C traceparent header with each Wave request

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 transactions connection on Business. Review them in the web app.

  • Vendors are read-only. The schema has no vendorCreate, vendorPatch, or vendorDelete.

  • Money transactions cannot reference a vendor. wave_create_expense_from_receipt records the name in the description.

  • wave_patch_estimate demands 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_account needs the account's current sequence as an optimistic-concurrency check.

  • Line items must reference a product. No free-text lines.

  • wave_create_deposit_transaction returns 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 network

The 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                  # 74 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 bundle

Contributions 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 tools
wave_auth_statusWave: Auth StatusA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
next_stepNo
token_sourceYes
lookup_errorsYes
detected_agentYes
writes_enabledYes
has_credentialsYes
sources_checkedYes
registered_toolsYes
write_tools_hiddenYes
default_business_idYes
config_fallback_disabledYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds valuable behavioral context beyond the annotations: it makes no network request to Wave and remains functional when credentials are invalid. This directly helps an agent understand failure modes and when to trust the tool's output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences with the core purpose front-loaded and the usage guidance in the second sentence. No filler or repetition of schema or annotation information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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 an output schema, the description covers what it reports, its offline behavior, the token-failure scenario, and when to invoke it. There are no missing operational details an agent would need.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is nothing for the description to clarify beyond the empty schema. The baseline of 4 for a zero-parameter tool is appropriate, and the description's focus on output semantics is fine.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific diagnostic purpose: report how the server resolved Wave credentials and whether write tools are enabled. This clearly distinguishes it from the many data-oriented sibling tools such as wave_get_user or wave_list_invoices.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit usage directive: use it first when other tools report authentication problems. It also explains why it is appropriate in that situation by noting it makes no Wave API request and works despite missing or expired tokens.

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 AccountA
Read-onlyIdempotent

Get one account by ID, including its current balance.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idYesThe Wave account ID.
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is fully covered structurally, and the description does not contradict any of them. The description adds a small behavioral clue that the balance is current rather than cached, and the schema notes response_format behavior (markdown vs json). It does not disclose not-found or error behavior, but with four rich annotations the bar is lower.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single efficient sentence that front-loads the verb and resource before appending the balance detail. There is no filler, no repetition of the title, and every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple get-by-ID tool, 100% schema coverage, four rich annotations, and the description's return hint ('including its current balance') form a nearly complete picture. The main omissions are edge-case behavior (e.g., account-not-found handling) and explicit return-structure detail, but with no output schema and a read-only op these are minor. Nothing an agent needs to make a correct call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter is well documented: account_id's purpose, business_id's base64 format and defaulting rules, and response_format's enum with a default of markdown. The tool description itself adds no parameter detail beyond what the schema provides, so the baseline of 3 applies. An agent has everything needed to populate the parameters correctly from the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Get one account by ID') plus a distinctive return detail ('including its current balance'). This clearly separates it from sibling wave_list_accounts (which retrieves multiple accounts) and other getters such as wave_get_business or wave_get_vendor. An agent can identify the tool's purpose without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The singular scope ('one account by ID') implies this tool is for when a single account ID is already known, but the description never names wave_list_accounts as the alternative for fetching all accounts or states when not to use it. The business_id parameter description does add operational guidance (business defaulting, pass on every call), but that is parameter-level, not tool-selection guidance. Usage context is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wave_get_businessWave: Get BusinessA
Read-onlyIdempotent

Get full detail for one business: currency, address, type, and settings.

ParametersJSON Schema
NameRequiredDescriptionDefault
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.2/5.0
Behavior4/5

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 fully covered. The description adds value on top by scoping what 'full detail' means (currency, address, type, settings), implicitly telling the agent which record domains this call will and will not surface. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single 12-word sentence with zero filler: verb, scope, and content enumeration all front-loaded in order of importance. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with two optional parameters and no output schema, the description tells the agent what the result contains, the schema documents the parameters, and the annotations carry the safety profile. The only minor omission is that the description doesn't mention the markdown/json output split, but the response_format schema field already covers that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already fully documented: business_id explains ID provenance and defaulting, response_format explains output modes and the default. The high coverage sets the baseline at 3; the description adds no parameter-specific meaning, but none is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states a specific verb ('Get'), a precise resource ('one business'), and enumerates the returned content ('currency, address, type, and settings'). 'One business' clearly differentiates it from the sibling wave_list_businesses, so an agent can distinguish the single-record getter without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Get full detail for one business' sets clear context: this is the single-entity retrieval path, contrasted with list-style siblings like wave_list_businesses. The business_id parameter description reinforces the workflow by naming wave_list_businesses as the ID source and wave_set_default_business as the fallback, though the description itself stops short of explicit when-to/when-not-to routing.

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 CountryA
Read-onlyIdempotent

Get one country and its provinces or states. Use this to find the province codes that address fields expect.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesISO 3166-1 alpha-2 code such as "US", "CA", or "GB".
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CurrencyA
Read-onlyIdempotent

Get one currency by ISO 4217 code.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesCurrency code such as "USD", "CAD", or "EUR".
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 CustomerA
Read-onlyIdempotent

Get one customer by ID, including address and shipping details.

ParametersJSON Schema
NameRequiredDescriptionDefault
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
customer_idYesThe Wave customer ID.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.8/5.0
Behavior3/5

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 useful return-content context ('address and shipping details') beyond the annotations, but does not disclose not-found behavior, error cases, or any other runtime characteristics. This is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler words. It states the action, the target resource, the selection mechanism, and a useful output detail, earning every word.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a low-complexity get-by-ID tool with rich annotations and 100% parameter documentation. The description tells the agent the key selection method and the included record fields, which is enough for a basic read call. It could mention not-found behavior or explicitly point to list_customers for non-ID lookup, but those are minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%; business_id, customer_id, and response_format are already fully documented in the input schema. The description adds no parameter-specific meaning beyond what the schema provides, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb, resource, and lookup key: 'Get one customer by ID'. It also adds scope with 'including address and shipping details', which distinguishes it from a plain customer fetch and implies it is not the list operation (wave_list_customers).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'by ID' implies the intended usage: use this when you already have a specific customer_id. However, it does not explicitly mention alternatives such as wave_list_customers for searching or listing, nor does it state when not to use this tool. Usage is implied rather than directly guided.

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 EstimateA
Read-onlyIdempotent

Get one estimate in full: line items, deposits, and acceptance history.

ParametersJSON Schema
NameRequiredDescriptionDefault
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
estimate_idYesThe Wave estimate ID.
include_historyNoInclude the acceptance and rejection audit trail.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown
include_attachmentsNoInclude attached files.
include_deposit_paymentsNoInclude deposit payments recorded against it.

TDQS

A4/5.0
Behavior3/5

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 that the tool returns line items, deposits, and acceptance history, which is useful. However, it does not disclose the default response format behavior (markdown vs json) or the effect of include_history/include_attachments/include_deposit_payments flags beyond what the schema already states.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that names the resource and the three key included components. No wasted words, and the most important scoping information ('one estimate') comes first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only single-record retrieval tool with 100% schema coverage and no output schema, the description is largely complete. It could be improved by noting that the response format defaults to markdown and that json returns the complete record, but the schema already covers those details. The main gap is not explicitly routing the agent to wave_list_estimates to obtain an estimate_id.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 adds a high-level summary of what the tool returns but does not add meaning beyond the schema for parameters like business_id, include_history, or response_format. Baseline 3 is appropriate when the schema carries the full parameter documentation burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Get one estimate in full: line items, deposits, and acceptance history' uses a specific verb ('Get'), a clear resource ('one estimate'), and enumerates the key included components. It distinguishes itself from sibling tools like wave_list_estimates (list vs. single) and wave_get_estimate_payment (payment vs. estimate).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a single-record retrieval use case, and the sibling list tool (wave_list_estimates) provides an implicit alternative. However, it does not explicitly state when to use this tool versus wave_get_estimate_payment or wave_list_estimates, nor does it mention any prerequisites like needing an estimate_id from a list call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wave_get_estimate_paymentWave: Get Estimate PaymentA
Read-onlyIdempotent

Get one estimate deposit payment by ID. To see every deposit on an estimate, call wave_get_estimate with include_deposit_payments=true.

ParametersJSON Schema
NameRequiredDescriptionDefault
payment_idYesThe Wave estimate payment ID.
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.3/5.0
Behavior3/5

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 the singular-scope behavior ('one estimate deposit payment') and the relationship to the parent estimate, but does not disclose other behavioral details such as error cases or response representation. This meets the baseline for a described, annotation-covered read operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no wasted words. The primary action is front-loaded, and the alternative invocation is provided in the second sentence. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple: a single read by ID with one required parameter. Annotations fully cover the operation safety, schema covers all parameters, and response_format offers output control. Nothing an agent needs to correctly invoke this tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 payment_id, business_id, and response_format. The description adds no meaning beyond saying the lookup is 'by ID,' which is already clear. Baseline 3 is appropriate because the schema carries the parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Get one estimate deposit payment by ID.' It also explicitly differentiates this tool from wave_get_estimate, which lists every deposit, so an agent can distinguish them immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly names the alternative tool and the exact condition for using it: 'To see every deposit on an estimate, call wave_get_estimate with include_deposit_payments=true.' This provides clear when-to-use guidance versus the sibling tool.

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 InvoiceA
Read-onlyIdempotent

Get one invoice in full: line items, taxes, discounts, and payments.

ParametersJSON Schema
NameRequiredDescriptionDefault
invoice_idYesThe Wave invoice ID.
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint, so the agent knows this is a safe, non-mutating call. The description adds value by indicating that the response includes line items, taxes, discounts, and payments, which helps the agent predict what data will be returned. 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that front-loads the core purpose. It is efficient and every word adds value, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity, the schema fully documents parameters, and the description covers the return content adequately. The lack of an output schema is compensated by the description's summary of what the response includes. No critical information appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Since schema description coverage is 100%, the baseline is 3. The description does not add extra meaning beyond what the schema already documents. It mentions 'in full' but does not elaborate on parameter details or relationships.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb (get) and resource (one invoice) and enumerates the key data fields (line items, taxes, discounts, payments). It does not explicitly differentiate from wave_list_invoices, but the singular 'one invoice' and 'in full' imply a detail-oriented retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving a single invoice with full detail, which is distinct from listing invoices. However, it does not state when to prefer this over wave_get_invoice_payment or wave_get_invoice_estimate_settings, nor does it mention any alternatives or exclusions.

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 SettingsA
Read-onlyIdempotent

Get the branding applied to invoices and estimates: accent color and logo.

ParametersJSON Schema
NameRequiredDescriptionDefault
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds scope context by naming the returned branding fields, but it does not disclose edge behaviors such as defaults when no branding is configured or auth expectations beyond what annotations imply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that states the action, resource, and key returned fields without filler. Every word contributes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, has rich parameter schema coverage, and the description states what it returns. It does not detail the response format, but given the read-only nature and low complexity, the description is sufficient for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and both parameters have clear meanings in the schema. The description adds no parameter-level semantics, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Get the branding applied to invoices and estimates,' then narrows it further to 'accent color and logo.' This makes it clearly distinct from sibling tools that fetch individual invoices or estimates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives like wave_get_invoice or wave_get_estimate, and no exclusions or context for selection. The agent must infer usage solely from the resource name and sibling list.

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 PaymentA
Read-onlyIdempotent

Get one invoice payment by ID. To see every payment on an invoice, call wave_get_invoice instead: it returns them all.

ParametersJSON Schema
NameRequiredDescriptionDefault
payment_idYesThe Wave invoice payment ID.
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already disclose readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the scoping behavior (single payment vs. all payments) but does not describe edge-case behavior such as not-found handling or output specifics, which would be useful beyond the static annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no redundant text. The primary purpose is front-loaded, and the sibling alternative is contained in a single efficient second sentence. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-record retrieval tool with three well-documented parameters, a required ID, and annotations carrying the safety profile, the description is complete. No output schema exists, but response_format in the schema already explains what the agent will receive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 payment_id, business_id, and response_format. The description does not add further parameter-level meaning beyond the schema, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states 'Get one invoice payment by ID', identifying both the action and resource with precision. It also differentiates from wave_get_invoice by noting that the sibling retrieves all payments on an invoice, which is especially helpful given the similar-sounding sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives direct when-to-use guidance: use this tool for a single payment by ID, and use wave_get_invoice when all payments on an invoice are needed. This explicit alternative routing removes ambiguity without requiring the agent to explore sibling schemas.

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 ApplicationA
Read-onlyIdempotent

Get the OAuth application that issued the current access token.

ParametersJSON Schema
NameRequiredDescriptionDefault
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 ProductA
Read-onlyIdempotent

Get one product by ID, including its accounts and default sales taxes.

ParametersJSON Schema
NameRequiredDescriptionDefault
product_idYesThe Wave product ID.
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4/5.0
Behavior3/5

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 by structured data. The description adds the useful detail that the response includes accounts and default sales taxes, but does not disclose other behavioral traits. This is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tight sentence with no wasted words. The core purpose and the key response inclusions are front-loaded, making it easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only getter with all parameters fully documented in the schema and annotations carrying the behavioral safety profile, the description is complete enough. It even hints at response contents, which partially compensates for the absence of an output schema. Minor gaps like error handling are 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.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all three parameters. The description adds no parameter-level meaning beyond what the schema already provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get'), a specific resource ('one product by ID'), and adds the distinguishing detail that the result includes accounts and default sales taxes. This clearly differentiates it from a list operation like wave_list_products.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'by ID' gives clear context that this tool is for fetching a single known product, rather than listing products. It does not explicitly name an alternative or exclusion, but the intended usage is unambiguous enough for an agent.

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 ProvinceA
Read-onlyIdempotent

Get one province or state by its code.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesProvince code, typically country-qualified, e.g. "CA-ON" or "US-NY".
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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 TaxA
Read-onlyIdempotent

Get one sales tax by ID, including its full rate history.

ParametersJSON Schema
NameRequiredDescriptionDefault
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
sales_tax_idYesThe Wave sales tax ID.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnlyHint, idempotentHint, destructiveHint), so the bar is lower. The description adds the behavioral detail that the response includes full rate history, which is useful context beyond the schema. However, it does not disclose any potential edge cases, error conditions, or authentication needs, but these are not critical for a read-only get operation. It adds some value 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, compact sentence that front-loads the core action and includes the distinctive detail about rate history. It has no fluff or redundant phrasing. It is appropriately sized for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple get-by-ID operation with a fully documented schema and read-only annotations, the description is nearly complete. It mentions the key differentiator (rate history) and the required ID is obvious. The absence of an output schema is compensated by the response_format parameter. The only minor gap is not explicitly stating the return format, but that is covered by the parameter. Overall, an agent has enough to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters (business_id, sales_tax_id, response_format) are already fully documented in the input schema. The description does not add any extra parameter-specific guidance beyond what the schema provides. Therefore, the baseline of 3 is appropriate; the description adds no incremental semantic value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific verb 'Get' and the resource 'one sales tax by ID', distinguishing it from sibling tools like wave_list_sales_taxes. It also adds a meaningful qualifier, 'including its full rate history', which is not in the title. This is precise and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool versus alternatives. It implies you need a specific sales tax ID, and since there is a list tool, it's reasonable to assume you first list to get IDs, but this is not stated. There is no mention of when not to use it or any alternative routing. The guidance is implied but not explicit.

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 UserA
Read-onlyIdempotent

Get the Wave user account that owns the current access token. Useful for confirming which account a token authenticates as.

ParametersJSON Schema
NameRequiredDescriptionDefault
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.1/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 VendorA
Read-onlyIdempotent

Get one vendor by ID, including address and shipping details.

ParametersJSON Schema
NameRequiredDescriptionDefault
vendor_idYesThe Wave vendor ID.
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is clear. The description adds context beyond that by revealing that the response includes address and shipping details, which is useful for an agent deciding whether this tool satisfies a request. No rate limits, auth, or error behavior are mentioned, but for a simple single-record get that is not a major gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that states the verb, resource, and the key output detail without any filler. Every word earns its place, and the length is appropriate for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich annotations and fully documented parameters, the main missing piece is a complete return specification since there is no output schema. The description partially compensates by noting address and shipping details, which is enough for an agent to select and invoke this tool correctly. It would be slightly stronger if it explicitly mentioned not-found behavior or the full record shape, but it is not necessary for the basic call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers 100% of the parameters with clear descriptions, including the business_id default behavior and the response_format enum. The description does not add any parameter-level meaning beyond the schema, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb (Get), a specific resource (one vendor by ID), and adds a distinctive return detail (including address and shipping details). This cleanly distinguishes it from sibling list tools like wave_list_vendors and from other get-by-ID tools such as wave_get_customer or wave_get_account.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'one vendor by ID' implies this is for fetching a single known vendor, but there is no explicit when-to-use guidance, no mention of wave_list_vendors for finding IDs, and no statement about when a different tool should be chosen. Usage is inferred from the name and description rather than spelled out.

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 AccountsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number for offset pagination.
typesNoFilter by type: ASSET, LIABILITY, EQUITY, INCOME, EXPENSE.
subtypesNoFilter by subtype, e.g. ["CASH_AND_BANK", "CREDIT_CARD"].
fetch_allNoWalk every page instead of returning just one. Slower, but complete.
page_sizeNoRecords per page (1-200).
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
is_archivedNoFilter to archived (true) or active (false) accounts.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown
excluded_subtypesNoSubtypes to omit.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the bar for additional context is lower. The description adds useful behavioral detail by stating that balances are included and by illustrating how type/subtype filters map to real-world transactional needs, which goes 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The primary function is front-loaded, and the second sentence provides immediately useful filter recipes. Every clause contributes to either what the tool does or how to apply it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich schema (all parameters documented, including pagination, business_id, response_format) and strong annotations (readOnly, idempotent, openWorld), the description is complete enough for an agent to call the tool correctly. It does not need to restate parameters or return shapes because the schema already covers those, and it adds the missing use-case guidance.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3ives are 3. The description adds meaning beyond the schema by explaining the practical intent of type and subtype filters (e.g., finding expense categories or bank accounts). This semantic guidance is not present in the parameter descriptions, which only list values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and a clear resource ('the chart of accounts'), adding that results include balances. It is easily distinguishable from sibling tools like wave_get_account (single account) and wave_list_account_types (types only) because it focuses on accounts themselves.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives concrete, actionable scenarios: filter by EXPENSE for expense categories, INCOME for revenue, ASSET with subtype CASH_AND_BANK for bank accounts, and LIABILITY with subtype CREDIT_CARD for cards. It implies when to use this tool (when locating an account for a transaction), though it does not explicitly mention alternatives or state 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_account_subtypesWave: List Account SubtypesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_typeNoFilter to one type: ASSET, LIABILITY, EQUITY, INCOME, EXPENSE.
creatable_onlyNoExclude system-created subtypes unavailable to new accounts.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 TypesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 BusinessesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number for offset pagination.
fetch_allNoWalk every page instead of returning just one. Slower, but complete.
page_sizeNoRecords per page (1-200).
is_archivedNoFilter to archived (true) or active (false) businesses.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.1/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 CountriesA
Read-onlyIdempotent

List the countries Wave supports, with each one's default currency.

ParametersJSON Schema
NameRequiredDescriptionDefault
searchNoCase-insensitive filter on country code or name.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.6/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 CurrenciesA
Read-onlyIdempotent

List the currency codes Wave supports. Wave supports about 160 currencies, so pass search to narrow the list.

ParametersJSON Schema
NameRequiredDescriptionDefault
searchNoCase-insensitive filter on code or name, e.g. "CAD" or "dollar".
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CustomersA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number for offset pagination.
sortNoNAME_ASC, NAME_DESC, CREATED_AT_ASC/DESC, MODIFIED_AT_ASC/DESC. Defaults to NAME_ASC.
emailNoExact email match, applied by Wave.
fetch_allNoWalk every page instead of returning just one. Slower, but complete.
page_sizeNoRecords per page (1-200).
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
name_containsNoCase-insensitive substring match on name, applied locally.
modified_afterNoISO 8601 timestamp; only customers changed after it.
modified_beforeNoISO 8601 timestamp; only customers changed before it.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint, idempotentHint, destructiveHint), lowering the bar. The description adds a genuinely important behavioral trait beyond annotations: name_contains is applied locally after fetching, so results can be incomplete without fetch_all=true. This is the kind of non-obvious runtime behavior that materially affects correctness.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler. The core purpose is front-loaded in the first sentence, and the second sentence delivers the single most important usage caveat. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter tool with no output schema, the description is reasonably complete: it names the salient return content (balances), flags the pagination/filtering trap, and leaves parameter documentation to a fully-covered schema. A small gap is the absence of any hint about response shape beyond balances, but the annotations and rich schema compensate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline of 3 applies — parameter meanings are fully documented in the schema. The description adds modest extra value by clarifying the interaction between name_contains and fetch_all and by noting Wave only supports exact email natively, but it doesn't carry the semantic burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description begins with a specific verb and resource — 'List customers' — and adds concrete inclusion detail ('outstanding and overdue balance'). This clearly distinguishes it from siblings like wave_get_customer (singular retrieval) and wave_list_vendors (different resource).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear actionable context: it explains that Wave only filters natively by exact email, while name_contains is a post-fetch local filter, then gives explicit guidance to combine name_contains with fetch_all=true for large lists. It lacks an explicit 'use wave_get_customer instead when...' exclusion, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wave_list_estimatesWave: List EstimatesB
Read-onlyIdempotent

List estimates (quotes), filtered by status, customer, or date range.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number for offset pagination.
sortNoA single value such as "ESTIMATE_DATE_DESC" or "TOTAL_DESC". Defaults to ESTIMATE_DATE_DESC.
statusNoDRAFT, SENT, VIEWED, ACCEPTED, APPROVED, CONVERTED, EXPIRED, REJECTED, ACTIVE, PAID, PARTIAL, UNPAID.
currencyNoCurrency code, e.g. "USD".
fetch_allNoWalk every page instead of returning just one. Slower, but complete.
page_sizeNoRecords per page (1-200).
amount_dueNoExact outstanding amount match.
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
customer_idNoOnly estimates for this customer.
modified_afterNoISO 8601 timestamp; only estimates changed after it.
estimate_numberNoExact estimate number match.
modified_beforeNoISO 8601 timestamp; only estimates changed before it.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown
estimate_date_endNoLatest estimate date, YYYY-MM-DD.
estimate_date_startNoEarliest estimate date, YYYY-MM-DD.

TDQS

B3.3/5.0
Behavior3/5

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 only the filtering capability; it does not mention pagination behavior, fetch_all implications, or the business_id default/fallback, so it adds modest context beyond annotations but not rich behavioral detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One front-loaded sentence with no filler; it names the operation and key filter categories immediately. Given the schema carries parameter detail, this is appropriately sized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 15-parameter tool with no output schema, the description is minimally viable: it identifies the operation and main filter dimensions, while the schema covers parameter specifics and annotations cover read-only/idempotent behavior. It lacks a pointer to the singular wave_get_estimate for detail lookup and does not characterize response_format or pagination behavior, though those are recoverable from schema defaults.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with every parameter, default, and enum already documented in the schema. The description's mention of filters by status, customer, or date range mirrors a subset of those parameter descriptions rather than adding new meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('estimates'), and clarifies the synonym 'quotes' plus common filters. It is clear but does not explicitly differentiate from sibling wave_get_estimate or the filtering scope of wave_list_invoices, so it misses the top tier for sibling distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a list/query use case but gives no when-to-use guidance, exclusions, or alternatives. Siblings like wave_get_estimate for single-record detail or wave_set_default_business for business context are not mentioned, leaving tool routing to inference.

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 InvoicesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number for offset pagination.
sortNoe.g. ["INVOICE_DATE_DESC"], ["AMOUNT_DUE_DESC"], ["CUSTOMER_NAME_ASC"]. Defaults to INVOICE_DATE_DESC.
statusNoDRAFT, SAVED, UNPAID, SENT, VIEWED, PARTIAL, PAID, OVERDUE, OVERPAID.
currencyNoCurrency code, e.g. "USD".
fetch_allNoWalk every page instead of returning just one. Slower, but complete.
page_sizeNoRecords per page (1-200).
source_idNoOnly invoices created from this source, such as an estimate ID.
amount_dueNoExact outstanding amount match, e.g. "250.00".
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
customer_idNoOnly invoices for this customer.
invoice_numberNoSubstring match applied by Wave: 12 also matches 112 and 120.
modified_afterNoISO 8601 timestamp; only invoices changed after it.
modified_beforeNoISO 8601 timestamp; only invoices changed before it.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown
invoice_date_endNoLatest invoice date, YYYY-MM-DD.
invoice_date_startNoEarliest invoice date, YYYY-MM-DD.

TDQS

A4.2/5.0
Behavior3/5

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 useful domain context about UNPAID vs OVERDUE semantics, but does not disclose other behavioral aspects such as pagination defaulting to a single page unless fetch_all is set, or the impact of the response_format parameter. With annotations carrying the core behavior, this is an adequate but not rich transparency contribution.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both purposeful. The first front-loads the core operation and filter capabilities; the second gives high-value status guidance. No filler, no repetition of schema details, and the structure moves from general purpose to specific filter usage.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 16 optional parameters and no output schema, the description provides enough orienting context: it names the primary filter axes and gives concrete status usage. The schema documents each parameter thoroughly, so the description does not need to repeat them. A small gap is that pagination behavior and the effect of response_format are left to the schema, but the overall definition is sufficient for correct tool selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds value beyond the schema by grouping filters into categories (status, customer, date range, amount due) and by explaining the practical difference between UNPAID and OVERDUE statuses. This helps an agent reason about filter combinations without opening the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('List invoices') and immediately lists the main filter dimensions (status, customer, date range, amount due), clearly distinguishing this plural listing tool from the singular wave_get_invoice sibling. The resource is unambiguous and the sentence is action-oriented.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear, actionable context on how to use the status filter: 'To find unpaid invoices use status "UNPAID"; "OVERDUE" narrows that to ones past their due date.' This is specific guidance that helps an agent select the right filter values. It does not explicitly compare to sibling tools like wave_get_invoice, but the listing intent is clear enough that no exclusion is needed.

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 ProductsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number for offset pagination.
sortNoNAME_ASC, NAME_DESC, CREATED_AT_ASC/DESC, MODIFIED_AT_ASC/DESC. Defaults to NAME_ASC.
is_soldNoOnly products sold to customers.
fetch_allNoWalk every page instead of returning just one. Slower, but complete.
is_boughtNoOnly products bought from vendors.
page_sizeNoRecords per page (1-200).
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
is_archivedNoFilter to archived (true) or active (false) products.
name_containsNoCase-insensitive substring match on name, applied locally.
modified_afterNoISO 8601 timestamp; only products changed after it.
modified_beforeNoISO 8601 timestamp; only products changed before it.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, fully covering the safety profile. The description adds domain context (products are referenced by line items) but discloses no behavioral traits like pagination defaults, local filtering, or return shape beyond what the schema already documents. Value-add is modest, consistent with annotations carrying the safety burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste: the core function is front-loaded, followed by a single high-value workflow note. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with a fully self-documenting 12-parameter schema, complete annotations, and a response_format parameter controlling output, the description is nearly sufficient. It supplies the key missing context — why and when the tool matters in invoice/estimate construction. Only an explicit pointer to wave_get_product for single-record lookups is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and every parameter has a meaningful description, so the schema does the heavy lifting. The description itself adds no parameter-level meaning (it mentions no filters or pagination), landing exactly at the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('List products and services') with no ambiguity. It is semantically distinct from the sibling wave_get_product, which is the singular retrieval counterpart, and the scope is clear enough that an agent need not open the schema to know what the tool enumerates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives clear contextual guidance: invoice and estimate line items must reference a product, so this list is 'the usual first step when building either one.' This tells the agent when the tool fits a workflow, though it does not name exclusions or explicitly route to wave_get_product when a single known product is needed.

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 TaxesA
Read-onlyIdempotent

List sales taxes, with their current rate and rate history.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number for offset pagination.
fetch_allNoWalk every page instead of returning just one. Slower, but complete.
page_sizeNoRecords per page (1-200).
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
is_archivedNoFilter to archived (true) or active (false) taxes.
modified_afterNoISO 8601 timestamp; only taxes changed after it.
modified_beforeNoISO 8601 timestamp; only taxes changed before it.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already disclose readOnlyHint, idempotentHint, and destructiveHint=false, so the description does not need to restate them. It adds a small output-content hint ('current rate and rate history') but nothing about paging, filtering scope, or response behavior beyond that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single 12-word sentence with no filler. The verb and resource are front-loaded, and the rate-history detail is relevant and non-redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list operation with rich schema descriptions and safety annotations, the description is nearly sufficient and names the key output content. A small gap is that, with no output schema present, it could explicitly mention the markdown/json response formats, though response_format documentation partially covers this.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each of the eight parameters already detailed. The tool description adds no parameter-level meaning, so it meets the baseline for a fully covered schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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 ('sales taxes'), and adds the distinctive detail that results include current rate and rate history. This clearly distinguishes it from the sibling single-record tool wave_get_sales_tax and from other list tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use is implied by the plural 'List' and the existence of wave_get_sales_tax, but there is no explicit when-to-use guidance, no mention of when to choose this over the singular getter, and no discussion of pagination or fetch_all behavior.

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 VendorsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number for offset pagination.
emailNoExact email match, applied by Wave.
fetch_allNoWalk every page instead of returning just one. Slower, but complete.
page_sizeNoRecords per page (1-200).
business_idNoBusiness to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call.
name_containsNoCase-insensitive substring match on name, applied locally.
modified_afterNoISO 8601 timestamp; only vendors changed after it.
modified_beforeNoISO 8601 timestamp; only vendors changed before it.
response_formatNoOutput format: "markdown" for a compact human-readable summary, "json" for the complete record.markdown

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes beyond the readOnlyHint annotation by explicitly stating that vendors cannot be created, changed, or deleted in Wave's API. It also exposes a non-obvious behavioral trait: name_contains is applied locally, not by Wave, and therefore should be paired with fetch_all=true on long vendor lists. This is valuable context that annotations and schema alone do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with purpose, followed by the read-only trait and the single caveat that matters for correctness. There is no filler, repetition, or schema re-stating; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter list tool with no output schema, the description covers the core semantics: purpose, read-only constraint, and the non-obvious local-filter caveat. It does not give list-versus-get selection guidance or pagination defaults, but those are partly addressed by the schema and the fetch_all advice. Reasonably complete, though a pointer to wave_get_vendor would make it fully self-contained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 adds real param-level nuance beyond the schema: email is an 'exact email' match by Wave, name_contains is 'applied locally', and fetch_all should be paired with name_contains for complete local filtering. It does not discuss page, page_size, or business_id, but those are already well described in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'List vendors -- the suppliers a business buys from', giving a specific verb and resource and clarifying the domain concept. 'Vendors are read-only... listed and read' also makes clear this is a read/list operation, distinguishing it from any create/update/delete intent and from the sibling wave_get_vendor by verb and scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No alternative tool is referenced, so there is no explicit guidance about when to use wave_list_vendors versus wave_get_vendor or the other list tools. The only usage direction is operational ('pair it with fetch_all=true') rather than selection guidance, and prerequisites such as business_id defaulting are left to the schema.

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 BusinessA
Idempotent

Set the business that later tool calls use when none is given. This is connector state, not a change in Wave. The hosted connector keeps it for the session; the local server keeps it until it restarts (set WAVE_BUSINESS_ID to make it permanent). Passing business_id explicitly always overrides it.

ParametersJSON Schema
NameRequiredDescriptionDefault
business_idYesThe Wave business ID to make the default: the base64 id from wave_list_businesses, or the bare business UUID.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare idempotentHint=true and destructiveHint=false, so safety profile is covered. The description adds valuable context: this is connector state not a Wave change, with precise persistence semantics (session vs local server until restart, WAVE_BUSINESS_ID for permanent). This enriches the annotation profile without contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with zero filler. The purpose is front-loaded, followed by state semantics and override note. Every sentence earns its place and the structure leads with the most actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter state setter with no output schema and informative annotations, the description covers purpose, persistence scope, override behavior, and side-effect-free nature. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the parameter description is already detailed (base64 id from wave_list_businesses or bare UUID). The description adds the override behavior—the parameter always takes precedence over the default—explaining a semantic not present in the schema, which raises value above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Set the business that later tool calls use when none is given.' It clearly differentiates from the sibling get/list tools by positioning itself as a connector-state setter rather than a Wave API operation, making the purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly explains when the tool applies ('when none is given') and lists an alternative behavior—'Passing business_id explicitly always overrides it.' It implies the use case of setting a long-lived default for subsequent calls, though it does not explicitly say 'use this only if you make multiple business-scoped calls' or list non-use conditions. Still clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 20 tool updatesv1.0.8
    • Changedwave_auth_status6 fields changed
      • removedOutput schema / properties / default_business_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / default_business_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / sources_checked / items / properties / path / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / sources_checked / items / properties / path / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / token_source / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / token_source / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedwave_get_account1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_business1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_customer1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_estimate1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_estimate_payment1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_invoice1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_invoice_estimate_settings1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_invoice_payment1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_product1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_sales_tax1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_get_vendor1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_list_accounts1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_list_customers1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_list_estimates1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_list_invoices2 fields changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
      • addedInput schema / properties / source_id
        Added value: +{
        +  "description": "Only invoices created from this source, such as an estimate ID.",
        +  "type": "string"
        +}
    • Changedwave_list_products1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_list_sales_taxes1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_list_vendors1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"Business to operate on. Defaults to the session business set by wave_set_default_business."New value: +"Business to operate on: the base64 id from wave_list_businesses (a bare business UUID is also accepted). Defaults to the business set by wave_set_default_business. When calls may be minutes apart, pass it on every call."
    • Changedwave_set_default_business1 field changed
      • changedInput schema / properties / business_id / description
        Previous value: -"The Wave business ID to make the default."New value: +"The Wave business ID to make the default: the base64 id from wave_list_businesses, or the bare business UUID."
  2. 2 tool updatesv1.0.6
    • Changedwave_auth_status1 field changed
      • changedOutput 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"
        +}
    • Changedwave_list_invoices1 field changed
      • changedInput schema / properties / invoice_number / description
        Previous value: -"Exact invoice number match."New value: +"Substring match applied by Wave: 12 also matches 112 and 120."
  3. 30 tool updatesv1.0.2
    • First observedwave_auth_status
    • First observedwave_get_account
    • First observedwave_get_business
    • First observedwave_get_country
    • First observedwave_get_currency
    • First observedwave_get_customer
    • First observedwave_get_estimate
    • First observedwave_get_estimate_payment
    • First observedwave_get_invoice
    • First observedwave_get_invoice_estimate_settings
    • First observedwave_get_invoice_payment
    • First observedwave_get_oauth_application
    • First observedwave_get_product
    • First observedwave_get_province
    • First observedwave_get_sales_tax
    • First observedwave_get_user
    • First observedwave_get_vendor
    • First observedwave_list_account_subtypes
    • First observedwave_list_account_types
    • First observedwave_list_accounts
    • First observedwave_list_businesses
    • First observedwave_list_countries
    • First observedwave_list_currencies
    • First observedwave_list_customers
    • First observedwave_list_estimates
    • First observedwave_list_invoices
    • First observedwave_list_products
    • First observedwave_list_sales_taxes
    • First observedwave_list_vendors
    • First observedwave_set_default_business

TDQS

A3.6/5.0

Scored across 30 tools

Disambiguation4/5

Most tools are clearly distinct list/get pairs per resource, but wave_list_account_types vs wave_list_account_subtypes are easy to confuse, and the auth-related tools (wave_get_user, wave_get_oauth_application, wave_auth_status) have overlapping purposes. The duplicate wave_get_vendor entry in the listing adds a small amount of ambiguity.

Naming Consistency4/5

The wave_<verb>_<resource> convention is followed for nearly every tool, with list/get used consistently. Minor deviations like wave_auth_status (no verb) and wave_get_invoice_estimate_settings (compound resource name) prevent a perfect score.

Tool Count3/5

30 tools is high for a read-only server, but it does cover many distinct Wave resources with list+get pairs. Several tools could reasonably be consolidated (e.g., currency/country/province lookups, account types/subtypes), making the set feel heavier than necessary.

Completeness2/5

The server is entirely read-only—no create, update, or delete tools exist—yet wave_auth_status says it reports whether write tools are enabled, and wave_list_account_subtypes references a wave_create_account tool that is not present. This leaves major workflows like creating invoices or customers impossible, which is a significant gap for a Wave connector.

Maintenance

ActivityMaintained
ResponsivenessSlow

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    This 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.
    3
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Comprehensive 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
    -
  • A
    license
    A
    quality
    D
    maintenance
    Enables Wave invoicing operations including listing invoices, retrieving details, and generating branded PDFs directly from AI assistants.
    5
    7 npm
    ISC
  • F
    license
    A
    quality
    F
    maintenance
    MCP server for Wave accounting that provides tools for managing chart of accounts, invoices, customers, vendors, products, and reports via the Wave GraphQL API.
    6
    -