Skip to main content
Glama
ninetails-io

gnucash-mcp

enter_statement

DestructiveIdempotent

Enter and reconcile a complete bank or card statement in one atomic save, using a dry-run to classify each line as new, matched, or ambiguous before committing.

Instructions

Enter a COMPLETE bank/card statement in one atomic call: create the new lines, claim the ones already in the book, and reconcile everything against the closing balance — all in one save, or nothing at all.

THE WORKFLOW (two calls around your judgment):

  1. dry_run=true (the DEFAULT) — transcribe the statement and get back a classification of every line: NEW (not in the book), MATCH (an existing unreconciled split corresponds), OVERLAP (already reconciled), AMBIGUOUS (several candidates). MATCH/AMBIGUOUS rows come with the candidate's full annotation (date, amount, description, notes, memo, short GUID) so you can adjudicate each one.

  2. Rule every MATCH/AMBIGUOUS row yourself, adapt annotations, confirm with the user.

  3. dry_run=false — NEW rows now carry interpreted description/notes and counter-splits; MATCH rows carry match=<split guid> claims. The server enters, claims, reconciles every statement-touched split at statement_date, and saves once.

TRANSCRIBE, DON'T INTERPRET (dry-run): amounts and balances go in EXACTLY as the statement prints them — for credit cards too (charges positive, balance as amount owed). The server applies the sign convention from the account's type; you never flip a sign. The gate opening + sum(lines) == closing must hold or the call rejects: transcribe every line.

INPUT — lines is a TSV block. Header: ref, date first, then any order of description, notes, raw, match, amount (required), then optional amt, acct, memo, qty counter-split groups (batch grammar). The statement account's own leg is SYNTHESIZED — never a column. Dry-run typically needs only::

ref<TAB>date<TAB>raw<TAB>amount
1<TAB>2026-07-03<TAB>POS DEBIT WHOLEFDS #123<TAB>-87.12
  • raw = the verbatim statement line; it lands on the bank leg's memo (provenance). description/notes are your interpretation (commit).

  • match = the split GUID this line claims instead of creating (from the dry-run candidates table). Claim rows may also carry raw (updates the claimed split's memo) and notes (updates the transaction's notes), and END at their last fixed column — they take no split cells. The claimed amount must equal the line amount exactly — fix the book first if they disagree.

  • A commit row with no counter-splits auto-fills from the most recent same-description 2-split transaction, adapted to the line amount (marked auto_filled_from:<guid>). The precedent must have exactly one leg on the statement account and no cross-commodity leg — anything else rejects with "supply explicit counter-splits". Explicit counter-splits must not name the statement account (its leg is synthesized).

SAFETY: the account's reconciled balance must tie to opening_balance (a prior unentered statement blocks commit), every created-vs-existing exact overlap must be explicitly claimed or forced, and the projected closing tie is verified BEFORE anything is written. The two force flags are INDEPENDENT: force_base=true lands onto an untied opening base (the consequent tie discrepancy is recorded, and duplicate detection STAYS ON); force_duplicates=true creates past exact twins you have adjudicated as distinct. Neither bypasses the statement's own self-check. After the save, the reconciled balance is read back and verified against the tie.

OUTPUT (dry-run): summary (class counts), lines (ref, class, cands, note — the note is the resolved disposition: the guard's refusal coaching verbatim, the auto-fill prediction, or "will claim …"), candidates — SELF-CONTAINED comparison rows sorted strongest-correspondence first (ref, candidate_guid, confidence, state, date_new/old + delta, amt_new/old + delta, cur, desc_new/old, notes_old, memo_old, cat_new/old, split_match, signals; _new = the statement line in book convention, _old = the existing split — never re-read your own input; cur is structurally blank on this surface), plus warnings (only when present; candidates likewise) and tie — the projected reconciled balance vs the closing, with a count of rows this exact payload would refuse at commit. The dry-run rehearses the SAME disposition procedure commit runs — force included. The tie is the only verdict; MATCH/AMBIGUOUS rows are yours to rule. OUTPUT (commit): results (ref, status, guid, note; status is created | claimed | skipped_duplicate, or on a refused statement rejected | statement_aborted — the note column carries the row's coaching and auto_filled_from:<guid> markers), plus, on success only, the new reconciled balance and the tie (a refusal returns just summary + results).

Args: account: Statement account ref (path, %short, or GUID). BANK/CASH/ASSET/CREDIT/LIABILITY only. statement_date: The statement's closing date (YYYY-MM-DD); every touched split reconciles at it. opening_balance: Opening balance, exactly as printed. closing_balance: Closing balance, exactly as printed. lines: The TSV block described above. dry_run: DEFAULT TRUE — the rehearsal is the workflow. force_base: Land onto an untied opening base; the tie discrepancy is recorded, twin detection stays on. force_duplicates: Create past exact unclaimed twins (you adjudicated them as distinct charges). show_all: Dry-run only. Lines with MEDIUM/HIGH candidates suppress their LOW amount-coincidences (the cands column notes "+N LOW suppressed"); show_all=true lists everything.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
linesYes
accountYes
dry_runNo
show_allNo
force_baseNo
statement_dateYes
closing_balanceYes
opening_balanceYes
force_duplicatesNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Addedv1.4.4

TDQS

A5/5.0
Behavior5/5

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

The description discloses atomic all-or-nothing saves, exact transcription requirements, sign conventions derived from account type, safety gate 'opening + sum(lines) == closing', independent force-flag effects, duplicate-detection behavior, auto-fill behavior, and read-back verification after commit. This richly supplements the annotations, which only mark the call as non-readOnly, non-open-world, idempotent, and destructive.

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

Conciseness5/5

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

Although long, the description is tightly organized into labeled sections: workflow, transcription rules, input grammar, safety, and output formats. The most important usage model is front-loaded, and the detailed examples and field enumerations are necessary given the tool's complexity. No sentence is filler.

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?

For a high-complexity tool with 9 parameters, zero schema parameter descriptions, a TSV input grammar, two execution modes, and safety-critical behavior, the description is essentially complete. It covers all required fields, explains both dry-run and commit output shapes, lists refusal conditions, and gives a runnable minimal input example. The presence of an output schema does not create any notable gap.

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

Parameters5/5

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

Schema description coverage is 0%, but the description compensates completely. Every parameter is explained: account ref formats and allowed types, statement_date as the reconciliation date, exact balance semantics, the full TSV grammar for lines, and the meaning and default of each boolean flag. The example line block conveys the required format better than a schema description could.

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 and resource: 'Enter a COMPLETE bank/card statement in one atomic call,' and immediately differentiates the tool by including create, claim, and reconcile behavior in a single save. This clearly separates it from generic transaction creation or standalone reconciliation tools among the siblings.

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?

The 'WORKFLOW' section explicitly prescribes a two-call pattern: dry_run first, adjudicate MATCH/AMBIGUOUS rows, then commit with dry_run=false. It also gives explicit conditions such as 'fix the book first if they disagree,' explains when force_base and force_duplicates are appropriate, and warns when the call will reject. This is unusually concrete operational guidance.

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

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