Skip to main content
Glama

Taokeh MCP server

Stage a historical document

stage_document

Bring ONE already-issued historical document (a sales invoice, or a supplier bill) across from the system this company is migrating FROM. This is the BULK migration door and it is NOT create_invoice_draft: nothing is posted, nothing is drafted for individual approval, and no approval card is raised per document. Staged documents group into monthly batches the owner reviews and approves together at /switch/documents. Use it ONLY for documents that were genuinely issued in the old system (or written in a paper book) — a NEW document belongs in create_invoice_draft / create_bill_draft. The lane must be OPEN (the owner turns it on at /switch → "Bring over your documents") and it can only be open before the books are locked; if it is closed the call is refused with instructions. IDEMPOTENCY IS ON sourceDocId: staging the same sourceDocId again UPDATES that pending row instead of filing a second one. Once the owner has ENTERED it, or deliberately LEFT IT OUT, nothing you send can change it, re-book it or bring it back — only the owner can. So re-running your whole export is always safe. THE CUTOVER: bring over only documents dated AFTER the company's accounting start date. Anything dated on or before it is already carried by the owner's opening balances, and Taokeh will flag it and refuse to enter it — staging those wastes both our time, so filter them out of your export if you can. ORDER MATTERS: stage the SUPPLIER BILLS for a period before the sales invoices for it, because Taokeh works out cost of sales from the stock that was bought. The server re-computes every quantity and the grand total from the lines (with SST); your own printed total goes in sourceTotal and is used ONLY to show the owner a tie against the server's figure. Anything the server cannot settle — a product that does not resolve, a customer name matching several contacts, a printed total that disagrees — is staged anyway, FLAGGED, and held out of bulk approve for the owner to open individually. The document keeps its ORIGINAL number (reference) and its ORIGINAL date, and posts marked as historical so Taokeh never e-invoices or chases it. PAPER: if you read this document off a photo or a scan, ATTACH IT — request_attachment_upload, PUT the bytes, pass attachmentToken here. The owner then reviews your figures beside the actual slip on that document's own screen, edits anything you misread, and approves it there; the original lands on the posted document. Without it they are approving your arithmetic on your word alone. Show your per-line working, and mark any balancing/catch-all line residual:true — a residual line carrying a material share of the total is flagged for the owner, because that is exactly where a misread hides. NOT EVERY LINE IS A CATALOGUED PRODUCT, and an old document is full of the ones that are not: a delivery or transport charge, a labour or installation line, a service fee, a rounding line. Those still go through as ordinary lines — productRef is REQUIRED and must not be blank, so put the line's OWN wording in it ("Delivery charge"), and Taokeh CREATES that wording as a non-stock item (MD, 2026-09-09) so the document derives normally — the row is flagged, the created item is named for the owner, and it carries no stock and no price of its own. That is the designed path: it is not an error, so do not drop the line, do not fold its amount into another line, and do not invent a SKU for it. Omitting productRef altogether is the one thing that fails — the call is refused at the boundary before anything is staged. ⛔ ROW KEYS ARE STRICT (MD, 2026-09-09): a key the schema does not list is REFUSED BY NAME — with the key it probably meant, e.g. sell_priceunitPrice — and NOTHING is staged. Send the contract's apiField, not the spreadsheet header. Unknown keys used to be dropped in silence, so a set could stage "successfully" with its prices missing; that is the bug this refusal closes. NOT IN THE CATALOGUE? IT IS NOW: a line whose productRef matches NOTHING is created as a NON-STOCK item named after the line's own wording (no stock, no price of its own, marked as created by the migration), so the document derives and the owner reviews figures instead of a blocked row. Tell the owner which items were added — the reply names them. A ref that matches SEVERAL products is still flagged rather than duplicated.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
linesYes
notesNoA SHORT note for the owner about this document — one or two sentences naming anything they should check. Not a place for lengthy reasoning.
partyNoThe customer (sales invoice) or supplier (purchase bill) name as printed. Matched against the existing contacts; a name matching several, or one that looks like shorthand for an existing contact, is flagged for the owner rather than guessed. Omit for a walk-in cash sale with no named customer.
docDateYesThe date the document was ORIGINALLY issued, YYYY-MM-DD. Never today unless it really was today — the whole point is that these documents keep their real dates.
docKindYes'sales_invoice' = an invoice this company ISSUED to a customer. 'purchase_bill' = a bill a supplier issued TO this company (inventory lines only, same rule as create_bill_draft). Other kinds are not supported yet.
partyIdNoThe Taokeh customer/vendor id, when you already resolved it with resolve_customer / resolve_vendor. Wins over `party`.
referenceNoThe document number exactly as printed in the old system (e.g. INV1603). Taokeh keeps it, so the customer's copy and yours still match. It must be unique in this company: a number already on the books is refused by name. Leave it out only if the document genuinely has no number. Before the first such invoice is entered, the owner must confirm where the real invoice series continues; Taokeh never silently starts migrated books at INV1.
needsReviewNoSet true when you want the owner to look at this one specifically. It is then held out of bulk approve and gets its own door.
sourceDocIdYesThe id this document has in the system you are migrating FROM — the primary key, row id or export id. THIS IS THE DEDUPE KEY: staging the same sourceDocId twice updates one row instead of booking the document twice, which is what makes re-running your export a no-op. If the old system has no id, use the document number, but use it consistently across the whole export.
sourceTotalNoThe grand total PRINTED on the source document. Advisory only — Taokeh re-derives its own figure and shows the two side by side, so the owner can see a whole batch tie to the old system's report. Send it whenever the paper states one; it is the single most useful check in the whole migration.
paymentMethodNo'CREDIT' (default) = it was on account, so it carries into receivables/payables. 'CASH' = it was settled at the counter. Get this right: it decides whether the document leaves a balance behind.
attachmentTokenNoThe ORIGINAL this document was read off — the photo of the handwritten cash-sale slip, the scanned invoice page. Call request_attachment_upload FIRST, PUT the raw bytes to its uploadUrl, then pass the token here (there is no inline base64 on this door: a backlog export would blow the context). The file rides the staged row, the owner sees it BESIDE your figures on the document's own review screen, and it lands on the posted invoice or bill automatically when they approve. Re-staging the same sourceDocId WITH a token replaces the file; re-staging without one leaves the file already there untouched, so a bare filing is repairable.

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed2 schema fields changed
    • addedInput schema / properties / lines / items / additionalProperties
      Added value: +false
    • addedInput schema / properties / lines / items / properties / description / description
      Added value: +"The line text as PRINTED on the historical document, when it says more than the product name does — a size, a grade, a job reference. It rides onto the posted line and is what the owner reads beside the original. THIS IS ALSO WHERE A NON-STOCK LINE LIVES: a delivery charge, a transport fee or a labour line has no catalogued product, so put its own wording in `productRef` (it is required and must not be blank) and any extra detail here — the line stages, is flagged as unresolved, and the owner picks or creates the item on the review screen. Do NOT drop the line and do not fold it into another one."
  2. Changed2 schema fields changed
    • changedInput schema / properties / lines / items / properties / quantity / description
      Previous value: -"The line quantity as the old document states it. On a measurement-profile workspace (see intake_contract's `measureProfile`) OMIT it whenever you give thickness/width/tally, or write the measure detail into the description ('2x2 = 10/10 12/14') — the server derives the authoritative quantity from those, and a quantity sent alongside a parseable tally is NOT used to compute: it is kept as your advisory figure and shown to the owner beside the server's. On the default passthrough workspace nothing is derived, so this IS the quantity — send it."New value: +"The line quantity as the old document states it. On a measurement-profile company (see intake_contract's `measureProfile`) OMIT it whenever you give thickness/width/tally, or write the measure detail into the description ('2x2 = 10/10 12/14') — the server derives the authoritative quantity from those, and a quantity sent alongside a parseable tally is NOT used to compute: it is kept as your advisory figure and shown to the owner beside the server's. On the default passthrough company nothing is derived, so this IS the quantity — send it."
    • changedInput schema / properties / lines / items / properties / thickness / description
      Previous value: -"Thickness in inches on a dimensional line — measurement-profile workspaces only (intake_contract shows this workspace's `measureProfile`). Give thickness + width + tally INSTEAD of a quantity and the server computes the authoritative quantity from them."New value: +"Thickness in inches on a dimensional line — measurement-profile companies only (intake_contract shows this company's `measureProfile`). Give thickness + width + tally INSTEAD of a quantity and the server computes the authoritative quantity from them."
  3. Changed4 schema fields changed
    • addedInput schema / properties / lines / items / properties / quantity / description
      Added value: +"The line quantity as the old document states it. On a measurement-profile workspace (see intake_contract's `measureProfile`) OMIT it whenever you give thickness/width/tally, or write the measure detail into the description ('2x2 = 10/10 12/14') — the server derives the authoritative quantity from those, and a quantity sent alongside a parseable tally is NOT used to compute: it is kept as your advisory figure and shown to the owner beside the server's. On the default passthrough workspace nothing is derived, so this IS the quantity — send it."
    • addedInput schema / properties / lines / items / properties / tally / description
      Added value: +"The piece tally as pieces/length_ft pairs — '10/10 12/14' is 10 pieces of 10 ft and 12 of 14 ft. With thickness and width this is what the quantity is derived FROM."
    • addedInput schema / properties / lines / items / properties / thickness / description
      Added value: +"Thickness in inches on a dimensional line — measurement-profile workspaces only (intake_contract shows this workspace's `measureProfile`). Give thickness + width + tally INSTEAD of a quantity and the server computes the authoritative quantity from them."
    • addedInput schema / properties / lines / items / properties / width / description
      Added value: +"Width in inches on a dimensional line. Goes with thickness and tally."
  4. Changed2 schema fields changed
    • changedInput schema / properties / docKind / description
      Previous value: -"'sales_invoice' = an invoice this workspace ISSUED to a customer. 'purchase_bill' = a bill a supplier issued TO this workspace (inventory lines only, same rule as create_bill_draft). Other kinds are not supported yet."New value: +"'sales_invoice' = an invoice this company ISSUED to a customer. 'purchase_bill' = a bill a supplier issued TO this company (inventory lines only, same rule as create_bill_draft). Other kinds are not supported yet."
    • changedInput schema / properties / reference / description
      Previous value: -"The document number exactly as printed in the old system (e.g. INV1603). Taokeh keeps it, so the customer's copy and yours still match. It must be unique in this workspace: a number already on the books is refused by name. Leave it out only if the document genuinely has no number. Before the first such invoice is entered, the owner must confirm where the real invoice series continues; Taokeh never silently starts migrated books at INV1."New value: +"The document number exactly as printed in the old system (e.g. INV1603). Taokeh keeps it, so the customer's copy and yours still match. It must be unique in this company: a number already on the books is refused by name. Leave it out only if the document genuinely has no number. Before the first such invoice is entered, the owner must confirm where the real invoice series continues; Taokeh never silently starts migrated books at INV1."
  5. Changed1 schema field changed
    • changedInput schema / properties / reference / description
      Previous value: -"The document number exactly as printed in the old system (e.g. INV1603). Taokeh keeps it, so the customer's copy and yours still match. It must be unique in this workspace: a number already on the books is refused by name. Leave it out only if the document genuinely has no number, and Taokeh will mint one."New value: +"The document number exactly as printed in the old system (e.g. INV1603). Taokeh keeps it, so the customer's copy and yours still match. It must be unique in this workspace: a number already on the books is refused by name. Leave it out only if the document genuinely has no number. Before the first such invoice is entered, the owner must confirm where the real invoice series continues; Taokeh never silently starts migrated books at INV1."
  6. Changed3 schema fields changed
    • addedInput schema / properties / attachmentToken
      Added value: +{
      +  "description": "The ORIGINAL this document was read off — the photo of the handwritten cash-sale slip, the scanned invoice page. Call request_attachment_upload FIRST, PUT the raw bytes to its uploadUrl, then pass the token here (there is no inline base64 on this door: a backlog export would blow the context). The file rides the staged row, the owner sees it BESIDE your figures on the document's own review screen, and it lands on the posted invoice or bill automatically when they approve. Re-staging the same sourceDocId WITH a token replaces the file; re-staging without one leaves the file already there untouched, so a bare filing is repairable.",
      +  "type": "string"
      +}
    • addedInput schema / properties / lines / items / properties / residual
      Added value: +{
      +  "description": "TRUE if this line is a balancing / catch-all figure rather than a real item — rounding, an adjustment, 'misc'. Say so honestly: Taokeh flags a residual line that carries a material share of the document, because that is where a misread hides. Never use a residual line to force a total to tie — report the gap instead.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / lines / items / properties / working / description
      Previous value: -"Your own arithmetic, kept for the owner to read. Never used to compute."New value: +"Your own arithmetic, kept for the owner to read. Never used to compute. On a handwritten slip this is what the owner checks you against — show the tally, the multiplication, the subtotal, in the order you did them."
  7. Added

TDQS

A3.9/5.0
Behavior1/5

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

The description is otherwise exemplary — it discloses dedupe/update semantics, flag-and-hold behavior for unresolved lines, original number/date preservation, and the paper-attachment flow. However, it explicitly and emphatically asserts 'IDEMPOTENCY IS ON sourceDocId' while the annotation declares idempotentHint=false — a direct contradiction that could cause an agent to misjudge re-run safety or duplicate prevention. Per the rubric, a description contradicting annotations forces score 1.

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

Conciseness4/5

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

Long but earned — this tool carries migration, idempotency, cutover, ordering, and approval constraints that a short description could not convey. It is front-loaded with purpose and sibling differentiation, and the ALL-CAPS keyword markers (BULK, CUTOVER, ORDER MATTERS, PAPER) aid agent scanning. Docked slightly because some content is redundant with the already-rich schema (e.g., attachmentToken re-staging semantics restate the schema's story).

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?

For a mutating 12-parameter tool with no output schema, the description covers nearly every operational behavior: closed-lane refusal with instructions, re-staging semantics, flag-and-hold of unsettled lines, owner-only changes after entry, and historical posting so Taokeh never e-invoices or chases the document. The one notable gap is that it never states what the call returns (staged row id/status), which matters more precisely because no output schema exists.

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 description coverage is 92% with already-rich property descriptions, so the baseline is 3. The description adds genuine operational meaning beyond the schema: sourceDocId as the key that makes re-running an export a no-op, sourceTotal as 'the single most useful check in the whole migration', residual lines flagged when they carry a material share, party matched 'flagged for the owner rather than guessed', and paymentMethod deciding 'whether the document leaves a balance behind'.

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 ('Bring ONE already-issued historical document... across from the system this company is migrating FROM') with the exact document kinds (sales invoice, supplier bill). Explicitly differentiates from sibling create_invoice_draft: 'it is NOT create_invoice_draft: nothing is posted, nothing is drafted for individual approval.' An agent can identify this as the bulk staging door 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?

Gives explicit when-to-use ('ONLY for documents that were genuinely issued in the old system (or written in a paper book)'), when-not ('a NEW document belongs in create_invoice_draft / create_bill_draft'), and names the alternatives. Also covers the lane-open/pre-books-locked precondition, the cutover date rule (filter out documents on or before accounting start date), and the ORDER MATTERS instruction to stage supplier bills before sales invoices.

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