Skip to main content
Glama
PNPC-MCP-Tally-Prime

PNPC-MCP-Tally-Prime

update_sales_invoice

DestructiveIdempotent

Update an existing TallyPrime Sales invoice voucher by replacing its item lines, party, and narration; match it by date and voucher number, and verify uniqueness before altering.

Instructions

Update an existing item-invoice Sales voucher in TallyPrime, replacing its item lines, party, and narration. Same fields as create_sales_invoice, plus voucherNumber. Matched by date + voucher number — use get_ledger_vouchers or get_vouchers first to confirm it exists and is unique. Refuses if another voucher type shares the same number on that date (confirmed live: Tally's Alter lookup ignores voucher type and can silently corrupt the wrong one) — resolve the collision in Tally first if that happens.

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": {
      "voucherNumber": "<voucherNumber>",
      "date": "<date>",
      "partyLedger": "<partyLedger>",
      "items": "<items>"
    },
    "name": "update_sales_invoice"
  }
}

Input Schema

NameRequiredDescriptionDefault
dateYesExisting invoice's date in DD-MM-YYYY format
itemsYesOne entry per invoice line — replaces all existing lines.
billNameNo
billTypeNo
buyerTrnNoThe buyer's TRN as it should appear on this invoice — same voucher-level snapshot field as create_sales_invoice's buyerTrn.
buyerNameNoName to print in this voucher's Buyer (Bill to) box, when it should differ from the customer ledger's own name — Tally's per-voucher Party Details mailing name. The ledger itself is not changed. Useful when many sales are posted against one shared ledger (e.g. cash or card sales) but each invoice needs its own readable buyer name.
narrationNoNew narration / description for the invoice
referenceNoFree-text reference for this invoice (Tally's voucher-level REFERENCE field).
vatLedgerNoDefault VAT ledger for items without their own override.
buyerStateNoThe buyer's Emirate/state as it should appear on this invoice's Party Details.
partyLedgerYesCustomer ledger name (the party being invoiced)
voucherTypeNoVoucher type of the existing voucher, if it isn't the default 'Sales' (e.g. 'Tax Invoice'). Used to find it and to check no other voucher shares its number.
buyerCountryNoThe buyer's country as it should appear on this invoice's Party Details.
referenceDateNoDate for the reference above, in DD-MM-YYYY format.
voucherNumberYesExact voucher number of the invoice to update
vatRatePercentNoDefault VAT rate. Required if vatLedger is set.
placeOfSupplyCountryNoUAE VAT Place of Supply Country for this invoice.
placeOfSupplyEmirateNoUAE VAT Place of Supply Emirate for this invoice.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.14.1
    • addedInput schema / properties / buyerName
      Added value: +{
      +  "description": "Name to print in this voucher's Buyer (Bill to) box, when it should differ from the customer ledger's own name — Tally's per-voucher Party Details mailing name. The ledger itself is not changed. Useful when many sales are posted against one shared ledger (e.g. cash or card sales) but each invoice needs its own readable buyer name.",
      +  "type": "string"
      +}
  2. Changed2 schema fields changedv1.14.0
    • addedInput schema / properties / items / items / properties / description
      Added value: +{
      +  "description": "Description lines shown under this stock line on the invoice, one array entry per line (e.g. a size, colour or service period). Optional.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / voucherType
      Added value: +{
      +  "description": "Voucher type of the existing voucher, if it isn't the default 'Sales' (e.g. 'Tax Invoice'). Used to find it and to check no other voucher shares its number.",
      +  "type": "string"
      +}
  3. Addedv1.11.2

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false, so the safety profile is supplied. The description nonetheless adds valuable behavior beyond that: it discloses the refusal condition and the reason ('Tally's Alter lookup ignores voucher type and can silently corrupt the wrong one'), which is exactly the kind of risk context annotations cannot express. It does not say whether omitted optional fields are cleared or preserved on an update, which is the main remaining behavioral gap.

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?

Front-loaded with the action and scope, then the identity/matching rule, then the failure mode. Every sentence carries information, though the parenthetical about Tally's Alter lookup is longer than needed and could be compressed without losing the warning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-required, 18-parameter destructive mutation with no output schema, the description covers identification and failure well. It is silent on the most consequential ambiguity of an update: whether optional fields left unsupplied are wiped or retained, and what a successful response confirms. That omission matters given the tool replaces lines and party.

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 already 89%, so the schema carries most parameter meaning; the description still adds real semantics, notably that matching is on date + voucher number as a composite key and that items 'replaces all existing lines'. The collision-refusal rule also gives voucherType a purpose that the field-level text only partly conveys.

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 ('Update an existing item-invoice Sales voucher in TallyPrime') plus the scope of what is replaced (item lines, party, narration). It explicitly positions itself against create_sales_invoice ('Same fields as create_sales_invoice, plus voucherNumber'), so an agent can distinguish it from the sibling create tool and the other update_* tools without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete precondition: call get_ledger_vouchers or get_vouchers first to confirm the voucher exists and is unique. It also gives a fallback instruction when the pre-check reveals a collision ('resolve the collision in Tally first'). It stops short of contrasting with update_voucher or explaining when to prefer this over a delete-and-recreate, so it is clear context but not exhaustive routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools