Skip to main content
Glama

Taokeh MCP server

Suggest bank-row categories (human reviews in Taokeh)

draft_bank_classification

Propose a category (and optionally a contact) for up to 50 bank rows still waiting for review — imported statement lines AND rows the owner typed in by hand, which land as UNCATEGORIZED — get their ids from bank_review_queue. PROPOSALS ONLY: this writes a suggestion the owner sees as an 'AI suggestion' badge on the Banking → Review screen; it never confirms, never posts, and nothing you send here moves money — the owner reviews and posts every line in /banking. Only SUGGESTED/UNCATEGORIZED rows accept a proposal (already-decided CONFIRMED/POSTED/IGNORED rows are rejected, and so is a statement line the owner paired with a book entry on Clear transactions — it is already in the books). A row that looks like a book entry still on no statement is accepted but comes back with possibleTwin (kind 'bookEntry') and a warning: propose a clearing (create_bank_clearing_draft) for it instead. possibleTwin is {entryId, ref, name, date, kind}, as on bank_review_queue: the warning already names the entry as the owner knows it; call it by name (null: "a bank entry" when ref starts BT- or REV-BT-, else "a book entry" — for kind 'cardLinePosted', "a card statement line"), never by a BT- code. A credit-card line that looks like the card bill already paid into the card comes back with possibleTwin (kind 'cardBill') and a warning: the owner should exclude it — there is no clearing for a card. A card payment whose card-statement line is already posted comes back with kind 'cardLinePosted': posting both would count the bill twice. category must be one of the review screen's own set. contactName applies only to CUSTOMER_PAYMENT (a customer) or SUPPLIER_PAYMENT (a vendor) and must match an EXISTING contact exactly — an unresolvable name rejects that row (create the contact first, or omit it). Send contactName whenever you know the payer: a CUSTOMER_PAYMENT or SUPPLIER_PAYMENT proposed without one is accepted, but Taokeh will not POST it until the owner picks the customer or supplier, because a payment with nobody on it would sit in receivables or payables under nobody. accountCode proposes the LEDGER ACCOUNT for the row (e.g. a hosting bill to 6500) and is accepted ONLY for the three categories whose account the owner picks by hand — EXPENSE, OTHER and INTERNAL_TRANSFER. EXPENSE is a plain expense paid by card or bank, no contact (it is not a supplier payment and never touches payables), and its accountCode must be one of the expense accounts expense_accounts lists. On a money-IN row EXPENSE is an EXPENSE REFUND — money that came back from something bought (a merchant refund on a card statement, say) — and books the card or bank against that same expense account, reducing the expense; propose it only when the line really is a refund of a purchase, never for a customer's payment. OTHER and INTERNAL_TRANSFER never take a receivables/payables control, a contra or clearing account (1016 Contra Clearing, Accumulated Depreciation, the gateway clearing account), Inventory, Opening Balance Equity or Retained Earnings — the owner's picker does not offer them either; OTHER never takes a bank, card or cash account (that is an INTERNAL_TRANSFER), and INTERNAL_TRANSFER takes ONLY one of them (a sales, expense or equity account is OTHER, or EXPENSE for money spent). On a money-OUT row OTHER never takes an account a loan on the Financing register uses: money out to a loan is recorded only through the loan register, so propose LOAN_PAYMENT with no accountCode and the owner picks the loan and the interest on that line's Loan payment panel (money IN to a loan's account, a loan received, is taken). An OWNER_WITHDRAWAL on money out is refused while the account Taokeh would repay first (2400, when no Shareholder Loan account is mapped) carries a loan on the register (never for a sole proprietor or partnership, which books it whole to Owner's Drawings, and an OWNER_DEPOSIT to Capital Contribution) — the owner's Post refuses one that would repay that loan — and the reply names the loan and the two proposals that work: LOAN_PAYMENT (no accountCode) if the money repays that loan, or OTHER with the drawings account if it is a drawing. An Owner withdrawal you proposed before that state is shown on Banking → Review as the loan fence places it (bank_review_queue's yourProposal.shownOnReviewAs) and is never batch-accepted. INTERNAL_TRANSFER never takes a credit-card account for money going out of a bank line — paying a card off is CARD_PAYMENT with that card's code — and on a card's own statement, money in from a bank account is the card bill being paid: it is never posted from the card side, so the owner excludes that line (the bank line that paid it posts as CARD_PAYMENT). A balance transfer between two cards is posted from the CHARGE line (money out, on the card that paid); the paid-off card's money-in line is never posted either, so the owner excludes it. Every other category already books against a fixed account (a customer payment to receivables, a bank charge to bank charges, and so on), so sending accountCode with one is rejected and the reply names the account that category already carries. The code must exist in this company's chart (expense_accounts lists the expense side); the line's own bank or card account is refused, because that would post the money against itself (under OTHER every bank, card and cash account is refused — that move is an INTERNAL_TRANSFER). CARD_PAYMENT is the one category that REQUIRES accountCode, and takes only a credit-card account: it means "this bill settles that card", so propose it with the card's code or not at all — a card payment is never an expense, and naming an expense account (or naming a card account under OTHER) is refused, because the card's spending was already booked line by line from the card statement. The account you propose arrives PRE-SELECTED in the owner's account dropdown on Banking → Review, marked as proposed by you — it saves them hunting the chart, it does not decide anything: if they have already picked an account themselves, theirs stands. allocations proposes WHICH invoices or bills the money settles — the question Taokeh's own matcher hands to a human whenever the payment is partial, spans several documents, or could clear more than one combination, and the one you may already know from a remittance advice or the payer's own message. Send it ONLY with CUSTOMER_PAYMENT on a money-IN row or SUPPLIER_PAYMENT on a money-OUT row, and ONLY together with contactName, because every line is checked against THAT contact's live open documents: up to 20 entries of { docNumber, amount }, where docNumber is the document number as Taokeh shows it (open_invoices / ap_aging list them). EVERY amount is in RINGGIT, and specifically the outstanding balance as Taokeh reports it on those tools — never the document's own foreign-currency figure, and never its gross total where the two differ; a foreign-currency invoice is settled in Banking, not here. The amounts must add up to the WHOLE line within 0.10 — a proposal that leaves part of the deposit unexplained is refused with the exact shortfall, never trimmed to fit — no line may exceed what its document still owes, and an unknown number, a duplicate, a FOREIGN-currency document dated AFTER the payment, or an OPENING invoice or bill for a line dated on or before the accounting start date, is refused too (a ringgit INVOICE or BILL dated after it is accepted: a customer's deposit, or an advance paid to a supplier, which sits on that party's account until the document's date and pays it then); the refusal names that contact's own open documents with their outstanding amounts, so you can correct it in one more turn. What it does is PRE-FILL: the owner's Match pane opens with those documents ticked and those amounts entered, under a banner saying you proposed it and quoting your note. It settles nothing — the owner reads it and clicks Save — and if a document has been paid or part-paid since you proposed it, the pane says your proposal no longer fits and fills in nothing rather than allocating a stale figure. It never reaches the one-tap Accept on the payments list either; that button only ever applies Taokeh's own exact match. note is your stated reason (≤300 chars), shown to the owner — write it well, because the owner reads it when deciding. Your proposals are also collected into a 'Proposals from your AI' panel on Banking → Review, where the owner can accept a whole batch of them in one tap after reading them grouped by category with your reasons; that acceptance sets the category and contact only and is still the owner's decision — it never posts to the ledger. If a row's existing suggestion says "You set this rule on ", the OWNER has written a standing rule for that payer (What Taokeh has learned → Bank rules) — proposing something different is allowed and is sometimes right, but say in your note that you are contradicting their own rule, and expect them to keep the rule. A proposal on a foreign-currency account's line is saved but comes back with a warning: Taokeh does not post or match those lines yet. An accountCode that is a foreign-currency bank or card (as a transfer or card-payment target) is rejected with the reason: Taokeh posts only ringgit accounts for now. Per-row outcomes are reported — nothing is silently skipped. A proposal that books the line to the Shareholder's Loan (OTHER with the loan's code) can be refused at Post when it would leave a posted owner withdrawal over-repaid (or, for a sole proprietor or partnership, a reclassified date no longer nil): the row then comes back applied with that sentence as a warning.

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": {
      "suggestions": "<suggestions>"
    },
    "name": "draft_bank_classification"
  }
}

Input Schema

NameRequiredDescriptionDefault
suggestionsYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / suggestions / items / properties / allocations
      Added value: +{
      +  "items": {
      +    "properties": {
      +      "amount": {
      +        "exclusiveMinimum": 0,
      +        "type": "number"
      +      },
      +      "docNumber": {
      +        "maxLength": 60,
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "docNumber",
      +      "amount"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 20,
      +  "minItems": 1,
      +  "type": "array"
      +}
  2. Changed1 schema field changed
    • addedInput schema / properties / suggestions / items / properties / accountCode
      Added value: +{
      +  "maxLength": 40,
      +  "type": "string"
      +}
  3. First observed

TDQS

A4.7/5.0
Behavior5/5

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

The annotations mark this as a non-read-only, non-destructive write, and the description adds substantial safety context beyond that: it writes only an 'AI suggestion' badge, never confirms or posts, never moves money, and reports per-row outcomes rather than silently skipping. It also discloses warnings, rejection reason patterns, and owner-review behavior, which is unusually complete for a write-style tool.

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

Conciseness2/5

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

The purpose and safety constraints are front-loaded, but the body is an enormous single paragraph mixing drafting rules, refusal conditions, UI behavior, and edge cases. Much of the content is valuable for this complex tool, but the wall-of-text structure and repeated re-statements of 'proposals only' and owner-review behavior make it harder to scan than necessary.

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?

There is no output schema, and the description compensates by explaining per-row outcomes, possibleTwin shapes, warnings, and what the reply names on rejection. Given the complexity of accounting-side effects and owner review, it leaves very little an agent would need to infer before calling the tool.

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%, so the description must carry all parameter meaning; it covers category constraints, contactName applicability and matching rules, accountCode requirements by category, allocations format and ringgit/outstanding-balance semantics, note length, and the transactionId source from bank_review_queue. It also explains the 50-row cap and allocation limits beyond what the bare schema shows.

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 states a specific verb and resource: propose a category/contact for up to 50 bank rows waiting for review, sourced from bank_review_queue. It explicitly distinguishes the tool from create_bank_clearing_draft for twin book entries, and from the owner's posting action, so an agent can tell exactly what this tool does and does not do.

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?

It gives explicit when-to-use and when-not-to-use rules: only SUGGESTED/UNCATEGORIZED rows accept proposals, confirmed/posted/ignored rows are rejected, paired statement lines are rejected, and alternative paths such as create_bank_clearing_draft or owner exclusion are named. It also routes specific twins and card scenarios to the correct alternative behavior rather than leaving them ambiguous.

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.

Resources