Skip to main content
Glama

Taokeh MCP server

Bank review queue

bank_review_queue
Read-only

The IMPORTED BANK REGISTER — the rows that came in on a bank or card statement, in ANY status, defaulting to the ones still awaiting review. By default (no status) it is exactly the unreviewed queue it has always been: the unposted rows of one statement, or of the latest imported statement if you don't name one. Pass status to read the settled history instead — 'confirmed' (categorised, not yet posted), 'posted' (in the ledger), 'ignored' (the owner set them aside) or 'all'. Pass from/to WITHOUT a statementId to read a DATE WINDOW across every statement this company has imported, rather than one statement; the payload then says scope:'window' and statement is null. A window holding more than 1000 rows still awaiting review is refused with the count — narrow the dates or name a statementId; settled history has no such ceiling. ⛔ HAND-RECORDED settlements are NEVER here whatever you pass: a receipt or supplier payment typed into Taokeh by hand has no statement behind it, and this tool is the imported register only. To find those, use search_documents with docType:'payment'. Each row still awaiting review carries Taokeh's LIVE suggested category + contact, a confidence score (0–1) and a plain-language reason, computed the SAME way the in-app Banking → Review screen computes them. A suggestion does NOT come only from the tenant's transaction history: the owner can write a standing RULE for a payer (What Taokeh has learned → Bank rules), and such a rule beats what Taokeh worked out on its own — those rows' reasons read "You set this rule on " rather than "Learned: … (×N)". If a suggestion looks unlike the payer's history, the rule is usually why; say so instead of calling the history wrong. A known supplier's money-out line is suggested as SUPPLIER_PAYMENT only when that supplier has open bills the amount could pay; otherwise it is suggested as EXPENSE with the supplier kept (a payment with no bill would leave payables negative). A money-out line whose learned or ruled account belongs to a loan on the register (Financing) is never suggested to that account: with exactly one ACTIVE loan on it, it is suggested as LOAN_PAYMENT (the owner records it with the interest on the line's Loan payment panel); otherwise the reason says the account is left for the owner. The same holds for an OWNER_WITHDRAWAL when the account Taokeh would repay first (2400, when no Shareholder Loan account is mapped) carries a loan on the register: LOAN_PAYMENT with one ACTIVE loan, else OTHER with no account and the reason (never for a sole proprietor or partnership, whose owner withdrawals repay no loan). EVERY row on a foreign-currency account carries notPostable, whatever its status, in Taokeh's own sentence naming the account: Taokeh posts only ringgit accounts for now, so such a line cannot be posted, matched to invoices or bills, or used for a refund — a POSTED one too (posted before the refusal shipped); it can still be unmatched or unposted in Banking. Never ask the owner to post, match or refund it. currency is the statement account's currency (MYR for a ringgit account), and every amount is in it; a date window across accounts in different currencies says currency: null and lists them in currencies. Sorted lowest-confidence first (the ones that need a human eye), capped at 200 with an honest truncation note, plus per-confidence bucket counts so you can say e.g. "46 are mechanical, 13 need eyes". A row can also carry possibleDuplicateOf: a receipt or supplier payment the owner already recorded BY HAND that looks like the same money as this imported line (same account, same amount, within three days) — it is only a resemblance, Taokeh decides nothing from it, and you should say so rather than propose a category for money that may already be in the books. What you CAN do with a row: review it, explain it, and PROPOSE a category with draft_bank_classification — and, for the three categories whose account the owner picks by hand (EXPENSE, OTHER and INTERNAL_TRANSFER), the LEDGER ACCOUNT too. EXPENSE is a plain expense paid by card or bank (no party — never A/P); an unrecognised card purchase is suggested as EXPENSE. On money IN, EXPENSE is an EXPENSE REFUND (money back from a purchase, booked against the expense account); Taokeh suggests it only for a credit on a card whose description reads as a refund (REFUND, RFND, REVERSAL, BAYARAN BALIK). Your proposal is written to the row as an "AI suggestion" the owner sees on Banking → Review, with your proposed account pre-selected in their dropdown and marked as yours; rows already carrying a proposal from you come back here as yourProposal, so you can see what you told them. An OWNER_WITHDRAWAL you proposed on money out while the account Taokeh would repay first (2400, when no Shareholder Loan account is mapped) carries a loan on the register is NOT pre-selected: the row shows what the loan fence makes of it — LOAN_PAYMENT with the one ACTIVE loan on it, else OTHER with no account — and yourProposal.shownOnReviewAs ({category, reason}) says so; tell the owner that, not that their row reads Owner withdrawal. What you can NEVER do: CONFIRM or POST a row — and proposing the account changes nothing about that: it fills a dropdown, the owner still clicks. Accepting a category and posting each line is always a human click in Taokeh; hand the owner the review link. (Since 2026-08-19 the owner can also accept Taokeh's confident suggestions, and post confirmed lines, from the /go command bar's approval deck — still one human tap either way. YOUR OWN proposals are accepted only on Banking → Review, where your reasons are one tap away on each row.) ⚠ SETTLED ROWS CARRY NO SUGGESTION. A row that has already been confirmed, posted or ignored comes back with suggestedCategory, suggestedContact, confidence, reason and possibleDuplicateOf all NULL — the classifier is not re-run over decided history, because a fresh guess printed beside a decision the owner already made reads as a second opinion on settled books. Those rows carry what was actually DECIDED instead: category, glAccount ({code,name}, null if the row has none), contact (the customer or supplier on the row), journalEntryId (null unless posted), splits (where the amount was divided across accounts) and allocations (the invoices or bills the money settled). A confirmed but not yet posted OWNER_WITHDRAWAL on money out is the exception: Taokeh decides it loan-first (the owner's loan, up to what was owed on the line's own date and still owed on every later date in the books, then drawings) at the moment it is posted, whatever glAccount or splits it shows, so read those as not yet decided; once posted they are what was booked. ⚠ A SOLE PROPRIETOR OR PARTNERSHIP has no Shareholder's Loan: when the company's business type (Settings → Company, else the type it declared in storefront seller verification) is one of those, an OWNER_DEPOSIT books to Capital Contribution (3050) and an OWNER_WITHDRAWAL books whole to Owner's Drawings, with no loan-first split; a Sdn Bhd, or a company that has not set its type, keeps the loan rule above. statusCounts always reports how the rows in scope break down by status. A statement line the owner PAIRED with a book entry on Clear transactions is already in the books through that entry: it is never in the unreviewed queue or the 'confirmed' list; 'all' lists it with pairedWith (the entry's reference and date), and its statusCounts count it as PAIRED — never propose a category for it or ask the owner to post it. A row still awaiting review may carry possibleTwin {entryId, ref, date, kind}. kind 'bookEntry': a book entry on no statement that is the same money (same account, same amount, within three days) — the owner's review row warns that it looks already in the books. For such a row, propose a clearing with create_bank_clearing_draft (that entryId + this row as statementLineId) instead of a category. kind 'cardBill': a money-in line on a CREDIT CARD statement with a payment into the card of the same amount already in the books (usually the bank line that paid the card bill) — it is the card bill itself, so posting it would count the same money twice; a card has no clearing, so tell the owner to exclude the line on Banking → Review instead of proposing a category. kind 'cardLinePosted': a money-out bank line paying into a credit card (a credit card payment, or any line booked to the card's own ledger account) whose card-statement settlement line (ref = that line's description) is already POSTED — posting both counts the bill twice, so the owner should unpost that card line, or post this one anyway if it is a different payment. Each is only a resemblance (a same-amount refund can look alike), so say so. A line that moves the Shareholder's Loan can be refused at Post when it would leave a posted owner withdrawal over-repaid (the loan in debit on some date) — or, for a sole proprietor or partnership, a date a manual journal reclassified no longer nil; the refusal names them and the steps.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
toNoLatest transaction date (YYYY-MM-DD).
fromNoEarliest transaction date (YYYY-MM-DD). WITHOUT a statementId, from/to widen the read to a DATE WINDOW across every imported statement — 'what did the bank register show in July' rather than 'what is on this one statement'.
statusNoWhich rows: 'unreviewed' (DEFAULT — everything not yet posted or ignored, i.e. the review queue), 'confirmed', 'posted', 'ignored', or 'all'. Only unreviewed rows carry suggestions; the rest carry what was decided.
statementIdNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • addedInput schema / properties / from
      Added value: +{
      +  "description": "Earliest transaction date (YYYY-MM-DD). WITHOUT a statementId, from/to widen the read to a DATE WINDOW across every imported statement — 'what did the bank register show in July' rather than 'what is on this one statement'.",
      +  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +  "type": "string"
      +}
    • addedInput schema / properties / status
      Added value: +{
      +  "description": "Which rows: 'unreviewed' (DEFAULT — everything not yet posted or ignored, i.e. the review queue), 'confirmed', 'posted', 'ignored', or 'all'. Only unreviewed rows carry suggestions; the rest carry what was decided.",
      +  "type": "string"
      +}
    • addedInput schema / properties / to
      Added value: +{
      +  "description": "Latest transaction date (YYYY-MM-DD).",
      +  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +  "type": "string"
      +}
  2. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations cover only readOnlyHint/openWorldHint, and the description goes far beyond them: the 1000-row window refusal with count, the 200-row cap with truncation note, lowest-confidence-first sort, settled rows returning null suggestions, notPostable on every foreign-currency row, and the hard rule that this tool can never confirm or post. These are exactly the behavioral traits an agent needs and that structured fields do not carry.

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?

At roughly 1500 words this is an order of magnitude longer than an agent needs for a four-parameter read tool. While it is front-loaded with the queue/window distinction, large stretches cover tangential domain rules (owner-withdrawal loan-first derivation, sole-proprietor capital contribution mapping, the /go command bar since 2026-08-19) that do not change how the tool is called and dilute the operative instructions.

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 fully, enumerating returned fields (suggestedCategory, confidence, reason, possibleDuplicateOf, possibleTwin kinds, statusCounts, pairedWith, yourProposal). For a signature-free tool returning a complex payload, nothing an agent needs appears to be missing.

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 75% and the description adds real meaning on top: `status` values are explained in terms of what is decided vs. suggested, and `from`/`to` are framed as switching scope to a whole-company window when no statementId is given. It stops short of documenting the statementId format or the window's currency behaviour at the parameter level, so it is strong but not exhaustive.

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 opening sentence states a specific resource and scope: the IMPORTED BANK REGISTER, rows that arrived on a bank or card statement, defaulting to those awaiting review. It also explicitly contrasts itself with the hand-recorded case routed to search_documents with docType:'payment'. An agent can distinguish this from every sibling without opening the schema.

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 conditions for each mode: omit `status` for the unreviewed queue, pass `status` to read settled history with each value's meaning, and pass `from`/`to` without `statementId` to switch to a cross-statement date window. It also names concrete alternatives for adjacent tasks (search_documents for hand-recorded settlements, create_bank_clearing_draft for a possibleTwin bookEntry, exclude-the-line for cardBill).

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