Satchel MCP docs
MCP tools reference

Tools overview

The satchel_ naming convention, output shapes, and MCP Apps widgets.

Satchel MCP exposes 7 tools: 6 read tools plus one write tool. All 7 names carry a satchel_ prefix — satchel_get_balance, satchel_move_money, and so on.

Why the satchel_ prefix

Most MCP clients let you connect several MCP servers at once. Without a namespace, tool names collide — more than one server might reasonably want to expose a list_accounts or get_balance tool. Prefixing every tool with satchel_ means Satchel MCP composes safely alongside any other MCP server a user has connected, with no naming conflicts and no ambiguity in the assistant's tool-choice reasoning about which server a call is going to.

The 6 read tools + 1 write tool

ToolReads / writesAvailable on
satchel_list_accountsreadstdio, remote
satchel_get_balancereadstdio, remote
satchel_list_cardsreadstdio, remote
satchel_list_transactionsreadstdio, remote
satchel_get_transactionreadstdio, remote
satchel_financial_summaryreadstdio, remote
satchel_move_moneywritestdio only

The 6 read tools are implemented once, in a module shared between the local stdio server and the hosted remote server — not forked or copy-pasted between them. That is a deliberate architectural choice: the exact same handler code answers a satchel_get_balance call whether it arrived over stdio or over the remote HTTP endpoint, so there is no second copy of the business logic to let drift out of sync.

satchel_move_money is stdio-only: the hosted remote server never registers it, at all — not gated by a flag, simply absent from that server's tool list. See Authentication & security for why, and the move-money reference for what it does where it is available.

Output shape: text + structuredContent

Every tool returns two things in its result:

  • content — human-readable text (formatted tables, summaries, currency-formatted amounts) that an assistant can relay directly to a user without further processing;
  • structuredContent — the same information as typed, machine-readable JSON, validated against a declared outputSchema.

Text-only MCP clients work unchanged from structuredContent; clients that support the richer MCP Apps widgets described below use it to drive the same data into a visual component instead of parsing text.

A tool that fails returns isError: true with an explanatory content message — written for the agent reading it, stating what failed and the most likely next step (for example, a 401 explains that authentication was rejected and to check the configured credentials, rather than echoing a bare upstream error code).

Money is always unsigned; direction is a separate field

Every amount Satchel MCP returns is unsigned123.45, never -123.45. Direction (money in vs. money out) is carried in its own field instead: direction: "in" | "out" in satchel_list_transactions, derived from the underlying API's payment_role (SENDER = out, RECIPIENT = in). The human-readable text form still shows a leading + or - for readability, but that sign is derived from the role field, never read from the numeric amount. See Architecture for why this is load-bearing throughout the codebase.

Derived data is labeled as derived

satchel_financial_summary's optional merchant grouping and subscription detection are heuristics — matching on transaction narrative text only when satchel:narratives is granted, not authoritative categories from the institution. Its structuredContent.derived field is true specifically to flag this: an assistant relaying the summary should treat "top merchants" and "detected subscriptions" as inferred, not as ground truth from the institution.

Widgets (MCP Apps / ui:// HTML)

satchel_financial_summary and satchel_move_money each advertise a rich HTML widget via _meta, following the MCP Apps proposal (SEP-1865) — a ui:// resource URI pointing at self-contained widget HTML, rendered by clients that support it inside a sandboxed iframe.

This is strictly additive. Every tool always also returns content (text) and structuredContent regardless of whether the client renders a widget — a tool never depends on its widget existing. A text-only client (for example Claude Code) works exactly the same as it would if widgets didn't exist at all; a client with UI support gets a nicer rendering of the same underlying data (sorted merchant bars and a money in/out/net readout for the summary; a confirmation/receipt view for a transfer). On the hosted remote server, the satchel_financial_summary widget HTML is currently omitted — the tool still returns full text and structuredContent there, just without the optional rich rendering.

On this page