Skip to main content
Glama

Taokeh MCP server

File a pending purchase-order correction draft (human approves in Taokeh)

update_purchase_order_draft

FILES A PENDING DRAFT ONLY — NOTHING CHANGES UNTIL A HUMAN REVIEWS AND APPROVES IT IN TAOKEH. Propose a correction to a PURCHASE ORDER that already exists — a wrong quantity or cost, a missing or extra line, the wrong date, term or notes. An admin or bookkeeper reviews a plain current → proposed DIFF and approves. A purchase order posts nothing and moves no stock, so the correction touches no ledger and no stock; a SENT order stays SENT, and Taokeh emails nobody — sending the corrected order to the supplier is the user's own step (an approved change stops the WhatsApp link the supplier was sent, so they need the order again). ROUTING — (1) the order should not stand: the owner cancels it in Taokeh (Purchase orders → the PO → Cancel); there is no AI lane for cancelling. (2) the order is wrong and not yet received in full: THIS tool — a DRAFT, a SENT or a PARTIAL (partly received) order all qualify. On a PARTIAL order a line that has received goods must keep its product and cannot go below the quantity already received (send it at least that), and it cannot be dropped from lines — the approval is refused by name otherwise; the supplier and currency are frozen once anything has arrived. (3) the order is CONVERTED (received in full, or the rest closed as never coming) or CANCELLED: it is closed to edits — the delivery bills are the documents now, corrected in Taokeh (Purchases → the bill → Edit). A NEW order is create_purchase_order_draft. WHAT YOU CAN CHANGE: poDate, term (null clears it), notes (null clears them) and lines. A purchase order is taxed from its lines' SST codes (rounded per code on the subtotal; an order entered before 7 Oct 2026 keeps the per-line rounding it was saved with), the same as the bill it becomes: a new line inherits the code this order already stores for its product; a new product takes the order's code when every line carries the same one; otherwise it carries no SST (the review shows the new total). An order with NO SST code on any line is taxed at a whole-document rate Taokeh stores only as an amount, so when such a taxed order's LINES change you must also send taxRate (see its field). WHAT YOU CANNOT, each refused by name: the SUPPLIER (an order to someone else is a different order), the PO NUMBER, the CURRENCY or exchange rate, the TAX, and marking sent, cancelling or converting. INVENTORY-ONLY lines, as on create_purchase_order_draft. WHAT HAPPENS ON APPROVAL: the document is updated IN PLACE — same id, same number — through the SAME update Taokeh's own Edit screen runs. Every field you leave out is carried across exactly as it stands (the party, the attention contact, the currency and its frozen exchange rate, the tax) and is never reset. LINES: lines is the FULL replacement set. READ THE LINES FIRST with search_document_lines — each row's lineNo is what a { keep: } entry refers to, and keep is how a line that is already right survives untouched (a measured line keeps its frozen unit and its rounding row). A changed or new line is written in full, in the create tool's line shape, and the server re-derives its quantity and amount. A proposal that changes nothing is refused rather than filed as an empty diff. STALE: if a person edits the document after you read it, the one-tap approval is refused and the reviewer is shown both versions — call revise_draft with this draft's kind to re-read and re-propose. Pass the document's REAL id from search_documents; a document number is refused. 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/ft)" (older documents print "/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: } 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.

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": {
      "purchaseOrderId": "<purchaseOrderId>",
      "proposed": "<proposed>"
    },
    "name": "update_purchase_order_draft"
  }
}

Input Schema

NameRequiredDescriptionDefault
notesNoA SHORT reviewer note in the reviewer's language: what was wrong, what you changed, and anything they should check before approving.
proposedYesONLY what you want changed. An unknown or not-patchable key is refused by name; a proposal the purchase order already agrees with is refused rather than filed.
needsReviewNoSet true when something gave you pause — a quantity you inferred, a price the user was unsure about. It flags the draft for the reviewer.
printedTotalNoThe grand total the corrected purchase order should show, if the user told you one — cross-checked against the server's own figure and flagged on the review screen.
purchaseOrderIdYesREQUIRED — the purchase order's real id, from search_documents. A PO number is refused.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / proposed / properties / term / description
      Previous value: -"The delivery/payment term as it should read (stored as written). Pass null to clear it."New value: +"The delivery/payment term as it should read (stored as written). Pass null to clear it. Bills made afterwards with Taokeh's \"Receive a delivery\" take it (a preset term such as 'Net 30' sets each one's due date from its own date); bills already made, and scanned bills matched to the order, keep their own."
  2. Changed2 schema fields changed
    • removedInput schema / properties / proposed / properties / lines / items / properties / discount / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "string"
      -  }
      -]
    • addedInput schema / properties / proposed / properties / lines / items / properties / discount / type
      Added value: +[
      +  "number",
      +  "string"
      +]
  3. Changed1 schema field changed
    • changedInput schema / properties / proposed / properties / lines / items / properties / keep / description
      Previous value: -"Keep an EXISTING line exactly as it stands: { keep: <lineNo> } and nothing else beside it — lineNo from search_document_lines. The stored line rides across VERBATIM (its frozen unit, its discount, its SST code) and, on a measured line, the engine's rounding row under it comes along automatically. Use this for every line that is already right. 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."New value: +"Keep an EXISTING line exactly as it stands: { keep: <lineNo> } and nothing else beside it — lineNo from search_document_lines. The stored line rides across VERBATIM (its frozen unit, its discount, its SST code) and, on a measured line, the engine's rounding row under it comes along automatically. Use this for every line that is already right. 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/ft)\" (older documents print \"/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."
  4. Changed1 schema field changed
    • changedInput schema / properties / proposed / properties / lines / items / properties / keep / description
      Previous value: -"Keep an EXISTING line exactly as it stands: { keep: <lineNo> } and nothing else beside it — lineNo from search_document_lines. The stored line rides across VERBATIM (its frozen unit, its discount, its SST code) and, on a measured line, the engine's rounding row under it comes along automatically. Use this for every line that is already right."New value: +"Keep an EXISTING line exactly as it stands: { keep: <lineNo> } and nothing else beside it — lineNo from search_document_lines. The stored line rides across VERBATIM (its frozen unit, its discount, its SST code) and, on a measured line, the engine's rounding row under it comes along automatically. Use this for every line that is already right. 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."
  5. Changed1 schema field changed
    • changedInput schema / properties / proposed / properties / lines / items / properties / unitCost / description
      Previous value: -"The cost per unit agreed with the supplier, in the document's own currency. 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: +"The cost per unit agreed with the supplier, in the document's own currency. 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."
  6. Changed1 schema field changed
    • changedInput schema / properties / proposed / properties / lines / items / properties / unitCost / description
      Previous value: -"The cost per unit agreed with the supplier, in the document's own currency."New value: +"The cost per unit agreed with the supplier, in the document's own currency. 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."
  7. Changed1 schema field 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."
  8. Added

TDQS

A4.7/5.0
Behavior5/5

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

Far exceeds the annotations (readOnly=false, destructive=false, idempotent=false): it discloses the human-approval gate, that the update is in place (same id, same number), that omitted fields are carried across and never reset, that a no-op diff is refused, that stale documents are refused with both versions shown, and that the supplier WhatsApp link is invalidated on approval. It also enumerates each refusal by name, which is exactly the behavioral context annotations cannot carry.

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 capitals, which is good, but the body is a dense ~700-word block with long ALL-CAPS clauses and no structural breaks beyond inline dashes. The per-foot/per-piece conversion paragraph is reproduced almost verbatim in the schema's `keep` field description, so a meaningful share of the text does not earn its place.

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, non-idempotent mutation with no output schema and partial-order edge cases, nothing material is missing: tax derivation, frozen supplier/currency after partial receipt, line-level replacement semantics, staleness, and the reviewer-visible diff are all covered. An agent could call this correctly from the description alone.

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 100%, so the baseline is 3, but the description adds real semantic value on top: it names the changeable set (poDate, term, notes, lines), establishes that 'lines' is a FULL replacement set, mandates reading lineNo via search_document_lines before proposing, and states the conditional requirement for taxRate on whole-document-taxed orders. It also clarifies that purchaseOrderId must be the real id, not a document number.

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?

Opens with a specific verb and resource ('Propose a correction to a PURCHASE ORDER that already exists') and immediately bounds it ('FILES A PENDING DRAFT ONLY — NOTHING CHANGES UNTIL A HUMAN REVIEWS AND APPROVES IT'). It names the sibling it is not ('A NEW order is create_purchase_order_draft'), so an agent can route without opening either 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?

The ROUTING block gives explicit when-to-use and when-not-to-use branches keyed to document state: cancel → no AI lane, DRAFT/SENT/PARTIAL → this tool, CONVERTED/CANCELLED → correct the bill in Taokeh, new order → create_purchase_order_draft. It also names the recovery path for a stale read ('call revise_draft with this draft's kind').

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