The tools
What an agent connected to Walletguide can actually call, how the tools are named, and which ones are marked destructive.
One tool per API route, generated from the same OpenAPI document as the endpoint reference. A tool takes the parameters its route takes.
Naming
<resource>_<action>, from the URL shape:
| Route | Tool |
|---|---|
GET /wallets | wallets_list |
GET /wallets/{walletId}/assets | assets_list |
GET /wallets/{walletId}/assets/{id} | assets_get |
POST /wallets/{walletId}/transactions/search | transactions_search |
POST /wallets/{walletId}/data/netWorthTimeSeries | data_netWorthTimeSeries |
How many
A connection is shown only the tools it can call: what the person ticked on the consent screen, and for an API key what its permissions allow. The numbers below are the catalogue each kind of connection is given, counted from the same filter the server applies (the OAuth scopes against each tool's required scope, and an API key's permissions against each route's), with get_started, which every connection has. A test recomputes them against the server, so the table changes when a route does:
| Connection | Tools |
|---|---|
| OAuth, read only | 68 |
| OAuth, read and write | 152 |
OAuth, read and wallet settings (walletguide:admin) | 83 |
OAuth, read and creating wallets (walletguide:create_wallets) | 69 |
| OAuth, read, write and wallet settings | 166 |
| OAuth, every option | 167 |
| API key, viewer | 68 |
| API key, editor | 152 |
API key naming wallet:manage and integrations:manage | 156 |
That gap is the argument for leaving writes off unless you need them: the read-only catalogue is roughly 17k tokens of context against 40k, spent before the model has read a single number of yours.
A tool the connection cannot call is not shown. It is absent from the catalogue rather than present and refused, so an agent never plans around a tool it cannot use; an OAuth client that calls one anyway gets HTTP 403 insufficient_scope naming the scope to sign in with (sign in). The routes check everything again on every call, and the person's role in the wallet still applies: a viewer's grant with write ticked changes nothing.
No connection is shown the tools that change members (invitations_create, invitations_delete, members_patch, members_delete) or wallets_delete, and no route creates or revokes an API key. Those stay with the person in the app; an agent with wallet settings can ask for them through the access_requests_* tools below. The same connection can read the ids it asks about: invitations_list (the pending invitations) and api_keys_list (the wallet's keys, by name, role and last use, never a secret), both only when the person's own role could manage them.
Annotations
Every tool carries the three MCP hints, always set, and repeats its title as annotations.title:
readOnlyHint— true for every tool that only reads, including everydata_*slice,get_startedandaccess_requests_getdestructiveHint— true for anything that deletes or overwrites dataopenWorldHint— always false; everything is scoped to one wallet
Of the tools that write, only these add data, flip a flag the matching call flips back, or only ask, and carry destructiveHint: false:
assetGroups_create assets_create categories_bulk
categories_create categoryGroups_bulk categoryGroups_create
comments_create comments_like cryptoTransactions_create
files_assign files_create_upload_url files_upload
merchants_create notifications_create notifications_mark_all_read
notifications_mark_read planItems_create scenarioChangeEvents_create
scenarios_create scenarios_duplicate securityTransactions_create
tags_create totalValueUpdates_create transactions_bulk
transactions_bulkAddTags transactions_create transactions_totalBalance
wallets_create integrations_connect_link integrations_sync
access_requests_invite access_requests_change_role
access_requests_remove_member access_requests_create_api_key
access_requests_revoke_invitation access_requests_revoke_api_key
access_requests_delete_walletThe rest are destructive. Updates are on that list because they overwrite the previous values: every *_patch, the wallet image tools, the bulk and intent edits (transactions_bulkUpdate, transactions_bulkEdit, transactions_edit), merchants_applyDefaults, which recategorizes every transaction of the merchant, and the transfer tools that set a pair (transfers_link, transfers_counterAsset, transfers_counterTransaction), since each releases whatever the position was paired with before. Deletes go further and are not reversible: a merge deletes the original of whatever it folds together, transactions_bulkDelete removes many rows at once, transactions_split replaces the existing split parts, and transactions_removeAssetHistory drops an asset's history before a date. A client that asks before running a destructive tool will ask for all of them.
Classification is per route rather than per HTTP method, so a POST that deletes or edits existing records is marked destructive, and a POST that only reads, such as transactions_search, is available to read-only grants.
The ones worth reaching for
data_*— the seventeen slices. Any question about a total, an average or a series belongs here.transactions_search— a POST that only reads; its filters are too structured for a query string. It is available to read-only grants for exactly that reason.files_create_upload_url— how an agent puts a document (a receipt, a statement, a broker's contract note) into the wallet. It returns a single-use link, valid for 15 minutes, and the agent sends the file there itself withcurl -F 'file=@Abrechnung.pdf' '<uploadUrl>', so the bytes never pass through the model's context. Pass the transaction ids when asking for the link and the file arrives attached. A trade in a depot is a security transaction, so its contract note goes insecurityTransactionIds, nottransactionIds. PDFs and PNGs are then read in the background for amount, date and document type.files_upload— the same with the file as base64 inside the call. Fine for a receipt photo of a few KB; a 100 KB PDF is some 76k tokens the model would have to reproduce exactly, so use the link for anything larger.files_assignattaches a file that is already there.files_download— the way back out: a link to the stored document, valid for 15 minutes, which the agent fetches itself withcurl -fsS -o Abrechnung.pdf '<url>'to read the original or attach it to an email.files_getreturns the record and what parsing read from it, not the document. The link carries its own access, so it should not end up anywhere shared.get_started— what this connection may do. For an OAuth grant it names each consent option the person left unticked and the tools that option would add, so an agent missing a tool can tell the person which box to tick when they reconnect; for an API key, the permissions it lacks. It carries no secret and no id, only scope, tool and permission names.wallets_list— the first call an OAuth-connected agent should make, since a grant can reach several wallets and tools need to be told which.access_requests_*— for a connection the person allowed to change wallet settings (walletguide:admin), and for no other: inviting someone (access_requests_invite), changing or removing a member (access_requests_change_role,access_requests_remove_member), withdrawing a pending invitation (access_requests_revoke_invitation), creating or revoking an API key (access_requests_create_api_key,access_requests_revoke_api_key) and deleting the wallet (access_requests_delete_wallet) stay with the person, so the agent can only ask. Each call stores the exact change and returns anapprovalUrlto hand to the person; nothing changes until they approve it in Walletguide, within an hour. The agent asks only for what the person could do themselves (deleting takes the owner), and at most ten requests per wallet wait at a time.access_requests_getreads the outcome:succeeded,failedwith the reason, orrejectedwhen declined or expired. An approved key's secret is shown to the person once, in the browser, and never to the agent. Asking changes nothing, so these carrydestructiveHint: false.
Setting a wallet up
An app connected over OAuth can set a wallet up for the person it acts for, with the permissions they allowed on the consent screen. The order an agent follows is in the agent setup guide: get_started, then wallets_list or wallets_create, then the bank connections, then the setup work.
wallets_createcreates a wallet with the person as its owner, as the app's own onboarding does, or a sample wallet that is deleted after 14 days. Only an app allowed to "Create wallets for you" sees it; API keys cannot create wallets. Send anidempotencyKey, so a retry answers with the wallet already created instead of a second one.integrations_connect_linkreturns a link that opens Walletguide's bank connection dialog, or with anassetIdthe reconnect dialog for a connection inerrororexpired. The person signs in with their bank there; the agent never sees bank credentials.integrations_syncrefreshes the bank connections now instead of at the next scheduled refresh. A refresh already pending is not queued twice.
The two integrations_* tools need integrations:manage: an owner or editor, through an app allowed to manage the wallet's settings, or an API key that holds it.
Results
Every tool answers { result: … }, with the route's response inside, unchanged. The envelope is declared in the output schema and the contents are not — describing every response shape put outputSchema at nearly half of the whole catalogue payload, which is context better spent on the inputs that tell a model what to send.