nz-openbank-mcp
Ask an AI assistant about your New Zealand bank accounts via Akahu — read-only by default, with writes gated behind explicit consent.
Accounts: list all connected accounts with masked numbers and balances, fetch one account, or get just its balance.
Transactions: list settled transactions filtered by account, date, category or amount; fetch one or many by id; search descriptions and merchants by text.
Pending items: view unsettled transactions for one account or across all accounts.
Identity: read the Akahu user's profile.
Refresh (write): ask Akahu to re-sync data for one account or all accounts (bypassable via
AKAHU_AUTOMATION_BYPASS).Support (write): report a transaction issue to Akahu (duplicate, enrichment error or suggestion), always with confirmation.
Name check (write): verify a name against the account holder, optionally scoped to one account; needs an extra scope and may be charged.
Safety: 10 of 14 tools are read-only; writes refuse unless
AKAHU_READ_ONLY=false, and each write shows exactly what will be sent before proceeding.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@nz-openbank-mcpshow my account balances and recent transactions"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Ask an AI assistant about your New Zealand bank accounts without handing your
banking credentials to anyone new. nz-openbank-mcp is a Model Context
Protocol server that talks to Akahu, the NZ open-finance
service, using a Personal App you create and control. It runs on your own
machine, starts read-only, and asks before anything changes.
Unofficial. Not affiliated with or endorsed by Akahu or any bank.
Try asking
"What did I spend on groceries last month, and at which shops?"
"Which subscriptions am I paying for, and how much do they cost per year?"
"Show my balances across every account."
"Find every payment to my landlord this year."
"Anything pending that has not settled yet?"
"Compare my eating-out spend in September and October."
Related MCP server: mcp-app-server
Why it is safe to try
Read-only by default | Write tools refuse until you set |
Consent per write | With writes on, every write asks you first and shows exactly what will be sent. |
Local and private | Runs on your machine over stdio and talks only to |
Masked account numbers | Only the bank code, the last four digits and the suffix are shown. |
Small and tested | Thin wrappers over Akahu endpoints, strict typing, and 100% line and branch test coverage enforced in CI. |
PyPI · Releases · Security policy
What it can do
The server exposes 14 tools. Ten only read; four change something and are off until you turn writes on.
Tool | Writes? | Purpose |
| Every connected account, with masked numbers and balances | |
| One account by id | |
| Just the balance of one account | |
| Unsettled transactions for one account | |
| Settled transactions, filtered by account, dates, category or amount (default 100) | |
| One transaction by id | |
| Several transactions in one request | |
| Unsettled transactions across all accounts | |
| Case-insensitive text search over description and merchant; without a start date, the 90 days up to the end date or today (default 50) | |
| The Akahu user's profile | |
| yes | Ask Akahu to fetch fresh data for every account |
| yes | Ask Akahu to fetch fresh data for one account |
| yes | Open a support ticket with Akahu about a transaction |
| yes | Check a name against the account holder; needs an extra scope (see Limits) and may be charged per call |
There are no spending reports, budgets or forecasts built in. The assistant works those out from the transactions, which keeps the server small and easy to audit.
Get your Akahu tokens
Sign in at my.akahu.nz/developers and create a Personal App.
Connect the bank accounts you want the assistant to see.
Copy the App Token (
app_token_...) and User Token (user_token_...).
Treat both like passwords. The install steps below keep them out of project files.
You also need uv. The plugins, the Desktop
Extension and the generic client setup all run the server with uvx, which
fetches the release and a matching Python.
Install
Where you use it | How | Where the tokens live |
Claude Code | Plugin from this repo's marketplace | OS keychain, prompted at install |
Claude Desktop |
| OS keychain, prompted at install |
Codex | Plugin from this repo's marketplace | Environment Codex starts in |
Cursor | Plugin from this repo's marketplace | Cursor plugin settings |
Grok Build | Plugin from this repo's marketplace | Environment Grok starts in |
claude.ai, ChatGPT, grok.com | Self-hosted HTTPS server with OAuth | Your server's environment |
Anything else that speaks MCP |
| Environment of the client |
Every option below starts with AKAHU_READ_ONLY=true and
AKAHU_AUTOMATION_BYPASS=false.
Claude Code
/plugin marketplace add thatskiff33/nz-openbank-mcp
/plugin install nz-openbank-mcp@nz-openbankClaude Code asks for both tokens and the two safety settings. /mcp should
then list the server as connected. To change a setting later, open /plugin,
pick the plugin and choose Configure options. More detail, including
updates and removal, is in plugin/README.md.
Claude Desktop
Download nz-openbank-mcp-X.Y.Z.mcpb from the
latest release
and open it, or use Settings -> Extensions -> Advanced -> Install
Extension. Desktop shows a form for the tokens and settings. To update,
install the newer .mcpb.
The Claude Code plugin does not work in Claude Desktop, because Desktop cannot collect plugin settings yet.
Codex, Grok Build
Neither host can prompt for a plugin secret, so the tokens come from the environment you start the host in. Read them from your OS secret store rather than writing them into a dotfile:
# macOS
export AKAHU_USER_TOKEN="$(security find-generic-password -s akahu-user-token -w)"
export AKAHU_APP_TOKEN="$(security find-generic-password -s akahu-app-token -w)"
# Linux (libsecret)
export AKAHU_USER_TOKEN="$(secret-tool lookup service akahu-user-token)"
export AKAHU_APP_TOKEN="$(secret-tool lookup service akahu-app-token)"In Codex, Grok Build and Cursor, an AKAHU_READ_ONLY or
AKAHU_AUTOMATION_BYPASS already set in the environment the host starts in
overrides the safe defaults.
Codex:
codex plugin marketplace add thatskiff33/nz-openbank-mcp
codex plugin add nz-openbank-mcp@nz-openbank
codex mcp list # shows the akahu serverCodex passes only the four AKAHU_* settings through to the server. Update
with codex plugin marketplace upgrade nz-openbank.
Grok Build:
grok plugin marketplace add thatskiff33/nz-openbank-mcp
grok plugin install nz-openbank-mcp --trust
grok mcp doctor akahu # should report 14 toolsGrok also loads Claude Code plugins. Install in one of the two, not both, or you get two copies of the server.
Cursor
agent plugin marketplace add https://github.com/thatskiff33/nz-openbank-mcpInstall nz-openbank-mcp from Customize (or /plugins in the Cursor
CLI), then enter the two tokens under Plugins -> Configure. Cursor stores
them, not the repo. Leave the safety settings empty to keep the defaults. The
server shows up as plugin-nz-openbank-mcp-akahu. Settings left unset there
fall back to the environment Cursor started in. To try a local checkout, start
the Cursor CLI with --plugin-dir /path/to/nz-openbank-mcp/plugin.
The Add to Cursor button at the top installs a plain MCP entry instead of
the plugin. It reads AKAHU_USER_TOKEN and AKAHU_APP_TOKEN from the
environment Cursor starts in, so set them as shown for Codex above.
Web connectors (claude.ai, ChatGPT, grok.com)
Web assistants can only reach servers on the public internet. Run the
nz-openbank-mcp-http entrypoint behind HTTPS with OAuth, then add a custom
connector in the assistant (for grok.com, at grok.com/connectors) pointing at
the server's /mcp URL. In OAuth mode this server acts as the OAuth
authorization server, Google confirms who is signing in, and only the Google
accounts or Workspace domains you allow get through. Google never sees your
Akahu tokens.
Setup, the Google client, the redirect allowlist and hardening are covered in
docs/public-https-streamable-http.md,
with a systemd example under deploy/linux-systemd/.
grok.com's connector callback,
https://grok.com/connectors-oauth-exchange-code/, is not in the default
redirect list. NZ_OPENBANK_MCP_ALLOWED_REDIRECT_URIS replaces that list, so
include any default entries you still need alongside it.
Any other MCP client
Point the client at this command and give it the settings as environment variables:
uvx nz-openbank-mcp # or pin: uvx --from nz-openbank-mcp==X.Y.Z nz-openbank-mcpexamples/claude_desktop_config.json
shows the shape most JSON-configured clients expect. To use it with Claude
Desktop instead of the extension, merge it into the config file and restart:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Docker
Each release is also published as a multi-arch image (amd64 and arm64), running as a non-root user with read-only mode on:
docker run -i --rm -e AKAHU_USER_TOKEN -e AKAHU_APP_TOKEN ghcr.io/thatskiff33/nz-openbank-mcp-e NAME with no value passes the variable through from your shell, so the
tokens stay out of the command line. For a JSON-configured client, use
"command": "docker" with those arguments. For the HTTP server, run
nz-openbank-mcp-http in the image; see the HTTPS guide.
Settings
The server reads settings from its process environment, plus an env file only
when AKAHU_ENV_FILE names one (process values win). It never picks up a
.env file from the working directory.
Variable | Default | Meaning |
| (required) | Your User Token |
| (required) | Your Personal App's App Token |
|
| Refuse every write tool |
|
| Skip the confirmation prompt for the two refresh tools |
|
| Seconds per Akahu request (1 to 120) |
|
|
|
| (unset) | Absolute path to an env file to load; on Linux and macOS it must be yours (or root's) and not writable by group or others |
|
| Must stay on |
|
| Allow another API host; honoured only from the process environment, never from an env file |
The server logs a warning at startup when a custom API host is in use. Set
AKAHU_ENV_FILE and AKAHU_ALLOW_CUSTOM_BASE_URL only in your own shell or
host config, never in project files of a repository you cloned.
The HTTP entrypoint has its own NZ_OPENBANK_MCP_* settings, listed in
.env.example and the HTTPS guide.
How writes are guarded
Three checks sit in front of every write tool:
Read-only switch. With
AKAHU_READ_ONLY=truethe tool refuses before any request leaves your machine.Confirmation. With writes on, the server asks you to approve each call through your assistant's confirmation prompt. The prompt lists every value that will be sent, such as the full text of a support ticket comment, in quotes with hidden characters made visible. Values over 1,000 characters are refused rather than shortened. Declining or dismissing the prompt cancels the call.
Narrow bypass.
AKAHU_AUTOMATION_BYPASS=trueskips the prompt only foracct_refresh_all_accountsandacct_refresh_account, which just ask Akahu to re-sync. Each skipped prompt is logged, the startup banner lists these tools, and the server will not start with the bypass on while read-only is also on. Support tickets and name checks always ask.
Limits
Akahu Personal Apps cannot reach app-scoped endpoints, so this server has no tools for categories (transactions carry theirs inline), the list of supported banks, payments or webhooks.
id_verify_name needs a scope you enable for your Personal App at
my.akahu.nz/developers; without it Akahu
answers 403.
Pending transactions have no id, can change before they settle, and are
marked "pending": true.
txn_get_transactions and txn_search_transactions read at most 20 pages
of results from Akahu per call. When a range holds more, the result has
"truncated": true; ask again with a narrower date range.
Reads and account refreshes are tried up to three times on network errors and Akahu server errors. Support tickets and name checks are sent once, because a request that timed out may still have reached Akahu. Rate-limit (429) responses are retried for every request.
Dates and amounts
Dates are New Zealand calendar days (Pacific/Auckland), even though Akahu
stores UTC timestamps. A date-only filter such as start_date=2026-10-18
covers that whole NZ day, at either end of a range; a full ISO 8601 timestamp
is passed to Akahu unchanged, and Akahu reads one without an offset as UTC.
Amounts are formatted in each account's currency, so a USD account shows
-USD 9.99. When an account's currency is unknown, currency is null and
amount has no currency symbol (for example -1,234.50); amount_raw is
the same amount as a plain number, rounded to cents. Other date formats are
rejected.
Privacy
NZ account numbers are masked to the bank code, the last four account digits and the suffix. In any other format, every digit but the last four is masked.
Tokens are never logged. Balances and transaction contents are not logged; request paths, which can include Akahu account or transaction ids, are logged with their status.
By default, over stdio, the server's only network traffic is to
api.akahu.io(plusuvxdownloading the package). HTTP mode adds Google for sign-in.Account and date filters are sent to Akahu; category and amount filters are applied after the data arrives. Personal Apps have no finer-grained access control, so the token can read everything you connected.
The privacy policy covers who sees what, and the threat model lists each risk with its mitigation and the risks that remain.
Release files (wheel, sdist and .mcpb) carry GitHub build provenance, and
PyPI uploads come from Trusted Publishing. To check a download:
gh attestation verify nz-openbank-mcp-X.Y.Z.mcpb --repo thatskiff33/nz-openbank-mcpReport vulnerabilities privately through SECURITY.md.
Development
git clone https://github.com/thatskiff33/nz-openbank-mcp.git
cd nz-openbank-mcp
uv sync --extra dev
uv run pytest # 100% line and branch coverage is required
uv run ruff check . && uv run mypy src
FASTMCP_ENV_FILE=/dev/null uv run fastmcp dev src/nz_openbank_mcp/server.pyTo use a local checkout from Claude Code:
claude mcp add nz-openbank --scope user \
--env AKAHU_APP_TOKEN=app_token_... --env AKAHU_USER_TOKEN=user_token_... \
-- uv --directory "$(pwd)" run nz-openbank-mcpThe host plugin manifests are generated. Edit plugin/plugin.base.toml, then
run uv run --no-project python scripts/sync_plugin_manifests.py. Releases
are described in PUBLISHING.md; further operator guides are
in docs/.
Contributions are welcome: see CONTRIBUTING.md, the code of conduct and the changelog. Ask questions in Discussions.
License and disclaimer
Licensed under Apache-2.0; see LICENSE.
Derived from nz-akahu-mcp by
severity1 (Apache-2.0) and substantially modified; see
NOTICE.
Thank you to severity1 for building and open-sourcing the original, which
this project would not exist without.
This software is provided as is. You are responsible for how you use it with your financial data. The maintainers accept no liability for data loss, unauthorised access or financial loss arising from its use.
Available Tools
14 toolsacct_get_accountGet AccountBRead-only
Fetch a single account by id.
Returns the same shape as one entry in list_accounts["accounts"]: id, name, type, status, formatted_account (masked), connection, balance (formatted with currency), currency.
| Name | Required | Description | Default |
|---|---|---|---|
| account_id | Yes | Akahu account id (e.g. "acc_chq_001"). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes the safety profile, so the description's main addition is the field-level return shape and the fact that formatted_account is masked. That is useful context, but because a full output schema exists, restating the fields is largely redundant and no error/not-found behavior is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, front-loaded sentences with the purpose first and the return shape second; nothing is padded. The field enumeration verges on duplicating the output schema, costing a little weight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read tool with annotations and an output schema, the definition covers what an agent needs to invoke it. It is thin on routing versus the balance and pending-transaction siblings, which is the main remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the account_id description already gives the Akahu format with an example. The description adds only 'by id', which is the baseline expectation rather than new meaning, so the standard 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch a single account by id'), which cleanly separates it from acct_list_accounts by cardinality. It does not explicitly name the sibling it displaces, but the singular-vs-list distinction is clear enough from the wording.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the 'single account by id' phrasing; there is no explicit guidance on when to prefer acct_get_account_balance (balance-only) or acct_get_pending_transactions, nor any note on what happens with an unknown id. The agent must infer the routing from sibling names alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
acct_get_account_balanceGet Account BalanceARead-only
Return just the balance for an account. Cheaper than get_account.
Returns {"id", "balance", "available", "currency"} where balance and available are currency-formatted strings (e.g. "$2,543.21" or "USD 100.00") and currency is the ISO 4217 code. All three are None if the account has no balance block; available alone is None if not reported.
| Name | Required | Description | Default |
|---|---|---|---|
| account_id | Yes | Akahu account id. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered; the description adds genuine value by disclosing the exact response keys and the null edge cases (all three None when no balance block, available alone None when unreported). It does not mention auth requirements or rate limits, but for a read-only balance lookup that is a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and the sibling comparison in the first sentence, then a compact return-shape paragraph. Slight redundancy with the existing output schema, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with an output schema and readOnlyHint, the definition covers selection rationale and the non-obvious null semantics. Only authentication context is absent, which is not critical here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single account_id parameter is already documented as an Akahu account id. The description adds no format, sourcing, or validity guidance beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Return just the balance for an account') and immediately contrasts scope with the sibling acct_get_account. An agent can distinguish this from acct_get_account without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Cheaper than get_account' gives a concrete cost-based selection signal for choosing this over the richer sibling. It stops short of explicit when-not guidance (e.g. use get_account when you also need account metadata), but the routing intent is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
acct_get_pending_transactionsGet Account Pending TransactionsARead-only
List pending (not-yet-settled) transactions for one account.
Pending entries affect available balance immediately and can change or vanish before they settle. Returns {"account_id", "transactions": [...]} where each transaction has account_id, date (YYYY-MM-DD, NZ calendar day), description, amount (formatted in the account's currency, e.g. "-$5.50"), amount_raw (number rounded to cents; negative = debit), currency (None if the account reports none, in which case amount has no symbol), type, merchant, category and pending (always true). Pending entries have no id.
| Name | Required | Description | Default |
|---|---|---|---|
| account_id | Yes | Akahu account id. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: pending entries can change or vanish before settling, and pending entries carry no id — both are non-obvious traits that affect how an agent should handle results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, followed by the volatility caveat, then the return shape. Every sentence is informative and there's no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Because an output schema exists, the detailed field-by-field return description is largely redundant, though it clarifies semantics the schema can't (e.g., negative amounts, currency may be None). Missing is explicit positioning relative to txn_get_pending_transactions; otherwise 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter, account_id, and schema description coverage is 100%, so the schema already carries the semantics. The description implies single-account scoping but adds no format, source, or validation guidance for the Akahu account id. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: list pending, not-yet-settled transactions scoped to one account. It's clear what the tool does, but it never distinguishes itself from the near-identically named sibling txn_get_pending_transactions, so an agent can't tell from the description which is account-scoped and which is global.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the parenthetical '(not-yet-settled)' and the note that pending entries affect available balance. There is no explicit 'use this when...' or 'for all-account pending use X instead', and the closest alternative is a sibling with an almost identical name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
acct_list_accountsList AccountsARead-only
List every connected account with masked numbers and formatted balances.
Returns {"accounts": [...]} where each entry has id, name, type (CHECKING/SAVINGS/CREDITCARD/FOREIGN/...), status, formatted_account (masked, e.g. "01-****-***4567-00"), connection (institution name, e.g. "ANZ"), balance (formatted with currency, e.g. "$2,543.21" or "USD 100.00") and currency (ISO 4217 code). balance and currency are None if the account has no balance block.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint already declaring a safe read operation, the description adds useful behavioral context beyond annotations: masked account numbers, formatted balances, field semantics, and the condition under which balance and currency are None. It does not cover ordering or pagination, but those appear irrelevant for a zero-parameter list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then efficiently documents the return shape. Every sentence contributes directly to selecting or using the tool, with no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only list tool, the description gives enough detail about scope, returned fields, masking, formatting, and null behavior. An output schema exists, but the added field notes further help an agent understand the result without being redundant.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is no parameter semantics to explain. A baseline of 4 is appropriate because the schema is empty and the description does not need to compensate for missing parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: “List every connected account,” and specifies the scope and output contents. This clearly distinguishes it from siblings like acct_get_account or acct_get_account_balance, which handle single accounts or balances.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used to retrieve all connected accounts, but it does not explicitly state when to use it instead of alternatives such as acct_get_account or acct_get_account_balance. There are no exclusions or routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
acct_refresh_accountRefresh AccountAIdempotent
Trigger Akahu to fetch fresh data for one specific account.
Rate-limited by your bank. Idempotent within rate-limit windows. Use when you only need to refresh one account (e.g. checking before a payday lookup). Requires write consent unless AKAHU_AUTOMATION_BYPASS=true.
Returns {"success": bool, "message": str | None, "account_id": str}.
| Name | Required | Description | Default |
|---|---|---|---|
| account_id | Yes | Akahu account id to refresh. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses the bank-side rate limit, refines idempotency as "within rate-limit windows" (consistent with idempotentHint=true, not contradicting it), and flags the write-consent requirement plus the AKAHU_AUTOMATION_BYPASS escape hatch. Also states the response shape, which is exactly the operational context an agent needs before calling a non-readOnly tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action, then constraints (rate limit, idempotency, consent), then the return shape. Every sentence carries a distinct, useful fact with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still previews the return fields and covers the two things that most often break this call in practice: bank rate limiting and the consent/bypass requirement. Nothing material is missing for a one-parameter mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single account_id parameter, so the baseline is 3. The description only restates "one specific account" and adds no format, prefix, or ID-source detail beyond what the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ("trigger Akahu to fetch fresh data") plus a scoped resource ("one specific account"), which implicitly separates it from the sibling acct_refresh_all_accounts. An agent can tell exactly what the call does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use when you only need to refresh one account (e.g. checking before a payday lookup)" gives a concrete selection condition, and the single-account scoping effectively steers agents away from the bulk-refresh sibling. It stops short of naming that sibling explicitly, so it is clear context rather than full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
acct_refresh_all_accountsRefresh All AccountsAIdempotent
Trigger Akahu to fetch fresh data for every connected account.
Rate-limited by your bank. Idempotent within rate-limit windows. Use before a query that needs the freshest balance or transaction data. Requires write consent unless AKAHU_AUTOMATION_BYPASS=true. Returns {"success": bool, "message": str | None}.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that it is rate-limited by the bank, that idempotency holds only within rate-limit windows, that write consent is required unless AKAHU_AUTOMATION_BYPASS=true, and the return shape. These are non-obvious operational facts an agent cannot get from readOnlyHint/idempotentHint alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action, then constraints, then the return shape — every sentence carries signal. The explicit return signature is slightly redundant since an output schema exists, but it is brief enough not to be waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter mutation-ish trigger, the description covers the action, timing guidance, rate-limit behavior, auth/consent requirement, and failure surface. Nothing an agent needs in order to call it correctly and interpret the result is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the baseline is 4. Nothing in the description needs to explain inputs, and it correctly spends no words doing so.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Trigger Akahu to fetch fresh data') and an explicit scope ('every connected account'), which cleanly separates it from the sibling acct_refresh_account that targets a single account. No schema inspection needed to know what it does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use before a query that needs the freshest balance or transaction data' gives a clear triggering condition. What's missing is an explicit when-not or a named alternative (e.g. use acct_refresh_account for one account), though the 'every connected account' scope makes the split inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
id_get_meGet MeARead-only
Return identity/profile data for the connected Akahu user.
Returns {"id": str, "email": str | None, "name": str | None}, where name joins the profile's first_name and last_name when present.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes that this is a safe read operation. The description adds useful detail about the returned identity fields and how name is assembled, but it does not cover auth requirements, error behavior, or other operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with the core action front-loaded and no wasted text. The return-value detail is compact and useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the empty input schema, existing output schema, and read-only annotation, the description is nearly complete for this simple tool. The main remaining gap is the lack of explicit sibling differentiation from id_verify_name.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is no parameter semantics for the description to document. The baseline for zero-parameter tools applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: return identity/profile data for the connected Akahu user. It is clear what the tool does, but it does not explicitly differentiate itself from the sibling id_verify_name tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the phrase 'for the connected Akahu user,' but the description gives no explicit when-to-use guidance or comparison with alternatives such as id_verify_name. It is adequate for a simple no-parameter identity lookup but leaves routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
id_verify_nameVerify NameA
Verify a name against the account holder via Akahu's identity check.
If account_id is provided, the check is scoped to that one account (POST /verify/name/{account_id}); otherwise Akahu matches against every identity source the user has connected (POST /verify/name).
Requires the appropriate Personal-App scope grant in your Akahu portal; without it Akahu returns 403 Forbidden. May incur a per-call charge from your bank. Always elicits user confirmation (not bypass-eligible).
Returns {"success": bool, "item": dict | None, "message": str | None} where item is Akahu's match-result envelope (shape documented at https://developers.akahu.nz/docs/enduring-verify-name).
| Name | Required | Description | Default |
|---|---|---|---|
| initials | No | Optional list of initial strings (e.g. ["J", "R"]). | |
| account_id | No | Optional account scope; omit to check all sources. | |
| given_name | No | Optional first name. | |
| family_name | Yes | Required. Surname to verify. | |
| middle_name | No | Optional middle name. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavioral context beyond the annotations: the required Personal-App scope grant, the 403 Forbidden failure mode, possible per-call bank charges, and mandatory user confirmation that cannot be bypassed. These are exactly the operational risks an agent needs before invoking a verification call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and scoping rule, followed by auth, cost, confirmation, and return details. It is efficient overall, though the explicit return-shape explanation is somewhat redundant given that an output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a verification tool with real-world cost and auth requirements, the description covers what it does, how scoping works, permission requirements, failure behavior, confirmation requirements, and return structure. An agent has enough information to invoke it correctly or recognize when it cannot.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters, including account_id's optional scoping behavior. The description reinforces how account_id changes the endpoint used, but does not add much parameter-level meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: verify a name against the account holder via Akahu's identity check. This clearly distinguishes it from all sibling tools, which handle accounts, transactions, or the user's own identity profile rather than name verification.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the key scoping decision: if account_id is provided, the check is limited to that account; otherwise Akahu checks every connected identity source. It also notes the required portal scope grant. It stops short of explicitly comparing against sibling tools such as id_get_me, but there is no direct alternative for name verification.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
txn_get_pending_transactionsGet Pending TransactionsARead-only
List all pending (not-yet-settled) transactions across the user's accounts.
Pending transactions affect available balance immediately but do not appear in get_transactions until they settle, and they can change or vanish before then. Returns {"transactions": [...]} where each entry has account_id, date (YYYY-MM-DD, NZ calendar day), description, amount (formatted in the account's currency), amount_raw, currency (None if unknown), type, merchant, category and pending (always true). Pending entries have no id.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although annotations already declare readOnlyHint=true, the description adds substantial behavioral context beyond that: pending entries affect available balance immediately, can change or vanish, are not returned by get_transactions until settlement, and lack an id. It also describes the response shape and key field semantics, which is valuable given the dynamic nature of pending transactions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and stays reasonably concise. It does enumerate return fields even though an output schema exists, which is somewhat redundant, but the added notes about pending behavior and missing id are useful rather than wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the zero-parameter schema, readOnly annotation, and existing output schema, the description is complete enough for an agent to call the tool correctly. It covers the key behavioral caveats around pending transactions and return semantics without leaving material gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there are no parameter semantics to explain; this matches the baseline of 4 for zero-parameter tools. The schema is empty with additionalProperties false, and the description does not need to add parameter detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: list all pending, not-yet-settled transactions across the user's accounts. It also distinguishes this tool from get_transactions by explaining that pending entries do not appear there until settlement, and the 'across the user's accounts' phrasing implicitly contrasts with the account-scoped sibling. An agent can identify the tool's role without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: pending transactions affect available balance immediately but are absent from get_transactions until they settle, and may change or disappear. However, it does not explicitly name acct_get_pending_transactions as the per-account alternative 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.
txn_get_transactionGet TransactionARead-only
Fetch one settled transaction by id.
Returns the same shape as one entry in get_transactions["transactions"].
| Name | Required | Description | Default |
|---|---|---|---|
| transaction_id | Yes | Akahu transaction id (e.g. "txn_a1b2c3"). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already declares the safe-read profile, and the output schema covers the return value, so the remaining burden is light. The description does add meaningful context: it says the lookup is restricted to settled transactions, implying pending ones are excluded, but it does not say what happens for an unknown id or whether pending ids error out.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the identifying scope ('one settled transaction by id') front-loaded. The second sentence carries non-redundant information linking the return shape to a sibling tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-record read with an output schema and one fully documented parameter, the description covers what to expect from the response shape. Minor gaps remain around not-found behavior and the settled/pending boundary, but nothing critical to a correct call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter already documents the Akahu transaction id format with an example. The description adds no syntax, format, or edge-case meaning beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch one settled transaction by id'), and the singular plus 'settled' qualifier distinguishes it from the plural list and pending siblings. It stops short of naming those siblings explicitly, so an agent must infer the contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by 'by id' and 'one' – the agent can infer this is the single-record lookup when an id is already known. No alternative is named (txn_get_transactions_by_ids, txn_search_transactions), and no when-not guidance is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
txn_get_transactionsGet TransactionsARead-only
List settled transactions with optional filters.
Returns {"transactions": [...], "truncated": bool} where each entry has id, account_id, date (YYYY-MM-DD, NZ calendar day), description, amount (formatted in the account's currency, e.g. "-$12.50" or "-USD 9.99"), amount_raw (number rounded to cents; negative = debit), currency (ISO code, or None when the account's currency is unknown, in which case amount has no symbol, e.g. "-1,234.50"), type, merchant (str | None), category (str | None). truncated is true when the scan stopped at the 20-page cap before reaching the end of the range; narrow the dates and call again.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max items returned, 1 to 500 (default 100). | |
| category | No | Exact category name (applied after fetching). | |
| end_date | No | Latest NZ day as YYYY-MM-DD (inclusive), or an ISO 8601 timestamp passed to Akahu as an inclusive upper bound (UTC if it has no offset). | |
| account_id | No | Scope to one account (sent to Akahu). | |
| max_amount | No | Upper bound on signed amount (applied after fetching). | |
| min_amount | No | Lower bound on signed amount (applied after fetching; negatives are debits). | |
| start_date | No | Earliest NZ day as YYYY-MM-DD (inclusive), or an ISO 8601 timestamp passed to Akahu as an exclusive lower bound (UTC if it has no offset). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only readOnlyHint=true in annotations, the description carries the behavioral load and does it well: exact return envelope, per-field semantics, the 20-page scan cap, and what truncated=true means plus the remedy. This is exactly the operational detail annotations cannot supply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in one line, then the return contract is packed into a single tight block. It is dense but nearly every clause conveys a distinct fact about format or edge cases; only the field enumeration borders on redundancy given an output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter read-only listing tool, an agent has everything needed to call it and interpret the result, including truncation handling. The per-field restatement is partly duplicative since an output schema is present, but the truncation and currency-unknown cases justify it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description earns above that by clarifying signed-amount semantics (negative = debit), the account-currency formatting variants, and the NZ-calendar-day convention that underpins the date filters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ("List settled transactions") plus scope ("optional filters"). The word "settled" quietly distinguishes it from the pending-transaction siblings, though it never names them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: "settled" excludes pending, and "narrow the dates and call again" gives recovery guidance for truncation. However, it never tells an agent when to prefer txn_search_transactions or txn_get_transactions_by_ids over this tool, so sibling routing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
txn_get_transactions_by_idsGet Transactions By IDsARead-only
Batch-fetch settled transactions by their ids in one request.
Useful when you have a list of transaction ids (e.g. from a prior query) and want to inspect them together. Returns {"transactions": [...]} with the same per-entry shape as get_transactions.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | List of Akahu transaction ids. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already covers the safety profile, and the description adds real value on top: it discloses the batch semantics, the "settled" filter, and the return envelope shape with a cross-reference to get_transactions so per-entry shape is inferable. It omits behavior for unknown/nonexistent ids and any batch-size cap, which would be the remaining behavioral gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, with the core action front-loaded and the usage hint immediately after. The return-shape sentence is partially redundant with the output schema, which is the only mild inefficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with an output schema and a readOnly annotation, the description covers what it does, when to use it, and what comes back. Only limits (max ids, unknown-id handling, result ordering) are absent, which is a modest but real gap for a batch API.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single `ids` array is documented as "List of Akahu transaction ids," so the schema does the heavy lifting. The description only restates the list-of-ids idea and adds no detail on ordering, duplicates, or a maximum batch length — baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("batch-fetch settled transactions by their ids") with the scoping qualifier "settled" and "in one request," which distinguishes it from txn_get_transaction (single), txn_get_transactions (list/filter), and txn_get_pending_transactions. An agent can route to it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Useful when you have a list of transaction ids (e.g. from a prior query) and want to inspect them together" gives a concrete triggering condition and a common source of the ids. It stops short of naming the alternatives it supersedes (e.g. looping txn_get_transaction vs. txn_search_transactions), so it is clear context without explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
txn_report_transaction_issueReport Transaction IssueA
Submit a support ticket about a transaction to Akahu staff.
Sends a ticket to a human at Akahu support. Always elicits user confirmation (not bypass-eligible); the prompt shows every value in the ticket, including the comment. Missing required values are collected before that prompt. issue_type validation:
"DUPLICATE": requires other_transaction_id (the paired duplicate).
"ENRICHMENT_ERROR": requires fields=[...] listing affected field names.
"ENRICHMENT_SUGGESTION": requires fields=[...] listing suggested fields.
Returns {"success": bool, "message": str | None}.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Affected field names; required for ENRICHMENT_* issue types. Omitted -> the user is prompted to supply them via elicitation. | |
| comment | No | Optional free-text context for the support agent, up to 1,000 characters. | |
| issue_type | Yes | One of "DUPLICATE", "ENRICHMENT_ERROR", "ENRICHMENT_SUGGESTION". | |
| transaction_id | Yes | Akahu transaction id the ticket is about. | |
| other_transaction_id | No | Paired transaction id; required for DUPLICATE. Omitted -> the user is prompted to supply it via elicitation. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavioral detail beyond annotations: it always elicits user confirmation, is not bypass-eligible, shows every ticket value including the comment, and collects missing required values before the confirmation prompt. It also discloses the return shape, while annotations already cover readOnly=false and destructive=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and appropriately sized for a tool with conditional validation and confirmation behavior. There is minor redundancy between 'Submit a support ticket about a transaction to Akahu staff' and 'Sends a ticket to a human at Akahu support.'
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's mutation/support complexity, rich annotations, complete schema coverage, and output schema, the description is complete. It covers confirmation behavior, conditional issue_type validation, elicitation of missing values, and return shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents parameter meanings and conditional requirements. The description reinforces the issue_type-to-required-field mapping, but mostly repeats what the schema already states rather than adding new syntax or format details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: submitting a support ticket about a transaction to Akahu staff. It clearly distinguishes this from sibling transaction retrieval tools, which only fetch transaction data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context makes clear when to use it: reporting a transaction issue to human support. It does not explicitly name when not to use it or compare against alternatives, but sibling tools are all retrieval/account operations rather than support-reporting alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
txn_search_transactionsSearch TransactionsARead-only
Case-insensitive substring search across description and merchant name.
Searches settled transactions in a date window until limit matches are
found. Without start_date the window is the 90 NZ days ending on end_date,
or ending today. Use for free-text lookups; prefer get_transactions when
filtering by account or amount. Returns {"transactions": [...],
"truncated": bool} with the same shape and meaning as get_transactions.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max matches returned, 1 to 500 (default 50). | |
| query | Yes | Substring to match (case-insensitive). | |
| end_date | No | Latest NZ day as YYYY-MM-DD (inclusive) or an ISO 8601 timestamp (UTC if it has no offset); defaults to no upper bound. | |
| start_date | No | Earliest NZ day as YYYY-MM-DD (inclusive) or an ISO 8601 timestamp (UTC if it has no offset); defaults to 90 days back. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint already covers the safety profile, so the description earns credit for adding substantive behavior: only settled transactions are searched (pending ones excluded despite sibling pending tools), matching stops once `limit` is reached, and the default window is 90 NZ days ending today. It stops short of covering performance or ordering of results, so it is not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the matching semantics, then the date-window behavior, then the usage routing and return shape. Every sentence carries information an agent needs; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still names the return shape and its equivalence to get_transactions, which is useful for chaining. Combined with the settled-only constraint and window defaults, an agent can call this correctly without further reading.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all four parameters are already documented, including the 90-day default and the 1-500 range on limit. The description restates the default window rather than adding new syntax or format detail, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: case-insensitive substring search across description and merchant name, restricted to settled transactions. The scope plus the explicit contrast with get_transactions lets an agent tell the two apart without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use for free-text lookups; prefer get_transactions when filtering by account or amount" gives both the when-to-use and the named alternative with the condition that selects it. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.6- Changed
txn_get_transactions9 fields changed- changed
Input schema / properties / account_id / descriptionPrevious value: -"Scope to one account (server-side filter)."New value: +"Scope to one account (sent to Akahu)." - changed
Input schema / properties / category / descriptionPrevious value: -"Exact Category.name match (client-side filter)."New value: +"Exact category name (applied after fetching)." - changed
Input schema / properties / end_date / descriptionPrevious value: -"ISO 8601 timestamp upper bound (server-side filter)."New value: +"Latest NZ day as YYYY-MM-DD (inclusive), or an ISO 8601\ntimestamp passed to Akahu as an inclusive upper bound (UTC if it\nhas no offset)." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max items returned (default 100)."New value: +"Max items returned, 1 to 500 (default 100)." - added
Input schema / properties / limit / maximumAdded value: +500 - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / max_amount / descriptionPrevious value: -"Upper bound on signed amount (client-side)."New value: +"Upper bound on signed amount (applied after fetching)." - changed
Input schema / properties / min_amount / descriptionPrevious value: -"Lower bound on signed amount (client-side; negatives are debits)."New value: +"Lower bound on signed amount (applied after fetching; negatives are debits)." - changed
Input schema / properties / start_date / descriptionPrevious value: -"ISO 8601 timestamp lower bound (server-side filter)."New value: +"Earliest NZ day as YYYY-MM-DD (inclusive), or an ISO 8601\ntimestamp passed to Akahu as an exclusive lower bound (UTC if it\nhas no offset)."
- Changed
txn_report_transaction_issue3 fields changed- changed
Input schema / properties / comment / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "maxLength": 1000, + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / comment / descriptionPrevious value: -"Optional free-text context for the support agent."New value: +"Optional free-text context for the support agent, up to\n1,000 characters." - added
Input schema / properties / issue_type / enumAdded value: +[ + "DUPLICATE", + "ENRICHMENT_ERROR", + "ENRICHMENT_SUGGESTION" +]
- Changed
txn_search_transactions5 fields changed- added
Input schema / properties / end_dateAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Latest NZ day as YYYY-MM-DD (inclusive) or an ISO 8601\ntimestamp (UTC if it has no offset); defaults to no upper bound." +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Max matches returned (default 50)."New value: +"Max matches returned, 1 to 500 (default 50)." - added
Input schema / properties / limit / maximumAdded value: +500 - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / start_dateAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Earliest NZ day as YYYY-MM-DD (inclusive) or an ISO 8601\ntimestamp (UTC if it has no offset); defaults to 90 days back." +}
14 tool updates
v0.1.0- First observed
acct_get_account - First observed
acct_get_account_balance - First observed
acct_get_pending_transactions - First observed
acct_list_accounts - First observed
acct_refresh_account - First observed
acct_refresh_all_accounts - First observed
id_get_me - First observed
id_verify_name - First observed
txn_get_pending_transactions - First observed
txn_get_transaction - First observed
txn_get_transactions - First observed
txn_get_transactions_by_ids - First observed
txn_report_transaction_issue - First observed
txn_search_transactions
TDQS
Scored across 14 tools
Tools are separated by resource (accounts vs transactions vs identity) and action, with the main overlaps being the pending-transaction pair (acct_get_pending_transactions per account vs txn_get_pending_transactions across all) and txn_get_transactions vs txn_search_transactions. Descriptions explicitly disambiguate these cases (e.g. 'prefer get_transactions when filtering by account or amount'), so misselection is unlikely but possible. acct_get_account, acct_get_account_balance and acct_list_accounts are clearly distinguished by scope and cost.
A single predictable pattern is used throughout: a short domain prefix (acct_/txn_/id_) followed by verb_noun (list_accounts, get_account, get_transactions, search_transactions, report_transaction_issue). Singular/plural distinctions (get_transaction vs get_transactions) are used meaningfully, and no naming style is mixed.
14 tools is well within the ideal range for a banking data aggregation API, and each tool earns its place: accounts, settled transactions, pending transactions, identity, refresh, and support/verification actions. The refresh pair (all vs one account) and the get/balance split are justified by differing cost and rate-limit behavior.
The surface covers the full read lifecycle for accounts and transactions (list, get, balance, pending, batch, search) plus identity, name verification, data refresh, and issue reporting. Minor gaps remain: there is no way to enumerate connected institutions/connections or consent state, and no pagination/offset control beyond the internal 20-page cap. These are workable around, but an agent cannot fully audit its data sources.
Maintenance
Related MCP Connectors
Managed MCP gateway with OAuth, per-agent permissions, shared accounts and activity logs.
Your OpenWork org's skills, plugins, workflows, and connections through one OAuth MCP URL.
Read-only access to your bank, investment, and crypto accounts: balances, transactions, holdings.
OAuth MCP for Google, Meta, X, LinkedIn, Reddit, TikTok, GSC, GA4, WordPress and GHL.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables secure, read-only access to personal European bank accounts through Enable Banking and Cloudflare Workers, allowing MCP clients to list accounts, retrieve balances, search transactions, and summarize cash flow.2MIT
- AlicenseNot gradedqualityAmaintenanceEnables existing apps to expose their users and data to external AI agents via MCP with OAuth 2.1 authentication and scoped tools.46 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to sign in with OAuth 2.1 and read a user's WHOOP recovery, sleep, strain, and workout data through read-only tools, while also receiving and forwarding signed WHOOP webhooks to your endpoints.17 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to securely connect to a personal HEY account through OAuth and perform scoped email, search, contact, calendar, todo, thread, and sending operations.MIT