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_price → unitPrice — 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. ⚠ NOT ON A DOCUMENT THE CUTOVER FENCE REFUSES: Taokeh will not grow the catalogue for a document it can never enter, so a pre-cutover row stages with no figures and an unresolved-product note ALONGSIDE its fence. The fence is the blocker; the product note is a consequence of it. Do not call resolve_product for such a row, do not ask the owner to add a catalogue item for it, and never route it to the manual bill form or the expense door — the only answers are to leave it out or to have the owner move the accounting start date.

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.

  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

A4.7/5.0
Behavior5/5

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

With sparse annotations (all hints false), the description carries the full burden and delivers richly: idempotency keyed to sourceDocId, the 'once entered or left out, only the owner can change it' irreversibility, strict row-key refusal at the boundary, non-stock item auto-creation, and the cutover fence refusing catalogue growth. The idempotentHint=false annotation is a coarse general hint while the description precisely scopes idempotency to a key — a nuance, not a hard contradiction.

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 description is thorough but verbose — a wall of text with ALL-CAPS emphasis, emoji section markers (⛔⚠), and repeated warnings. For a tool with 12 params and many edge cases, depth is justified, but the aggressive formatting hurts scannability and several points (e.g., the non-stock path) are restated multiple times. Not under-specified, but not tight.

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 the most complex tool in the set, nothing material is missing: when to use vs. siblings, dedupe semantics, cutover fence, ordering, flagging/held-out-of-approve behavior, original number/date preservation, historical posting so it is never e-invoiced, paper attachment, residual lines, strict keys, and non-stock creation. The reply content for created items is even disclosed ('the reply names them'). No output schema exists, but the return is adequately described inline.

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 92%, so the schema already documents most parameters well. The description still adds genuine value: it explains the attachmentToken flow (call request_attachment_upload first, PUT bytes, then pass token), reinforces sourceDocId as the dedupe key, and clarifies productRef is required and auto-creates non-stock items. This exceeds the baseline 3 but the schema is doing most of the heavy lifting.

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 opens with a precise verb+resource ('Bring ONE already-issued historical document... across') and immediately differentiates itself from create_invoice_draft by stating what it is NOT ('nothing is posted, nothing is drafted for individual approval, and no approval card is raised per document'). An agent can confidently distinguish it from the create_*_draft siblings without opening any 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?

Extremely explicit: names the exact alternatives (create_invoice_draft / create_bill_draft) for NEW documents, states the lane must be OPEN and only before books are locked, gives the cutover date rule (documents dated AFTER the accounting start date), and orders supplier bills before sales invoices. No inference is left to the agent.

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