Skip to main content
Glama
ninetails-io

gnucash-mcp

create_transactions

Create many double-entry transactions atomically from a TSV table, with validation, duplicate detection, and dry-run support.

Instructions

Create MANY transactions in one atomic command (bulk entry).

INPUT — transactions is a TSV block: a header row, then one row per transaction. The HEADER DECLARES THE LAYOUT. Base form: splits are (amount, account) column PAIRS, repeated as wide as a transaction needs::

ref<TAB>date<TAB>description<TAB>amt1<TAB>acct1<TAB>amt2<TAB>acct2...
1<TAB>2026-05-21<TAB>Gas<TAB>-54.19<TAB>Assets:Checking<TAB>54.19<TAB>Expenses:Auto:Fuel

Two opt-in extensions, each activated by naming it in the header (legacy headers parse exactly as before):

  • PER-SPLIT MEMOS — declare memo split columns; splits become (amount, account, memo) TRIPLES::

    ref<TAB>date<TAB>description<TAB>amt1<TAB>acct1<TAB>memo1<TAB>amt2<TAB>acct2<TAB>memo2
    1<TAB>2026-05-21<TAB>Gas<TAB>-54.19<TAB>Assets:Checking<TAB>card #4471<TAB>54.19<TAB>Expenses:Auto:Fuel

    Empty memo cells mid-row keep their tabs; a row may simply END once its last split's amount and account are present (trailing memo/qty cells are read as empty — no placeholder tabs needed, as above).

  • PER-TRANSACTION NOTES — declare a notes column directly after description::

    ref<TAB>date<TAB>description<TAB>notes<TAB>amt1<TAB>acct1...

    FIELD TARGETING for statement entry: description is the clean name; notes is what the purchase WAS — interpreted, not transcribed — and is what humans see in GnuCash's double-line register; the bank leg's memo is where the RAW statement line goes (provenance, visible only in expanded split view). Prefer filling notes whenever the description alone doesn't tell the story.

  • PER-TRANSACTION CURRENCY — declare a cur column after description (before or after notes); an ISO code cell sets THAT ROW's transaction currency, an empty cell keeps the book default::

    ref<TAB>date<TAB>description<TAB>cur<TAB>amt1<TAB>acct1<TAB>amt2<TAB>acct2
    1<TAB>2026-07-15<TAB>USD Card Payment<TAB>USD<TAB>-500<TAB>Assets:USD Checking<TAB>500<TAB>Liabilities:USD Card

    With cur, the row's amt cells are in that currency and must balance in it. Use it when NO leg is in the book's default currency (a USD-to-USD transfer inside a CNY book needs no invented CNY values and no qty). Splits on accounts of any OTHER commodity still need qty. The currency must already exist in the book, and cur cannot combine with an auto-fill row.

  • PER-SPLIT QUANTITY — declare qty split columns for splits whose ACCOUNT commodity differs from the book default (investment shares, foreign-currency accounts)::

    ref<TAB>date<TAB>description<TAB>amt1<TAB>acct1<TAB>qty1<TAB>amt2<TAB>acct2<TAB>qty2
    1<TAB>2026-07-01<TAB>VFIFX Purchase<TAB>-505.17<TAB>Assets:Checking<TAB><TAB>505.17<TAB>Assets:401k:VFIFX<TAB>7.7936

    amount stays in the book's default currency (the transaction currency — batch never changes that); qty is the amount in the account's own commodity. An EMPTY qty cell means the account uses the default currency (quantity == amount). A non-default-commodity account with an empty qty rejects that row.

  • PER-SPLIT ACTION — declare act split columns for GnuCash's typed movement tag ("Buy"/"Sell"/"Dividend" on investment legs — desktop convention; "Wire"/"ATM" on bank legs). Same group mechanics as memo/qty; empty cells skip it. Rarely needed for plain spending.

All extensions combine; when several split fields are declared, the header's FIRST group fixes their order (e.g. amt, acct, memo, qty).

AUTO-FILL — a row with NO split cells at all (ends right after description/notes) reproduces the most recent transaction with the same description — splits, memos, and quantities included — exactly like calling create_transaction without splits::

1<TAB>2026-07-01<TAB>Rent
2<TAB>2026-07-01<TAB>Netflix

Auto-filled rows are marked auto_filled_from:<guid> in the results reason column; a row whose description matches nothing rejects ("no matching transaction to auto-fill from"). Use dry_run=true to preview what a batch of auto-fills would book. Perfect for recurring monthly entries. Transaction notes are NOT copied from the source (notes are often time-bound — "first appearance, investigate" must not replicate); supply a notes cell when the new instance needs one.

  • ref: YOUR correlation key per row (e.g. 1, 2, 3), unique within the batch. It is echoed back so you can match results to what you sent; the server never reuses or interprets it.

  • date: ISO YYYY-MM-DD. amount/qty: decimal STRINGS (never raw JSON numbers). Each transaction needs

    =2 splits balancing to zero in the default currency. Rows may differ in width (2 splits vs 3).

  • The transaction currency is always the book default — for a transaction denominated in another currency, use create_transaction with its currency parameter.

BEHAVIOR — one book-open, one atomic save:

  • A STRUCTURAL error (unbalanced, unknown account, bad pairs) aborts the WHOLE batch by default; nothing is written. Pass on_error="skip" to write the good rows and reject only the bad ones.

  • A duplicate rejects ONLY its row; force=True overrides all blocking duplicates (as in create_transaction). dry_run=True validates + screens without writing.

OUTPUT — a JSON envelope of two TSV tables joined by ref:

  • results (always): ref, status, txn_guid, dup_count, reason. status is created | rejected | would_create (dry_run); reason is a code like duplicate_detected or the validation message.

  • duplicates (only when matches exist): ref, confidence, guid, date, amount, description, signals — the columns create_transaction emits, keyed back to the offending ref. Σ(dup_count) equals the duplicates row count.

Args: transactions: The TSV block described above. force: Override ALL blocking (HIGH) duplicates this batch. dry_run: Validate + screen, write nothing. on_error: "abort" (default) or "skip" for structural errors.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
forceNo
dry_runNo
on_errorNoabort
transactionsYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes
Behavior4/5

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

Despite no annotations, the description thoroughly discloses behavior: one book-open/one atomic save, structural errors abort the whole batch by default, on_error='skip' behavior, duplicate handling, force and dry_run semantics, and detailed OUTPUT envelope structure. It explains what references are echoed back and what the server never reuses. Slightly lower score because it doesn't explicitly state auth/permission needs or reversibility of the writes, but the write semantics are very well covered.

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

Conciseness4/5

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

Exceptionally well-structured with clear sections (INPUT, BEHAVIOR, OUTPUT), code-block examples, and consistent formatting that makes a complex format navigable. It is long, but the complexity of a TSV-driven bulk tool with six extensions arguably justifies the length. A small deduction because some sections (e.g., the notes/memo targeting discussion) verge on over-detailed for the headline decision, though the information is genuinely valuable.

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

Completeness5/5

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

This is a high-complexity tool (TSV parsing with header-declared layout, six combinable extensions, atomic batch behavior, auto-fill semantics) with zero annotation coverage and zero schema description coverage. The description compensates fully: it exhaustively documents input format, all extensions with examples, edge cases (empty qty, trailing memo cells, row width variance), error handling modes, output tables, and the interaction between extensions (first group fixes order). Complete for an agent to invoke correctly.

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

Parameters4/5

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

Schema coverage is 0%, so the description carries the full burden, and it does remarkably well. It documents the transactions TSV format in exhaustive detail (header-driven layout, six extensions, per-row semantics for ref/date/amount/qty/cur/notes/memo, auto-fill behavior). It also explains force, dry_run, and on_error with concrete values and defaults. This exceeds what the bare input schema provides for all 4 params.

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

Purpose5/5

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

The description opens with a specific verb+resource: 'Create MANY transactions in one atomic command (bulk entry).' It clearly distinguishes itself from the sibling create_transaction (single) by emphasizing MANY and bulk entry. The purpose is unmistakable and differentiated.

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

Usage Guidelines5/5

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

Provides extensive when-to-use guidance: explicitly names create_transaction as the alternative for non-default currency transactions ('use create_transaction with its currency parameter'), explains when extensions apply (cur for multi-currency, qty for investment/foreign accounts), and when auto-fill is ideal ('Perfect for recurring monthly entries'). Contrasts with create_transaction_from_scheduled implicitly through auto-fill mechanics.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ninetails-io/gnucash-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server