Skip to main content
Glama

Ekwo OS — open source accounting: ledger, invoices and VAT on your own Supabase or Postgres

Record a payment

record_payment
Destructive

Records money in or out, books it (bank against the customer or supplier account) and, unless you say otherwise, matches it against that contact's oldest open invoices up to the amount paid. Matching is what makes an invoice count as paid. The entry it produces cannot be unposted, though the matching can be undone with unreconcile.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "company_id": "<company_id>",
      "amount": "<amount>",
      "payment_date": "<payment_date>"
    },
    "name": "record_payment"
  }
}

Input Schema

NameRequiredDescriptionDefault
memoNo
amountYesA positive decimal string; the direction carries the sign.
directionNoinbound: a customer paid you. outbound: you paid a supplier. May be left out when document_id is given.
referenceNo
client_refNoYour own reference for this creation. Calling again with the same one returns what was created the first time (`replayed: true`) instead of creating a second — use it whenever a call might be repeated after a timeout.
company_idYesThe company to work in. Ask list_companies if unsure.
contact_idNoWho paid or was paid. Needed for the payment to be matched against their invoices.
journal_idNo
document_idNoThe posted document this money pays. It names the contact and the direction, read off what is still open on it, and the matching is offered to that document alone rather than to the oldest open items.
journal_codeNoThe bank or cash journal, by code, e.g. BNK. Not needed when bank_account_id is given: the account knows its journal.
payment_dateYes
currency_codeNoLeft out: the currency the company keeps its books in.
exchange_rateNoUnits of the payment currency for one unit of the company currency, as a rate table states it. Only needed when the payment is in another currency; the realised difference against the invoice is booked at matching.
bank_account_idNoWhich bank account the money moved on. list_bank_accounts says what exists. Given alone, it also names the journal; left out, the default account of the journal is used.
match_open_itemsNoDefault true: match the payment against the oldest open invoices of that contact, up to the amount paid.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed33 schema fields changed
    • removedInput schema / properties / amount / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "number"
      -  }
      -]
    • addedInput schema / properties / amount / description
      Added value: +"A positive decimal string; the direction carries the sign."
    • addedInput schema / properties / amount / type
      Added value: +[
      +  "string",
      +  "number"
      +]
    • addedInput schema / properties / bank_account_id / description
      Added value: +"Which bank account the money moved on. list_bank_accounts says what exists. Given alone, it also names the journal; left out, the default account of the journal is used."
    • addedInput schema / properties / bank_account_id / format
      Added value: +"uuid"
    • addedInput schema / properties / bank_account_id / pattern
      Added value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    • addedInput schema / properties / client_ref / description
      Added value: +"Your own reference for this creation. Calling again with the same one returns what was created the first time (`replayed: true`) instead of creating a second — use it whenever a call might be repeated after a timeout."
    • addedInput schema / properties / client_ref / maxLength
      Added value: +200
    • addedInput schema / properties / client_ref / minLength
      Added value: +1
    • addedInput schema / properties / company_id / description
      Added value: +"The company to work in. Ask list_companies if unsure."
    • addedInput schema / properties / company_id / format
      Added value: +"uuid"
    • addedInput schema / properties / company_id / pattern
      Added value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    • addedInput schema / properties / contact_id / description
      Added value: +"Who paid or was paid. Needed for the payment to be matched against their invoices."
    • addedInput schema / properties / contact_id / format
      Added value: +"uuid"
    • addedInput schema / properties / contact_id / pattern
      Added value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    • addedInput schema / properties / currency_code / description
      Added value: +"Left out: the currency the company keeps its books in."
    • addedInput schema / properties / currency_code / maxLength
      Added value: +3
    • addedInput schema / properties / currency_code / minLength
      Added value: +3
    • addedInput schema / properties / direction / description
      Added value: +"inbound: a customer paid you. outbound: you paid a supplier. May be left out when document_id is given."
    • addedInput schema / properties / document_id / description
      Added value: +"The posted document this money pays. It names the contact and the direction, read off what is still open on it, and the matching is offered to that document alone rather than to the oldest open items."
    • addedInput schema / properties / document_id / format
      Added value: +"uuid"
    • addedInput schema / properties / document_id / pattern
      Added value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    • removedInput schema / properties / exchange_rate / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "number"
      -  }
      -]
    • addedInput schema / properties / exchange_rate / description
      Added value: +"Units of the payment currency for one unit of the company currency, as a rate table states it. Only needed when the payment is in another currency; the realised difference against the invoice is booked at matching."
    • addedInput schema / properties / exchange_rate / type
      Added value: +[
      +  "string",
      +  "number"
      +]
    • addedInput schema / properties / journal_code / description
      Added value: +"The bank or cash journal, by code, e.g. BNK. Not needed when bank_account_id is given: the account knows its journal."
    • addedInput schema / properties / journal_code / minLength
      Added value: +1
    • addedInput schema / properties / journal_id / format
      Added value: +"uuid"
    • addedInput schema / properties / journal_id / pattern
      Added value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    • addedInput schema / properties / match_open_items / description
      Added value: +"Default true: match the payment against the oldest open invoices of that contact, up to the amount paid."
    • addedInput schema / properties / memo / minLength
      Added value: +1
    • addedInput schema / properties / payment_date / pattern
      Added value: +"^\\d{4}-\\d{2}-\\d{2}$"
    • addedInput schema / properties / reference / minLength
      Added value: +1
  2. First observed

TDQS

A4.4/5.0
Behavior5/5

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

Goes well beyond destructiveHint: it names exactly which part is irreversible (the posted entry) and which part is reversible (the matching, via unreconcile), and discloses the silent default side effect of matching against the oldest open invoices. That is precisely the behavioural detail an agent needs before a destructive financial write.

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?

Three tight sentences, front-loaded with the core effect, then the matching consequence, then the irreversibility warning. No filler.

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

Completeness4/5

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

Covers the mutation risk and the default matching side effect for a 15-parameter destructive tool, with no output schema to explain. Minor gap: nothing about the return value or the client_ref replay behaviour, which the schema carries instead.

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

Parameters3/5

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

Schema coverage is 73% and already documents match_open_items, direction, contact_id and amount semantics in similar words, so the description mostly restates rather than extends. The 'unless you say otherwise' framing ties to match_open_items but adds no new syntax or constraints.

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?

States a specific verb and resource plus the two things it does in one call: books the cash entry and matches it against open invoices. It also names a sibling (unreconcile) as the undo path, which separates it from pure matching tools.

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

Usage Guidelines4/5

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

Explains the default behaviour (auto-matching unless told otherwise) and that the resulting entry cannot be unposted, pointing to unreconcile for undoing matching. It does not, however, say when to prefer this over sibling paths like settle_from_statement or reconcile_many for already-booked movements.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.