Skip to main content
Glama

Taokeh MCP server

File a pending correction draft for a posted bill (admin approves in Taokeh)

update_bill_draft

FILES A PENDING DRAFT ONLY — NOTHING CHANGES UNTIL A HUMAN REVIEWS AND APPROVES IT IN TAOKEH. Propose a correction to a supplier bill ALREADY POSTED in Taokeh — the door for a bill that went onto the books with a wrong line, a wrong quantity or cost, the wrong date, the wrong payment term or the wrong payment method. To change, add or remove LINES, read them first with search_document_lines (docType 'bill') and NAME each line you keep with its lineNo (or send { keep: } for a line that is already right): a line with a lineNo IS that line of the bill, a line without one is a NEW line, and a line you leave out is REMOVED — on a bill that received goods against a purchase order, a removed line's goods go back to being owed on the order (see lines). It files a pending DRAFT an ADMIN reviews as a DIFF (current → proposed) and approves; only that tap rewrites the bill, and it keeps the SAME bill number, the original attached document, and the link to the purchase order the bill was converted from. Pass purchaseId, the bill's REAL id from search_documents — a bill number is refused, because two suppliers can print the same number and correcting the wrong one is worse than asking. ROUTING — three different mistakes, three different doors. (1) THE PURCHASE NEVER HAPPENED (keyed twice, entered on the wrong company, the wrong supplier's bill): the owner VOIDS it — Purchasing → the bill → Void, in Taokeh. There is deliberately NO AI lane for voiding. Tell them where to click. (2) THE PURCHASE HAPPENED BUT THE BILL IS WRONG (a wrong line, quantity or unit cost, the wrong date, term, due date or payment method): THIS tool. (3) SOMETHING CHANGED AFTER THE PURCHASE (goods went back to the supplier, the supplier credited a price difference later): a DEBIT NOTE against the bill, which the owner raises in Taokeh (Purchasing → Debit notes) — a real event that belongs on the books as its own document. WHAT YOU CAN CHANGE: purchaseDate, paymentMethod ('CASH' paid on the spot, or 'CREDIT' on account), term (the supplier's payment term, stored as written — changing an on-account bill to one of the five presets, Due on Receipt / Net 7 / Net 14 / Net 30 / Net 60, re-derives the due date from the bill date unless you also send dueDate), dueDate (only when the due date ITSELF is wrong — correcting just the bill date already moves the due date by the same number of days), and lines — the FULL REPLACEMENT SET, so send every line the bill should have, including the ones that were already right. Everything you do NOT send is carried across exactly as the bill has it: the supplier, the currency and its frozen exchange rate, the location the goods were received into, the batch (lot) each line was received into, and each line's SST code. On a bill with no purchase order each replacement line keeps the UNIT it has on the bill: a line identical to one of the bill's own lines keeps that line's unit, any other line takes the product's one unit on the bill (a product new to the bill: its own unit). Here unit is only the price basis — it never sets a line's unit — and a line measured from its size and tally is booked in the measurement's unit (tons for timber). When the product is on the bill in more than one unit, a changed line of it that is not measured is refused, and the user makes that change on the bill's Edit screen in Taokeh. Batches: without line numbers, a replacement line of a product the bill already carries is received into the same batch as the original line of that product; with line numbers, a named line keeps its own batch and a NEW line of a product the bill already received into stock goes into that product's lot on the bill, by lot number (the lot keeps its own expiry) — refused when the bill received it into more than one lot (raise the quantity on the right line instead). WHAT YOU CANNOT, each refused by name: the SUPPLIER (a different supplier is a different document — the owner voids and re-enters); the BILL NUMBER (preserved across an edit; Taokeh's own Edit screen cannot change it either); the CURRENCY or the RATE (frozen at posting); and a bill posted with a whole-document tax rate instead of per-line SST codes (Taokeh does not store that rate, so a correction from here would drop the input tax — the owner corrects it on the app's Edit screen). WHAT BLOCKS AN EDIT OUTRIGHT, checked when you file and again when the admin taps, each refusal naming the real next step: the document is not a bill (an opening balance or a debit note has its own page); it is validated on MyInvois as a self-billed e-invoice; a live debit note has been raised against it; a payment has been allocated to it; or it is dated inside a period the company has locked. A proposal that changes nothing is refused rather than filed as an empty diff. If the bill is edited by someone else after you read it, the admin is shown BOTH versions and the one-tap approval is refused — that is by design; call revise_draft (kind 'bill_update') to re-read and re-propose. An edit in Taokeh re-books the bill under a NEW id with the same number: a pending draft FOLLOWS it, and calling this tool with the old id is refused with the new id named — re-read the bill before proposing against it.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
notesNoA SHORT reviewer note in the reviewer's language: what was wrong, what you changed, and anything they should double-check before they approve a rewrite of a posted bill.
proposedYesONLY what you want changed. An unknown or not-patchable key is refused by name; a proposal the bill already agrees with is refused rather than filed.
purchaseIdYesREQUIRED — the posted bill's real id, from search_documents. A bill number is refused: correcting the wrong document silently is worse than asking which one they mean.
needsReviewNoSet true when something gave you pause — it flags the draft for the reviewer.
printedTotalNoThe grand total the corrected bill should show, if the user told you one — cross-checked against the server's own derivation and flagged on the review screen.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • changedInput schema / properties / proposed / properties / lines / description
      Previous value: -"The FULL replacement line set — every line the corrected bill should have, not only the one that was wrong. Same shape as create_bill_draft. Omit it entirely when you are only correcting header fields. A line Taokeh converted from a per-foot or per-piece price prints in tons at a whole-ringgit rate under a note like \"(150' @ RM 0.50/feet)\": send such a line in its FILED form — thickness, width, tally, unit 'feet' or 'pcs', the per-foot or per-piece price (on a purchase, the supplier's cost) and only the grade as the description, never the printed note. On a correction, a PURCHASE line may instead be sent back exactly as it stands on the document; a SELLING line sent back exactly as it stands is read back into its filed form only when its note's price reproduces it (otherwise keep it with { keep: <lineNo> } where offered, or correct the header only); any other line carrying the note follows the rule for a new line — a selling line read back only at its own tons and rate with no discount, a purchase line refused. ⛔ LINE KEYS ARE STRICT: a key this schema does not list is REFUSED BY NAME and NOTHING is filed. A BILL THAT RECEIVED GOODS AGAINST A PURCHASE ORDER: you can correct the header, or prices/discounts/SST codes with EVERY line of the whole bill sent back exactly as it is (same products, quantities, order and units — lines not on the order included); any other line change, on any line, is refused at filing and is made by the user on the bill's Edit screen in Taokeh (Purchases → the bill → Edit). A header-only correction (no `lines`) reposts the bill's own lines unchanged."New value: +"The FULL replacement line set — every line the corrected bill should have, not only the one that was wrong. Same shape as create_bill_draft. Omit it entirely when you are only correcting header fields. A line Taokeh converted from a per-foot or per-piece price prints in tons at a whole-ringgit rate under a note like \"(150' @ RM 0.50/feet)\": send such a line in its FILED form — thickness, width, tally, unit 'feet' or 'pcs', the per-foot or per-piece price (on a purchase, the supplier's cost) and only the grade as the description, never the printed note. On a correction, a PURCHASE line may instead be sent back exactly as it stands on the document; a SELLING line sent back exactly as it stands is read back into its filed form only when its note's price reproduces it (otherwise keep it with { keep: <lineNo> } where offered, or correct the header only); any other line carrying the note follows the rule for a new line — a selling line read back only at its own tons and rate with no discount, a purchase line refused. ⛔ LINE KEYS ARE STRICT: a key this schema does not list is REFUSED BY NAME and NOTHING is filed. LINE NUMBERS: give each line you keep or correct its `lineNo` (or { keep: <lineNo> }); a line without one is new, a line left out is removed. A line with a lineNo keeps its batch, its stock treatment and, when you omit taxCode, its own SST code; it keeps its product and unit (a different one is refused — drop the line and add a new one instead). A lineNo that is not on this bill, or the same lineNo twice, is refused. If the bill is edited in Taokeh after you read it, a draft that names lines can no longer be approved or revised — read the bill again and file a fresh one. A BILL THAT RECEIVED GOODS AGAINST A PURCHASE ORDER: WITHOUT line numbers you can only correct the header, or prices/discounts/SST codes with EVERY line of the whole bill sent back exactly as it is (same products, quantities, order and units — lines not on the order included); WITH line numbers you can change quantities, add lines and remove lines, and each named line keeps what it received against the order (a removed line's goods go back to being owed). A header-only correction (no `lines`) reposts the bill's own lines unchanged."
    • addedInput schema / properties / proposed / properties / lines / items / properties / keep
      Added value: +{
      +  "description": "Keep a line of the bill exactly as it stands: { keep: <lineNo> } and nothing else beside it. Counts as naming that line, so the whole set is read by line number.",
      +  "exclusiveMinimum": 0,
      +  "maximum": 9007199254740991,
      +  "type": "integer"
      +}
    • addedInput schema / properties / proposed / properties / lines / items / properties / lineNo
      Added value: +{
      +  "description": "The bill's OWN line this line is — its lineNo from search_document_lines (docType 'bill'). Send it on every line you keep or correct; leave it off a NEW line. Once ANY line carries one, the whole set is read by line number: a line you leave out is REMOVED. A line keeps its product and its unit — to change the product, leave the line out and add the new product as a new line.",
      +  "exclusiveMinimum": 0,
      +  "maximum": 9007199254740991,
      +  "type": "integer"
      +}
    • changedInput schema / properties / proposed / properties / lines / items / properties / productRef / description
      Previous value: -"The product id from resolve_product, or its exact SKU. Never a guessed name."New value: +"REQUIRED on every line except a { keep } — the product id from resolve_product, or its exact SKU. Never a guessed name."
    • changedInput schema / properties / proposed / properties / lines / items / properties / taxCode / description
      Previous value: -"Leave it OUT and the server inherits the ORIGINAL bill's own SST code for this product, so a correction never quietly changes the input tax — an omitted code must never mean 'no SST'. Only set it when the code itself is what is wrong. A NEW product on a taxed bill has nothing to inherit and is refused by name."New value: +"Leave it OUT and the server inherits the ORIGINAL bill's own SST code for this product (on a line with a lineNo: that line's own code), so a correction never quietly changes the input tax — an omitted code must never mean 'no SST'. Only set it when the code itself is what is wrong. A NEW product on a taxed bill has nothing to inherit and is refused by name."
    • changedInput schema / properties / proposed / properties / lines / items / properties / unitCost / description
      Previous value: -"Up to four decimals (e.g. 0.0325), exactly as invoiced — but a per-foot or per-piece price that Taokeh converts to tons: two decimals. Put a discount or tax in its own field, never folded into the cost."New value: +"REQUIRED on every line except a { keep }. Up to four decimals (e.g. 0.0325), exactly as invoiced — but a per-foot or per-piece price that Taokeh converts to tons: two decimals. Put a discount or tax in its own field, never folded into the cost."
    • removedInput schema / properties / proposed / properties / lines / items / required
      Removed value: -[
      -  "productRef",
      -  "unitCost"
      -]
  2. Changed1 schema field changed
    • changedInput schema / properties / proposed / properties / lines / description
      Previous value: -"The FULL replacement line set — every line the corrected bill should have, not only the one that was wrong. Same shape as create_bill_draft. Omit it entirely when you are only correcting header fields. ⛔ LINE KEYS ARE STRICT: a key this schema does not list is REFUSED BY NAME and NOTHING is filed. A BILL THAT RECEIVED GOODS AGAINST A PURCHASE ORDER: you can correct the header, or prices/discounts/SST codes with EVERY line of the whole bill sent back exactly as it is (same products, quantities, order and units — lines not on the order included); any other line change, on any line, is refused at filing and is made by the user on the bill's Edit screen in Taokeh (Purchases → the bill → Edit). A header-only correction (no `lines`) reposts the bill's own lines unchanged."New value: +"The FULL replacement line set — every line the corrected bill should have, not only the one that was wrong. Same shape as create_bill_draft. Omit it entirely when you are only correcting header fields. A line Taokeh converted from a per-foot or per-piece price prints in tons at a whole-ringgit rate under a note like \"(150' @ RM 0.50/feet)\": send such a line in its FILED form — thickness, width, tally, unit 'feet' or 'pcs', the per-foot or per-piece price (on a purchase, the supplier's cost) and only the grade as the description, never the printed note. On a correction, a PURCHASE line may instead be sent back exactly as it stands on the document; a SELLING line sent back exactly as it stands is read back into its filed form only when its note's price reproduces it (otherwise keep it with { keep: <lineNo> } where offered, or correct the header only); any other line carrying the note follows the rule for a new line — a selling line read back only at its own tons and rate with no discount, a purchase line refused. ⛔ LINE KEYS ARE STRICT: a key this schema does not list is REFUSED BY NAME and NOTHING is filed. A BILL THAT RECEIVED GOODS AGAINST A PURCHASE ORDER: you can correct the header, or prices/discounts/SST codes with EVERY line of the whole bill sent back exactly as it is (same products, quantities, order and units — lines not on the order included); any other line change, on any line, is refused at filing and is made by the user on the bill's Edit screen in Taokeh (Purchases → the bill → Edit). A header-only correction (no `lines`) reposts the bill's own lines unchanged."
  3. Changed1 schema field changed
    • changedInput schema / properties / proposed / properties / lines / items / properties / unitCost / description
      Previous value: -"Two decimals at most (whole sen, or whole cents in another currency), exactly as invoiced; put a discount or tax in its own field, never folded into the cost."New value: +"Up to four decimals (e.g. 0.0325), exactly as invoiced — but a per-foot or per-piece price that Taokeh converts to tons: two decimals. Put a discount or tax in its own field, never folded into the cost."
  4. Changed1 schema field changed
    • addedInput schema / properties / proposed / properties / lines / items / properties / unitCost / description
      Added value: +"Two decimals at most (whole sen, or whole cents in another currency), exactly as invoiced; put a discount or tax in its own field, never folded into the cost."
  5. Changed2 schema fields changed
    • changedInput schema / properties / proposed / properties / lines / items / properties / tally / description
      Previous value: -"The piece tally (dimensional lines)."New value: +"The tally as pieces/length_ft pairs — '10/10 12/14' is 10 pieces of 10 ft and 12 of 14 ft — OR the total running feet like 400' when the paper gives no cut list. Never invent a cut list (no '1/400'). With thickness and width this is what the quantity is derived FROM. Every token must be a pieces/length pair — a tally with anything else in it (a grade word, a stray number, '=') is refused; put grade words in the description. A total-feet tally needs thickness and width (or a named size) to work out the tons, and has no pieces, so it cannot carry a per-piece price — both are refused."
    • addedInput schema / properties / proposed / properties / lines / items / properties / unit / description
      Added value: +"The unit the PRICE is quoted in. On a timber company: 'feet' = per running foot, 'pcs' = per piece, 'ton' or omitted = per ton. A per-foot/per-piece price is converted to the per-ton rate from thickness/width/tally, or from a cut list in the description ('2x2 = 10/10 12/14'); a description cut list the server cannot read cleanly is refused — send thickness/width/tally instead."
  6. Changed1 schema field changed
    • changedInput schema / properties / proposed / properties / lines / description
      Previous value: -"The FULL replacement line set — every line the corrected bill should have, not only the one that was wrong. Same shape as create_bill_draft. Omit it entirely when you are only correcting header fields. ⛔ LINE KEYS ARE STRICT: a key this schema does not list is REFUSED BY NAME and NOTHING is filed."New value: +"The FULL replacement line set — every line the corrected bill should have, not only the one that was wrong. Same shape as create_bill_draft. Omit it entirely when you are only correcting header fields. ⛔ LINE KEYS ARE STRICT: a key this schema does not list is REFUSED BY NAME and NOTHING is filed. A BILL THAT RECEIVED GOODS AGAINST A PURCHASE ORDER: you can correct the header, or prices/discounts/SST codes with EVERY line of the whole bill sent back exactly as it is (same products, quantities, order and units — lines not on the order included); any other line change, on any line, is refused at filing and is made by the user on the bill's Edit screen in Taokeh (Purchases → the bill → Edit). A header-only correction (no `lines`) reposts the bill's own lines unchanged."
  7. Changed1 schema field changed
    • changedInput schema / properties / proposed / properties / term / description
      Previous value: -"The SUPPLIER's payment term as it should read, stored as written (do not round a real term to the nearest familiar one). Pass null to clear it. Correcting the term does NOT move the due date; if the due date is wrong too, propose `dueDate` alongside it."New value: +"The SUPPLIER's payment term as it should read, stored as written (do not round a real term to the nearest familiar one). Pass null to clear it. On an ON-ACCOUNT bill, changing to one of the five preset terms re-derives the due date from the bill date (+ 0/7/14/30/60 days), shown to the reviewer before approval; an unrecognised term moves nothing. To change the term but KEEP the current due date, send `dueDate` alongside it — a stated dueDate always wins."
  8. Added

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare non-read-only, non-destructive, non-idempotent, but the description goes well beyond them: pending-draft/human-approval gating, the diff-review model, refusals named individually, edit-blocking preconditions checked twice (filing and approval), and id-following across Taokeh edits. It stops short of describing the response payload, but carries far more than the annotations.

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

Conciseness3/5

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

The critical constraint is front-loaded in caps, but the body is enormously long and repetitive — lineNo semantics, batch inheritance, and refusal messaging are restated in both the description and the schema, and several asides (e.g. the timber cut-list examples) could be trimmed without losing selection ability.

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 nested, five-parameter mutation tool with no output schema, the description covers the full decision surface: what can change, what is refused by name, what blocks an edit, concurrency behavior, and downstream effects on purchase-order obligations. Nothing needed to call it correctly is missing.

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 coverage is 100%, yet the description still adds non-derivable meaning: the full-replacement-set contract for `lines`, lineNo-driven removal and batch/stock inheritance, the `keep` shorthand semantics, unit-as-price-basis rules, and the rule that an omitted taxCode inherits rather than clears. These are integration behaviors the schema alone does not convey.

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 states a precise verb and resource — it files a pending correction draft for a bill already posted — and immediately scopes it ('NOTHING CHANGES UNTIL A HUMAN REVIEWS AND APPROVES IT'). It is cleanly distinguished from siblings like create_bill_draft and update_supplier_debit_note_draft, and from the two non-AI paths (void, debit note).

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 ROUTING section explicitly enumerates three mistake classes and assigns each to its door: void in Taokeh, this tool, or a debit note, with the click path for the two it does not handle. It also names when to prefer revise_draft (concurrent edit) and when to re-read the bill.

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