Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
WAVE_BUSINESS_IDNoDefault business. Otherwise the token's business, or the only non-personal oneauto
WAVE_MCP_DATA_DIRNoWhere imported ledgers are stored (mode 600)~/.local/share/wave-mcp
WAVE_MCP_TOOLSETSNoComma list: context,customers,vendors,products,accounts,sales_taxes,invoices,estimates,payments,transactions,reports,ledger,graphqlall
WAVE_MCP_HTTP_HOSTNoHTTP transport host127.0.0.1
WAVE_MCP_HTTP_PATHNoHTTP transport path/mcp
WAVE_MCP_HTTP_PORTNoHTTP transport port8787
WAVE_MCP_LOG_LEVELNodebug, info, warn, error, silent (stderr only)info
WAVE_MCP_READ_ONLYNoRegister only read toolsoff
WAVE_MCP_HTTP_TOKENNoBearer token for HTTP (credentials file); required off loopback
WAVE_MCP_SCAN_LIMITNoMax records a report or search walks5000
WAVE_MCP_TIMEOUT_MSNoPer request timeout30000
WAVE_MCP_MAX_RETRIESNoPer request max retries3
WAVE_CREDENTIALS_FILENoOverride the credentials file path~/.config/wave-mcp/credentials.env
WAVE_MCP_CACHE_TTL_MSNoCache for scans and reference data; any write clears it120000
WAVE_MCP_ALLOWED_HOSTSNoHost/Origin allow-list for HTTPloopback
WAVE_MCP_MAX_CONCURRENCYNoConcurrent Wave requests (Wave's limits are tight)2
WAVE_MCP_MAX_RESPONSE_CHARSNoHard cap per tool result (trailing list items are dropped, with a note)60000

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

Wave accounting (waveapps.com). Call wave_get_context first; if credentials are missing or expired the user signs in with node /app/bin/wave-mcp.js login in a terminal on f32f40788a38. Full guide: the wave://guide resource.

  • Uses Wave's public GraphQL API, plus Wave's web-app API for transactions.

  • Call wave_get_context first: it shows the businesses this credential reaches and the default one. Every other tool takes an optional businessId.

  • Lists are paginated (page/pageSize, or offset/limit for reports and payments). Ask for small pages, follow nextPage/nextOffset only when needed, and prefer detail="summary".

  • Transactions (live): wave_list_transactions, wave_get_transaction, wave_update_transaction and wave_delete_transaction use Wave's web-app API, which needs a browser session (wave_get_context shows auth.webSession). Sessions end when the user signs out of Wave or they time out; then ask the user to run node /app/bin/wave-mcp.js login in a terminal on f32f40788a38 and paste a request copied from the Wave web app (the command explains how). No restart is needed. Edits send the transaction's sequence, so they never overwrite a newer change.

  • Wave's public API has no reports. wave_run_report computes them from an imported Data Export (wave_import_ledger, a snapshot: check ledger.importedAt) or falls back to invoices and current balances; every report states its basis. wave_list_ledger_transactions searches that snapshot.

  • Never ask the user to paste access tokens, session tokens or curl commands into the chat. The user sets credentials in a terminal on f32f40788a38: node /app/bin/wave-mcp.js login (pastes a request copied from the browser) or node /app/bin/wave-mcp.js secrets set WAVE_ACCESS_TOKEN. You may run node /app/bin/wave-mcp.js check yourself to verify; it prints no secrets.

  • Writes change real books. wave_send_* tools email real customers; confirm recipients and amounts with the user first. wave_create_transaction supports dryRun.

  • Line items on invoices and estimates must reference a product (wave_list_products).

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
prompts
{
  "listChanged": true
}
resources
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
wave_get_contextA

Start here. Returns the signed-in Wave user, how credentials are configured, the businesses this credential reaches, which one is the default, whether writes are enabled, and what the public API cannot do. Works without credentials and then explains how to set them up.

wave_list_businessesA

List the Wave businesses this credential can access (paginated).

wave_get_businessB

Full details of one business: address, contact info, currency, timezone, whether Wave can email invoices for it, and invoice/estimate branding.

wave_get_referenceA

Reference data needed to fill other tools' inputs: currencies, countries, one country with its provinces/states (kind=country, code=CA), a province by code, account types, and account subtypes (needed by wave_create_account). Lists are paginated.

wave_graphql_queryA

Escape hatch for reads the other tools do not shape the way you need: run one GraphQL query (never a mutation) against Wave's public API and get the raw data. Select only the fields you need, and always pass page/pageSize on connections. Schema: the wave://schema resource. Example: query($id: ID!){ business(id:$id){ customers(page:1,pageSize:5){ edges{ node{ id name } } } } }

wave_list_customersA

List customers with their outstanding and overdue balances. Filter by exact email, archive state or modification time; use search for a name substring.

wave_get_customerA

One customer with address, shipping details, notes and outstanding/overdue amounts. Deleted customers are still returned by ID, marked deleted: true.

wave_create_customerC

Create a customer. Only name is required.

wave_update_customerA

Change fields on a customer. Only the fields you pass are changed; nested address/shipping objects replace the existing ones.

wave_delete_customerA

Delete a customer. Wave removes it from lists, but the record stays readable by ID (wave_get_customer shows deleted: true); there is no undelete through the API.

wave_list_vendorsA

List vendors (suppliers). Wave's API cannot create, change or delete vendors, and bills are not exposed.

wave_get_vendorC

One vendor with address and contact details.

wave_list_productsA

List products/services (the items invoice and estimate lines must reference), with price, income/expense accounts and default sales taxes. Active only unless isArchived=true.

wave_get_productB

One product/service with its accounts and default sales taxes.

wave_create_productA

Create a product or service. Give it an incomeAccountId to sell it on invoices, an expenseAccountId to buy it, or both.

wave_update_productB

Change a product/service. defaultSalesTaxIds replaces the whole list.

wave_archive_productA

Archive a product/service so it can no longer be added to new invoices. Past invoices keep it. The API cannot un-archive (web app only).

wave_list_accountsA

List the chart of accounts with current balances. Find transaction accounts with filters: bank accounts are types=[ASSET] subtypes=[CASH_AND_BANK]; credit cards subtypes=[CREDIT_CARD]; expense categories types=[EXPENSE]; income categories types=[INCOME].

wave_get_accountB

One account with type, subtype, normal balance, current balance (account and business currency) and its sequence number.

wave_create_accountA

Add an account to the chart of accounts. The subtype decides its type (see wave_get_reference kind=account_subtypes).

wave_update_accountA

Rename an account or change its description/number. Wave requires the account's current sequence (optimistic locking); it is read automatically when omitted. Pass null for description/displayId to clear them.

wave_archive_accountA

Archive an account (hide it while keeping its history). Wave refuses for system accounts and accounts with a balance. No un-archive through the API.

wave_list_sales_taxesA

List sales taxes with current rate (as a fraction: 0.13 = 13%). detail="full" adds the dated rate history.

wave_get_sales_taxC

One sales tax with its full dated rate history.

wave_create_sales_taxB

Create a sales tax. abbreviation must be unique in the business (max 10 characters).

wave_update_sales_taxA

Change a sales tax. To change the rate, pass rates with an effective date; rates replaces the dated rate list, so include existing entries you want to keep (see wave_get_sales_tax).

wave_archive_sales_taxA

Archive a sales tax so it can no longer be applied. No un-archive through the API.

wave_list_invoicesA

List invoices with totals, amount due and status. Filter by status, customer, invoice date range, modification time, number, currency or the estimate they came from (sourceId). detail="full" adds line items and payments (pages of at most 25).

wave_get_invoiceC

One invoice with line items, taxes, discounts, payments, reminders, PDF and customer view links.

wave_create_invoiceA

Create an invoice for a customer. Created as DRAFT unless status=SAVED (approved). Number, dates, title and notes default to the business's invoice settings. Taxes default per product; pass taxIds:[] for none. Nothing is emailed.

wave_update_invoiceB

Change an invoice. Passing items replaces every line; omit items to keep them. Wave may refuse changes to paid invoices.

wave_clone_invoiceA

Copy an invoice into a new draft.

wave_approve_invoiceA

Approve a draft invoice, which posts it to the books (status SAVED). Does not email it.

wave_send_invoiceA

Email an invoice through Wave to real recipients. Irreversible: confirm recipients first. Requires email sending enabled for the business (wave_get_business emailSendEnabled).

wave_mark_invoice_sentA

Record that an invoice was sent outside Wave (no email goes out).

wave_delete_invoiceB

Permanently delete an invoice.

wave_get_invoice_paymentC

One invoice payment with account, method, currency details and processor info.

wave_record_invoice_paymentA

Record a payment received outside Wave against an invoice (cash, cheque, bank transfer...). paymentAccountId is the account the money went into (usually types=[ASSET] subtypes=[CASH_AND_BANK]). The invoice must be approved, not a draft.

wave_update_invoice_paymentC

Change a manually recorded invoice payment.

wave_delete_invoice_paymentA

Delete a recorded invoice payment; the invoice becomes unpaid by that amount.

wave_send_invoice_payment_receiptB

Email a receipt for an invoice payment to real recipients. Irreversible.

wave_list_estimatesA

List estimates (quotes) with totals, deposit state and status. detail="full" adds line items, deposit payments and acceptance history (pages of at most 25).

wave_get_estimateB

One estimate with items, taxes, discounts, deposit settings and payments, acceptance history and attachments.

wave_create_estimateB

Create a draft estimate (quote). Each line needs a product and a unitPrice. Optionally ask for a deposit. Nothing is emailed.

wave_update_estimateA

Change an estimate. Wave's patch requires customer, status, title, dates, currency and exchange rate; any you omit are copied from the current estimate. Passing items replaces every line.

wave_clone_estimateB

Copy an estimate into a new draft.

wave_approve_estimateA

Approve a draft estimate so it can be sent. Does not email it.

wave_mark_estimate_acceptedC

Record that the customer accepted the estimate.

wave_reset_estimate_acceptanceB

Undo the customer's acceptance so the estimate can be changed or re-accepted.

wave_convert_estimate_to_invoiceA

Create an invoice from an estimate (deposits paid carry over). Returns the new invoiceId.

wave_generate_estimate_pdfB

Generate (or regenerate) the estimate PDF and return its URL.

wave_send_estimate_acceptance_emailA

Email the customer the confirmation that their estimate acceptance was recorded. Irreversible.

wave_delete_estimateB

Permanently delete an estimate.

wave_send_estimateA

Email an estimate through Wave to real recipients. Irreversible: confirm recipients first. The estimate must be approved.

wave_mark_estimate_sentA

Record that an estimate was sent outside Wave (no email goes out).

wave_get_estimate_paymentB

One estimate deposit payment (or refund/void) with its estimate.

wave_record_estimate_depositB

Record a deposit received outside Wave against an estimate. paymentAccountId is where the money went (a CASH_AND_BANK account).

wave_update_estimate_depositC

Change a manually recorded estimate deposit.

wave_delete_estimate_paymentC

Delete a recorded estimate deposit payment.

wave_send_estimate_deposit_receiptB

Email a receipt for an estimate deposit to real recipients. Irreversible.

wave_create_transactionA

Record a bank/credit-card transaction and categorize it, as if entered in Wave's Transactions page. Expense paid by card: anchor {accountId: card, direction: WITHDRAWAL}, line {accountId: expense category, balance: INCREASE}. Sale deposited to bank: anchor {bank, DEPOSIT}, line {income account, INCREASE}. Split across several lines; they must total the anchor. Keep the returned id: wave_get_transaction / wave_list_transactions read it back. Use dryRun=true to validate without writing. Wave does not document de-duplication by externalId: if a call timed out, check the Wave web app before retrying.

wave_create_transactionsA

Create up to 50 money transactions in one request (same shape as wave_create_transaction). Every transaction is checked first (amounts balance; debit and credit sides make sense for the accounts); nothing is sent if any fails. Wave applies the batch as one request and reports input errors by path (transactions.N...).

wave_list_transactionsA

List and search the business's transactions as Wave's Transactions page shows them: bank and card transactions, expenses, deposits, transfers, bill and invoice payments. Live data. Filter by date range, text in the description, bank/card account (accountId), category accounts (categoryIds) or uncategorizedOnly. Cursor pagination: pass nextCursor back as cursor. Each row has the amount, direction, bank/card account, category (or categories when split), vendor, sales tax and review status. IDs work with wave_get_transaction, wave_update_transaction and wave_delete_transaction. Uses Wave's web-app API (unofficial), which needs a web session: if it is missing or expired, the user runs node /app/bin/wave-mcp.js login in a terminal on f32f40788a38.

wave_get_transactionA

One transaction with every line: bank/card side (anchor), category lines with order numbers, amounts, sales tax, vendor/customer, tags, review status, its current sequence, and which fields Wave allows editing. Uses Wave's web-app API (unofficial), which needs a web session: if it is missing or expired, the user runs node /app/bin/wave-mcp.js login in a terminal on f32f40788a38.

wave_update_transactionA

Edit a transaction as in the Wave web app: date, description, notes, reviewed (verified), bank/card account, total amount, category, vendor or customer, or the full set of split lines. Journal entries (journalEntry: true) have no bank side: edit their lines, keeping debits equal to credits. Single-category transactions: use categoryId / vendorId / customerId / amount / salesTax directly. Split transactions: pass lines (every line to keep, with order from wave_get_transaction; omit order to add a line; lines left out are removed). Line amounts include sales tax and must add up to the amount. Reads the transaction first and sends its current sequence, so it never overwrites a newer edit. dryRun=true shows the change without saving. Confirm with the user before changing amounts or accounts. Uses Wave's web-app API (unofficial), which needs a web session: if it is missing or expired, the user runs node /app/bin/wave-mcp.js login in a terminal on f32f40788a38.

wave_delete_transactionA

Delete a transaction, as the web app's Delete does. Changes the books and account balances: confirm with the user first. Wave refuses for transactions that must be removed at their source (e.g. invoice payments, payroll). Uses Wave's web-app API (unofficial), which needs a web session: if it is missing or expired, the user runs node /app/bin/wave-mcp.js login in a terminal on f32f40788a38.

wave_list_paymentsA

List money received: invoice payments and estimate deposits, newest first, with totals. These are the only transaction records Wave's public API can read; bank/card transactions, expenses and money transactions created through the API cannot be listed. Filter by payment date range and customer.

wave_run_reportA

Financial reports computed by this server (Wave's API has no report endpoint). Rows are paginated with limit/offset; totals always cover every row. From the imported ledger (wave_import_ledger; any period, default year to date; balance-sheet style reports as of endDate): profit_and_loss, balance_sheet, cash_flow, trial_balance, account_balances, account_transactions/general_ledger (filter with account or accountId), sales_tax (sales and purchases), aged_payables, purchases_by_vendor. Without a ledger, profit_and_loss, balance_sheet, trial_balance and account_balances fall back to current account balances from the API (as of now only), and sales_tax to invoices. Live from invoices (invoice date range): income_by_customer, sales_by_product, invoice_summary; as of today: aged_receivables; customer_statement needs customerId. Not possible: tax_line, payroll_wage_tax, payroll_benefits_deductions.

wave_import_ledgerA

Load the full transaction journal from Wave's Data Export so transactions can be listed and date-range reports run. Wave's public API cannot read transactions; this is the supported way to get them. Get the file: Wave → Settings → Data Export → Accounting (CSV) → Export; Wave emails a download link (valid 24 hours). Pass the path of the downloaded .zip (or the accounting .csv inside it) on the machine running this server. Replaces any earlier import for the business. Nothing is sent to Wave; the ledger is stored locally (mode 600).

wave_list_ledger_transactionsA

List and search transactions from an imported Data Export snapshot (wave_import_ledger). For live data use wave_list_transactions; this works offline and includes invoices, bills and journal entries: bank and card transactions, expenses, invoices, bills, payments, transfers and journal entries. Filter by date range, account (ID or name), text, customer, vendor, amount, direction or uncategorized only. Newest first by default. Each row has the amount on the bank/card account (or the journal total), the categories used, and the transaction ID for wave_get_ledger_transaction.

wave_get_ledger_transactionA

One transaction from the imported ledger with every journal line (account, debit, credit, line description, sales tax). IDs come from wave_list_ledger_transactions.

wave_list_ledger_accountsA

Accounts that appear in the imported ledger, with their type, where the type came from (Wave chart of accounts or export labels) and line counts. Use the names or IDs to filter wave_list_ledger_transactions and account_transactions reports.

Prompts

Interactive templates invoked by user choice

NameDescription
month_end_reviewReview a month: sales, payments received, receivables and tax collected
chase_overdue_invoicesFind overdue invoices and plan follow-ups
record_expenseRecord a purchase as a categorized money transaction

Resources

Contextual data attached and managed by the client

NameDescription
limitationsGaps in Wave's public API and the reports this server cannot produce
guideUsage guide for agents: first steps, the sign-in command the user runs, tool map and safety rules (the wave-accounting skill)
schemaFull public schema snapshot, for wave_graphql_query (about 135 KB)

TDQS

B3.3/5.0

Scored across 72 tools

Disambiguation3/5

Resources are generally separable (customer/product/account/tax/invoice/estimate), but the set contains many near-parallel or easily confused pairs: wave_list_transactions vs wave_list_ledger_transactions, wave_get_transaction vs wave_get_ledger_transaction, wave_create_transaction vs wave_create_transactions, wave_send_invoice vs wave_mark_invoice_sent, and wave_list_payments vs the transaction listers. The long descriptions do resolve most conflicts (live web-app data vs imported Data Export snapshot), but an agent must read carefully to avoid picking the wrong twin, and wave_graphql_query overlaps with most read tools.

Naming Consistency4/5

Names follow a steady wave_verb_noun pattern with a shared verb vocabulary (list/get/create/update/delete/archive/approve/send/mark), and the invoice/estimate/transaction families mirror each other predictably. Minor deviations exist: wave_create_transactions (plural batch) next to wave_create_transaction, 'record' vs 'create' for payments/deposits, and one-off verbs like run_report, import_ledger, graphql_query.

Tool Count2/5

72 tools is far beyond a comfortable surface for an agent, even for a broad accounting domain. Much of the bulk comes from duplicated CRUD families (live transaction API, imported-ledger reader, and parallel invoice/estimate payment lifecycles), which inflates the count without adding distinct capability.

Completeness5/5

Coverage is unusually thorough: customers, products, accounts, sales taxes, invoices, estimates, invoice payments, estimate deposits, transactions, ledger import, and a large report suite, each with read/create/update/delete-or-archive paths. Remaining gaps (vendor writes, bills, un-archive, payroll reports) are explicitly documented as Wave API limitations rather than omissions, and escape hatches (wave_graphql_query, ledger import) cover the rest.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues