jaz-clio 5.4.7 → 5.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/skills/api/SKILL.md +1 -1
- package/assets/skills/cli/SKILL.md +1 -1
- package/assets/skills/conversion/SKILL.md +1 -1
- package/assets/skills/jobs/SKILL.md +1 -1
- package/assets/skills/practice/SKILL.md +1 -1
- package/assets/skills/transaction-recipes/SKILL.md +1 -1
- package/cli.mjs +102 -110
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -668,14 +668,15 @@ Strings are replaced with values relative to the transaction date.`);t.command("
|
|
|
668
668
|
path: iss.path ? [${Ba(v)}, ...iss.path] : [${Ba(v)}]
|
|
669
669
|
})));`),f.write(`newResult[${Ba(v)}] = ${y}.value`)}f.write("payload.value = newResult;"),f.write("return payload;");let D=f.compile();return(v,y)=>D(d,v,y)},o,i=Fu,s=!mv.jitless,c=s&&aT.value,u=t.catchall,l;e._zod.parse=(d,f)=>{l??(l=r.value);let p=d.value;if(!i(p))return d.issues.push({expected:"object",code:"invalid_type",input:p,inst:e}),d;let m=[];if(s&&c&&f?.async===!1&&f.jitless!==!0)o||(o=n(t.shape)),d=o(d,f);else{d.value={};let y=l.shape;for(let b of l.keys){let S=y[b],E=S._zod.run({value:p[b],issues:[]},f),A=S._zod.optin==="optional"&&S._zod.optout==="optional";E instanceof Promise?m.push(E.then(O=>A?l6(O,d,b,p):Sv(O,d,b))):A?l6(E,d,b,p):Sv(E,d,b)}}if(!u)return m.length?Promise.all(m).then(()=>d):d;let h=[],g=l.keySet,D=u._zod,v=D.def.type;for(let y of Object.keys(p)){if(g.has(y))continue;if(v==="never"){h.push(y);continue}let b=D.run({value:p[y],issues:[]},f);b instanceof Promise?m.push(b.then(S=>Sv(S,d,y))):Sv(b,d,y)}return h.length&&d.issues.push({code:"unrecognized_keys",keys:h,input:p,inst:e}),m.length?Promise.all(m).then(()=>d):d}});function d6(e,t,r,n){for(let o of e)if(o.issues.length===0)return t.value=o.value,t;return t.issues.push({code:"invalid_union",input:t.value,inst:r,errors:e.map(o=>o.issues.map(i=>ko(i,n,co())))}),t}var _T=L("$ZodUnion",(e,t)=>{Dt.init(e,t),yt(e._zod,"optin",()=>t.options.some(r=>r._zod.optin==="optional")?"optional":void 0),yt(e._zod,"optout",()=>t.options.some(r=>r._zod.optout==="optional")?"optional":void 0),yt(e._zod,"values",()=>{if(t.options.every(r=>r._zod.values))return new Set(t.options.flatMap(r=>Array.from(r._zod.values)))}),yt(e._zod,"pattern",()=>{if(t.options.every(r=>r._zod.pattern)){let r=t.options.map(n=>n._zod.pattern);return new RegExp(`^(${r.map(n=>Yf(n.source)).join("|")})$`)}}),e._zod.parse=(r,n)=>{let o=!1,i=[];for(let s of t.options){let a=s._zod.run({value:r.value,issues:[]},n);if(a instanceof Promise)i.push(a),o=!0;else{if(a.issues.length===0)return a;i.push(a)}}return o?Promise.all(i).then(s=>d6(s,r,e,n)):d6(i,r,e,n)}}),W6=L("$ZodDiscriminatedUnion",(e,t)=>{_T.init(e,t);let r=e._zod.parse;yt(e._zod,"propValues",()=>{let o={};for(let i of t.options){let s=i._zod.propValues;if(!s||Object.keys(s).length===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(i)}"`);for(let[a,c]of Object.entries(s)){o[a]||(o[a]=new Set);for(let u of c)o[a].add(u)}}return o});let n=qf(()=>{let o=t.options,i=new Map;for(let s of o){let a=s._zod.propValues[t.discriminator];if(!a||a.size===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(s)}"`);for(let c of a){if(i.has(c))throw new Error(`Duplicate discriminator value "${String(c)}"`);i.set(c,s)}}return i});e._zod.parse=(o,i)=>{let s=o.value;if(!Fu(s))return o.issues.push({code:"invalid_type",expected:"object",input:s,inst:e}),o;let a=n.value.get(s?.[t.discriminator]);return a?a._zod.run(o,i):t.unionFallback?r(o,i):(o.issues.push({code:"invalid_union",errors:[],note:"No matching discriminator",input:s,path:[t.discriminator],inst:e}),o)}}),Z6=L("$ZodIntersection",(e,t)=>{Dt.init(e,t),e._zod.parse=(r,n)=>{let o=r.value,i=t.left._zod.run({value:o,issues:[]},n),s=t.right._zod.run({value:o,issues:[]},n);return i instanceof Promise||s instanceof Promise?Promise.all([i,s]).then(([c,u])=>p6(r,c,u)):p6(r,i,s)}});function vT(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e==+t)return{valid:!0,data:e};if(Pu(e)&&Pu(t)){let r=Object.keys(t),n=Object.keys(e).filter(i=>r.indexOf(i)!==-1),o={...e,...t};for(let i of n){let s=vT(e[i],t[i]);if(!s.valid)return{valid:!1,mergeErrorPath:[i,...s.mergeErrorPath]};o[i]=s.data}return{valid:!0,data:o}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};let r=[];for(let n=0;n<e.length;n++){let o=e[n],i=t[n],s=vT(o,i);if(!s.valid)return{valid:!1,mergeErrorPath:[n,...s.mergeErrorPath]};r.push(s.data)}return{valid:!0,data:r}}return{valid:!1,mergeErrorPath:[]}}function p6(e,t,r){if(t.issues.length&&e.issues.push(...t.issues),r.issues.length&&e.issues.push(...r.issues),Ua(e))return e;let n=vT(t.value,r.value);if(!n.valid)throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(n.mergeErrorPath)}`);return e.value=n.data,e}var K6=L("$ZodRecord",(e,t)=>{Dt.init(e,t),e._zod.parse=(r,n)=>{let o=r.value;if(!Pu(o))return r.issues.push({expected:"record",code:"invalid_type",input:o,inst:e}),r;let i=[];if(t.keyType._zod.values){let s=t.keyType._zod.values;r.value={};for(let c of s)if(typeof c=="string"||typeof c=="number"||typeof c=="symbol"){let u=t.valueType._zod.run({value:o[c],issues:[]},n);u instanceof Promise?i.push(u.then(l=>{l.issues.length&&r.issues.push(...oi(c,l.issues)),r.value[c]=l.value})):(u.issues.length&&r.issues.push(...oi(c,u.issues)),r.value[c]=u.value)}let a;for(let c in o)s.has(c)||(a=a??[],a.push(c));a&&a.length>0&&r.issues.push({code:"unrecognized_keys",input:o,inst:e,keys:a})}else{r.value={};for(let s of Reflect.ownKeys(o)){if(s==="__proto__")continue;let a=t.keyType._zod.run({value:s,issues:[]},n);if(a instanceof Promise)throw new Error("Async schemas not supported in object keys currently");if(a.issues.length){r.issues.push({origin:"record",code:"invalid_key",issues:a.issues.map(u=>ko(u,n,co())),input:s,path:[s],inst:e}),r.value[a.value]=a.value;continue}let c=t.valueType._zod.run({value:o[s],issues:[]},n);c instanceof Promise?i.push(c.then(u=>{u.issues.length&&r.issues.push(...oi(s,u.issues)),r.value[a.value]=u.value})):(c.issues.length&&r.issues.push(...oi(s,c.issues)),r.value[a.value]=c.value)}}return i.length?Promise.all(i).then(()=>r):r}});var X6=L("$ZodEnum",(e,t)=>{Dt.init(e,t);let r=nT(t.entries);e._zod.values=new Set(r),e._zod.pattern=new RegExp(`^(${r.filter(n=>cT.has(typeof n)).map(n=>typeof n=="string"?_s(n):n.toString()).join("|")})$`),e._zod.parse=(n,o)=>{let i=n.value;return e._zod.values.has(i)||n.issues.push({code:"invalid_value",values:r,input:i,inst:e}),n}}),Q6=L("$ZodLiteral",(e,t)=>{Dt.init(e,t),e._zod.values=new Set(t.values),e._zod.pattern=new RegExp(`^(${t.values.map(r=>typeof r=="string"?_s(r):r?r.toString():String(r)).join("|")})$`),e._zod.parse=(r,n)=>{let o=r.value;return e._zod.values.has(o)||r.issues.push({code:"invalid_value",values:t.values,input:o,inst:e}),r}});var eY=L("$ZodTransform",(e,t)=>{Dt.init(e,t),e._zod.parse=(r,n)=>{let o=t.transform(r.value,r);if(n.async)return(o instanceof Promise?o:Promise.resolve(o)).then(s=>(r.value=s,r));if(o instanceof Promise)throw new Fi;return r.value=o,r}}),tY=L("$ZodOptional",(e,t)=>{Dt.init(e,t),e._zod.optin="optional",e._zod.optout="optional",yt(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),yt(e._zod,"pattern",()=>{let r=t.innerType._zod.pattern;return r?new RegExp(`^(${Yf(r.source)})?$`):void 0}),e._zod.parse=(r,n)=>t.innerType._zod.optin==="optional"?t.innerType._zod.run(r,n):r.value===void 0?r:t.innerType._zod.run(r,n)}),rY=L("$ZodNullable",(e,t)=>{Dt.init(e,t),yt(e._zod,"optin",()=>t.innerType._zod.optin),yt(e._zod,"optout",()=>t.innerType._zod.optout),yt(e._zod,"pattern",()=>{let r=t.innerType._zod.pattern;return r?new RegExp(`^(${Yf(r.source)}|null)$`):void 0}),yt(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(r,n)=>r.value===null?r:t.innerType._zod.run(r,n)}),nY=L("$ZodDefault",(e,t)=>{Dt.init(e,t),e._zod.optin="optional",yt(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(r,n)=>{if(r.value===void 0)return r.value=t.defaultValue,r;let o=t.innerType._zod.run(r,n);return o instanceof Promise?o.then(i=>f6(i,t)):f6(o,t)}});function f6(e,t){return e.value===void 0&&(e.value=t.defaultValue),e}var oY=L("$ZodPrefault",(e,t)=>{Dt.init(e,t),e._zod.optin="optional",yt(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(r,n)=>(r.value===void 0&&(r.value=t.defaultValue),t.innerType._zod.run(r,n))}),iY=L("$ZodNonOptional",(e,t)=>{Dt.init(e,t),yt(e._zod,"values",()=>{let r=t.innerType._zod.values;return r?new Set([...r].filter(n=>n!==void 0)):void 0}),e._zod.parse=(r,n)=>{let o=t.innerType._zod.run(r,n);return o instanceof Promise?o.then(i=>m6(i,e)):m6(o,e)}});function m6(e,t){return!e.issues.length&&e.value===void 0&&e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}var sY=L("$ZodCatch",(e,t)=>{Dt.init(e,t),e._zod.optin="optional",yt(e._zod,"optout",()=>t.innerType._zod.optout),yt(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(r,n)=>{let o=t.innerType._zod.run(r,n);return o instanceof Promise?o.then(i=>(r.value=i.value,i.issues.length&&(r.value=t.catchValue({...r,error:{issues:i.issues.map(s=>ko(s,n,co()))},input:r.value}),r.issues=[]),r)):(r.value=o.value,o.issues.length&&(r.value=t.catchValue({...r,error:{issues:o.issues.map(i=>ko(i,n,co()))},input:r.value}),r.issues=[]),r)}});var aY=L("$ZodPipe",(e,t)=>{Dt.init(e,t),yt(e._zod,"values",()=>t.in._zod.values),yt(e._zod,"optin",()=>t.in._zod.optin),yt(e._zod,"optout",()=>t.out._zod.optout),e._zod.parse=(r,n)=>{let o=t.in._zod.run(r,n);return o instanceof Promise?o.then(i=>h6(i,t,n)):h6(o,t,n)}});function h6(e,t,r){return Ua(e)?e:t.out._zod.run({value:e.value,issues:e.issues},r)}var cY=L("$ZodReadonly",(e,t)=>{Dt.init(e,t),yt(e._zod,"propValues",()=>t.innerType._zod.propValues),yt(e._zod,"values",()=>t.innerType._zod.values),yt(e._zod,"optin",()=>t.innerType._zod.optin),yt(e._zod,"optout",()=>t.innerType._zod.optout),e._zod.parse=(r,n)=>{let o=t.innerType._zod.run(r,n);return o instanceof Promise?o.then(g6):g6(o)}});function g6(e){return e.value=Object.freeze(e.value),e}var uY=L("$ZodCustom",(e,t)=>{Gr.init(e,t),Dt.init(e,t),e._zod.parse=(r,n)=>r,e._zod.check=r=>{let n=r.value,o=t.fn(n);if(o instanceof Promise)return o.then(i=>y6(i,r,n,e));y6(o,r,n,e)}});function y6(e,t,r,n){if(!e){let o={code:"custom",input:r,inst:n,path:[...n._zod.def.path??[]],continue:!n._zod.def.abort};n._zod.def.params&&(o.params=n._zod.def.params),t.issues.push(dT(o))}}var hfe=e=>{let t=typeof e;switch(t){case"number":return Number.isNaN(e)?"NaN":"number";case"object":{if(Array.isArray(e))return"array";if(e===null)return"null";if(Object.getPrototypeOf(e)!==Object.prototype&&e.constructor)return e.constructor.name}}return t},gfe=()=>{let e={string:{unit:"characters",verb:"to have"},file:{unit:"bytes",verb:"to have"},array:{unit:"items",verb:"to have"},set:{unit:"items",verb:"to have"}};function t(n){return e[n]??null}let r={regex:"input",email:"email address",url:"URL",emoji:"emoji",uuid:"UUID",uuidv4:"UUIDv4",uuidv6:"UUIDv6",nanoid:"nanoid",guid:"GUID",cuid:"cuid",cuid2:"cuid2",ulid:"ULID",xid:"XID",ksuid:"KSUID",datetime:"ISO datetime",date:"ISO date",time:"ISO time",duration:"ISO duration",ipv4:"IPv4 address",ipv6:"IPv6 address",cidrv4:"IPv4 range",cidrv6:"IPv6 range",base64:"base64-encoded string",base64url:"base64url-encoded string",json_string:"JSON string",e164:"E.164 number",jwt:"JWT",template_literal:"input"};return n=>{switch(n.code){case"invalid_type":return`Invalid input: expected ${n.expected}, received ${hfe(n.input)}`;case"invalid_value":return n.values.length===1?`Invalid input: expected ${yv(n.values[0])}`:`Invalid option: expected one of ${hv(n.values,"|")}`;case"too_big":{let o=n.inclusive?"<=":"<",i=t(n.origin);return i?`Too big: expected ${n.origin??"value"} to have ${o}${n.maximum.toString()} ${i.unit??"elements"}`:`Too big: expected ${n.origin??"value"} to be ${o}${n.maximum.toString()}`}case"too_small":{let o=n.inclusive?">=":">",i=t(n.origin);return i?`Too small: expected ${n.origin} to have ${o}${n.minimum.toString()} ${i.unit}`:`Too small: expected ${n.origin} to be ${o}${n.minimum.toString()}`}case"invalid_format":{let o=n;return o.format==="starts_with"?`Invalid string: must start with "${o.prefix}"`:o.format==="ends_with"?`Invalid string: must end with "${o.suffix}"`:o.format==="includes"?`Invalid string: must include "${o.includes}"`:o.format==="regex"?`Invalid string: must match pattern ${o.pattern}`:`Invalid ${r[o.format]??n.format}`}case"not_multiple_of":return`Invalid number: must be a multiple of ${n.divisor}`;case"unrecognized_keys":return`Unrecognized key${n.keys.length>1?"s":""}: ${hv(n.keys,", ")}`;case"invalid_key":return`Invalid key in ${n.origin}`;case"invalid_union":return"Invalid input";case"invalid_element":return`Invalid value in ${n.origin}`;default:return"Invalid input"}}};function lY(){return{localeError:gfe()}}var ET=class{constructor(){this._map=new Map,this._idmap=new Map}add(t,...r){let n=r[0];if(this._map.set(t,n),n&&typeof n=="object"&&"id"in n){if(this._idmap.has(n.id))throw new Error(`ID ${n.id} already exists in the registry`);this._idmap.set(n.id,t)}return this}clear(){return this._map=new Map,this._idmap=new Map,this}remove(t){let r=this._map.get(t);return r&&typeof r=="object"&&"id"in r&&this._idmap.delete(r.id),this._map.delete(t),this}get(t){let r=t._zod.parent;if(r){let n={...this.get(r)??{}};return delete n.id,{...n,...this._map.get(t)}}return this._map.get(t)}has(t){return this._map.has(t)}};function yfe(){return new ET}var Hf=yfe();function dY(e,t){return new e({type:"string",...he(t)})}function pY(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...he(t)})}function IT(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...he(t)})}function fY(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...he(t)})}function mY(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...he(t)})}function hY(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...he(t)})}function gY(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...he(t)})}function yY(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...he(t)})}function DY(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...he(t)})}function bY(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...he(t)})}function vY(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...he(t)})}function SY(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...he(t)})}function _Y(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...he(t)})}function EY(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...he(t)})}function IY(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...he(t)})}function CY(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...he(t)})}function xY(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...he(t)})}function AY(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...he(t)})}function wY(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...he(t)})}function TY(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...he(t)})}function OY(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...he(t)})}function RY(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...he(t)})}function $Y(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...he(t)})}function NY(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...he(t)})}function kY(e,t){return new e({type:"string",format:"date",check:"string_format",...he(t)})}function FY(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...he(t)})}function PY(e,t){return new e({type:"string",format:"duration",check:"string_format",...he(t)})}function LY(e,t){return new e({type:"number",checks:[],...he(t)})}function jY(e,t){return new e({type:"number",check:"number_format",abort:!1,format:"safeint",...he(t)})}function MY(e,t){return new e({type:"boolean",...he(t)})}function BY(e,t){return new e({type:"null",...he(t)})}function UY(e){return new e({type:"unknown"})}function qY(e,t){return new e({type:"never",...he(t)})}function Ev(e,t){return new DT({check:"less_than",...he(t),value:e,inclusive:!1})}function Wf(e,t){return new DT({check:"less_than",...he(t),value:e,inclusive:!0})}function Iv(e,t){return new bT({check:"greater_than",...he(t),value:e,inclusive:!1})}function Zf(e,t){return new bT({check:"greater_than",...he(t),value:e,inclusive:!0})}function Cv(e,t){return new W9({check:"multiple_of",...he(t),value:e})}function xv(e,t){return new K9({check:"max_length",...he(t),maximum:e})}function Lu(e,t){return new X9({check:"min_length",...he(t),minimum:e})}function Av(e,t){return new Q9({check:"length_equals",...he(t),length:e})}function CT(e,t){return new e6({check:"string_format",format:"regex",...he(t),pattern:e})}function xT(e){return new t6({check:"string_format",format:"lowercase",...he(e)})}function AT(e){return new r6({check:"string_format",format:"uppercase",...he(e)})}function wT(e,t){return new n6({check:"string_format",format:"includes",...he(t),includes:e})}function TT(e,t){return new o6({check:"string_format",format:"starts_with",...he(t),prefix:e})}function OT(e,t){return new i6({check:"string_format",format:"ends_with",...he(t),suffix:e})}function qa(e){return new s6({check:"overwrite",tx:e})}function RT(e){return qa(t=>t.normalize(e))}function $T(){return qa(e=>e.trim())}function NT(){return qa(e=>e.toLowerCase())}function kT(){return qa(e=>e.toUpperCase())}function zY(e,t,r){return new e({type:"array",element:t,...he(r)})}function YY(e,t,r){let n=he(r);return n.abort??(n.abort=!0),new e({type:"custom",check:"custom",fn:t,...n})}function JY(e,t,r){return new e({type:"custom",check:"custom",fn:t,...he(r)})}function ju(e){return!!e._zod}function Es(e,t){return ju(e)?Gf(e,t):e.safeParse(t)}function wv(e){if(!e)return;let t;if(ju(e)?t=e._zod?.def?.shape:t=e.shape,!!t){if(typeof t=="function")try{return t()}catch{return}return t}}function GY(e){if(ju(e)){let i=e._zod?.def;if(i){if(i.value!==void 0)return i.value;if(Array.isArray(i.values)&&i.values.length>0)return i.values[0]}}let r=e._def;if(r){if(r.value!==void 0)return r.value;if(Array.isArray(r.values)&&r.values.length>0)return r.values[0]}let n=e.value;if(n!==void 0)return n}var Xf={};mi(Xf,{ZodISODate:()=>HY,ZodISODateTime:()=>VY,ZodISODuration:()=>ZY,ZodISOTime:()=>WY,date:()=>PT,datetime:()=>FT,duration:()=>jT,time:()=>LT});var VY=L("ZodISODateTime",(e,t)=>{T6.init(e,t),$t.init(e,t)});function FT(e){return NY(VY,e)}var HY=L("ZodISODate",(e,t)=>{O6.init(e,t),$t.init(e,t)});function PT(e){return kY(HY,e)}var WY=L("ZodISOTime",(e,t)=>{R6.init(e,t),$t.init(e,t)});function LT(e){return FY(WY,e)}var ZY=L("ZodISODuration",(e,t)=>{$6.init(e,t),$t.init(e,t)});function jT(e){return PY(ZY,e)}var KY=(e,t)=>{Dv.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:r=>g9(e,r)},flatten:{value:r=>h9(e,r)},addIssue:{value:r=>e.issues.push(r)},addIssues:{value:r=>e.issues.push(...r)},isEmpty:{get(){return e.issues.length===0}}})},m3e=L("ZodError",KY),Qf=L("ZodError",KY,{Parent:Error});var XY=y9(Qf),QY=D9(Qf),e4=fT(Qf),t4=mT(Qf);var Ut=L("ZodType",(e,t)=>(Dt.init(e,t),e.def=t,Object.defineProperty(e,"_def",{value:t}),e.check=(...r)=>e.clone({...t,checks:[...t.checks??[],...r.map(n=>typeof n=="function"?{_zod:{check:n,def:{check:"custom"},onattach:[]}}:n)]}),e.clone=(r,n)=>ni(e,r,n),e.brand=()=>e,e.register=((r,n)=>(r.add(e,n),e)),e.parse=(r,n)=>XY(e,r,n,{callee:e.parse}),e.safeParse=(r,n)=>e4(e,r,n),e.parseAsync=async(r,n)=>QY(e,r,n,{callee:e.parseAsync}),e.safeParseAsync=async(r,n)=>t4(e,r,n),e.spa=e.safeParseAsync,e.refine=(r,n)=>e.check(mme(r,n)),e.superRefine=r=>e.check(hme(r)),e.overwrite=r=>e.check(qa(r)),e.optional=()=>Bt(e),e.nullable=()=>o4(e),e.nullish=()=>Bt(o4(e)),e.nonoptional=r=>ame(e,r),e.array=()=>Be(e),e.or=r=>bt([e,r]),e.and=r=>Ov(e,r),e.transform=r=>BT(e,u4(r)),e.default=r=>ome(e,r),e.prefault=r=>sme(e,r),e.catch=r=>ume(e,r),e.pipe=r=>BT(e,r),e.readonly=()=>pme(e),e.describe=r=>{let n=e.clone();return Hf.add(n,{description:r}),n},Object.defineProperty(e,"description",{get(){return Hf.get(e)?.description},configurable:!0}),e.meta=(...r)=>{if(r.length===0)return Hf.get(e);let n=e.clone();return Hf.add(n,r[0]),n},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e)),i4=L("_ZodString",(e,t)=>{_v.init(e,t),Ut.init(e,t);let r=e._zod.bag;e.format=r.format??null,e.minLength=r.minimum??null,e.maxLength=r.maximum??null,e.regex=(...n)=>e.check(CT(...n)),e.includes=(...n)=>e.check(wT(...n)),e.startsWith=(...n)=>e.check(TT(...n)),e.endsWith=(...n)=>e.check(OT(...n)),e.min=(...n)=>e.check(Lu(...n)),e.max=(...n)=>e.check(xv(...n)),e.length=(...n)=>e.check(Av(...n)),e.nonempty=(...n)=>e.check(Lu(1,...n)),e.lowercase=n=>e.check(xT(n)),e.uppercase=n=>e.check(AT(n)),e.trim=()=>e.check($T()),e.normalize=(...n)=>e.check(RT(...n)),e.toLowerCase=()=>e.check(NT()),e.toUpperCase=()=>e.check(kT())}),xfe=L("ZodString",(e,t)=>{_v.init(e,t),i4.init(e,t),e.email=r=>e.check(pY(Afe,r)),e.url=r=>e.check(yY(wfe,r)),e.jwt=r=>e.check($Y(zfe,r)),e.emoji=r=>e.check(DY(Tfe,r)),e.guid=r=>e.check(IT(r4,r)),e.uuid=r=>e.check(fY(Tv,r)),e.uuidv4=r=>e.check(mY(Tv,r)),e.uuidv6=r=>e.check(hY(Tv,r)),e.uuidv7=r=>e.check(gY(Tv,r)),e.nanoid=r=>e.check(bY(Ofe,r)),e.guid=r=>e.check(IT(r4,r)),e.cuid=r=>e.check(vY(Rfe,r)),e.cuid2=r=>e.check(SY($fe,r)),e.ulid=r=>e.check(_Y(Nfe,r)),e.base64=r=>e.check(TY(Bfe,r)),e.base64url=r=>e.check(OY(Ufe,r)),e.xid=r=>e.check(EY(kfe,r)),e.ksuid=r=>e.check(IY(Ffe,r)),e.ipv4=r=>e.check(CY(Pfe,r)),e.ipv6=r=>e.check(xY(Lfe,r)),e.cidrv4=r=>e.check(AY(jfe,r)),e.cidrv6=r=>e.check(wY(Mfe,r)),e.e164=r=>e.check(RY(qfe,r)),e.datetime=r=>e.check(FT(r)),e.date=r=>e.check(PT(r)),e.time=r=>e.check(LT(r)),e.duration=r=>e.check(jT(r))});function P(e){return dY(xfe,e)}var $t=L("ZodStringFormat",(e,t)=>{Et.init(e,t),i4.init(e,t)}),Afe=L("ZodEmail",(e,t)=>{v6.init(e,t),$t.init(e,t)});var r4=L("ZodGUID",(e,t)=>{D6.init(e,t),$t.init(e,t)});var Tv=L("ZodUUID",(e,t)=>{b6.init(e,t),$t.init(e,t)});var wfe=L("ZodURL",(e,t)=>{S6.init(e,t),$t.init(e,t)});var Tfe=L("ZodEmoji",(e,t)=>{_6.init(e,t),$t.init(e,t)});var Ofe=L("ZodNanoID",(e,t)=>{E6.init(e,t),$t.init(e,t)});var Rfe=L("ZodCUID",(e,t)=>{I6.init(e,t),$t.init(e,t)});var $fe=L("ZodCUID2",(e,t)=>{C6.init(e,t),$t.init(e,t)});var Nfe=L("ZodULID",(e,t)=>{x6.init(e,t),$t.init(e,t)});var kfe=L("ZodXID",(e,t)=>{A6.init(e,t),$t.init(e,t)});var Ffe=L("ZodKSUID",(e,t)=>{w6.init(e,t),$t.init(e,t)});var Pfe=L("ZodIPv4",(e,t)=>{N6.init(e,t),$t.init(e,t)});var Lfe=L("ZodIPv6",(e,t)=>{k6.init(e,t),$t.init(e,t)});var jfe=L("ZodCIDRv4",(e,t)=>{F6.init(e,t),$t.init(e,t)});var Mfe=L("ZodCIDRv6",(e,t)=>{P6.init(e,t),$t.init(e,t)});var Bfe=L("ZodBase64",(e,t)=>{j6.init(e,t),$t.init(e,t)});var Ufe=L("ZodBase64URL",(e,t)=>{M6.init(e,t),$t.init(e,t)});var qfe=L("ZodE164",(e,t)=>{B6.init(e,t),$t.init(e,t)});var zfe=L("ZodJWT",(e,t)=>{U6.init(e,t),$t.init(e,t)});var s4=L("ZodNumber",(e,t)=>{ST.init(e,t),Ut.init(e,t),e.gt=(n,o)=>e.check(Iv(n,o)),e.gte=(n,o)=>e.check(Zf(n,o)),e.min=(n,o)=>e.check(Zf(n,o)),e.lt=(n,o)=>e.check(Ev(n,o)),e.lte=(n,o)=>e.check(Wf(n,o)),e.max=(n,o)=>e.check(Wf(n,o)),e.int=n=>e.check(n4(n)),e.safe=n=>e.check(n4(n)),e.positive=n=>e.check(Iv(0,n)),e.nonnegative=n=>e.check(Zf(0,n)),e.negative=n=>e.check(Ev(0,n)),e.nonpositive=n=>e.check(Wf(0,n)),e.multipleOf=(n,o)=>e.check(Cv(n,o)),e.step=(n,o)=>e.check(Cv(n,o)),e.finite=()=>e;let r=e._zod.bag;e.minValue=Math.max(r.minimum??Number.NEGATIVE_INFINITY,r.exclusiveMinimum??Number.NEGATIVE_INFINITY)??null,e.maxValue=Math.min(r.maximum??Number.POSITIVE_INFINITY,r.exclusiveMaximum??Number.POSITIVE_INFINITY)??null,e.isInt=(r.format??"").includes("int")||Number.isSafeInteger(r.multipleOf??.5),e.isFinite=!0,e.format=r.format??null});function st(e){return LY(s4,e)}var Yfe=L("ZodNumberFormat",(e,t)=>{q6.init(e,t),s4.init(e,t)});function n4(e){return jY(Yfe,e)}var Jfe=L("ZodBoolean",(e,t)=>{z6.init(e,t),Ut.init(e,t)});function gr(e){return MY(Jfe,e)}var Gfe=L("ZodNull",(e,t)=>{Y6.init(e,t),Ut.init(e,t)});function UT(e){return BY(Gfe,e)}var Vfe=L("ZodUnknown",(e,t)=>{J6.init(e,t),Ut.init(e,t)});function Nt(){return UY(Vfe)}var Hfe=L("ZodNever",(e,t)=>{G6.init(e,t),Ut.init(e,t)});function Wfe(e){return qY(Hfe,e)}var Zfe=L("ZodArray",(e,t)=>{V6.init(e,t),Ut.init(e,t),e.element=t.element,e.min=(r,n)=>e.check(Lu(r,n)),e.nonempty=r=>e.check(Lu(1,r)),e.max=(r,n)=>e.check(xv(r,n)),e.length=(r,n)=>e.check(Av(r,n)),e.unwrap=()=>e.element});function Be(e,t){return zY(Zfe,e,t)}var a4=L("ZodObject",(e,t)=>{H6.init(e,t),Ut.init(e,t),Ze.defineLazy(e,"shape",()=>t.shape),e.keyof=()=>En(Object.keys(e._zod.def.shape)),e.catchall=r=>e.clone({...e._zod.def,catchall:r}),e.passthrough=()=>e.clone({...e._zod.def,catchall:Nt()}),e.loose=()=>e.clone({...e._zod.def,catchall:Nt()}),e.strict=()=>e.clone({...e._zod.def,catchall:Wfe()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=r=>Ze.extend(e,r),e.merge=r=>Ze.merge(e,r),e.pick=r=>Ze.pick(e,r),e.omit=r=>Ze.omit(e,r),e.partial=(...r)=>Ze.partial(l4,e,r[0]),e.required=(...r)=>Ze.required(d4,e,r[0])});function ee(e,t){let r={type:"object",get shape(){return Ze.assignProp(this,"shape",{...e}),this.shape},...Ze.normalizeParams(t)};return new a4(r)}function sn(e,t){return new a4({type:"object",get shape(){return Ze.assignProp(this,"shape",{...e}),this.shape},catchall:Nt(),...Ze.normalizeParams(t)})}var c4=L("ZodUnion",(e,t)=>{_T.init(e,t),Ut.init(e,t),e.options=t.options});function bt(e,t){return new c4({type:"union",options:e,...Ze.normalizeParams(t)})}var Kfe=L("ZodDiscriminatedUnion",(e,t)=>{c4.init(e,t),W6.init(e,t)});function qT(e,t,r){return new Kfe({type:"union",options:t,discriminator:e,...Ze.normalizeParams(r)})}var Xfe=L("ZodIntersection",(e,t)=>{Z6.init(e,t),Ut.init(e,t)});function Ov(e,t){return new Xfe({type:"intersection",left:e,right:t})}var Qfe=L("ZodRecord",(e,t)=>{K6.init(e,t),Ut.init(e,t),e.keyType=t.keyType,e.valueType=t.valueType});function kt(e,t,r){return new Qfe({type:"record",keyType:e,valueType:t,...Ze.normalizeParams(r)})}var MT=L("ZodEnum",(e,t)=>{X6.init(e,t),Ut.init(e,t),e.enum=t.entries,e.options=Object.values(t.entries);let r=new Set(Object.keys(t.entries));e.extract=(n,o)=>{let i={};for(let s of n)if(r.has(s))i[s]=t.entries[s];else throw new Error(`Key ${s} not found in enum`);return new MT({...t,checks:[],...Ze.normalizeParams(o),entries:i})},e.exclude=(n,o)=>{let i={...t.entries};for(let s of n)if(r.has(s))delete i[s];else throw new Error(`Key ${s} not found in enum`);return new MT({...t,checks:[],...Ze.normalizeParams(o),entries:i})}});function En(e,t){let r=Array.isArray(e)?Object.fromEntries(e.map(n=>[n,n])):e;return new MT({type:"enum",entries:r,...Ze.normalizeParams(t)})}var eme=L("ZodLiteral",(e,t)=>{Q6.init(e,t),Ut.init(e,t),e.values=new Set(t.values),Object.defineProperty(e,"value",{get(){if(t.values.length>1)throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");return t.values[0]}})});function ce(e,t){return new eme({type:"literal",values:Array.isArray(e)?e:[e],...Ze.normalizeParams(t)})}var tme=L("ZodTransform",(e,t)=>{eY.init(e,t),Ut.init(e,t),e._zod.parse=(r,n)=>{r.addIssue=i=>{if(typeof i=="string")r.issues.push(Ze.issue(i,r.value,t));else{let s=i;s.fatal&&(s.continue=!1),s.code??(s.code="custom"),s.input??(s.input=r.value),s.inst??(s.inst=e),s.continue??(s.continue=!0),r.issues.push(Ze.issue(s))}};let o=t.transform(r.value,r);return o instanceof Promise?o.then(i=>(r.value=i,r)):(r.value=o,r)}});function u4(e){return new tme({type:"transform",transform:e})}var l4=L("ZodOptional",(e,t)=>{tY.init(e,t),Ut.init(e,t),e.unwrap=()=>e._zod.def.innerType});function Bt(e){return new l4({type:"optional",innerType:e})}var rme=L("ZodNullable",(e,t)=>{rY.init(e,t),Ut.init(e,t),e.unwrap=()=>e._zod.def.innerType});function o4(e){return new rme({type:"nullable",innerType:e})}var nme=L("ZodDefault",(e,t)=>{nY.init(e,t),Ut.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});function ome(e,t){return new nme({type:"default",innerType:e,get defaultValue(){return typeof t=="function"?t():t}})}var ime=L("ZodPrefault",(e,t)=>{oY.init(e,t),Ut.init(e,t),e.unwrap=()=>e._zod.def.innerType});function sme(e,t){return new ime({type:"prefault",innerType:e,get defaultValue(){return typeof t=="function"?t():t}})}var d4=L("ZodNonOptional",(e,t)=>{iY.init(e,t),Ut.init(e,t),e.unwrap=()=>e._zod.def.innerType});function ame(e,t){return new d4({type:"nonoptional",innerType:e,...Ze.normalizeParams(t)})}var cme=L("ZodCatch",(e,t)=>{sY.init(e,t),Ut.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});function ume(e,t){return new cme({type:"catch",innerType:e,catchValue:typeof t=="function"?t:()=>t})}var lme=L("ZodPipe",(e,t)=>{aY.init(e,t),Ut.init(e,t),e.in=t.in,e.out=t.out});function BT(e,t){return new lme({type:"pipe",in:e,out:t})}var dme=L("ZodReadonly",(e,t)=>{cY.init(e,t),Ut.init(e,t)});function pme(e){return new dme({type:"readonly",innerType:e})}var p4=L("ZodCustom",(e,t)=>{uY.init(e,t),Ut.init(e,t)});function fme(e){let t=new Gr({check:"custom"});return t._zod.check=e,t}function f4(e,t){return YY(p4,e??(()=>!0),t)}function mme(e,t={}){return JY(p4,e,t)}function hme(e){let t=fme(r=>(r.addIssue=n=>{if(typeof n=="string")r.issues.push(Ze.issue(n,r.value,t._zod.def));else{let o=n;o.fatal&&(o.continue=!1),o.code??(o.code="custom"),o.input??(o.input=r.value),o.inst??(o.inst=t),o.continue??(o.continue=!t._zod.def.abort),r.issues.push(Ze.issue(o))}},e(r.value,r)));return t}function zT(e,t){return BT(u4(e),t)}co(lY());var JT="2025-11-25";var m4=[JT,"2025-06-18","2025-03-26","2024-11-05","2024-10-07"],Is="io.modelcontextprotocol/related-task",$v="2.0",Ar=f4(e=>e!==null&&(typeof e=="object"||typeof e=="function")),h4=bt([P(),st().int()]),g4=P(),a8e=sn({ttl:bt([st(),UT()]).optional(),pollInterval:st().optional()}),gme=ee({ttl:st().optional()}),yme=ee({taskId:P()}),GT=sn({progressToken:h4.optional(),[Is]:yme.optional()}),zn=ee({_meta:GT.optional()}),em=zn.extend({task:gme.optional()}),y4=e=>em.safeParse(e).success,wr=ee({method:P(),params:zn.loose().optional()}),uo=ee({_meta:GT.optional()}),lo=ee({method:P(),params:uo.loose().optional()}),Tr=sn({_meta:GT.optional()}),Nv=bt([P(),st().int()]),D4=ee({jsonrpc:ce($v),id:Nv,...wr.shape}).strict(),VT=e=>D4.safeParse(e).success,b4=ee({jsonrpc:ce($v),...lo.shape}).strict(),v4=e=>b4.safeParse(e).success,HT=ee({jsonrpc:ce($v),id:Nv,result:Tr}).strict(),tm=e=>HT.safeParse(e).success;var Oe;(function(e){e[e.ConnectionClosed=-32e3]="ConnectionClosed",e[e.RequestTimeout=-32001]="RequestTimeout",e[e.ParseError=-32700]="ParseError",e[e.InvalidRequest=-32600]="InvalidRequest",e[e.MethodNotFound=-32601]="MethodNotFound",e[e.InvalidParams=-32602]="InvalidParams",e[e.InternalError=-32603]="InternalError",e[e.UrlElicitationRequired=-32042]="UrlElicitationRequired"})(Oe||(Oe={}));var WT=ee({jsonrpc:ce($v),id:Nv.optional(),error:ee({code:st().int(),message:P(),data:Nt().optional()})}).strict();var S4=e=>WT.safeParse(e).success;var _4=bt([D4,b4,HT,WT]),c8e=bt([HT,WT]),kv=Tr.strict(),Dme=uo.extend({requestId:Nv.optional(),reason:P().optional()}),Fv=lo.extend({method:ce("notifications/cancelled"),params:Dme}),bme=ee({src:P(),mimeType:P().optional(),sizes:Be(P()).optional(),theme:En(["light","dark"]).optional()}),rm=ee({icons:Be(bme).optional()}),Mu=ee({name:P(),title:P().optional()}),E4=Mu.extend({...Mu.shape,...rm.shape,version:P(),websiteUrl:P().optional(),description:P().optional()}),vme=Ov(ee({applyDefaults:gr().optional()}),kt(P(),Nt())),Sme=zT(e=>e&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0?{form:{}}:e,Ov(ee({form:vme.optional(),url:Ar.optional()}),kt(P(),Nt()).optional())),_me=sn({list:Ar.optional(),cancel:Ar.optional(),requests:sn({sampling:sn({createMessage:Ar.optional()}).optional(),elicitation:sn({create:Ar.optional()}).optional()}).optional()}),Eme=sn({list:Ar.optional(),cancel:Ar.optional(),requests:sn({tools:sn({call:Ar.optional()}).optional()}).optional()}),Ime=ee({experimental:kt(P(),Ar).optional(),sampling:ee({context:Ar.optional(),tools:Ar.optional()}).optional(),elicitation:Sme.optional(),roots:ee({listChanged:gr().optional()}).optional(),tasks:_me.optional()}),Cme=zn.extend({protocolVersion:P(),capabilities:Ime,clientInfo:E4}),ZT=wr.extend({method:ce("initialize"),params:Cme});var xme=ee({experimental:kt(P(),Ar).optional(),logging:Ar.optional(),completions:Ar.optional(),prompts:ee({listChanged:gr().optional()}).optional(),resources:ee({subscribe:gr().optional(),listChanged:gr().optional()}).optional(),tools:ee({listChanged:gr().optional()}).optional(),tasks:Eme.optional()}),Ame=Tr.extend({protocolVersion:P(),capabilities:xme,serverInfo:E4,instructions:P().optional()}),KT=lo.extend({method:ce("notifications/initialized"),params:uo.optional()});var Pv=wr.extend({method:ce("ping"),params:zn.optional()}),wme=ee({progress:st(),total:Bt(st()),message:Bt(P())}),Tme=ee({...uo.shape,...wme.shape,progressToken:h4}),Lv=lo.extend({method:ce("notifications/progress"),params:Tme}),Ome=zn.extend({cursor:g4.optional()}),nm=wr.extend({params:Ome.optional()}),om=Tr.extend({nextCursor:g4.optional()}),Rme=En(["working","input_required","completed","failed","cancelled"]),im=ee({taskId:P(),status:Rme,ttl:bt([st(),UT()]),createdAt:P(),lastUpdatedAt:P(),pollInterval:Bt(st()),statusMessage:Bt(P())}),Bu=Tr.extend({task:im}),$me=uo.merge(im),sm=lo.extend({method:ce("notifications/tasks/status"),params:$me}),jv=wr.extend({method:ce("tasks/get"),params:zn.extend({taskId:P()})}),Mv=Tr.merge(im),Bv=wr.extend({method:ce("tasks/result"),params:zn.extend({taskId:P()})}),u8e=Tr.loose(),Uv=nm.extend({method:ce("tasks/list")}),qv=om.extend({tasks:Be(im)}),zv=wr.extend({method:ce("tasks/cancel"),params:zn.extend({taskId:P()})}),I4=Tr.merge(im),C4=ee({uri:P(),mimeType:Bt(P()),_meta:kt(P(),Nt()).optional()}),x4=C4.extend({text:P()}),XT=P().refine(e=>{try{return atob(e),!0}catch{return!1}},{message:"Invalid Base64 string"}),A4=C4.extend({blob:XT}),am=En(["user","assistant"]),Uu=ee({audience:Be(am).optional(),priority:st().min(0).max(1).optional(),lastModified:Xf.datetime({offset:!0}).optional()}),w4=ee({...Mu.shape,...rm.shape,uri:P(),description:Bt(P()),mimeType:Bt(P()),annotations:Uu.optional(),_meta:Bt(sn({}))}),Nme=ee({...Mu.shape,...rm.shape,uriTemplate:P(),description:Bt(P()),mimeType:Bt(P()),annotations:Uu.optional(),_meta:Bt(sn({}))}),QT=nm.extend({method:ce("resources/list")}),kme=om.extend({resources:Be(w4)}),Fme=nm.extend({method:ce("resources/templates/list")}),Pme=om.extend({resourceTemplates:Be(Nme)}),e1=zn.extend({uri:P()}),Lme=e1,t1=wr.extend({method:ce("resources/read"),params:Lme}),jme=Tr.extend({contents:Be(bt([x4,A4]))}),Mme=lo.extend({method:ce("notifications/resources/list_changed"),params:uo.optional()}),Bme=e1,Ume=wr.extend({method:ce("resources/subscribe"),params:Bme}),qme=e1,zme=wr.extend({method:ce("resources/unsubscribe"),params:qme}),Yme=uo.extend({uri:P()}),Jme=lo.extend({method:ce("notifications/resources/updated"),params:Yme}),Gme=ee({name:P(),description:Bt(P()),required:Bt(gr())}),Vme=ee({...Mu.shape,...rm.shape,description:Bt(P()),arguments:Bt(Be(Gme)),_meta:Bt(sn({}))}),Hme=nm.extend({method:ce("prompts/list")}),Wme=om.extend({prompts:Be(Vme)}),Zme=zn.extend({name:P(),arguments:kt(P(),P()).optional()}),Kme=wr.extend({method:ce("prompts/get"),params:Zme}),r1=ee({type:ce("text"),text:P(),annotations:Uu.optional(),_meta:kt(P(),Nt()).optional()}),n1=ee({type:ce("image"),data:XT,mimeType:P(),annotations:Uu.optional(),_meta:kt(P(),Nt()).optional()}),o1=ee({type:ce("audio"),data:XT,mimeType:P(),annotations:Uu.optional(),_meta:kt(P(),Nt()).optional()}),Xme=ee({type:ce("tool_use"),name:P(),id:P(),input:kt(P(),Nt()),_meta:kt(P(),Nt()).optional()}),Qme=ee({type:ce("resource"),resource:bt([x4,A4]),annotations:Uu.optional(),_meta:kt(P(),Nt()).optional()}),ehe=w4.extend({type:ce("resource_link")}),i1=bt([r1,n1,o1,ehe,Qme]),the=ee({role:am,content:i1}),rhe=Tr.extend({description:P().optional(),messages:Be(the)}),nhe=lo.extend({method:ce("notifications/prompts/list_changed"),params:uo.optional()}),ohe=ee({title:P().optional(),readOnlyHint:gr().optional(),destructiveHint:gr().optional(),idempotentHint:gr().optional(),openWorldHint:gr().optional()}),ihe=ee({taskSupport:En(["required","optional","forbidden"]).optional()}),T4=ee({...Mu.shape,...rm.shape,description:P().optional(),inputSchema:ee({type:ce("object"),properties:kt(P(),Ar).optional(),required:Be(P()).optional()}).catchall(Nt()),outputSchema:ee({type:ce("object"),properties:kt(P(),Ar).optional(),required:Be(P()).optional()}).catchall(Nt()).optional(),annotations:ohe.optional(),execution:ihe.optional(),_meta:kt(P(),Nt()).optional()}),s1=nm.extend({method:ce("tools/list")}),she=om.extend({tools:Be(T4)}),Yv=Tr.extend({content:Be(i1).default([]),structuredContent:kt(P(),Nt()).optional(),isError:gr().optional()}),l8e=Yv.or(Tr.extend({toolResult:Nt()})),ahe=em.extend({name:P(),arguments:kt(P(),Nt()).optional()}),cm=wr.extend({method:ce("tools/call"),params:ahe}),che=lo.extend({method:ce("notifications/tools/list_changed"),params:uo.optional()}),d8e=ee({autoRefresh:gr().default(!0),debounceMs:st().int().nonnegative().default(300)}),um=En(["debug","info","notice","warning","error","critical","alert","emergency"]),uhe=zn.extend({level:um}),a1=wr.extend({method:ce("logging/setLevel"),params:uhe}),lhe=uo.extend({level:um,logger:P().optional(),data:Nt()}),dhe=lo.extend({method:ce("notifications/message"),params:lhe}),phe=ee({name:P().optional()}),fhe=ee({hints:Be(phe).optional(),costPriority:st().min(0).max(1).optional(),speedPriority:st().min(0).max(1).optional(),intelligencePriority:st().min(0).max(1).optional()}),mhe=ee({mode:En(["auto","required","none"]).optional()}),hhe=ee({type:ce("tool_result"),toolUseId:P().describe("The unique identifier for the corresponding tool call."),content:Be(i1).default([]),structuredContent:ee({}).loose().optional(),isError:gr().optional(),_meta:kt(P(),Nt()).optional()}),ghe=qT("type",[r1,n1,o1]),Rv=qT("type",[r1,n1,o1,Xme,hhe]),yhe=ee({role:am,content:bt([Rv,Be(Rv)]),_meta:kt(P(),Nt()).optional()}),Dhe=em.extend({messages:Be(yhe),modelPreferences:fhe.optional(),systemPrompt:P().optional(),includeContext:En(["none","thisServer","allServers"]).optional(),temperature:st().optional(),maxTokens:st().int(),stopSequences:Be(P()).optional(),metadata:Ar.optional(),tools:Be(T4).optional(),toolChoice:mhe.optional()}),bhe=wr.extend({method:ce("sampling/createMessage"),params:Dhe}),lm=Tr.extend({model:P(),stopReason:Bt(En(["endTurn","stopSequence","maxTokens"]).or(P())),role:am,content:ghe}),c1=Tr.extend({model:P(),stopReason:Bt(En(["endTurn","stopSequence","maxTokens","toolUse"]).or(P())),role:am,content:bt([Rv,Be(Rv)])}),vhe=ee({type:ce("boolean"),title:P().optional(),description:P().optional(),default:gr().optional()}),She=ee({type:ce("string"),title:P().optional(),description:P().optional(),minLength:st().optional(),maxLength:st().optional(),format:En(["email","uri","date","date-time"]).optional(),default:P().optional()}),_he=ee({type:En(["number","integer"]),title:P().optional(),description:P().optional(),minimum:st().optional(),maximum:st().optional(),default:st().optional()}),Ehe=ee({type:ce("string"),title:P().optional(),description:P().optional(),enum:Be(P()),default:P().optional()}),Ihe=ee({type:ce("string"),title:P().optional(),description:P().optional(),oneOf:Be(ee({const:P(),title:P()})),default:P().optional()}),Che=ee({type:ce("string"),title:P().optional(),description:P().optional(),enum:Be(P()),enumNames:Be(P()).optional(),default:P().optional()}),xhe=bt([Ehe,Ihe]),Ahe=ee({type:ce("array"),title:P().optional(),description:P().optional(),minItems:st().optional(),maxItems:st().optional(),items:ee({type:ce("string"),enum:Be(P())}),default:Be(P()).optional()}),whe=ee({type:ce("array"),title:P().optional(),description:P().optional(),minItems:st().optional(),maxItems:st().optional(),items:ee({anyOf:Be(ee({const:P(),title:P()}))}),default:Be(P()).optional()}),The=bt([Ahe,whe]),Ohe=bt([Che,xhe,The]),Rhe=bt([Ohe,vhe,She,_he]),$he=em.extend({mode:ce("form").optional(),message:P(),requestedSchema:ee({type:ce("object"),properties:kt(P(),Rhe),required:Be(P()).optional()})}),Nhe=em.extend({mode:ce("url"),message:P(),elicitationId:P(),url:P().url()}),khe=bt([$he,Nhe]),Fhe=wr.extend({method:ce("elicitation/create"),params:khe}),Phe=uo.extend({elicitationId:P()}),Lhe=lo.extend({method:ce("notifications/elicitation/complete"),params:Phe}),qu=Tr.extend({action:En(["accept","decline","cancel"]),content:zT(e=>e===null?void 0:e,kt(P(),bt([P(),st(),gr(),Be(P())])).optional())}),jhe=ee({type:ce("ref/resource"),uri:P()});var Mhe=ee({type:ce("ref/prompt"),name:P()}),Bhe=zn.extend({ref:bt([Mhe,jhe]),argument:ee({name:P(),value:P()}),context:ee({arguments:kt(P(),P()).optional()}).optional()}),Uhe=wr.extend({method:ce("completion/complete"),params:Bhe});var qhe=Tr.extend({completion:sn({values:Be(P()).max(100),total:Bt(st().int()),hasMore:Bt(gr())})}),zhe=ee({uri:P().startsWith("file://"),name:P().optional(),_meta:kt(P(),Nt()).optional()}),Yhe=wr.extend({method:ce("roots/list"),params:zn.optional()}),u1=Tr.extend({roots:Be(zhe)}),Jhe=lo.extend({method:ce("notifications/roots/list_changed"),params:uo.optional()}),p8e=bt([Pv,ZT,Uhe,a1,Kme,Hme,QT,Fme,t1,Ume,zme,cm,s1,jv,Bv,Uv,zv]),f8e=bt([Fv,Lv,KT,Jhe,sm]),m8e=bt([kv,lm,c1,qu,u1,Mv,qv,Bu]),h8e=bt([Pv,bhe,Fhe,Yhe,jv,Bv,Uv,zv]),g8e=bt([Fv,Lv,dhe,Jme,Mme,che,nhe,sm,Lhe]),y8e=bt([kv,Ame,qhe,rhe,Wme,kme,Pme,jme,Yv,she,Mv,qv,Bu]),Ie=class e extends Error{constructor(t,r,n){super(`MCP error ${t}: ${r}`),this.code=t,this.data=n,this.name="McpError"}static fromError(t,r,n){if(t===Oe.UrlElicitationRequired&&n){let o=n;if(o.elicitations)return new YT(o.elicitations,r)}return new e(t,r,n)}},YT=class extends Ie{constructor(t,r=`URL elicitation${t.length>1?"s":""} required`){super(Oe.UrlElicitationRequired,r,{elicitations:t})}get elicitations(){return this.data?.elicitations??[]}};function Cs(e){return e==="completed"||e==="failed"||e==="cancelled"}var Z8e=new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");function l1(e){let r=wv(e)?.method;if(!r)throw new Error("Schema is missing a method literal");let n=GY(r);if(typeof n!="string")throw new Error("Schema method literal must be a string");return n}function d1(e,t){let r=Es(e,t);if(!r.success)throw r.error;return r.data}var Khe=6e4,Jv=class{constructor(t){this._options=t,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this._timeoutInfo=new Map,this._pendingDebouncedNotifications=new Set,this._taskProgressTokens=new Map,this._requestResolvers=new Map,this.setNotificationHandler(Fv,r=>{this._oncancel(r)}),this.setNotificationHandler(Lv,r=>{this._onprogress(r)}),this.setRequestHandler(Pv,r=>({})),this._taskStore=t?.taskStore,this._taskMessageQueue=t?.taskMessageQueue,this._taskStore&&(this.setRequestHandler(jv,async(r,n)=>{let o=await this._taskStore.getTask(r.params.taskId,n.sessionId);if(!o)throw new Ie(Oe.InvalidParams,"Failed to retrieve task: Task not found");return{...o}}),this.setRequestHandler(Bv,async(r,n)=>{let o=async()=>{let i=r.params.taskId;if(this._taskMessageQueue){let a;for(;a=await this._taskMessageQueue.dequeue(i,n.sessionId);){if(a.type==="response"||a.type==="error"){let c=a.message,u=c.id,l=this._requestResolvers.get(u);if(l)if(this._requestResolvers.delete(u),a.type==="response")l(c);else{let d=c,f=new Ie(d.error.code,d.error.message,d.error.data);l(f)}else{let d=a.type==="response"?"Response":"Error";this._onerror(new Error(`${d} handler missing for request ${u}`))}continue}await this._transport?.send(a.message,{relatedRequestId:n.requestId})}}let s=await this._taskStore.getTask(i,n.sessionId);if(!s)throw new Ie(Oe.InvalidParams,`Task not found: ${i}`);if(!Cs(s.status))return await this._waitForTaskUpdate(i,n.signal),await o();if(Cs(s.status)){let a=await this._taskStore.getTaskResult(i,n.sessionId);return this._clearTaskQueue(i),{...a,_meta:{...a._meta,[Is]:{taskId:i}}}}return await o()};return await o()}),this.setRequestHandler(Uv,async(r,n)=>{try{let{tasks:o,nextCursor:i}=await this._taskStore.listTasks(r.params?.cursor,n.sessionId);return{tasks:o,nextCursor:i,_meta:{}}}catch(o){throw new Ie(Oe.InvalidParams,`Failed to list tasks: ${o instanceof Error?o.message:String(o)}`)}}),this.setRequestHandler(zv,async(r,n)=>{try{let o=await this._taskStore.getTask(r.params.taskId,n.sessionId);if(!o)throw new Ie(Oe.InvalidParams,`Task not found: ${r.params.taskId}`);if(Cs(o.status))throw new Ie(Oe.InvalidParams,`Cannot cancel task in terminal status: ${o.status}`);await this._taskStore.updateTaskStatus(r.params.taskId,"cancelled","Client cancelled task execution.",n.sessionId),this._clearTaskQueue(r.params.taskId);let i=await this._taskStore.getTask(r.params.taskId,n.sessionId);if(!i)throw new Ie(Oe.InvalidParams,`Task not found after cancellation: ${r.params.taskId}`);return{_meta:{},...i}}catch(o){throw o instanceof Ie?o:new Ie(Oe.InvalidRequest,`Failed to cancel task: ${o instanceof Error?o.message:String(o)}`)}}))}async _oncancel(t){if(!t.params.requestId)return;this._requestHandlerAbortControllers.get(t.params.requestId)?.abort(t.params.reason)}_setupTimeout(t,r,n,o,i=!1){this._timeoutInfo.set(t,{timeoutId:setTimeout(o,r),startTime:Date.now(),timeout:r,maxTotalTimeout:n,resetTimeoutOnProgress:i,onTimeout:o})}_resetTimeout(t){let r=this._timeoutInfo.get(t);if(!r)return!1;let n=Date.now()-r.startTime;if(r.maxTotalTimeout&&n>=r.maxTotalTimeout)throw this._timeoutInfo.delete(t),Ie.fromError(Oe.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:r.maxTotalTimeout,totalElapsed:n});return clearTimeout(r.timeoutId),r.timeoutId=setTimeout(r.onTimeout,r.timeout),!0}_cleanupTimeout(t){let r=this._timeoutInfo.get(t);r&&(clearTimeout(r.timeoutId),this._timeoutInfo.delete(t))}async connect(t){if(this._transport)throw new Error("Already connected to a transport. Call close() before connecting to a new transport, or use a separate Protocol instance per connection.");this._transport=t;let r=this.transport?.onclose;this._transport.onclose=()=>{r?.(),this._onclose()};let n=this.transport?.onerror;this._transport.onerror=i=>{n?.(i),this._onerror(i)};let o=this._transport?.onmessage;this._transport.onmessage=(i,s)=>{o?.(i,s),tm(i)||S4(i)?this._onresponse(i):VT(i)?this._onrequest(i,s):v4(i)?this._onnotification(i):this._onerror(new Error(`Unknown message type: ${JSON.stringify(i)}`))},await this._transport.start()}_onclose(){let t=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._taskProgressTokens.clear(),this._pendingDebouncedNotifications.clear();for(let n of this._requestHandlerAbortControllers.values())n.abort();this._requestHandlerAbortControllers.clear();let r=Ie.fromError(Oe.ConnectionClosed,"Connection closed");this._transport=void 0,this.onclose?.();for(let n of t.values())n(r)}_onerror(t){this.onerror?.(t)}_onnotification(t){let r=this._notificationHandlers.get(t.method)??this.fallbackNotificationHandler;r!==void 0&&Promise.resolve().then(()=>r(t)).catch(n=>this._onerror(new Error(`Uncaught error in notification handler: ${n}`)))}_onrequest(t,r){let n=this._requestHandlers.get(t.method)??this.fallbackRequestHandler,o=this._transport,i=t.params?._meta?.[Is]?.taskId;if(n===void 0){let l={jsonrpc:"2.0",id:t.id,error:{code:Oe.MethodNotFound,message:"Method not found"}};i&&this._taskMessageQueue?this._enqueueTaskMessage(i,{type:"error",message:l,timestamp:Date.now()},o?.sessionId).catch(d=>this._onerror(new Error(`Failed to enqueue error response: ${d}`))):o?.send(l).catch(d=>this._onerror(new Error(`Failed to send an error response: ${d}`)));return}let s=new AbortController;this._requestHandlerAbortControllers.set(t.id,s);let a=y4(t.params)?t.params.task:void 0,c=this._taskStore?this.requestTaskStore(t,o?.sessionId):void 0,u={signal:s.signal,sessionId:o?.sessionId,_meta:t.params?._meta,sendNotification:async l=>{if(s.signal.aborted)return;let d={relatedRequestId:t.id};i&&(d.relatedTask={taskId:i}),await this.notification(l,d)},sendRequest:async(l,d,f)=>{if(s.signal.aborted)throw new Ie(Oe.ConnectionClosed,"Request was cancelled");let p={...f,relatedRequestId:t.id};i&&!p.relatedTask&&(p.relatedTask={taskId:i});let m=p.relatedTask?.taskId??i;return m&&c&&await c.updateTaskStatus(m,"input_required"),await this.request(l,d,p)},authInfo:r?.authInfo,requestId:t.id,requestInfo:r?.requestInfo,taskId:i,taskStore:c,taskRequestedTtl:a?.ttl,closeSSEStream:r?.closeSSEStream,closeStandaloneSSEStream:r?.closeStandaloneSSEStream};Promise.resolve().then(()=>{a&&this.assertTaskHandlerCapability(t.method)}).then(()=>n(t,u)).then(async l=>{if(s.signal.aborted)return;let d={result:l,jsonrpc:"2.0",id:t.id};i&&this._taskMessageQueue?await this._enqueueTaskMessage(i,{type:"response",message:d,timestamp:Date.now()},o?.sessionId):await o?.send(d)},async l=>{if(s.signal.aborted)return;let d={jsonrpc:"2.0",id:t.id,error:{code:Number.isSafeInteger(l.code)?l.code:Oe.InternalError,message:l.message??"Internal error",...l.data!==void 0&&{data:l.data}}};i&&this._taskMessageQueue?await this._enqueueTaskMessage(i,{type:"error",message:d,timestamp:Date.now()},o?.sessionId):await o?.send(d)}).catch(l=>this._onerror(new Error(`Failed to send response: ${l}`))).finally(()=>{this._requestHandlerAbortControllers.delete(t.id)})}_onprogress(t){let{progressToken:r,...n}=t.params,o=Number(r),i=this._progressHandlers.get(o);if(!i){this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(t)}`));return}let s=this._responseHandlers.get(o),a=this._timeoutInfo.get(o);if(a&&s&&a.resetTimeoutOnProgress)try{this._resetTimeout(o)}catch(c){this._responseHandlers.delete(o),this._progressHandlers.delete(o),this._cleanupTimeout(o),s(c);return}i(n)}_onresponse(t){let r=Number(t.id),n=this._requestResolvers.get(r);if(n){if(this._requestResolvers.delete(r),tm(t))n(t);else{let s=new Ie(t.error.code,t.error.message,t.error.data);n(s)}return}let o=this._responseHandlers.get(r);if(o===void 0){this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(t)}`));return}this._responseHandlers.delete(r),this._cleanupTimeout(r);let i=!1;if(tm(t)&&t.result&&typeof t.result=="object"){let s=t.result;if(s.task&&typeof s.task=="object"){let a=s.task;typeof a.taskId=="string"&&(i=!0,this._taskProgressTokens.set(a.taskId,r))}}if(i||this._progressHandlers.delete(r),tm(t))o(t);else{let s=Ie.fromError(t.error.code,t.error.message,t.error.data);o(s)}}get transport(){return this._transport}async close(){await this._transport?.close()}async*requestStream(t,r,n){let{task:o}=n??{};if(!o){try{yield{type:"result",result:await this.request(t,r,n)}}catch(s){yield{type:"error",error:s instanceof Ie?s:new Ie(Oe.InternalError,String(s))}}return}let i;try{let s=await this.request(t,Bu,n);if(s.task)i=s.task.taskId,yield{type:"taskCreated",task:s.task};else throw new Ie(Oe.InternalError,"Task creation did not return a task");for(;;){let a=await this.getTask({taskId:i},n);if(yield{type:"taskStatus",task:a},Cs(a.status)){a.status==="completed"?yield{type:"result",result:await this.getTaskResult({taskId:i},r,n)}:a.status==="failed"?yield{type:"error",error:new Ie(Oe.InternalError,`Task ${i} failed`)}:a.status==="cancelled"&&(yield{type:"error",error:new Ie(Oe.InternalError,`Task ${i} was cancelled`)});return}if(a.status==="input_required"){yield{type:"result",result:await this.getTaskResult({taskId:i},r,n)};return}let c=a.pollInterval??this._options?.defaultTaskPollInterval??1e3;await new Promise(u=>setTimeout(u,c)),n?.signal?.throwIfAborted()}}catch(s){yield{type:"error",error:s instanceof Ie?s:new Ie(Oe.InternalError,String(s))}}}request(t,r,n){let{relatedRequestId:o,resumptionToken:i,onresumptiontoken:s,task:a,relatedTask:c}=n??{};return new Promise((u,l)=>{let d=v=>{l(v)};if(!this._transport){d(new Error("Not connected"));return}if(this._options?.enforceStrictCapabilities===!0)try{this.assertCapabilityForMethod(t.method),a&&this.assertTaskCapability(t.method)}catch(v){d(v);return}n?.signal?.throwIfAborted();let f=this._requestMessageId++,p={...t,jsonrpc:"2.0",id:f};n?.onprogress&&(this._progressHandlers.set(f,n.onprogress),p.params={...t.params,_meta:{...t.params?._meta||{},progressToken:f}}),a&&(p.params={...p.params,task:a}),c&&(p.params={...p.params,_meta:{...p.params?._meta||{},[Is]:c}});let m=v=>{this._responseHandlers.delete(f),this._progressHandlers.delete(f),this._cleanupTimeout(f),this._transport?.send({jsonrpc:"2.0",method:"notifications/cancelled",params:{requestId:f,reason:String(v)}},{relatedRequestId:o,resumptionToken:i,onresumptiontoken:s}).catch(b=>this._onerror(new Error(`Failed to send cancellation: ${b}`)));let y=v instanceof Ie?v:new Ie(Oe.RequestTimeout,String(v));l(y)};this._responseHandlers.set(f,v=>{if(!n?.signal?.aborted){if(v instanceof Error)return l(v);try{let y=Es(r,v.result);y.success?u(y.data):l(y.error)}catch(y){l(y)}}}),n?.signal?.addEventListener("abort",()=>{m(n?.signal?.reason)});let h=n?.timeout??Khe,g=()=>m(Ie.fromError(Oe.RequestTimeout,"Request timed out",{timeout:h}));this._setupTimeout(f,h,n?.maxTotalTimeout,g,n?.resetTimeoutOnProgress??!1);let D=c?.taskId;if(D){let v=y=>{let b=this._responseHandlers.get(f);b?b(y):this._onerror(new Error(`Response handler missing for side-channeled request ${f}`))};this._requestResolvers.set(f,v),this._enqueueTaskMessage(D,{type:"request",message:p,timestamp:Date.now()}).catch(y=>{this._cleanupTimeout(f),l(y)})}else this._transport.send(p,{relatedRequestId:o,resumptionToken:i,onresumptiontoken:s}).catch(v=>{this._cleanupTimeout(f),l(v)})})}async getTask(t,r){return this.request({method:"tasks/get",params:t},Mv,r)}async getTaskResult(t,r,n){return this.request({method:"tasks/result",params:t},r,n)}async listTasks(t,r){return this.request({method:"tasks/list",params:t},qv,r)}async cancelTask(t,r){return this.request({method:"tasks/cancel",params:t},I4,r)}async notification(t,r){if(!this._transport)throw new Error("Not connected");this.assertNotificationCapability(t.method);let n=r?.relatedTask?.taskId;if(n){let a={...t,jsonrpc:"2.0",params:{...t.params,_meta:{...t.params?._meta||{},[Is]:r.relatedTask}}};await this._enqueueTaskMessage(n,{type:"notification",message:a,timestamp:Date.now()});return}if((this._options?.debouncedNotificationMethods??[]).includes(t.method)&&!t.params&&!r?.relatedRequestId&&!r?.relatedTask){if(this._pendingDebouncedNotifications.has(t.method))return;this._pendingDebouncedNotifications.add(t.method),Promise.resolve().then(()=>{if(this._pendingDebouncedNotifications.delete(t.method),!this._transport)return;let a={...t,jsonrpc:"2.0"};r?.relatedTask&&(a={...a,params:{...a.params,_meta:{...a.params?._meta||{},[Is]:r.relatedTask}}}),this._transport?.send(a,r).catch(c=>this._onerror(c))});return}let s={...t,jsonrpc:"2.0"};r?.relatedTask&&(s={...s,params:{...s.params,_meta:{...s.params?._meta||{},[Is]:r.relatedTask}}}),await this._transport.send(s,r)}setRequestHandler(t,r){let n=l1(t);this.assertRequestHandlerCapability(n),this._requestHandlers.set(n,(o,i)=>{let s=d1(t,o);return Promise.resolve(r(s,i))})}removeRequestHandler(t){this._requestHandlers.delete(t)}assertCanSetRequestHandler(t){if(this._requestHandlers.has(t))throw new Error(`A request handler for ${t} already exists, which would be overridden`)}setNotificationHandler(t,r){let n=l1(t);this._notificationHandlers.set(n,o=>{let i=d1(t,o);return Promise.resolve(r(i))})}removeNotificationHandler(t){this._notificationHandlers.delete(t)}_cleanupTaskProgressHandler(t){let r=this._taskProgressTokens.get(t);r!==void 0&&(this._progressHandlers.delete(r),this._taskProgressTokens.delete(t))}async _enqueueTaskMessage(t,r,n){if(!this._taskStore||!this._taskMessageQueue)throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");let o=this._options?.maxTaskQueueSize;await this._taskMessageQueue.enqueue(t,r,n,o)}async _clearTaskQueue(t,r){if(this._taskMessageQueue){let n=await this._taskMessageQueue.dequeueAll(t,r);for(let o of n)if(o.type==="request"&&VT(o.message)){let i=o.message.id,s=this._requestResolvers.get(i);s?(s(new Ie(Oe.InternalError,"Task cancelled or completed")),this._requestResolvers.delete(i)):this._onerror(new Error(`Resolver missing for request ${i} during task ${t} cleanup`))}}}async _waitForTaskUpdate(t,r){let n=this._options?.defaultTaskPollInterval??1e3;try{let o=await this._taskStore?.getTask(t);o?.pollInterval&&(n=o.pollInterval)}catch{}return new Promise((o,i)=>{if(r.aborted){i(new Ie(Oe.InvalidRequest,"Request cancelled"));return}let s=setTimeout(o,n);r.addEventListener("abort",()=>{clearTimeout(s),i(new Ie(Oe.InvalidRequest,"Request cancelled"))},{once:!0})})}requestTaskStore(t,r){let n=this._taskStore;if(!n)throw new Error("No task store configured");return{createTask:async o=>{if(!t)throw new Error("No request provided");return await n.createTask(o,t.id,{method:t.method,params:t.params},r)},getTask:async o=>{let i=await n.getTask(o,r);if(!i)throw new Ie(Oe.InvalidParams,"Failed to retrieve task: Task not found");return i},storeTaskResult:async(o,i,s)=>{await n.storeTaskResult(o,i,s,r);let a=await n.getTask(o,r);if(a){let c=sm.parse({method:"notifications/tasks/status",params:a});await this.notification(c),Cs(a.status)&&this._cleanupTaskProgressHandler(o)}},getTaskResult:o=>n.getTaskResult(o,r),updateTaskStatus:async(o,i,s)=>{let a=await n.getTask(o,r);if(!a)throw new Ie(Oe.InvalidParams,`Task "${o}" not found - it may have been cleaned up`);if(Cs(a.status))throw new Ie(Oe.InvalidParams,`Cannot update task "${o}" from terminal status "${a.status}" to "${i}". Terminal states (completed, failed, cancelled) cannot transition to other states.`);await n.updateTaskStatus(o,i,s,r);let c=await n.getTask(o,r);if(c){let u=sm.parse({method:"notifications/tasks/status",params:c});await this.notification(u),Cs(c.status)&&this._cleanupTaskProgressHandler(o)}},listTasks:o=>n.listTasks(o,r)}}};function O4(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function R4(e,t){let r={...e};for(let n in t){let o=n,i=t[o];if(i===void 0)continue;let s=r[o];O4(s)&&O4(i)?r[o]={...s,...i}:r[o]=i}return r}var yJ=vt(ZO(),1),DJ=vt(gJ(),1);function qve(){let e=new yJ.default({strict:!1,validateFormats:!0,validateSchema:!1,allErrors:!0});return(0,DJ.default)(e),e}var AS=class{constructor(t){this._ajv=t??qve()}getValidator(t){let r="$id"in t&&typeof t.$id=="string"?this._ajv.getSchema(t.$id)??this._ajv.compile(t):this._ajv.compile(t);return n=>r(n)?{valid:!0,data:n,errorMessage:void 0}:{valid:!1,data:void 0,errorMessage:this._ajv.errorsText(r.errors)}}};var wS=class{constructor(t){this._server=t}requestStream(t,r,n){return this._server.requestStream(t,r,n)}createMessageStream(t,r){let n=this._server.getClientCapabilities();if((t.tools||t.toolChoice)&&!n?.sampling?.tools)throw new Error("Client does not support sampling tools capability.");if(t.messages.length>0){let o=t.messages[t.messages.length-1],i=Array.isArray(o.content)?o.content:[o.content],s=i.some(l=>l.type==="tool_result"),a=t.messages.length>1?t.messages[t.messages.length-2]:void 0,c=a?Array.isArray(a.content)?a.content:[a.content]:[],u=c.some(l=>l.type==="tool_use");if(s){if(i.some(l=>l.type!=="tool_result"))throw new Error("The last message must contain only tool_result content if any is present");if(!u)throw new Error("tool_result blocks are not matching any tool_use from the previous message")}if(u){let l=new Set(c.filter(f=>f.type==="tool_use").map(f=>f.id)),d=new Set(i.filter(f=>f.type==="tool_result").map(f=>f.toolUseId));if(l.size!==d.size||![...l].every(f=>d.has(f)))throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match")}}return this.requestStream({method:"sampling/createMessage",params:t},lm,r)}elicitInputStream(t,r){let n=this._server.getClientCapabilities(),o=t.mode??"form";switch(o){case"url":{if(!n?.elicitation?.url)throw new Error("Client does not support url elicitation.");break}case"form":{if(!n?.elicitation?.form)throw new Error("Client does not support form elicitation.");break}}let i=o==="form"&&t.mode===void 0?{...t,mode:"form"}:t;return this.requestStream({method:"elicitation/create",params:i},qu,r)}async getTask(t,r){return this._server.getTask({taskId:t},r)}async getTaskResult(t,r,n){return this._server.getTaskResult({taskId:t},r,n)}async listTasks(t,r){return this._server.listTasks(t?{cursor:t}:void 0,r)}async cancelTask(t,r){return this._server.cancelTask({taskId:t},r)}};function bJ(e,t,r){if(!e)throw new Error(`${r} does not support task creation (required for ${t})`);switch(t){case"tools/call":if(!e.tools?.call)throw new Error(`${r} does not support task creation for tools/call (required for ${t})`);break;default:break}}function vJ(e,t,r){if(!e)throw new Error(`${r} does not support task creation (required for ${t})`);switch(t){case"sampling/createMessage":if(!e.sampling?.createMessage)throw new Error(`${r} does not support task creation for sampling/createMessage (required for ${t})`);break;case"elicitation/create":if(!e.elicitation?.create)throw new Error(`${r} does not support task creation for elicitation/create (required for ${t})`);break;default:break}}var TS=class extends Jv{constructor(t,r){super(r),this._serverInfo=t,this._loggingLevels=new Map,this.LOG_LEVEL_SEVERITY=new Map(um.options.map((n,o)=>[n,o])),this.isMessageIgnored=(n,o)=>{let i=this._loggingLevels.get(o);return i?this.LOG_LEVEL_SEVERITY.get(n)<this.LOG_LEVEL_SEVERITY.get(i):!1},this._capabilities=r?.capabilities??{},this._instructions=r?.instructions,this._jsonSchemaValidator=r?.jsonSchemaValidator??new AS,this.setRequestHandler(ZT,n=>this._oninitialize(n)),this.setNotificationHandler(KT,()=>this.oninitialized?.()),this._capabilities.logging&&this.setRequestHandler(a1,async(n,o)=>{let i=o.sessionId||o.requestInfo?.headers["mcp-session-id"]||void 0,{level:s}=n.params,a=um.safeParse(s);return a.success&&this._loggingLevels.set(i,a.data),{}})}get experimental(){return this._experimental||(this._experimental={tasks:new wS(this)}),this._experimental}registerCapabilities(t){if(this.transport)throw new Error("Cannot register capabilities after connecting to transport");this._capabilities=R4(this._capabilities,t)}setRequestHandler(t,r){let o=wv(t)?.method;if(!o)throw new Error("Schema is missing a method literal");let i;if(ju(o)){let a=o;i=a._zod?.def?.value??a.value}else{let a=o;i=a._def?.value??a.value}if(typeof i!="string")throw new Error("Schema method literal must be a string");if(i==="tools/call"){let a=async(c,u)=>{let l=Es(cm,c);if(!l.success){let m=l.error instanceof Error?l.error.message:String(l.error);throw new Ie(Oe.InvalidParams,`Invalid tools/call request: ${m}`)}let{params:d}=l.data,f=await Promise.resolve(r(c,u));if(d.task){let m=Es(Bu,f);if(!m.success){let h=m.error instanceof Error?m.error.message:String(m.error);throw new Ie(Oe.InvalidParams,`Invalid task creation result: ${h}`)}return m.data}let p=Es(Yv,f);if(!p.success){let m=p.error instanceof Error?p.error.message:String(p.error);throw new Ie(Oe.InvalidParams,`Invalid tools/call result: ${m}`)}return p.data};return super.setRequestHandler(t,a)}return super.setRequestHandler(t,r)}assertCapabilityForMethod(t){switch(t){case"sampling/createMessage":if(!this._clientCapabilities?.sampling)throw new Error(`Client does not support sampling (required for ${t})`);break;case"elicitation/create":if(!this._clientCapabilities?.elicitation)throw new Error(`Client does not support elicitation (required for ${t})`);break;case"roots/list":if(!this._clientCapabilities?.roots)throw new Error(`Client does not support listing roots (required for ${t})`);break;case"ping":break}}assertNotificationCapability(t){switch(t){case"notifications/message":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${t})`);break;case"notifications/resources/updated":case"notifications/resources/list_changed":if(!this._capabilities.resources)throw new Error(`Server does not support notifying about resources (required for ${t})`);break;case"notifications/tools/list_changed":if(!this._capabilities.tools)throw new Error(`Server does not support notifying of tool list changes (required for ${t})`);break;case"notifications/prompts/list_changed":if(!this._capabilities.prompts)throw new Error(`Server does not support notifying of prompt list changes (required for ${t})`);break;case"notifications/elicitation/complete":if(!this._clientCapabilities?.elicitation?.url)throw new Error(`Client does not support URL elicitation (required for ${t})`);break;case"notifications/cancelled":break;case"notifications/progress":break}}assertRequestHandlerCapability(t){if(this._capabilities)switch(t){case"completion/complete":if(!this._capabilities.completions)throw new Error(`Server does not support completions (required for ${t})`);break;case"logging/setLevel":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${t})`);break;case"prompts/get":case"prompts/list":if(!this._capabilities.prompts)throw new Error(`Server does not support prompts (required for ${t})`);break;case"resources/list":case"resources/templates/list":case"resources/read":if(!this._capabilities.resources)throw new Error(`Server does not support resources (required for ${t})`);break;case"tools/call":case"tools/list":if(!this._capabilities.tools)throw new Error(`Server does not support tools (required for ${t})`);break;case"tasks/get":case"tasks/list":case"tasks/result":case"tasks/cancel":if(!this._capabilities.tasks)throw new Error(`Server does not support tasks capability (required for ${t})`);break;case"ping":case"initialize":break}}assertTaskCapability(t){vJ(this._clientCapabilities?.tasks?.requests,t,"Client")}assertTaskHandlerCapability(t){this._capabilities&&bJ(this._capabilities.tasks?.requests,t,"Server")}async _oninitialize(t){let r=t.params.protocolVersion;return this._clientCapabilities=t.params.capabilities,this._clientVersion=t.params.clientInfo,{protocolVersion:m4.includes(r)?r:JT,capabilities:this.getCapabilities(),serverInfo:this._serverInfo,...this._instructions&&{instructions:this._instructions}}}getClientCapabilities(){return this._clientCapabilities}getClientVersion(){return this._clientVersion}getCapabilities(){return this._capabilities}async ping(){return this.request({method:"ping"},kv)}async createMessage(t,r){if((t.tools||t.toolChoice)&&!this._clientCapabilities?.sampling?.tools)throw new Error("Client does not support sampling tools capability.");if(t.messages.length>0){let n=t.messages[t.messages.length-1],o=Array.isArray(n.content)?n.content:[n.content],i=o.some(u=>u.type==="tool_result"),s=t.messages.length>1?t.messages[t.messages.length-2]:void 0,a=s?Array.isArray(s.content)?s.content:[s.content]:[],c=a.some(u=>u.type==="tool_use");if(i){if(o.some(u=>u.type!=="tool_result"))throw new Error("The last message must contain only tool_result content if any is present");if(!c)throw new Error("tool_result blocks are not matching any tool_use from the previous message")}if(c){let u=new Set(a.filter(d=>d.type==="tool_use").map(d=>d.id)),l=new Set(o.filter(d=>d.type==="tool_result").map(d=>d.toolUseId));if(u.size!==l.size||![...u].every(d=>l.has(d)))throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match")}}return t.tools?this.request({method:"sampling/createMessage",params:t},c1,r):this.request({method:"sampling/createMessage",params:t},lm,r)}async elicitInput(t,r){switch(t.mode??"form"){case"url":{if(!this._clientCapabilities?.elicitation?.url)throw new Error("Client does not support url elicitation.");let o=t;return this.request({method:"elicitation/create",params:o},qu,r)}case"form":{if(!this._clientCapabilities?.elicitation?.form)throw new Error("Client does not support form elicitation.");let o=t.mode==="form"?t:{...t,mode:"form"},i=await this.request({method:"elicitation/create",params:o},qu,r);if(i.action==="accept"&&i.content&&o.requestedSchema)try{let a=this._jsonSchemaValidator.getValidator(o.requestedSchema)(i.content);if(!a.valid)throw new Ie(Oe.InvalidParams,`Elicitation response content does not match requested schema: ${a.errorMessage}`)}catch(s){throw s instanceof Ie?s:new Ie(Oe.InternalError,`Error validating elicitation response: ${s instanceof Error?s.message:String(s)}`)}return i}}}createElicitationCompletionNotifier(t,r){if(!this._clientCapabilities?.elicitation?.url)throw new Error("Client does not support URL elicitation (required for notifications/elicitation/complete)");return()=>this.notification({method:"notifications/elicitation/complete",params:{elicitationId:t}},r)}async listRoots(t,r){return this.request({method:"roots/list",params:t},u1,r)}async sendLoggingMessage(t,r){if(this._capabilities.logging&&!this.isMessageIgnored(t.level,r))return this.notification({method:"notifications/message",params:t})}async sendResourceUpdated(t){return this.notification({method:"notifications/resources/updated",params:t})}async sendResourceListChanged(){return this.notification({method:"notifications/resources/list_changed"})}async sendToolListChanged(){return this.notification({method:"notifications/tools/list_changed"})}async sendPromptListChanged(){return this.notification({method:"notifications/prompts/list_changed"})}};import _J from"node:process";var OS=class{append(t){this._buffer=this._buffer?Buffer.concat([this._buffer,t]):t}readMessage(){if(!this._buffer)return null;let t=this._buffer.indexOf(`
|
|
670
670
|
`);if(t===-1)return null;let r=this._buffer.toString("utf8",0,t).replace(/\r$/,"");return this._buffer=this._buffer.subarray(t+1),zve(r)}clear(){this._buffer=void 0}};function zve(e){return _4.parse(JSON.parse(e))}function SJ(e){return JSON.stringify(e)+`
|
|
671
|
-
`}var RS=class{constructor(t=_J.stdin,r=_J.stdout){this._stdin=t,this._stdout=r,this._readBuffer=new OS,this._started=!1,this._ondata=n=>{this._readBuffer.append(n),this.processReadBuffer()},this._onerror=n=>{this.onerror?.(n)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(;;)try{let t=this._readBuffer.readMessage();if(t===null)break;this.onmessage?.(t)}catch(t){this.onerror?.(t)}}async close(){this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0&&this._stdin.pause(),this._readBuffer.clear(),this.onclose?.()}send(t){return new Promise(r=>{let n=SJ(t);this._stdout.write(n)?r():this._stdout.once("drain",r)})}};var qi=["INVOICE","BILL","CUSTOMER_CREDIT_NOTE","SUPPLIER_CREDIT_NOTE","SALE_PAYMENT","PURCHASE_PAYMENT","BATCH_PAYMENT","CONTACT","ITEM","CAPSULE","SCHEDULED_TRANSACTION","JOURNAL","BANK_RECORD","CASHFLOW_TRANSACTION","FIXED_ASSET","CHART_OF_ACCOUNT","TAX_PROFILE"];TD();async function EJ(e,t){let n=(await ps((s,a)=>Ai(e,{offset:s,limit:a}))).data;if(n.length===0)return{mapping:{},failures:t.map(s=>({name:s,candidates:[]}))};let o={},i=[];for(let s of t){let a=pb(s,n);if(a)o[s]=a.resourceId;else{let c=gu(s,n,{threshold:.3,limit:3});i.push({name:s,candidates:c.map(u=>u.item.name)})}}return{mapping:o,failures:i}}async function IJ(e,t){if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)){let l=(await ba(e,t)).data;return{resourceId:l.resourceId,displayName:l.billingName||l.name||"Unknown"}}let n=t.trim(),i=(await ro(e,{filter:{billingName:{contains:n}},limit:50})).data;if(i.length===0&&(i=(await ts(e,{offset:0,limit:500})).data),i.length===0)throw new Error("No contacts found. Create one in Jaz first.");let s=n.toLowerCase(),a=i.find(u=>u.billingName?.toLowerCase()===s||u.name?.toLowerCase()===s);if(a)return{resourceId:a.resourceId,displayName:a.billingName||a.name||"Unknown"};let c=fb(n,i,{threshold:.5,limit:5});if(c.length>=1&&c[0].score>=.7){let u=c[0],l=c.length>1?c[1].score:0;if(c.length===1||u.score-l>=.1){let d=u.item;return{resourceId:d.resourceId,displayName:d.billingName||d.name||"Unknown"}}}if(c.length>1){let u=c.map(l=>`${l.item.billingName||l.item.name} (${(l.score*100).toFixed(0)}%)`).join(", ");throw new Error(`Multiple contacts match "${n}": ${u}. Be more specific.`)}throw new Error(`No contact matching "${n}".`)}async function CJ(e,t){if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)){let o=await qc(e,t);return{resourceId:o.data.resourceId,displayName:o.data.name}}let n=await ga(e,t);return{resourceId:n.resourceId,displayName:n.name}}async function $S(e,t){return e.list("/api/v1/bank-rules",t)}async function Um(e,t){let r=await e.get(`/api/v1/bank-rules/${t}`),n=r;if(n?.data&&Array.isArray(n.data.data)&&n.data.data.length>0)return{data:n.data.data[0]};let o=r;if(o?.data&&typeof o.data=="object"&&o.data!==null&&"resourceId"in o.data)return{data:o.data};throw new Error(`Unexpected response shape from GET /bank-rules/${t}`)}async function NS(e,t){return e.search("/api/v1/bank-rules/search",t)}async function kS(e,t){return e.post("/api/v1/bank-rules",t)}async function FS(e,t,r){return e.put(`/api/v1/bank-rules/${t}`,r)}async function PS(e,t){await e.delete(`/api/v1/bank-rules/${t}`)}async function LS(e,t){return e.list("/api/v1/fixed-assets",t)}async function jS(e,t){return e.get(`/api/v1/fixed-assets/${t}`)}async function MS(e,t){return e.search("/api/v1/fixed-assets/search",{...t,sort:t.sort??{sortBy:["purchaseDate"],order:"DESC"}})}async function BS(e,t){return e.post("/api/v1/fixed-assets",t)}async function US(e,t,r){return e.put(`/api/v1/fixed-assets/${t}`,r)}async function qS(e,t){await e.delete(`/api/v1/fixed-assets/${t}`)}async function zS(e,t,r){return e.post(`/api/v1/discard-fixed-assets/${t}`,{...r,resourceId:t})}async function qm(e,t){return e.post("/api/v1/mark-as-sold/fixed-assets",t)}async function YS(e,t){return e.post("/api/v1/transfer-fixed-assets",t)}async function JS(e,t){return e.post(`/api/v1/undo-disposal/fixed-assets/${t}`,{})}async function GS(e,t){return zr(e,"/api/v1/fixed-assets/bulk-upsert","fixedAssets",t)}async function VS(e,t){return e.list("/api/v1/scheduled/subscriptions",t)}async function zm(e,t){return e.get(`/api/v1/scheduled/subscriptions/${t}`)}async function HS(e,t){return e.post("/api/v1/scheduled/subscriptions",t)}async function WS(e,t,r){let n={...r};if(n.endDate){let o=!n.startDate,i=!n.repeat&&!n.interval;if(o||i){let s=await zm(e,t);if(o&&(n.startDate=s.data.startDate),i){if(!s.data.interval)throw new Error("Subscription missing repeat configuration \u2014 cannot auto-fill for update");n.repeat=s.data.interval}}}return e.put(`/api/v1/scheduled/subscriptions/${t}`,n)}async function ZS(e,t){await e.delete(`/api/v1/scheduled/subscriptions/${t}`)}async function KS(e,t,r){return e.put(`/api/v1/scheduled/cancel-subscriptions/${t}`,{resourceId:t,cancelDateType:r?.cancelDateType??"END_OF_CURRENT_PERIOD",proratedAdjustmentLineText:r?.proratedAdjustmentLineText??"Prorated adjustment",...r?.endDate?{endDate:r.endDate}:{}})}async function XS(e,t){return e.search("/api/v1/scheduled-transaction/search",{...t,sort:t.sort??{sortBy:["startDate"],order:"DESC"}})}async function QS(e,t){return e.list("/api/v1/contact-groups",t)}async function e_(e,t){return e.get(`/api/v1/contact-groups/${t}`)}async function t_(e,t){return e.search("/api/v1/contact-groups/search",t)}async function r_(e,t){return e.post("/api/v1/contact-groups",t)}async function n_(e,t,r){return e.put(`/api/v1/contact-groups/${t}`,r)}async function o_(e,t){await e.delete(`/api/v1/contact-groups/${t}`)}async function i_(e,t){return e.list("/api/v1/inventory-items",t)}async function s_(e,t){return e.post("/api/v1/inventory-items",t)}async function a_(e,t){return e.get(`/api/v1/inventory-item-balance/${t}`)}async function c_(e,t){return e.list("/api/v1/custom-fields",t)}async function u_(e,t){return e.get(`/api/v1/custom-fields/${t}`)}async function l_(e,t){return e.search("/api/v1/custom-fields/search",t)}async function d_(e,t){return e.post("/api/v1/custom-fields",t)}async function p_(e,t,r){return e.put(`/api/v1/custom-fields/${t}`,r)}async function f_(e,t){await e.delete(`/api/v1/custom-fields/${t}`)}var Yve=["invoices","bills","customer-credit-notes","supplier-credit-notes"],Jve=["journals","cash-entries"],Gve=["sale-schedules","purchase-schedules","subscription-schedules","journal-schedules"],sl=[...Yve,...Jve,...Gve];function xJ(e){return{updated:e.updated??[],failed:(e.failed??[]).map(t=>({...t,errorCode:t.errorCode??"UNKNOWN_ERROR"}))}}async function Ym(e,t,r){let n=await e.post(`/api/v1/quick-fix/${t}`,r);return xJ(n)}async function Jm(e,t,r){let n=await e.post(`/api/v1/quick-fix/${t}/line-items`,r);return xJ(n)}async function m_(e,t){return e.list("/api/v1/nano-classifiers",t)}async function h_(e,t){return{data:(await e.get(`/api/v1/nano-classifiers/${t}`)).data.data[0]}}async function g_(e,t){return e.search("/api/v1/nano-classifiers/search",t)}async function Gm(e,t){return e.post("/api/v1/nano-classifiers",{...t,printable:t.printable??!1})}async function Vm(e,t,r){return e.put(`/api/v1/nano-classifiers/${t}`,r)}async function y_(e,t){await e.delete(`/api/v1/nano-classifiers/${t}`)}async function D_(e,t){return e.post("/api/v1/export-records",t)}async function b_(e,t){return e.post("/api/v1/export-records/preview",t)}async function v_(e,t){return e.get(`/api/v1/export-records/columns/${t}`)}async function Hm(e,t={}){return e.search("/api/v1/background-jobs/search",t)}var Vve=new Set(["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"]);function al(e){ar(e,"items"),e.forEach((t,r)=>{if(!t||typeof t!="object")throw new Error(`items[${r}] must be an object with {btResourceId, btType}.`);let n=t;if(typeof n.btResourceId!="string"||n.btResourceId.trim()==="")throw new Error(`items[${r}].btResourceId is required (non-empty string).`);if(typeof n.btType!="string"||!Vve.has(n.btType))throw new Error(`items[${r}].btType must be one of SALE | PURCHASE | SALE_CREDIT_NOTE | PURCHASE_CREDIT_NOTE.`)})}async function S_(e,t){let r=await e.post("/api/v1/drafts/validate",{items:t});return{data:Wve(r.data)}}function Hve(e){return{btResourceId:e.btResourceId,btType:e.btType,eligible:e.eligible,errors:e.errors,displayData:e.displayData,contactSignals:e.contactInsight??null,breakdown:e.breakdown??null}}function Wve(e){return{eligibleCount:e.eligibleCount,ineligibleCount:e.ineligibleCount,results:e.results.map(Hve),columns:e.columns,errorColumns:e.errorColumns,contactSignalsMeta:e.contactInsightsMeta??null}}async function __(e,t){return e.post("/api/v1/drafts/convert-to-active",{items:t})}async function E_(e,t){return e.post("/api/v1/drafts/submit-for-approval",{items:t})}function oR(e,t){if(!e||typeof e!="object")throw new Error(`${t} is required.`);let r=e,n=r.lineItems;if(!Array.isArray(n)||n.length===0)throw new Error(`${t}.lineItems array is empty.`);if(n.length>500)throw new Error(`max 500 ${t}.lineItems per call.`);eo([r],["valueDate","dueDate"]);let o=r.recordedPayment;o&&typeof o=="object"&&eo([o],["valueDate"])}async function I_(e,t){return e.post("/api/v1/reconciliations/quick-reconcile",t)}async function C_(e,t){return e.post("/api/v1/reconciliations/bank-rule",t)}async function x_(e,t){return e.post("/api/v1/reconciliations/direct-cash-entry",t)}async function A_(e,t){return e.post("/api/v1/reconciliations/cash-journal",t)}async function w_(e,t){return e.post("/api/v1/reconciliations/manual-journal",t)}async function T_(e,t){return e.post("/api/v1/reconciliations/cash-transfer",t)}async function O_(e,t){return e.post("/api/v1/reconciliations/invoice-receipt",t)}async function R_(e,t){return e.post("/api/v1/reconciliations/bill-receipt",t)}var Xm={type:"string",description:"Resource ID of the record"},go={type:"string",description:"Transaction date (YYYY-MM-DD)"},Wm={type:"string",description:"Due date (YYYY-MM-DD)"},yo={type:"string",description:"Reference number"},yr={type:"string",description:"Notes or memo text"},cl={type:"string",description:"Tag name for categorization"};var AJ={type:"boolean",description:"Save as draft (default true). Set false to finalize immediately."},Zve={type:"string",description:"Contact resourceId (customer or supplier)"},tc={type:"string",description:"Bank/cash account resourceId"},Kve={type:"number",description:"Payment amount (in bank currency)"},Xve={type:"string",description:"Period start date (YYYY-MM-DD)"},iR={type:"string",description:"Period end date (YYYY-MM-DD)"},wJ={type:"string",description:"Currency code (e.g. SGD, USD)"},sR={type:"string",description:"Display name"},cR={limit:{type:"number",description:"Max results per page (default 20, max 1000)."},offset:{type:"number",description:"Page offset (0-indexed). Use with limit to paginate."}},Qa={type:"object",properties:{sourceCurrency:{type:"string"},exchangeRate:{type:"number"}}},aR={type:"string",enum:[...qi],description:"Entity type to export"},TJ={type:"string",description:'Structured search query using dashboard syntax (e.g., "status:unpaid $500+ date:this month"). Mutually exclusive with filter \u2014 pass one or the other, never both.'},OJ={type:"object",description:'Raw JSON filter object (e.g., {"status":{"in":["UNPAID"]}}). Mutually exclusive with query \u2014 pass one or the other, never both.'},RJ={type:"array",items:{type:"object",properties:{path:{type:"string",description:"Column path from get_export_columns (e.g., s.reference)"},header:{type:"string",description:"Column header label in the export file"},type:{type:"string",enum:["STRING","NUMBER","CURRENCY","DATE","BOOLEAN"],description:"Column data type (optional)"}},required:["path","header"]},description:"Custom column definitions. Omit to use default columns. Use get_export_columns to discover available paths."},$J={type:"object",properties:{field:{type:"string",description:"Column path to sort by (e.g., s.total_amount)"},direction:{type:"string",enum:["ASC","DESC"],description:"Sort direction"}},required:["field"],description:"Sort results by a column path."},un={type:"array",items:{type:"object",properties:{customFieldName:{type:"string"},actualValue:{type:"string"}}},description:'Custom field values: [{ customFieldName: "PO Number", actualValue: "PO-123" }]'},Qve={type:"array",items:{type:"object",properties:{resourceId:{type:"string",description:"Capsule type resourceId"},type:{type:"string",enum:["invoice","bill"],description:"Resource type"},selectedClasses:{type:"array",items:{type:"object",properties:{className:{type:"string"},resourceId:Xm}}},printable:{type:"boolean"}}},description:"Nano classifier config for line items. Each entry links a capsule type with selected classes."},ec={type:"array",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Account resourceId"},type:{type:"string",enum:["DEBIT","CREDIT"],description:"Debit or credit"},amount:{type:"number",description:"Amount"},description:{type:"string",description:"Line description"}},required:["accountResourceId","type","amount"]},description:"Journal entries (debit/credit lines with accountResourceId, type, amount)"},di={type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description/name"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:tc,taxProfileResourceId:{type:"string"},classifierConfig:Qve},required:["name","quantity","unitPrice"]},description:"Line items \u2014 include accountResourceId on each line when finalizing (saveAsDraft: false)"},Zm={type:"string",enum:[...U3],description:"Payment method (default BANK_TRANSFER)"};function FJ(e){let t=e.limit,r=e.offset;return{limit:t,offset:r,sortBy:void 0,sortOrder:void 0}}function gt(e,t,r,n,o){return{name:e,description:t,params:{...cR},required:[],group:r,readOnly:!0,isConcurrencySafe:!0,maxResultSizeChars:5e4,...o?{searchHint:o}:{},execute:async(i,s)=>{let{limit:a,offset:c}=FJ(s);return kp((u,l)=>n(i.client,u,l),a,c,20)}}}function Yn(e,t,r,n,o){return{name:e,description:t,params:{resourceId:{type:"string",description:"Resource ID (UUID)"}},required:["resourceId"],group:r,readOnly:!0,isConcurrencySafe:!0,maxResultSizeChars:2e4,...o?{searchHint:o}:{},execute:async(i,s)=>n(i.client,s.resourceId)}}function ln(e,t,r,n,o){return{name:e,description:t,params:{resourceId:{type:"string",description:"Resource ID (UUID)"}},required:["resourceId"],group:r,readOnly:!1,isDestructive:!0,...o?{searchHint:o}:{},execute:async(i,s)=>(await n(i.client,s.resourceId),{deleted:!0,resourceId:s.resourceId})}}var eSe={invoice:new Set(["reference","valueDate","dueDate","contactResourceId","lineItems","notes","invoiceNotes","internalNotes","tag","tags","isTaxVatApplicable","isTaxVATApplicable","taxInclusion","terms","currency","customFields","capsuleResourceId","taxProfileResourceId","customerPaymentProfileResourceId"]),bill:new Set(["reference","valueDate","dueDate","contactResourceId","lineItems","invoiceNotes","internalNotes","tag","tags","isTaxVatApplicable","isTaxVATApplicable","taxInclusion","terms","currency","customFields","capsuleResourceId","taxProfileResourceId"]),customer_credit_note:new Set(["reference","valueDate","contactResourceId","lineItems","invoiceNotes","tag","tags","isTaxVatApplicable","isTaxVATApplicable","taxInclusion","currency","customFields","capsuleResourceId","taxProfileResourceId"]),supplier_credit_note:new Set(["reference","valueDate","contactResourceId","lineItems","invoiceNotes","tag","tags","isTaxVatApplicable","isTaxVATApplicable","taxInclusion","currency","customFields","capsuleResourceId","taxProfileResourceId"])};function NJ(e){if(typeof e!="string"||/^\d{4}-\d{2}-\d{2}$/.test(e))return e;let t=/^(\d{4}-\d{2}-\d{2})T/.exec(e);return t?t[1]:e}var tSe=new Set(["name","quantity","unitPrice","unit","accountResourceId","taxProfileResourceId","description","classifierConfig","itemResourceId","discount"]);function rSe(e){return Array.isArray(e)?e.map(t=>{let r={};for(let[n,o]of Object.entries(t))if(o!=null)if(n==="organizationAccountResourceId")r.accountResourceId=o;else if(n==="taxProfile"&&typeof o=="object"&&o!==null){let i=o.resourceId;i&&(r.taxProfileResourceId=i)}else if(n==="discount"&&typeof o=="object"&&o!==null){let i=o.rateValue;i&&Number(i)!==0&&(r.discount=o)}else tSe.has(n)&&(r[n]=o);return r}):e}async function Km(e,t,r,n){let s=(await(t==="invoice"?io:t==="bill"?to:t==="customer_credit_note"?$o:No)(e,r)).data,a=eSe[t],c={};for(let[f,p]of Object.entries(s))a.has(f)&&p!==null&&p!==void 0&&(c[f]=p);c.valueDate&&(c.valueDate=NJ(c.valueDate)),c.dueDate&&(c.dueDate=NJ(c.dueDate)),c.lineItems&&(c.lineItems=rSe(c.lineItems));for(let[f,p]of Object.entries(n))p!==void 0&&(c[f]=p);let u=t==="invoice"?so:t==="bill"?_n:ur,{missingFields:l,ready:d}=on(c,u);if(!d)throw new Error(`Cannot finalize: missing ${l.join(", ")}. Use search_accounts (filter by accountType) and search_contacts to resolve, then pass the missing fields to this tool.`);return c}async function kJ(e,t,r,n){if((await e(t,r)).data.status==="DRAFT")throw new Error(`Cannot pay a DRAFT ${n}. Finalize it first with finalize_${n}.`)}var ul=[{name:"get_organization",description:"Get organization details (name, currency, country, lock date, fiscal year end).",params:{},required:[],group:"organization",readOnly:!0,searchHint:"get organization details currency country fiscal year",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async e=>Pn(e.client)},gt("list_accounts","List chart of accounts. Returns account name, code, type, class, status. Paginated \u2014 response includes totalElements. Use limit/offset to page.","accounts",(e,t,r)=>Ai(e,{limit:r,offset:t}),"list chart of accounts with code type class status"),Rt({name:"search_accounts",description:'Search chart of accounts by name, code, class, type, status. For OR search (name or code), use filter param: {"or":{"name":{"contains":"X"},"code":{"contains":"X"}}}.',group:"accounts",fields:ef,defaults:tf,fetcher:hu,searchHint:"find accounts by name code type class status"}),{name:"create_account",description:"Create a new chart of accounts entry. Auto-checks for duplicates by name \u2014 returns existing account if found. Code must be unique. Account class is inferred from accountType.",params:{name:{type:"string",description:"Account name"},code:{type:"string",description:"Account code (unique)"},accountType:{type:"string",description:`Exact API values. Classic set: "Bank Accounts", "Cash", "Current Asset", "Fixed Asset", "Inventory", "Current Liability", "Non-current Liability", "Shareholders Equity", "Operating Revenue", "Other Revenue", "Operating Expense", "Direct Costs". IFRS 18 set (effective 2027): "Discontinued Expense", "Discontinued Income", "Finance Cost", "Financing Income", "Goodwill", "Income Tax Expense", "Investing Expense", "Investing Income", "Investment". Unambiguous variants are normalized client-side ("income tax" \u2192 "Income Tax Expense", "investments" \u2192 "Investment", "finance costs" \u2192 "Finance Cost"). For "interest expense" / "interest income", pick the explicit IFRS 18 string yourself \u2014 these can land in either Financing or Investing under IFRS 18 depending on the entity's main business activity, so motherboard does NOT auto-classify.`},currencyCode:{type:"string",description:'Currency code (e.g., "SGD")'}},required:["name","code","accountType"],group:"accounts",readOnly:!1,searchHint:"create new chart of accounts entry with type code",execute:async(e,t)=>{let r=t.name,n=await sb(e.client,r);if(n)return{_guard:"duplicate_skipped",message:`Account "${r}" already exists.`,existing:n};let o=mu(t.accountType);return gp(e.client,{code:t.code,name:r,accountType:o,currencyCode:t.currencyCode})}},{name:"update_account",description:"Update an existing chart of accounts entry (name or code).",params:{resourceId:{type:"string",description:"Account resourceId"},name:{type:"string",description:"New account name"},code:{type:"string",description:"New account code"}},required:["resourceId"],group:"accounts",readOnly:!1,searchHint:"update rename chart of accounts entry name code",execute:async(e,t)=>{let r=t.resourceId,n=(await Nz(e.client,r)).data,i=Object.fromEntries(["name","code","classificationType","taxProfileResourceId","currency","description"].filter(s=>n[s]!==void 0&&n[s]!==null).map(s=>[s,n[s]]));return!i.classificationType&&n.accountType&&(i.classificationType=n.accountType),t.name!==void 0&&(i.name=t.name),t.code!==void 0&&(i.code=t.code),kz(e.client,r,i)}},{name:"bulk_upsert_chart_of_accounts",description:"Create or update chart-of-accounts entries in bulk (max 500 per call). SYNC: returns `{ resourceIds: string[], failedRows: ImportedRowError[], failedCount: number }` immediately \u2014 no jobId polling. Each successful row contributes one resourceId; each failure surfaces a `failedRows[]` entry with `rowIndex`, `columnName`, `columnValue`, `errorCode`, `errorMessage`. Common per-row errors: `ORGANIZATION_CHART_OF_ACCOUNT_DUPLICATED` when a row's `name` collides with an existing account in the org (dedup is by NAME not code). Other rows in the batch still succeed (PARTIAL_SUCCESS pattern). Provide `resourceId` per account to update; omit to create. Accepts the classic 12 + 9 IFRS 18 `accountType` values per rule 140; common variants are normalized client-side via normalizeAccountType. Use this tool for CoA imports, IFRS 18 migrations, and bulk template seeding. For one-off creates with auto-dedup-on-name, use `create_account` instead.",params:{accounts:{type:"array",description:"Array of chart-of-accounts entries (max 500). Mix create and update freely.",items:{type:"object",properties:{resourceId:{type:"string",description:"Account resourceId (UUID) \u2014 provide to update, omit to create"},code:{type:"string",description:"Account code (unique per org)"},name:{type:"string",description:"Account name (unique per org \u2014 dedup key)"},accountType:{type:"string",description:'Classic 12 or IFRS 18 set per create_account description (e.g. "Operating Expense", "Finance Cost"). Variants normalized client-side ("income tax" \u2192 "Income Tax Expense"). Required for create.'},currencyCode:{type:"string",description:'Currency code (e.g. "SGD"). Defaults to org functional currency.'},description:{type:"string",description:"Optional description / memo"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Account status"}}}}},required:["accounts"],group:"accounts",readOnly:!1,searchHint:"bulk create or update chart of accounts import COA migration",execute:async(e,t)=>{ar(t.accounts,"accounts",500,"chart-of-accounts entries");let r=t.accounts.map(ub);return(await lb(e.client,r)).data}},gt("list_contacts","List contacts (customers/suppliers). Returns billingName, name, emails, status. Paginated \u2014 response includes totalElements. Use limit/offset to page.","contacts",(e,t,r)=>ts(e,{limit:r,offset:t}),"list customers suppliers contacts with email status"),Rt({name:"search_contacts",description:"Search contacts by name, email, customer/supplier role, status.",group:"contacts",fields:Bp,defaults:Up,fetcher:ro,searchHint:"find customers suppliers by name email role status"}),{name:"get_contact",description:"Get full contact details by resourceId.",params:{resourceId:{type:"string",description:"Contact resourceId (UUID)"}},required:["resourceId"],group:"contacts",readOnly:!0,searchHint:"get contact customer supplier details by id",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>ba(e.client,t.resourceId)},{name:"get_contact_signals",description:`Get contact signals \u2014 read-only pattern intelligence (cadence, outliers, divergences, severity) for a single contact. USE THIS for stand-alone contact-history lookup before drafting a transaction (e.g. "what does this supplier normally look like?"). Do NOT use validate_drafts unless you already have a specific draft to score. Returns null when the contact has no qualifying history yet (sampleSize < 5) or the freshness layer is unavailable. Per-pair cache (contactId \xD7 btType) \u2014 duplicate calls for the same pair return the same result. Three response slices populate ONLY on the validate_drafts path (severitySummary, outlierFlags, revealedDivergences) \u2014 those require a draft to compare against, so they're always empty/null here.`,params:{resourceId:{type:"string",description:"Contact resourceId (UUID)"},btType:{type:"string",description:"Business-transaction type to scope the signal sample to.",enum:["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"]}},required:["resourceId","btType"],group:"contacts",readOnly:!0,searchHint:"contact signals patterns cadence outliers severity history",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=t.resourceId;return $z(r,"resourceId","Call search_contacts to get a valid contact resourceId."),EM(e.client,r,t.btType)}},{name:"create_contact",description:"Create a new contact. Auto-checks for duplicates by name \u2014 returns existing contact if found instead of creating a duplicate.",params:{billingName:{type:"string",description:"Official billing name"},name:{type:"string",description:"Display name (usually same as billingName)"},email:{type:"string",description:"Primary email address"},customer:{type:"boolean",description:"Is a customer (default true)"},supplier:{type:"boolean",description:"Is a supplier (default false)"}},required:["billingName"],group:"contacts",readOnly:!1,searchHint:"create new customer or supplier contact",execute:async(e,t)=>{let r=t.name??t.billingName,n=await hp(e.client,r);return n?{_guard:"duplicate_skipped",message:`Contact "${r}" already exists.`,existing:n}:Yc(e.client,{billingName:t.billingName,name:r,emails:t.email?[t.email]:void 0,customer:t.customer??!0,supplier:t.supplier??!1})}},{name:"update_contact",description:"Update an existing contact. Fetches current data first so you only need to send changed fields.",params:{resourceId:{type:"string",description:"Contact resourceId"},billingName:{type:"string"},name:sR,email:{type:"string"}},required:["resourceId"],group:"contacts",readOnly:!1,searchHint:"update existing contact billing name email details",execute:async(e,t)=>{let{resourceId:r,...n}=t,{data:o}=await ba(e.client,r),i=["billingName","name","email","customer","supplier","taxId","phone","status","currencyCode","customerPaymentTerms"],s=o,a=Object.fromEntries(i.filter(c=>s[c]!==void 0&&s[c]!==null).map(c=>[c,s[c]]));return Object.assign(a,n),Oy(e.client,r,a)}},gt("list_invoices","List invoices. Returns reference, date, status, contact, totalAmount. Paginated \u2014 response includes totalElements. Use limit/offset to page.","invoices",(e,t,r)=>Ab(e,{limit:r,offset:t}),"list sales invoices with pagination and status"),Rt({name:"search_invoices",description:'Search invoices. Supports comma-separated status (e.g., "UNPAID,PARTIALLY_PAID"). Use filter param for advanced queries (nested paths, OR groups).',group:"invoices",fields:xu,defaults:Au,fetcher:Tu,searchHint:"find sales invoices by status date contact amount"}),{name:"get_invoice",description:"Get full invoice details including line items, payments, totals.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"invoices",readOnly:!0,searchHint:"get invoice details line items payments totals",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>io(e.client,t.resourceId)},{name:"create_invoice",description:`Create a new invoice. IMPORTANT:
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
671
|
+
`}var RS=class{constructor(t=_J.stdin,r=_J.stdout){this._stdin=t,this._stdout=r,this._readBuffer=new OS,this._started=!1,this._ondata=n=>{this._readBuffer.append(n),this.processReadBuffer()},this._onerror=n=>{this.onerror?.(n)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(;;)try{let t=this._readBuffer.readMessage();if(t===null)break;this.onmessage?.(t)}catch(t){this.onerror?.(t)}}async close(){this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0&&this._stdin.pause(),this._readBuffer.clear(),this.onclose?.()}send(t){return new Promise(r=>{let n=SJ(t);this._stdout.write(n)?r():this._stdout.once("drain",r)})}};var qi=["INVOICE","BILL","CUSTOMER_CREDIT_NOTE","SUPPLIER_CREDIT_NOTE","SALE_PAYMENT","PURCHASE_PAYMENT","BATCH_PAYMENT","CONTACT","ITEM","CAPSULE","SCHEDULED_TRANSACTION","JOURNAL","BANK_RECORD","CASHFLOW_TRANSACTION","FIXED_ASSET","CHART_OF_ACCOUNT","TAX_PROFILE"];TD();async function EJ(e,t){let n=(await ps((s,a)=>Ai(e,{offset:s,limit:a}))).data;if(n.length===0)return{mapping:{},failures:t.map(s=>({name:s,candidates:[]}))};let o={},i=[];for(let s of t){let a=pb(s,n);if(a)o[s]=a.resourceId;else{let c=gu(s,n,{threshold:.3,limit:3});i.push({name:s,candidates:c.map(u=>u.item.name)})}}return{mapping:o,failures:i}}async function IJ(e,t){if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)){let l=(await ba(e,t)).data;return{resourceId:l.resourceId,displayName:l.billingName||l.name||"Unknown"}}let n=t.trim(),i=(await ro(e,{filter:{billingName:{contains:n}},limit:50})).data;if(i.length===0&&(i=(await ts(e,{offset:0,limit:500})).data),i.length===0)throw new Error("No contacts found. Create one in Jaz first.");let s=n.toLowerCase(),a=i.find(u=>u.billingName?.toLowerCase()===s||u.name?.toLowerCase()===s);if(a)return{resourceId:a.resourceId,displayName:a.billingName||a.name||"Unknown"};let c=fb(n,i,{threshold:.5,limit:5});if(c.length>=1&&c[0].score>=.7){let u=c[0],l=c.length>1?c[1].score:0;if(c.length===1||u.score-l>=.1){let d=u.item;return{resourceId:d.resourceId,displayName:d.billingName||d.name||"Unknown"}}}if(c.length>1){let u=c.map(l=>`${l.item.billingName||l.item.name} (${(l.score*100).toFixed(0)}%)`).join(", ");throw new Error(`Multiple contacts match "${n}": ${u}. Be more specific.`)}throw new Error(`No contact matching "${n}".`)}async function CJ(e,t){if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)){let o=await qc(e,t);return{resourceId:o.data.resourceId,displayName:o.data.name}}let n=await ga(e,t);return{resourceId:n.resourceId,displayName:n.name}}async function $S(e,t){return e.list("/api/v1/bank-rules",t)}async function Um(e,t){let r=await e.get(`/api/v1/bank-rules/${t}`),n=r;if(n?.data&&Array.isArray(n.data.data)&&n.data.data.length>0)return{data:n.data.data[0]};let o=r;if(o?.data&&typeof o.data=="object"&&o.data!==null&&"resourceId"in o.data)return{data:o.data};throw new Error(`Unexpected response shape from GET /bank-rules/${t}`)}async function NS(e,t){return e.search("/api/v1/bank-rules/search",t)}async function kS(e,t){return e.post("/api/v1/bank-rules",t)}async function FS(e,t,r){return e.put(`/api/v1/bank-rules/${t}`,r)}async function PS(e,t){await e.delete(`/api/v1/bank-rules/${t}`)}async function LS(e,t){return e.list("/api/v1/fixed-assets",t)}async function jS(e,t){return e.get(`/api/v1/fixed-assets/${t}`)}async function MS(e,t){return e.search("/api/v1/fixed-assets/search",{...t,sort:t.sort??{sortBy:["purchaseDate"],order:"DESC"}})}async function BS(e,t){return e.post("/api/v1/fixed-assets",t)}async function US(e,t,r){return e.put(`/api/v1/fixed-assets/${t}`,r)}async function qS(e,t){await e.delete(`/api/v1/fixed-assets/${t}`)}async function zS(e,t,r){return e.post(`/api/v1/discard-fixed-assets/${t}`,{...r,resourceId:t})}async function qm(e,t){return e.post("/api/v1/mark-as-sold/fixed-assets",t)}async function YS(e,t){return e.post("/api/v1/transfer-fixed-assets",t)}async function JS(e,t){return e.post(`/api/v1/undo-disposal/fixed-assets/${t}`,{})}async function GS(e,t){return zr(e,"/api/v1/fixed-assets/bulk-upsert","fixedAssets",t)}async function VS(e,t){return e.list("/api/v1/scheduled/subscriptions",t)}async function zm(e,t){return e.get(`/api/v1/scheduled/subscriptions/${t}`)}async function HS(e,t){return e.post("/api/v1/scheduled/subscriptions",t)}async function WS(e,t,r){let n={...r};if(n.endDate){let o=!n.startDate,i=!n.repeat&&!n.interval;if(o||i){let s=await zm(e,t);if(o&&(n.startDate=s.data.startDate),i){if(!s.data.interval)throw new Error("Subscription missing repeat configuration \u2014 cannot auto-fill for update");n.repeat=s.data.interval}}}return e.put(`/api/v1/scheduled/subscriptions/${t}`,n)}async function ZS(e,t){await e.delete(`/api/v1/scheduled/subscriptions/${t}`)}async function KS(e,t,r){return e.put(`/api/v1/scheduled/cancel-subscriptions/${t}`,{resourceId:t,cancelDateType:r?.cancelDateType??"END_OF_CURRENT_PERIOD",proratedAdjustmentLineText:r?.proratedAdjustmentLineText??"Prorated adjustment",...r?.endDate?{endDate:r.endDate}:{}})}async function XS(e,t){return e.search("/api/v1/scheduled-transaction/search",{...t,sort:t.sort??{sortBy:["startDate"],order:"DESC"}})}async function QS(e,t){return e.list("/api/v1/contact-groups",t)}async function e_(e,t){return e.get(`/api/v1/contact-groups/${t}`)}async function t_(e,t){return e.search("/api/v1/contact-groups/search",t)}async function r_(e,t){return e.post("/api/v1/contact-groups",t)}async function n_(e,t,r){return e.put(`/api/v1/contact-groups/${t}`,r)}async function o_(e,t){await e.delete(`/api/v1/contact-groups/${t}`)}async function i_(e,t){return e.list("/api/v1/inventory-items",t)}async function s_(e,t){return e.post("/api/v1/inventory-items",t)}async function a_(e,t){return e.get(`/api/v1/inventory-item-balance/${t}`)}async function c_(e,t){return e.list("/api/v1/custom-fields",t)}async function u_(e,t){return e.get(`/api/v1/custom-fields/${t}`)}async function l_(e,t){return e.search("/api/v1/custom-fields/search",t)}async function d_(e,t){return e.post("/api/v1/custom-fields",t)}async function p_(e,t,r){return e.put(`/api/v1/custom-fields/${t}`,r)}async function f_(e,t){await e.delete(`/api/v1/custom-fields/${t}`)}var Yve=["invoices","bills","customer-credit-notes","supplier-credit-notes"],Jve=["journals","cash-entries"],Gve=["sale-schedules","purchase-schedules","subscription-schedules","journal-schedules"],sl=[...Yve,...Jve,...Gve];function xJ(e){return{updated:e.updated??[],failed:(e.failed??[]).map(t=>({...t,errorCode:t.errorCode??"UNKNOWN_ERROR"}))}}async function Ym(e,t,r){let n=await e.post(`/api/v1/quick-fix/${t}`,r);return xJ(n)}async function Jm(e,t,r){let n=await e.post(`/api/v1/quick-fix/${t}/line-items`,r);return xJ(n)}async function m_(e,t){return e.list("/api/v1/nano-classifiers",t)}async function h_(e,t){return{data:(await e.get(`/api/v1/nano-classifiers/${t}`)).data.data[0]}}async function g_(e,t){return e.search("/api/v1/nano-classifiers/search",t)}async function Gm(e,t){return e.post("/api/v1/nano-classifiers",{...t,printable:t.printable??!1})}async function Vm(e,t,r){return e.put(`/api/v1/nano-classifiers/${t}`,r)}async function y_(e,t){await e.delete(`/api/v1/nano-classifiers/${t}`)}async function D_(e,t){return e.post("/api/v1/export-records",t)}async function b_(e,t){return e.post("/api/v1/export-records/preview",t)}async function v_(e,t){return e.get(`/api/v1/export-records/columns/${t}`)}async function Hm(e,t={}){return e.search("/api/v1/background-jobs/search",t)}var Vve=new Set(["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"]);function al(e){ar(e,"items"),e.forEach((t,r)=>{if(!t||typeof t!="object")throw new Error(`items[${r}] must be an object with {btResourceId, btType}.`);let n=t;if(typeof n.btResourceId!="string"||n.btResourceId.trim()==="")throw new Error(`items[${r}].btResourceId is required (non-empty string).`);if(typeof n.btType!="string"||!Vve.has(n.btType))throw new Error(`items[${r}].btType must be one of SALE | PURCHASE | SALE_CREDIT_NOTE | PURCHASE_CREDIT_NOTE.`)})}async function S_(e,t){let r=await e.post("/api/v1/drafts/validate",{items:t});return{data:Wve(r.data)}}function Hve(e){return{btResourceId:e.btResourceId,btType:e.btType,eligible:e.eligible,errors:e.errors,displayData:e.displayData,contactSignals:e.contactInsight??null,breakdown:e.breakdown??null}}function Wve(e){return{eligibleCount:e.eligibleCount,ineligibleCount:e.ineligibleCount,results:e.results.map(Hve),columns:e.columns,errorColumns:e.errorColumns,contactSignalsMeta:e.contactInsightsMeta??null}}async function __(e,t){return e.post("/api/v1/drafts/convert-to-active",{items:t})}async function E_(e,t){return e.post("/api/v1/drafts/submit-for-approval",{items:t})}function oR(e,t){if(!e||typeof e!="object")throw new Error(`${t} is required.`);let r=e,n=r.lineItems;if(!Array.isArray(n)||n.length===0)throw new Error(`${t}.lineItems array is empty.`);if(n.length>500)throw new Error(`max 500 ${t}.lineItems per call.`);eo([r],["valueDate","dueDate"]);let o=r.recordedPayment;o&&typeof o=="object"&&eo([o],["valueDate"])}async function I_(e,t){return e.post("/api/v1/reconciliations/quick-reconcile",t)}async function C_(e,t){return e.post("/api/v1/reconciliations/bank-rule",t)}async function x_(e,t){return e.post("/api/v1/reconciliations/direct-cash-entry",t)}async function A_(e,t){return e.post("/api/v1/reconciliations/cash-journal",t)}async function w_(e,t){return e.post("/api/v1/reconciliations/manual-journal",t)}async function T_(e,t){return e.post("/api/v1/reconciliations/cash-transfer",t)}async function O_(e,t){return e.post("/api/v1/reconciliations/invoice-receipt",t)}async function R_(e,t){return e.post("/api/v1/reconciliations/bill-receipt",t)}var Xm={type:"string",description:"Resource ID of the record"},go={type:"string",description:"Transaction date (YYYY-MM-DD)"},Wm={type:"string",description:"Due date (YYYY-MM-DD)"},yo={type:"string",description:"Reference number"},yr={type:"string",description:"Notes or memo text"},cl={type:"string",description:"Tag name for categorization"};var AJ={type:"boolean",description:"Save as draft (default true). Set false to finalize immediately."},Zve={type:"string",description:"Contact resourceId (customer or supplier)"},tc={type:"string",description:"Bank/cash account resourceId"},Kve={type:"number",description:"Payment amount (in bank currency)"},Xve={type:"string",description:"Period start date (YYYY-MM-DD)"},iR={type:"string",description:"Period end date (YYYY-MM-DD)"},wJ={type:"string",description:"Currency code (e.g. SGD, USD)"},sR={type:"string",description:"Display name"},cR={limit:{type:"number",description:"Max results per page (default 20, max 1000)."},offset:{type:"number",description:"Page offset (0-indexed). Use with limit to paginate."}},Qa={type:"object",properties:{sourceCurrency:{type:"string"},exchangeRate:{type:"number"}}},aR={type:"string",enum:[...qi],description:"Entity type to export"},TJ={type:"string",description:'Structured search query using dashboard syntax (e.g., "status:unpaid $500+ date:this month"). Mutually exclusive with filter \u2014 pass one or the other, never both.'},OJ={type:"object",description:'Raw JSON filter object (e.g., {"status":{"in":["UNPAID"]}}). Mutually exclusive with query \u2014 pass one or the other, never both.'},RJ={type:"array",items:{type:"object",properties:{path:{type:"string",description:"Column path from get_export_columns (e.g., s.reference)"},header:{type:"string",description:"Column header label in the export file"},type:{type:"string",enum:["STRING","NUMBER","CURRENCY","DATE","BOOLEAN"],description:"Column data type (optional)"}},required:["path","header"]},description:"Custom column definitions. Omit to use default columns. Use get_export_columns to discover available paths."},$J={type:"object",properties:{field:{type:"string",description:"Column path to sort by (e.g., s.total_amount)"},direction:{type:"string",enum:["ASC","DESC"],description:"Sort direction"}},required:["field"],description:"Sort results by a column path."},un={type:"array",items:{type:"object",properties:{customFieldName:{type:"string"},actualValue:{type:"string"}}},description:'Custom field values: [{ customFieldName: "PO Number", actualValue: "PO-123" }]'},Qve={type:"array",items:{type:"object",properties:{resourceId:{type:"string",description:"Capsule type resourceId"},type:{type:"string",enum:["invoice","bill"],description:"Resource type"},selectedClasses:{type:"array",items:{type:"object",properties:{className:{type:"string"},resourceId:Xm}}},printable:{type:"boolean"}}},description:"Nano classifier config for line items. Each entry links a capsule type with selected classes."},ec={type:"array",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Account resourceId"},type:{type:"string",enum:["DEBIT","CREDIT"],description:"Debit or credit"},amount:{type:"number",description:"Amount"},description:{type:"string",description:"Line description"}},required:["accountResourceId","type","amount"]},description:"Journal entries (debit/credit lines with accountResourceId, type, amount)"},di={type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description/name"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:tc,taxProfileResourceId:{type:"string"},classifierConfig:Qve},required:["name","quantity","unitPrice"]},description:"Line items \u2014 include accountResourceId on each line when finalizing (saveAsDraft: false)"},Zm={type:"string",enum:[...U3],description:"Payment method (default BANK_TRANSFER)"};function FJ(e){let t=e.limit,r=e.offset;return{limit:t,offset:r,sortBy:void 0,sortOrder:void 0}}function gt(e,t,r,n,o){return{name:e,description:t,params:{...cR},required:[],group:r,readOnly:!0,isConcurrencySafe:!0,maxResultSizeChars:5e4,...o?{searchHint:o}:{},execute:async(i,s)=>{let{limit:a,offset:c}=FJ(s);return kp((u,l)=>n(i.client,u,l),a,c,20)}}}function Yn(e,t,r,n,o){return{name:e,description:t,params:{resourceId:{type:"string",description:"Resource ID (UUID)"}},required:["resourceId"],group:r,readOnly:!0,isConcurrencySafe:!0,maxResultSizeChars:2e4,...o?{searchHint:o}:{},execute:async(i,s)=>n(i.client,s.resourceId)}}function ln(e,t,r,n,o){return{name:e,description:t,params:{resourceId:{type:"string",description:"Resource ID (UUID)"}},required:["resourceId"],group:r,readOnly:!1,isDestructive:!0,...o?{searchHint:o}:{},execute:async(i,s)=>(await n(i.client,s.resourceId),{deleted:!0,resourceId:s.resourceId})}}var eSe={invoice:new Set(["reference","valueDate","dueDate","contactResourceId","lineItems","notes","invoiceNotes","internalNotes","tag","tags","isTaxVatApplicable","isTaxVATApplicable","taxInclusion","terms","currency","customFields","capsuleResourceId","taxProfileResourceId","customerPaymentProfileResourceId"]),bill:new Set(["reference","valueDate","dueDate","contactResourceId","lineItems","invoiceNotes","internalNotes","tag","tags","isTaxVatApplicable","isTaxVATApplicable","taxInclusion","terms","currency","customFields","capsuleResourceId","taxProfileResourceId"]),customer_credit_note:new Set(["reference","valueDate","contactResourceId","lineItems","invoiceNotes","tag","tags","isTaxVatApplicable","isTaxVATApplicable","taxInclusion","currency","customFields","capsuleResourceId","taxProfileResourceId"]),supplier_credit_note:new Set(["reference","valueDate","contactResourceId","lineItems","invoiceNotes","tag","tags","isTaxVatApplicable","isTaxVATApplicable","taxInclusion","currency","customFields","capsuleResourceId","taxProfileResourceId"])};function NJ(e){if(typeof e!="string"||/^\d{4}-\d{2}-\d{2}$/.test(e))return e;let t=/^(\d{4}-\d{2}-\d{2})T/.exec(e);return t?t[1]:e}var tSe=new Set(["name","quantity","unitPrice","unit","accountResourceId","taxProfileResourceId","description","classifierConfig","itemResourceId","discount"]);function rSe(e){return Array.isArray(e)?e.map(t=>{let r={};for(let[n,o]of Object.entries(t))if(o!=null)if(n==="organizationAccountResourceId")r.accountResourceId=o;else if(n==="taxProfile"&&typeof o=="object"&&o!==null){let i=o.resourceId;i&&(r.taxProfileResourceId=i)}else if(n==="discount"&&typeof o=="object"&&o!==null){let i=o.rateValue;i&&Number(i)!==0&&(r.discount=o)}else tSe.has(n)&&(r[n]=o);return r}):e}async function Km(e,t,r,n){let s=(await(t==="invoice"?io:t==="bill"?to:t==="customer_credit_note"?$o:No)(e,r)).data,a=eSe[t],c={};for(let[f,p]of Object.entries(s))a.has(f)&&p!==null&&p!==void 0&&(c[f]=p);c.valueDate&&(c.valueDate=NJ(c.valueDate)),c.dueDate&&(c.dueDate=NJ(c.dueDate)),c.lineItems&&(c.lineItems=rSe(c.lineItems));for(let[f,p]of Object.entries(n))p!==void 0&&(c[f]=p);let u=t==="invoice"?so:t==="bill"?_n:ur,{missingFields:l,ready:d}=on(c,u);if(!d)throw new Error(`Cannot finalize: missing ${l.join(", ")}. Use search_accounts (filter by accountType) and search_contacts to resolve, then pass the missing fields to this tool.`);return c}async function kJ(e,t,r,n){if((await e(t,r)).data.status==="DRAFT")throw new Error(`Cannot pay a DRAFT ${n}. Finalize it first with finalize_${n}.`)}var ul=[{name:"get_organization",description:"Get organization details (name, currency, country, lock date, fiscal year end).",params:{},required:[],group:"organization",readOnly:!0,searchHint:"get organization details currency country fiscal year",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async e=>Pn(e.client)},gt("list_accounts","List chart of accounts. Returns account name, code, type, class, status. Paginated \u2014 response includes totalElements. Use limit/offset to page.","accounts",(e,t,r)=>Ai(e,{limit:r,offset:t}),"list chart of accounts with code type class status"),Rt({name:"search_accounts",description:'Search chart of accounts by name, code, class, type, status. For OR search (name or code), use filter param: {"or":{"name":{"contains":"X"},"code":{"contains":"X"}}}.',group:"accounts",fields:ef,defaults:tf,fetcher:hu,searchHint:"find accounts by name code type class status"}),{name:"create_account",description:"Create a new chart of accounts entry. Auto-checks for duplicates by name \u2014 returns existing account if found. Code must be unique. Account class is inferred from accountType.",params:{name:{type:"string",description:"Account name"},code:{type:"string",description:"Account code (unique)"},accountType:{type:"string",description:`Exact API values. Classic set: "Bank Accounts", "Cash", "Current Asset", "Fixed Asset", "Inventory", "Current Liability", "Non-current Liability", "Shareholders Equity", "Operating Revenue", "Other Revenue", "Operating Expense", "Direct Costs". IFRS 18 set (effective 2027): "Discontinued Expense", "Discontinued Income", "Finance Cost", "Financing Income", "Goodwill", "Income Tax Expense", "Investing Expense", "Investing Income", "Investment". Unambiguous variants are normalized client-side ("income tax" \u2192 "Income Tax Expense", "investments" \u2192 "Investment", "finance costs" \u2192 "Finance Cost"). For "interest expense" / "interest income", pick the explicit IFRS 18 string yourself \u2014 these can land in either Financing or Investing under IFRS 18 depending on the entity's main business activity, so motherboard does NOT auto-classify.`},currencyCode:{type:"string",description:'Currency code (e.g., "SGD")'}},required:["name","code","accountType"],group:"accounts",readOnly:!1,searchHint:"create new chart of accounts entry with type code",execute:async(e,t)=>{let r=t.name,n=await sb(e.client,r);if(n)return{_guard:"duplicate_skipped",message:`Account "${r}" already exists.`,existing:n};let o=mu(t.accountType);return gp(e.client,{code:t.code,name:r,accountType:o,currencyCode:t.currencyCode})}},{name:"update_account",description:"Update an existing chart of accounts entry (name or code).",params:{resourceId:{type:"string",description:"Account resourceId"},name:{type:"string",description:"New account name"},code:{type:"string",description:"New account code"}},required:["resourceId"],group:"accounts",readOnly:!1,searchHint:"update rename chart of accounts entry name code",execute:async(e,t)=>{let r=t.resourceId,n=(await Nz(e.client,r)).data,i=Object.fromEntries(["name","code","classificationType","taxProfileResourceId","currency","description"].filter(s=>n[s]!==void 0&&n[s]!==null).map(s=>[s,n[s]]));return!i.classificationType&&n.accountType&&(i.classificationType=n.accountType),t.name!==void 0&&(i.name=t.name),t.code!==void 0&&(i.code=t.code),kz(e.client,r,i)}},{name:"bulk_upsert_chart_of_accounts",description:`Bulk create/update CoA entries (max 500). SYNC: returns { resourceIds, failedRows: [{rowIndex, columnName, columnValue, errorCode, errorMessage}], failedCount } \u2014 no jobId polling. PARTIAL_SUCCESS: failed rows surface in failedRows[]; others still succeed.
|
|
672
|
+
|
|
673
|
+
resourceId per row \u2192 update; omit \u2192 create. Note: dedup is by NAME (not code) \u2014 duplicate name surfaces ORGANIZATION_CHART_OF_ACCOUNT_DUPLICATED per row. Accepts classic 12 + 9 IFRS 18 accountType values; common variants normalized via normalizeAccountType.
|
|
674
|
+
|
|
675
|
+
Use for CoA imports / IFRS 18 migration / template seeding. For one-off creates with dedup, use create_account.`,params:{accounts:{type:"array",description:"Array of chart-of-accounts entries (max 500). Mix create and update freely.",items:{type:"object",properties:{resourceId:{type:"string",description:"Account resourceId (UUID) \u2014 provide to update, omit to create"},code:{type:"string",description:"Account code (unique per org)"},name:{type:"string",description:"Account name (unique per org \u2014 dedup key)"},accountType:{type:"string",description:'Classic 12 or IFRS 18 set per create_account description (e.g. "Operating Expense", "Finance Cost"). Variants normalized client-side ("income tax" \u2192 "Income Tax Expense"). Required for create.'},currencyCode:{type:"string",description:'Currency code (e.g. "SGD"). Defaults to org functional currency.'},description:{type:"string",description:"Optional description / memo"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Account status"}}}}},required:["accounts"],group:"accounts",readOnly:!1,searchHint:"bulk create or update chart of accounts import COA migration",execute:async(e,t)=>{ar(t.accounts,"accounts",500,"chart-of-accounts entries");let r=t.accounts.map(ub);return(await lb(e.client,r)).data}},gt("list_contacts","List contacts (customers/suppliers). Returns billingName, name, emails, status. Paginated \u2014 response includes totalElements. Use limit/offset to page.","contacts",(e,t,r)=>ts(e,{limit:r,offset:t}),"list customers suppliers contacts with email status"),Rt({name:"search_contacts",description:"Search contacts by name, email, customer/supplier role, status.",group:"contacts",fields:Bp,defaults:Up,fetcher:ro,searchHint:"find customers suppliers by name email role status"}),{name:"get_contact",description:"Get full contact details by resourceId.",params:{resourceId:{type:"string",description:"Contact resourceId (UUID)"}},required:["resourceId"],group:"contacts",readOnly:!0,searchHint:"get contact customer supplier details by id",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>ba(e.client,t.resourceId)},{name:"get_contact_signals",description:`Read-only contact pattern intelligence (cadence, outliers, divergences, severity). USE THIS for stand-alone history lookup before drafting (e.g. "what does this supplier normally look like?"). Use validate_drafts instead when you have a specific draft to score.
|
|
676
|
+
|
|
677
|
+
Returns null when the contact has no qualifying history yet (sampleSize < 5) or the freshness layer is unavailable. Per-pair cache (contactId \xD7 btType) \u2014 duplicate calls for the same pair return the same result.
|
|
678
|
+
|
|
679
|
+
Three response slices (severitySummary, outlierFlags, revealedDivergences) populate ONLY on the validate_drafts path \u2014 empty/null here.`,params:{resourceId:{type:"string",description:"Contact resourceId (UUID)"},btType:{type:"string",description:"Business-transaction type to scope the signal sample to.",enum:["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"]}},required:["resourceId","btType"],group:"contacts",readOnly:!0,searchHint:"contact signals patterns cadence outliers severity history",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=t.resourceId;return $z(r,"resourceId","Call search_contacts to get a valid contact resourceId."),EM(e.client,r,t.btType)}},{name:"create_contact",description:"Create a new contact. Auto-checks for duplicates by name \u2014 returns existing contact if found instead of creating a duplicate.",params:{billingName:{type:"string",description:"Official billing name"},name:{type:"string",description:"Display name (usually same as billingName)"},email:{type:"string",description:"Primary email address"},customer:{type:"boolean",description:"Is a customer (default true)"},supplier:{type:"boolean",description:"Is a supplier (default false)"}},required:["billingName"],group:"contacts",readOnly:!1,searchHint:"create new customer or supplier contact",execute:async(e,t)=>{let r=t.name??t.billingName,n=await hp(e.client,r);return n?{_guard:"duplicate_skipped",message:`Contact "${r}" already exists.`,existing:n}:Yc(e.client,{billingName:t.billingName,name:r,emails:t.email?[t.email]:void 0,customer:t.customer??!0,supplier:t.supplier??!1})}},{name:"update_contact",description:"Update an existing contact. Fetches current data first so you only need to send changed fields.",params:{resourceId:{type:"string",description:"Contact resourceId"},billingName:{type:"string"},name:sR,email:{type:"string"}},required:["resourceId"],group:"contacts",readOnly:!1,searchHint:"update existing contact billing name email details",execute:async(e,t)=>{let{resourceId:r,...n}=t,{data:o}=await ba(e.client,r),i=["billingName","name","email","customer","supplier","taxId","phone","status","currencyCode","customerPaymentTerms"],s=o,a=Object.fromEntries(i.filter(c=>s[c]!==void 0&&s[c]!==null).map(c=>[c,s[c]]));return Object.assign(a,n),Oy(e.client,r,a)}},gt("list_invoices","List invoices. Returns reference, date, status, contact, totalAmount. Paginated \u2014 response includes totalElements. Use limit/offset to page.","invoices",(e,t,r)=>Ab(e,{limit:r,offset:t}),"list sales invoices with pagination and status"),Rt({name:"search_invoices",description:'Search invoices. Supports comma-separated status (e.g., "UNPAID,PARTIALLY_PAID"). Use filter param for advanced queries (nested paths, OR groups).',group:"invoices",fields:xu,defaults:Au,fetcher:Tu,searchHint:"find sales invoices by status date contact amount"}),{name:"get_invoice",description:"Get full invoice details including line items, payments, totals.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"invoices",readOnly:!0,searchHint:"get invoice details line items payments totals",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>io(e.client,t.resourceId)},{name:"create_invoice",description:'Create invoice. lineItem text field = `name` (not "description"). saveAsDraft defaults true \u2014 false only on "finalize".\n\nREQUIRED: contactResourceId (search first), and accountResourceId per lineItem when finalizing. lineItem minimum: `{ name, unitPrice, quantity, accountResourceId }`. Currency: `{ sourceCurrency: "USD", exchangeRate: 1.35 }`. Dates YYYY-MM-DD.\n\nreference MUST be unique per org \u2014 auto-generate with timestamp if user doesn\'t specify (e.g. INV-20260309-1430). Duplicate \u2192 422.',params:{reference:{type:"string",description:"Invoice reference number"},valueDate:{type:"string",description:"Invoice date (YYYY-MM-DD)"},dueDate:{type:"string",description:"Due date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Contact resourceId"},lineItems:di,currency:Qa,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:yr,tag:cl,customFields:un},required:["reference","valueDate","dueDate","contactResourceId","lineItems"],group:"invoices",readOnly:!1,searchHint:"create new sales invoice draft with line items",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return La(e.client,i)}},{name:"update_invoice",description:'Update an existing draft invoice (change reference, dates, line items, notes, custom fields). Use when the user says "update", "change", "fix", or "correct" a draft invoice. Line items CAN be fully replaced \u2014 pass the complete updated lineItems array.',params:{resourceId:{type:"string",description:"Invoice resourceId"},reference:yo,valueDate:go,dueDate:Wm,lineItems:di,notes:yr,customFields:un},required:["resourceId"],group:"invoices",readOnly:!1,searchHint:"update draft invoice reference dates line items",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return wb(e.client,r,s)}},{name:"delete_invoice",description:"Delete a draft invoice. Cannot delete finalized invoices.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"invoices",readOnly:!1,searchHint:"permanently delete a draft invoice",isDestructive:!0,execute:async(e,t)=>Tb(e.client,t.resourceId)},{name:"pay_invoice",description:"Record a payment against an invoice. Invoice must be APPROVED/UNPAID before payment \u2014 draft or voided invoices cannot be paid. If the invoice is still a DRAFT, call finalize_invoice first.",params:{resourceId:{type:"string",description:"Invoice resourceId"},paymentAmount:{type:"number",description:"Amount to pay (in bank currency)"},transactionAmount:{type:"number",description:"Amount in invoice currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId for payment"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Zm,customFields:un},required:["resourceId","paymentAmount","accountResourceId","valueDate"],group:"invoices",readOnly:!1,searchHint:"record payment against an approved invoice",isDestructive:!0,execute:async(e,t)=>{let r=t.resourceId,n=Number(t.paymentAmount);if(!Number.isFinite(n)||n<=0)throw new Error("paymentAmount must be a positive number");let o=Number(t.transactionAmount??n);if(!Number.isFinite(o)||o<=0)throw new Error("transactionAmount must be a positive number");return await kJ(io,e.client,r,"invoice"),bf(e.client,r,{paymentAmount:n,transactionAmount:o,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference||`PMT-${Date.now()}`,paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1,customFields:t.customFields})}},{name:"finalize_invoice",description:"Finalize a draft invoice (set saveAsDraft=false). Can optionally update fields in the same call. IMPORTANT: Every lineItem MUST have accountResourceId. If the draft was created without it, pass lineItems with accountResourceId added (search accounts first, e.g. Operating Revenue for sales).",params:{resourceId:{type:"string",description:"Invoice resourceId"},reference:yo,valueDate:go,dueDate:Wm,lineItems:di,notes:yr},required:["resourceId"],group:"invoices",readOnly:!1,searchHint:"approve finalize draft invoice for sending",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await Km(e.client,"invoice",r,i);if(s.reference){let a=s.reference;((await Tu(e.client,{filter:{reference:{eq:a}},limit:1,offset:0,sort:{sortBy:["valueDate"],order:"DESC"}})).data??[]).filter(l=>l.resourceId!==r).length>0&&(s.reference=`${a}-${Date.now()%1e4}`)}return Sf(e.client,r,s)}},{name:"apply_credits_to_invoice",description:`Apply customer credit note(s) to an invoice. You MUST call this tool to actually apply credits \u2014 do not just describe the steps.
|
|
679
680
|
Steps: 1) search_customer_credit_notes with status UNAPPLIED for the same contact. 2) If CN is still DRAFT, call finalize_customer_credit_note first. 3) Call this tool with creditNoteResourceId and amountApplied for each CN.`,params:{resourceId:{type:"string",description:"Invoice resourceId"},credits:{type:"array",items:{type:"object",properties:{creditNoteResourceId:{type:"string",description:"Customer credit note resourceId"},amountApplied:{type:"number",description:"Amount to apply"}},required:["creditNoteResourceId","amountApplied"]},description:"Credits to apply"}},required:["resourceId","credits"],group:"invoices",readOnly:!1,searchHint:"apply customer credit note to invoice balance",isDestructive:!0,execute:async(e,t)=>Ob(e.client,t.resourceId,t.credits)},{name:"download_invoice_pdf",description:"Download an invoice as PDF. Returns { fileUrl }.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"invoices",readOnly:!0,searchHint:"download invoice as PDF document file",isConcurrencySafe:!0,execute:async(e,t)=>Rb(e.client,t.resourceId)},gt("list_bills","List bills (purchase invoices). Returns reference, date, status, contact, amounts. Paginated \u2014 response includes totalElements. Use limit/offset to page.","bills",(e,t,r)=>Sy(e,{limit:r,offset:t}),"list purchase bills with pagination and status"),Rt({name:"search_bills",description:'Search bills. Supports comma-separated status (e.g., "UNPAID,PARTIALLY_PAID"). Use filter param for advanced queries.',group:"bills",fields:Fp,defaults:Pp,fetcher:ya,searchHint:"find purchase bills by status date supplier amount"}),{name:"get_bill",description:"Get full bill details.",params:{resourceId:Xm},required:["resourceId"],group:"bills",readOnly:!0,searchHint:"get bill details line items payments totals",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>to(e.client,t.resourceId)},{name:"create_bill",description:`Create a new bill. Same rules as create_invoice: name not description, saveAsDraft defaults true, accountResourceId REQUIRED on lineItems for finalized bills (search accounts first, e.g. Operating Expense). When selecting a tax profile, use search_tax_profiles with appliesTo "purchase" \u2014 sales-only profiles cause 422. reference MUST be unique \u2014 generate one with a timestamp if user doesn't specify.`,params:{reference:yo,valueDate:go,dueDate:Wm,contactResourceId:Zve,lineItems:di,currency:Qa,saveAsDraft:AJ,notes:yr,tag:cl,customFields:un},required:["reference","valueDate","dueDate","contactResourceId","lineItems"],group:"bills",readOnly:!1,searchHint:"create new purchase bill draft with line items",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return Da(e.client,i)}},{name:"update_bill",description:'Update an existing draft bill (change reference, dates, line items, notes, custom fields). Use when the user says "update", "change", "fix", or "correct" a draft bill. Line items CAN be fully replaced \u2014 pass the complete updated lineItems array.',params:{resourceId:{type:"string",description:"Bill resourceId"},reference:yo,valueDate:go,dueDate:Wm,lineItems:di,notes:yr,customFields:un},required:["resourceId"],group:"bills",readOnly:!1,searchHint:"update draft bill reference dates line items",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return _y(e.client,r,s)}},{name:"delete_bill",description:"Delete a draft bill.",params:{resourceId:Xm},required:["resourceId"],group:"bills",readOnly:!1,searchHint:"permanently delete a draft bill",isDestructive:!0,execute:async(e,t)=>Ey(e.client,t.resourceId)},{name:"pay_bill",description:"Record a payment against a bill. Bill must be APPROVED before payment \u2014 draft or voided bills cannot be paid.",params:{resourceId:Xm,paymentAmount:Kve,transactionAmount:{type:"number",description:"Amount in bill currency (defaults to paymentAmount for same-currency)"},accountResourceId:tc,valueDate:go,reference:yo,paymentMethod:Zm,customFields:un},required:["resourceId","paymentAmount","accountResourceId","valueDate"],group:"bills",readOnly:!1,searchHint:"record payment against an approved bill",isDestructive:!0,execute:async(e,t)=>{let r=t.resourceId,n=Number(t.paymentAmount);if(!Number.isFinite(n)||n<=0)throw new Error("paymentAmount must be a positive number");let o=Number(t.transactionAmount??n);if(!Number.isFinite(o)||o<=0)throw new Error("transactionAmount must be a positive number");return await kJ(to,e.client,r,"bill"),Sd(e.client,r,{paymentAmount:n,transactionAmount:o,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference||`PMT-${Date.now()}`,paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1,customFields:t.customFields})}},{name:"finalize_bill",description:"Finalize a draft bill (set saveAsDraft=false). Can optionally update fields in the same call. IMPORTANT: Every lineItem MUST have accountResourceId. If the draft was created without it, pass lineItems with accountResourceId added (search accounts first, e.g. Operating Expense for purchases).",params:{resourceId:{type:"string",description:"Bill resourceId"},reference:yo,valueDate:go,dueDate:Wm,lineItems:di,notes:yr},required:["resourceId"],group:"bills",readOnly:!1,searchHint:"approve finalize draft bill for processing",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await Km(e.client,"bill",r,i);return vd(e.client,r,s)}},{name:"apply_credits_to_bill",description:"Apply supplier credit note(s) to a bill. IMPORTANT: The credit note must be FINALIZED first (status UNAPPLIED, not DRAFT). If it is still a draft, call finalize_supplier_credit_note first. Then search_supplier_credit_notes with status UNAPPLIED to find available credits for the contact, and pass creditNoteResourceId and amountApplied for each.",params:{resourceId:{type:"string",description:"Bill resourceId"},credits:{type:"array",items:{type:"object",properties:{creditNoteResourceId:{type:"string",description:"Supplier credit note resourceId"},amountApplied:{type:"number",description:"Amount to apply"}},required:["creditNoteResourceId","amountApplied"]},description:"Credits to apply"}},required:["resourceId","credits"],group:"bills",readOnly:!1,searchHint:"apply supplier credit note to bill balance",isDestructive:!0,execute:async(e,t)=>Iy(e.client,t.resourceId,t.credits)},gt("list_journals","List journal entries. Paginated \u2014 response includes totalElements. Use limit/offset to page.","journals",(e,t,r)=>Ub(e,{limit:r,offset:t}),"list journal entries with pagination and status"),Yn("get_journal","Get full journal entry details by resourceId. Returns journal lines, amounts, status, and metadata.","journals",(e,t)=>ri(e,t),"get journal entry details debit credit lines"),Rt({name:"search_journals",description:"Search journals by status, type, date, reference, tag. Status uses ACTIVE (not FINALIZED). Supports comma-separated status/type.",group:"journals",fields:jp,defaults:Mp,fetcher:_f,searchHint:"find journals by status type date reference tag"}),{name:"create_journal",description:`Create a journal entry. IMPORTANT:
|
|
680
681
|
- Each entry needs accountResourceId, type (DEBIT or CREDIT), and amount.
|
|
681
682
|
- Total debits MUST equal total credits \u2014 the API rejects unbalanced journals.
|
|
@@ -695,64 +696,41 @@ Steps: 1) search_customer_credit_notes with status UNAPPLIED for the same contac
|
|
|
695
696
|
- reference MUST be unique \u2014 generate one with a timestamp if user doesn't specify.`,params:{reference:{type:"string",description:"Credit note reference number"},valueDate:{type:"string",description:"Credit note date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Customer contact resourceId"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:tc},required:["name","quantity","unitPrice"]},description:"Credit note line items"},currency:Qa,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:yr,tag:cl,customFields:un},required:["valueDate","contactResourceId","lineItems"],group:"customer_credit_notes",readOnly:!1,searchHint:"create new customer credit note draft",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return i.reference||(i.reference=`CCN-${Date.now()}`),wf(e.client,i)}},{name:"delete_customer_credit_note",description:"Delete a draft customer credit note.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"}},required:["resourceId"],group:"customer_credit_notes",readOnly:!1,searchHint:"permanently delete draft customer credit note",isDestructive:!0,execute:async(e,t)=>x0(e.client,t.resourceId)},{name:"update_customer_credit_note",description:'Update a draft customer credit note (change amount, line items, contact, date, notes). Use when the user says "update", "change", "fix", or "correct" a credit note.',params:{resourceId:{type:"string",description:"Customer credit note resourceId"},reference:yo,valueDate:go,lineItems:di,notes:yr,tag:cl,customFields:un},required:["resourceId"],group:"customer_credit_notes",readOnly:!1,searchHint:"update customer credit note lines reference",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return C0(e.client,r,s)}},{name:"finalize_customer_credit_note",description:"Finalize a draft customer credit note (set saveAsDraft=false). Status becomes UNAPPLIED.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"},reference:yo,valueDate:go,lineItems:di,notes:yr},required:["resourceId"],group:"customer_credit_notes",readOnly:!1,searchHint:"approve finalize customer credit note",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await Km(e.client,"customer_credit_note",r,i);return Tf(e.client,r,s)}},{name:"create_customer_credit_note_refund",description:"Record a refund payment against a customer credit note.",params:{creditNoteId:{type:"string",description:"Customer credit note resourceId"},paymentAmount:{type:"number",description:"Refund amount"},transactionAmount:{type:"number",description:"Amount in credit note currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Zm},required:["creditNoteId","paymentAmount","accountResourceId","valueDate"],group:"customer_credit_notes",readOnly:!1,searchHint:"refund customer credit note to bank account",isDestructive:!0,execute:async(e,t)=>{let r=Number(t.paymentAmount);if(!Number.isFinite(r)||r<=0)throw new Error("paymentAmount must be a positive number");let n=Number(t.transactionAmount??r);if(!Number.isFinite(n)||n<=0)throw new Error("transactionAmount must be a positive number");return Of(e.client,t.creditNoteId,{paymentAmount:r,transactionAmount:n,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference??"",paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1})}},{name:"list_customer_credit_note_refunds",description:"List refund payments for a customer credit note.",params:{creditNoteId:{type:"string",description:"Customer credit note resourceId"}},required:["creditNoteId"],group:"customer_credit_notes",readOnly:!0,searchHint:"list refunds on a customer credit note",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>A0(e.client,t.creditNoteId)},gt("list_supplier_credit_notes","List supplier credit notes (AP adjustments/refunds). Paginated \u2014 response includes totalElements. Use limit/offset to page.","supplier_credit_notes",(e,t,r)=>O0(e,{limit:r,offset:t}),"list supplier credit notes with status pagination"),Rt({name:"search_supplier_credit_notes",description:"Search supplier credit notes by reference, status, contact, tag. Status: DRAFT, UNAPPLIED, PARTIALLY_APPLIED, APPLIED, VOID.",group:"supplier_credit_notes",fields:Ds,defaults:Lp,fetcher:Rf,searchHint:"find supplier credit notes by status contact reference"}),{name:"get_supplier_credit_note",description:"Get full supplier credit note details including line items.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"}},required:["resourceId"],group:"supplier_credit_notes",readOnly:!0,searchHint:"get supplier credit note details line items",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>No(e.client,t.resourceId)},{name:"create_supplier_credit_note",description:`Create a supplier credit note. Saves as draft by default.
|
|
696
697
|
- Status when finalized is UNAPPLIED (not APPROVED).
|
|
697
698
|
- Line items use "name" for item description.
|
|
698
|
-
- contactResourceId required \u2014 search contacts first.`,params:{reference:{type:"string",description:"Credit note reference number"},valueDate:{type:"string",description:"Credit note date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Supplier contact resourceId"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:tc},required:["name","quantity","unitPrice"]},description:"Credit note line items"},currency:Qa,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:yr,tag:cl,customFields:un},required:["valueDate","contactResourceId","lineItems"],group:"supplier_credit_notes",readOnly:!1,searchHint:"create new supplier credit note draft",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return i.reference||(i.reference=`SCN-${Date.now()}`),$f(e.client,i)}},{name:"delete_supplier_credit_note",description:"Delete a draft supplier credit note.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"}},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"permanently delete draft supplier credit note",isDestructive:!0,execute:async(e,t)=>$0(e.client,t.resourceId)},{name:"update_supplier_credit_note",description:'Update a draft supplier credit note (change amount, line items, contact, date, notes). Use when the user says "update", "change", "fix", or "correct" a credit note.',params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:di,notes:yr,tag:cl,customFields:un},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"update supplier credit note lines reference",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return R0(e.client,r,s)}},{name:"finalize_supplier_credit_note",description:"Finalize a draft supplier credit note (set saveAsDraft=false). Status becomes UNAPPLIED.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:di,notes:yr},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"approve finalize supplier credit note",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await Km(e.client,"supplier_credit_note",r,i);return Nf(e.client,r,s)}},{name:"create_supplier_credit_note_refund",description:"Record a refund payment against a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"},paymentAmount:{type:"number",description:"Refund amount"},transactionAmount:{type:"number",description:"Amount in credit note currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Zm},required:["creditNoteId","paymentAmount","accountResourceId","valueDate"],group:"supplier_credit_notes",readOnly:!1,searchHint:"refund supplier credit note from bank account",isDestructive:!0,execute:async(e,t)=>{let r=Number(t.paymentAmount);if(!Number.isFinite(r)||r<=0)throw new Error("paymentAmount must be a positive number");let n=Number(t.transactionAmount??r);if(!Number.isFinite(n)||n<=0)throw new Error("transactionAmount must be a positive number");return kf(e.client,t.creditNoteId,{paymentAmount:r,transactionAmount:n,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference??"",paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1})}},{name:"list_supplier_credit_note_refunds",description:"List refund payments for a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"}},required:["creditNoteId"],group:"supplier_credit_notes",readOnly:!0,searchHint:"list refunds on a supplier credit note",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>N0(e.client,t.creditNoteId)},{name:"list_currencies",description:"List currencies enabled for the organization. Returns currency code, name, symbol, and whether it is the base currency.",params:{},required:[],group:"currencies",readOnly:!0,searchHint:"list active currencies in organization",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>Ff(e.client)},{name:"add_currency",description:"Enable one or more currencies for the organization.",params:{currencies:{type:"array",items:{type:"string"},description:'Currency codes to add (e.g., ["USD", "EUR"])'}},required:["currencies"],group:"currencies",readOnly:!1,searchHint:"add new currency to organization",execute:async(e,t)=>{let r=t.currencies,n=await Ff(e.client),o=new Set(n.data.map(c=>c.currencyCode.toUpperCase())),i=r.filter(c=>o.has(c.toUpperCase())),s=r.filter(c=>!o.has(c.toUpperCase()));if(s.length===0)return{_guard:"duplicate_skipped",message:`All currencies already enabled: ${r.join(", ")}.`,existing:i};let a=await F0(e.client,s);return i.length>0?{...a,_note:`Skipped already-enabled: ${i.join(", ")}`}:a}},{name:"list_currency_rates",description:"List exchange rates for a specific currency. IMPORTANT: You MUST call list_currencies first to discover which currencies the org has enabled \u2014 never guess or assume currency codes.",params:{currencyCode:{type:"string",description:'Currency code (e.g., "USD")'},...cR},required:["currencyCode"],group:"currencies",readOnly:!0,searchHint:"list exchange rates for a currency pair",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>{let{limit:r,offset:n}=FJ(t),o=t.currencyCode;return kp((i,s)=>P0(e.client,o,{limit:s,offset:i}),r,n,100)}},{name:"add_currency_rate",description:'Add or set an exchange rate for a currency. ALWAYS use this tool even when the user says "update rate" \u2014 it handles both new and existing rates. Rate is relative to the base currency. Call list_currencies first to get valid currency codes.',params:{currencyCode:{type:"string",description:"Currency code"},rate:{type:"number",description:"Exchange rate (e.g., 1.35 for 1 USD = 1.35 SGD)"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"add new exchange rate for currency pair",execute:async(e,t)=>L0(e.client,t.currencyCode,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"update_currency_rate",description:'Update an EXISTING exchange rate record by its resourceId. Requires the rate resourceId from list_currency_rates. WARNING: If the user says "update the rate" or "set the rate", they almost always mean add_currency_rate (which creates/overwrites for a date). Only use this tool when explicitly modifying an existing rate record by ID.',params:{currencyCode:{type:"string",description:"Currency code"},resourceId:{type:"string",description:"Rate resourceId"},rate:{type:"number",description:"New exchange rate"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","resourceId","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"update existing exchange rate value",execute:async(e,t)=>j0(e.client,t.currencyCode,t.resourceId,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"start_currency_rates_import_job",description:"Start an async job to import currency rates from a CSV file URL.",params:{currencyCode:{type:"string",description:"Currency code"},csvUrl:{type:"string",description:"URL of the CSV file to import"}},required:["currencyCode","csvUrl"],group:"currencies",readOnly:!1,searchHint:"import exchange rates from external source",execute:async(e,t)=>M0(e.client,t.currencyCode,t.csvUrl)},{name:"get_currency_rates_import_job_status",description:"Check the status of a currency rates import job.",params:{jobId:{type:"string",description:"Job ID from start_currency_rates_import_job"}},required:["jobId"],group:"currencies",readOnly:!0,searchHint:"check status of currency rates import job",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>B0(e.client,t.jobId)},{name:"bulk_upsert_currency_rates",description:"Create exchange rates in bulk (max 500 per call). Auto-enables currencies not yet enabled in the org \u2014 no need to call add_currency first. Requires rateDirection per rate. Response surfaces per-row failures: `failedRows[]` (each with rowIndex, columnName, columnValue, errorCode, errorMessage) + `failedCount` alongside `resourceIds[]` for successful inserts. Omitting `rateApplicableTo` defaults it to `rateApplicableFrom - 0.999ms` (no temporal gap).",params:{rates:{type:"array",description:"Array of exchange rates to create",items:{type:"object",properties:{sourceCurrencyCode:{type:"string",description:"Source currency code (ISO 4217, e.g. USD, EUR)"},rate:{type:"number",description:"Exchange rate value (must be > 0)"},rateDirection:{type:"string",description:"Rate direction",enum:["FUNCTIONAL_TO_SOURCE","SOURCE_TO_FUNCTIONAL"]},rateApplicableFrom:{type:"string",description:"Rate start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"Rate end date (YYYY-MM-DD, optional)"}},required:["sourceCurrencyCode","rate","rateDirection","rateApplicableFrom"]}}},required:["rates"],group:"currencies",readOnly:!1,searchHint:"bulk create or update multiple currency rates",execute:async(e,t)=>(await U0(e.client,t.rates)).data},gt("list_tax_profiles","List tax profiles (GST, VAT, etc.). Returns name, rate, tax type.","tax_profiles",(e,t,r)=>du(e,{limit:r,offset:t}),"list tax profiles GST VAT rates"),gt("list_tax_types","List available tax types. Use the tax type code when creating tax profiles.","tax_profiles",(e,t,r)=>ZD(e,{limit:r,offset:t}),"list available tax types for profile creation"),{name:"create_tax_profile",description:"Create a new tax profile. List tax types first to get the taxTypeCode. Automatically checks for duplicates by name \u2014 returns existing profile if found.",params:{name:{type:"string",description:'Tax profile name (e.g., "GST 9%")'},taxRate:{type:"number",description:"Tax rate as percentage (e.g., 9 for 9%)"},taxTypeCode:{type:"string",description:"Tax type code (from list_tax_types)"}},required:["name","taxRate","taxTypeCode"],group:"tax_profiles",readOnly:!1,searchHint:"create new tax profile GST VAT rate",execute:async(e,t)=>{let r=t.name,n=await ab(e.client,r);return n?{_guard:"duplicate_skipped",message:`Tax profile "${r}" already exists.`,existing:n}:KD(e.client,{name:r,taxRate:t.taxRate,taxTypeCode:t.taxTypeCode})}},gt("list_cash_in","List cash-in entries (direct cash receipts). Paginated.","cash_entries",(e,t,r)=>Hb(e,{limit:r,offset:t}),"list cash in receipt entries with pagination"),{name:"create_cash_in",description:`Record money received INTO a bank account from an EXTERNAL source (customer payment, refund received, deposit from outside).
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
EXCEPTION \u2014 fx-reval: Jaz auto-handles all period-end IAS 21.23 FX translation. The fx-reval recipe is VERIFICATION ONLY (independent cross-check via clio calc fx-reval against what Jaz auto-posted). Do NOT invoke execute_recipe(name: 'fx-reval', ...) \u2014 would double-post. See jaz-recipes/references/fx-revaluation.md for the verification flow.
|
|
735
|
-
|
|
736
|
-
YOUR NEXT STEP: call execute_recipe with the same parameters plus startDate to post the entries. The execute_recipe tool IS available to you \u2014 ALWAYS use it (not create_journal/create_invoice/create_cash_out) when an API key is configured.
|
|
737
|
-
|
|
738
|
-
PRACTICE-AWARE WORKFLOW: when invoked inside a practitioner engagement (jaz-practice skill loaded), read the engagement-type playbook first \u2014 practice/references/{monthly-close,quarterly-gst,annual-statutory,onboarding}.md specifies which CLIENT.md fields drive the recipe parameters (e.g. CLIENT.recurring_accruals[i].gl_account for accrued-expense, CLIENT.coa_mapping['Prepaid Insurance'] for prepaid-expense), what the validate-execute-finalize sequence is, and which error classes from execute_recipe halt vs auto-recover.
|
|
739
|
-
|
|
740
|
-
NAME ALIASES: file-name aliases used in jaz-recipes references map to canonical engine names: prepaid-amortization \u2192 prepaid-expense, bank-loan \u2192 loan, ifrs16-lease \u2192 lease, bad-debt-provision \u2192 ecl, accrued-expenses \u2192 accrued-expense, fx-revaluation \u2192 fx-reval, declining-balance \u2192 depreciation. Use the canonical engine name when calling this tool.`,params:{recipe:{type:"string",enum:[...Ma],description:"Recipe type"},amount:{type:"number",description:"Amount (for amortization, accrued-expense, dividend, ecl, provision, fx-reval)"},principal:{type:"number",description:"Principal (for loan, fixed-deposit)"},startDate:{type:"string",description:"Start date YYYY-MM-DD (REQUIRED for blueprint generation \u2014 default to today if user does not specify)"},currency:{type:"string",description:"Currency code (e.g. SGD, USD)"},periods:{type:"number",description:"Number of periods (for amortization, accrued-expense, leave-accrual)"},frequency:{type:"string",enum:["monthly","quarterly","annual"],description:"Frequency (for depreciation, amortization, accrued-expense)"},annualRate:{type:"number",description:"Annual interest/discount rate %"},termMonths:{type:"number",description:"Term in months"},monthlyPayment:{type:"number",description:"Monthly lease payment (for lease)"},usefulLifeMonths:{type:"number",description:"Asset useful life in months (hire purchase)"},cost:{type:"number",description:"Asset cost"},salvageValue:{type:"number",description:"Salvage value"},usefulLifeYears:{type:"number",description:"Useful life in years"},method:{type:"string",enum:["sl","ddb","150db"],description:"Depreciation method"},acquisitionDate:{type:"string",description:"Acquisition date YYYY-MM-DD"},disposalDate:{type:"string",description:"Disposal date YYYY-MM-DD"},proceeds:{type:"number",description:"Disposal proceeds"},bookRate:{type:"number",description:"Original booking exchange rate"},closingRate:{type:"number",description:"Period-end closing exchange rate"},baseCurrency:{type:"string",description:"Base (functional) currency"},buckets:{type:"array",items:{type:"object",properties:{name:{type:"string"},balance:{type:"number"},rate:{type:"number"}},required:["name","balance","rate"]},description:"ECL aging buckets"},existingProvision:{type:"number",description:"Existing ECL provision balance"},compounding:{type:"string",enum:["none","monthly","quarterly","annually"],description:"Compounding method"},employees:{type:"number",description:"Number of employees"},daysPerYear:{type:"number",description:"Leave days per employee per year"},dailyRate:{type:"number",description:"Average daily rate"},declarationDate:{type:"string",description:"Board resolution date YYYY-MM-DD"},paymentDate:{type:"string",description:"Settlement date YYYY-MM-DD"},withholdingRate:{type:"number",description:"Withholding tax rate %"}},required:["recipe"],group:"recipes",readOnly:!0,searchHint:"plan multi-step transaction recipe offline. Covers depreciation (straight-line, DDB, 150DB), amortization, prepaid amortization, deferred revenue, IFRS 16 leases, hire purchase, loan schedules, fixed deposits, FX revaluation, ECL (expected credit loss), IAS 37 provisions, asset disposal, accrued expenses, leave accrual, dividend.",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>{let r=t.recipe,n=xr(r,t);return{...ku(r,n),_nextStep:"Call execute_recipe with the same parameters plus startDate to create all transactions. The execute_recipe tool IS available \u2014 use it now."}}},{name:"execute_recipe",description:`Execute a transaction recipe end-to-end \u2014 run calculator, create capsule, post all entries in one call.
|
|
741
|
-
PREFERRED over manual transaction creation \u2014 replaces ~20 manual tool calls. After plan_recipe, ALWAYS use this tool (not create_journal/create_invoice/create_cash_out).
|
|
742
|
-
Supported recipes: ${Ma.join(", ")}
|
|
743
|
-
Requires startDate (to generate blueprint with dated steps).
|
|
744
|
-
Auto-resolves accounts from chart of accounts. Provide bankAccountName for recipes with cash-in/cash-out steps, contactName for recipes with invoice/bill steps.`,params:{recipe:{type:"string",enum:[...Ma],description:"Recipe type"},amount:{type:"number"},principal:{type:"number"},startDate:{type:"string",description:"Start date YYYY-MM-DD (REQUIRED for execution)"},currency:{type:"string"},periods:{type:"number"},frequency:{type:"string",enum:["monthly","quarterly","annual"]},annualRate:{type:"number"},termMonths:{type:"number"},monthlyPayment:{type:"number"},usefulLifeMonths:{type:"number"},cost:{type:"number"},salvageValue:{type:"number"},usefulLifeYears:{type:"number"},method:{type:"string",enum:["sl","ddb","150db"]},acquisitionDate:{type:"string"},disposalDate:{type:"string"},proceeds:{type:"number"},bookRate:{type:"number"},closingRate:{type:"number"},baseCurrency:{type:"string"},buckets:{type:"array",items:{type:"object",properties:{name:{type:"string"},balance:{type:"number"},rate:{type:"number"}},required:["name","balance","rate"]}},existingProvision:{type:"number"},compounding:{type:"string",enum:["none","monthly","quarterly","annually"]},employees:{type:"number"},daysPerYear:{type:"number"},dailyRate:{type:"number"},declarationDate:{type:"string"},paymentDate:{type:"string"},withholdingRate:{type:"number"},bankAccountName:{type:"string",description:"Bank/cash account name (for cash-in/cash-out steps) \u2014 auto-resolved by fuzzy match"},contactName:{type:"string",description:"Contact name (for invoice/bill steps) \u2014 auto-resolved by fuzzy match"},existingTxnId:{type:"string",description:"Attach to existing transaction \u2014 skip initial step"},referencePrefix:{type:"string",description:"Reference prefix (generates prefix-1, prefix-2, ...)"},finalize:{type:"boolean",description:"Approve transactions immediately (default: drafts)"}},required:["recipe","startDate"],group:"recipes",readOnly:!1,searchHint:"execute transaction recipe capsule blueprint with dated steps. Posts depreciation, amortization, prepaid, deferred revenue, IFRS 16 lease, hire purchase, loan, fixed deposit, FX revaluation, ECL, IAS 37 provision, asset disposal, accrued expense, leave accrual, dividend entries.",maxResultSizeChars:1e5,execute:async(e,t)=>{let r=t.recipe,n=xr(r,t),o=Lf(n);if(!o)throw new Error("No blueprint generated. Ensure startDate is provided.");let i=ku(r,n),s=await EJ(e.client,i.plan.requiredAccounts);if(s.failures.length>0){let u=s.failures.map(l=>`${l.name}${l.candidates.length>0?` (closest: ${l.candidates.join(", ")})`:""}`).join("; ");throw new Error(`Cannot auto-resolve ${s.failures.length} account(s): ${u}. Create them in Jaz first.`)}let a;t.contactName&&(a=(await IJ(e.client,t.contactName)).resourceId);let c;return t.bankAccountName&&(c=(await CJ(e.client,t.bankAccountName)).resourceId),W0(e.client,{blueprint:o,calcType:r,accountMap:s.mapping,bankAccountId:c,contactId:a,existingTxnId:t.existingTxnId,referencePrefix:t.referencePrefix,finalize:t.finalize})}},{name:"create_scheduled_journal",description:`Create a scheduled (recurring) journal. CRITICAL:
|
|
745
|
-
- Use schedulerEntries (NOT journalEntries) \u2014 each needs accountResourceId, amount, type (DEBIT/CREDIT), name.
|
|
746
|
-
- Use repeat (NOT frequency/interval): WEEKLY, MONTHLY, QUARTERLY, YEARLY.
|
|
747
|
-
- Total debits MUST equal total credits.
|
|
748
|
-
- Flat structure \u2014 reference, valueDate, saveAsDraft at top level (not nested).
|
|
749
|
-
Dynamic strings for reference/name/notes: {{Day}}, {{Date}}, {{Date+X}}, {{DateRange:X}}, {{Month}}, {{Month+X}}, {{MonthRange:X}}, {{Year}}, {{Year+X}} \u2014 replaced with values relative to the transaction date.`,params:{reference:{type:"string",description:"Journal reference"},valueDate:{type:"string",description:"Template date (YYYY-MM-DD)"},startDate:{type:"string",description:"First occurrence (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence (YYYY-MM-DD, optional)"},repeat:{type:"string",enum:["WEEKLY","MONTHLY","QUARTERLY","YEARLY"],description:"Recurrence interval"},schedulerEntries:{type:"array",items:{type:"object",properties:{accountResourceId:tc,amount:{type:"number"},type:{type:"string",enum:["DEBIT","CREDIT"]},name:{type:"string",description:"Line description"}},required:["accountResourceId","amount","type"]}},notes:{type:"string",description:"Journal notes"}},required:["startDate","repeat","valueDate","schedulerEntries"],group:"schedulers",readOnly:!1,searchHint:"create recurring scheduled journal entry",execute:async(e,t)=>If(e.client,{status:"ACTIVE",startDate:t.startDate,endDate:t.endDate,repeat:t.repeat,valueDate:t.valueDate,schedulerEntries:t.schedulerEntries,reference:t.reference,internalNotes:t.notes})},{name:"create_scheduled_invoice",description:`Create a scheduled (recurring) invoice. Use for fixed-amount recurring invoices where you want full control over currency, tax, and line items each period.
|
|
750
|
-
DIFFERENT from subscriptions: no proration, but currency/tax/items can differ per occurrence.
|
|
751
|
-
CRITICAL:
|
|
752
|
-
- saveAsDraft MUST be false (API rejects INVALID_SALE_STATUS otherwise).
|
|
753
|
-
- Use repeat (NOT frequency/interval): WEEKLY, MONTHLY, QUARTERLY, YEARLY.
|
|
754
|
-
- Each lineItem needs name, unitPrice, quantity, accountResourceId.
|
|
755
|
-
Dynamic strings for reference/name/notes: {{Day}}, {{Date}}, {{Date+X}}, {{DateRange:X}}, {{Month}}, {{Month+X}}, {{MonthRange:X}}, {{Year}}, {{Year+X}} \u2014 replaced with values relative to the transaction date.`,params:{startDate:{type:"string",description:"First occurrence (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence (YYYY-MM-DD, optional)"},repeat:{type:"string",enum:["WEEKLY","MONTHLY","QUARTERLY","YEARLY"],description:"Recurrence interval"},contactResourceId:{type:"string",description:"Customer contact resourceId"},reference:{type:"string",description:"Invoice reference"},valueDate:{type:"string",description:"Template issue date (YYYY-MM-DD)"},dueDate:{type:"string",description:"Template due date (YYYY-MM-DD)"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string"},unitPrice:{type:"number"},quantity:{type:"number"},accountResourceId:tc,taxProfileResourceId:{type:"string"}},required:["name","unitPrice","quantity","accountResourceId"]}},tag:{type:"string",description:"Tag name"}},required:["startDate","repeat","contactResourceId","reference","valueDate","dueDate","lineItems"],group:"schedulers",readOnly:!1,searchHint:"create recurring scheduled invoice subscription",execute:async(e,t)=>vf(e.client,{status:"ACTIVE",startDate:t.startDate,endDate:t.endDate,repeat:t.repeat,invoice:{reference:t.reference,valueDate:t.valueDate,dueDate:t.dueDate,contactResourceId:t.contactResourceId,lineItems:t.lineItems,tags:t.tag?[t.tag]:void 0,saveAsDraft:!1}})},{name:"create_scheduled_bill",description:`Create a scheduled (recurring) bill. CRITICAL:
|
|
699
|
+
- contactResourceId required \u2014 search contacts first.`,params:{reference:{type:"string",description:"Credit note reference number"},valueDate:{type:"string",description:"Credit note date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Supplier contact resourceId"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:tc},required:["name","quantity","unitPrice"]},description:"Credit note line items"},currency:Qa,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:yr,tag:cl,customFields:un},required:["valueDate","contactResourceId","lineItems"],group:"supplier_credit_notes",readOnly:!1,searchHint:"create new supplier credit note draft",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return i.reference||(i.reference=`SCN-${Date.now()}`),$f(e.client,i)}},{name:"delete_supplier_credit_note",description:"Delete a draft supplier credit note.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"}},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"permanently delete draft supplier credit note",isDestructive:!0,execute:async(e,t)=>$0(e.client,t.resourceId)},{name:"update_supplier_credit_note",description:'Update a draft supplier credit note (change amount, line items, contact, date, notes). Use when the user says "update", "change", "fix", or "correct" a credit note.',params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:di,notes:yr,tag:cl,customFields:un},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"update supplier credit note lines reference",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return R0(e.client,r,s)}},{name:"finalize_supplier_credit_note",description:"Finalize a draft supplier credit note (set saveAsDraft=false). Status becomes UNAPPLIED.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:di,notes:yr},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"approve finalize supplier credit note",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await Km(e.client,"supplier_credit_note",r,i);return Nf(e.client,r,s)}},{name:"create_supplier_credit_note_refund",description:"Record a refund payment against a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"},paymentAmount:{type:"number",description:"Refund amount"},transactionAmount:{type:"number",description:"Amount in credit note currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Zm},required:["creditNoteId","paymentAmount","accountResourceId","valueDate"],group:"supplier_credit_notes",readOnly:!1,searchHint:"refund supplier credit note from bank account",isDestructive:!0,execute:async(e,t)=>{let r=Number(t.paymentAmount);if(!Number.isFinite(r)||r<=0)throw new Error("paymentAmount must be a positive number");let n=Number(t.transactionAmount??r);if(!Number.isFinite(n)||n<=0)throw new Error("transactionAmount must be a positive number");return kf(e.client,t.creditNoteId,{paymentAmount:r,transactionAmount:n,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference??"",paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1})}},{name:"list_supplier_credit_note_refunds",description:"List refund payments for a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"}},required:["creditNoteId"],group:"supplier_credit_notes",readOnly:!0,searchHint:"list refunds on a supplier credit note",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>N0(e.client,t.creditNoteId)},{name:"list_currencies",description:"List currencies enabled for the organization. Returns currency code, name, symbol, and whether it is the base currency.",params:{},required:[],group:"currencies",readOnly:!0,searchHint:"list active currencies in organization",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>Ff(e.client)},{name:"add_currency",description:"Enable one or more currencies for the organization.",params:{currencies:{type:"array",items:{type:"string"},description:'Currency codes to add (e.g., ["USD", "EUR"])'}},required:["currencies"],group:"currencies",readOnly:!1,searchHint:"add new currency to organization",execute:async(e,t)=>{let r=t.currencies,n=await Ff(e.client),o=new Set(n.data.map(c=>c.currencyCode.toUpperCase())),i=r.filter(c=>o.has(c.toUpperCase())),s=r.filter(c=>!o.has(c.toUpperCase()));if(s.length===0)return{_guard:"duplicate_skipped",message:`All currencies already enabled: ${r.join(", ")}.`,existing:i};let a=await F0(e.client,s);return i.length>0?{...a,_note:`Skipped already-enabled: ${i.join(", ")}`}:a}},{name:"list_currency_rates",description:"List exchange rates for a specific currency. IMPORTANT: You MUST call list_currencies first to discover which currencies the org has enabled \u2014 never guess or assume currency codes.",params:{currencyCode:{type:"string",description:'Currency code (e.g., "USD")'},...cR},required:["currencyCode"],group:"currencies",readOnly:!0,searchHint:"list exchange rates for a currency pair",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>{let{limit:r,offset:n}=FJ(t),o=t.currencyCode;return kp((i,s)=>P0(e.client,o,{limit:s,offset:i}),r,n,100)}},{name:"add_currency_rate",description:'Add or set an exchange rate for a currency. ALWAYS use this tool even when the user says "update rate" \u2014 it handles both new and existing rates. Rate is relative to the base currency. Call list_currencies first to get valid currency codes.',params:{currencyCode:{type:"string",description:"Currency code"},rate:{type:"number",description:"Exchange rate (e.g., 1.35 for 1 USD = 1.35 SGD)"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"add new exchange rate for currency pair",execute:async(e,t)=>L0(e.client,t.currencyCode,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"update_currency_rate",description:'Update an EXISTING exchange rate record by its resourceId. Requires the rate resourceId from list_currency_rates. WARNING: If the user says "update the rate" or "set the rate", they almost always mean add_currency_rate (which creates/overwrites for a date). Only use this tool when explicitly modifying an existing rate record by ID.',params:{currencyCode:{type:"string",description:"Currency code"},resourceId:{type:"string",description:"Rate resourceId"},rate:{type:"number",description:"New exchange rate"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","resourceId","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"update existing exchange rate value",execute:async(e,t)=>j0(e.client,t.currencyCode,t.resourceId,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"start_currency_rates_import_job",description:"Start an async job to import currency rates from a CSV file URL.",params:{currencyCode:{type:"string",description:"Currency code"},csvUrl:{type:"string",description:"URL of the CSV file to import"}},required:["currencyCode","csvUrl"],group:"currencies",readOnly:!1,searchHint:"import exchange rates from external source",execute:async(e,t)=>M0(e.client,t.currencyCode,t.csvUrl)},{name:"get_currency_rates_import_job_status",description:"Check the status of a currency rates import job.",params:{jobId:{type:"string",description:"Job ID from start_currency_rates_import_job"}},required:["jobId"],group:"currencies",readOnly:!0,searchHint:"check status of currency rates import job",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>B0(e.client,t.jobId)},{name:"bulk_upsert_currency_rates",description:"Create exchange rates in bulk (max 500 per call). Auto-enables currencies not yet enabled in the org \u2014 no need to call add_currency first. Requires rateDirection per rate. Response surfaces per-row failures: `failedRows[]` (each with rowIndex, columnName, columnValue, errorCode, errorMessage) + `failedCount` alongside `resourceIds[]` for successful inserts. Omitting `rateApplicableTo` defaults it to `rateApplicableFrom - 0.999ms` (no temporal gap).",params:{rates:{type:"array",description:"Array of exchange rates to create",items:{type:"object",properties:{sourceCurrencyCode:{type:"string",description:"Source currency code (ISO 4217, e.g. USD, EUR)"},rate:{type:"number",description:"Exchange rate value (must be > 0)"},rateDirection:{type:"string",description:"Rate direction",enum:["FUNCTIONAL_TO_SOURCE","SOURCE_TO_FUNCTIONAL"]},rateApplicableFrom:{type:"string",description:"Rate start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"Rate end date (YYYY-MM-DD, optional)"}},required:["sourceCurrencyCode","rate","rateDirection","rateApplicableFrom"]}}},required:["rates"],group:"currencies",readOnly:!1,searchHint:"bulk create or update multiple currency rates",execute:async(e,t)=>(await U0(e.client,t.rates)).data},gt("list_tax_profiles","List tax profiles (GST, VAT, etc.). Returns name, rate, tax type.","tax_profiles",(e,t,r)=>du(e,{limit:r,offset:t}),"list tax profiles GST VAT rates"),gt("list_tax_types","List available tax types. Use the tax type code when creating tax profiles.","tax_profiles",(e,t,r)=>ZD(e,{limit:r,offset:t}),"list available tax types for profile creation"),{name:"create_tax_profile",description:"Create a new tax profile. List tax types first to get the taxTypeCode. Automatically checks for duplicates by name \u2014 returns existing profile if found.",params:{name:{type:"string",description:'Tax profile name (e.g., "GST 9%")'},taxRate:{type:"number",description:"Tax rate as percentage (e.g., 9 for 9%)"},taxTypeCode:{type:"string",description:"Tax type code (from list_tax_types)"}},required:["name","taxRate","taxTypeCode"],group:"tax_profiles",readOnly:!1,searchHint:"create new tax profile GST VAT rate",execute:async(e,t)=>{let r=t.name,n=await ab(e.client,r);return n?{_guard:"duplicate_skipped",message:`Tax profile "${r}" already exists.`,existing:n}:KD(e.client,{name:r,taxRate:t.taxRate,taxTypeCode:t.taxTypeCode})}},gt("list_cash_in","List cash-in entries (direct cash receipts). Paginated.","cash_entries",(e,t,r)=>Hb(e,{limit:r,offset:t}),"list cash in receipt entries with pagination"),{name:"create_cash_in",description:`Record money received INTO a bank account from an EXTERNAL source (customer payment, refund received, deposit). For inter-account moves use create_cash_transfer.
|
|
700
|
+
|
|
701
|
+
accountResourceId MUST be a Bank/Cash account (from list_bank_accounts) \u2014 any other type fails. Cannot appear in lines (API enforces separation).
|
|
702
|
+
|
|
703
|
+
lines = offsetting entries: { accountResourceId, type (DEBIT/CREDIT), amount }. Offset accounts must be regular P&L or balance-sheet accounts (revenue, expense, asset, liability) \u2014 NOT bank/cash and NOT controlled accounts (AR/AP).`,params:{reference:{type:"string",description:"Reference number"},valueDate:{type:"string",description:"Date (YYYY-MM-DD)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},lines:ec,notes:yr,tags:{type:"array",items:{type:"string"},description:"Tags (string array)"},currency:Qa,saveAsDraft:{type:"boolean",description:"Save as draft (default false)"}},required:["valueDate","accountResourceId","lines"],group:"cash_entries",readOnly:!1,searchHint:"create new cash in receipt entry",execute:async(e,t)=>{let{notes:r,...n}=t,o={...n,...r!==void 0&&{internalNotes:r}};return o.reference||(o.reference=`CI-${Date.now()}`),Ru(e.client,o)}},gt("list_cash_out","List cash-out entries (direct cash disbursements). Paginated.","cash_entries",(e,t,r)=>Kb(e,{limit:r,offset:t}),"list cash out payment entries with pagination"),{name:"create_cash_out",description:`Record money paid OUT FROM a bank account to an EXTERNAL party (expense, supplier payment, reimbursement, withdrawal). For inter-account moves use create_cash_transfer.
|
|
704
|
+
|
|
705
|
+
accountResourceId MUST be a Bank/Cash account (from list_bank_accounts). Cannot appear in lines (API enforces separation; error: "CashOut journal account cannot be in CashIn Entries").
|
|
706
|
+
|
|
707
|
+
lines = offsetting entries: { accountResourceId, type: 'DEBIT' (typical for the expense leg), amount > 0 }. Offset accounts must be regular P&L or balance-sheet accounts \u2014 NOT bank/cash and NOT controlled accounts (AR/AP). Example: { accountResourceId: "<expense-acct>", type: "DEBIT", amount: 100 }.`,params:{reference:{type:"string",description:"Reference number"},valueDate:{type:"string",description:"Date (YYYY-MM-DD)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},lines:ec,notes:yr,tags:{type:"array",items:{type:"string"},description:"Tags (string array)"},currency:Qa,saveAsDraft:{type:"boolean",description:"Save as draft (default false)"}},required:["valueDate","accountResourceId","lines"],group:"cash_entries",readOnly:!1,searchHint:"create new cash out payment entry",execute:async(e,t)=>{let{notes:r,...n}=t,o={...n,...r!==void 0&&{internalNotes:r}};return o.reference||(o.reference=`CO-${Date.now()}`),$u(e.client,o)}},{name:"get_cash_in",description:"Get a cash-in entry by resourceId.",params:{resourceId:{type:"string",description:"Cash-in resourceId"}},required:["resourceId"],group:"cash_entries",readOnly:!0,searchHint:"get cash in receipt entry details",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Wb(e.client,t.resourceId)},{name:"update_cash_in",description:'Update an existing cash-in entry (change amount, date, reference, notes, tags, or entry lines). Use when the user says "update", "change", "fix", or "adjust" a cash-in that was just created or found. Do NOT create a new entry \u2014 use this tool instead. NOTE: cash entries created without saveAsDraft:true are ACTIVE (finalized) and cannot be updated \u2014 they must be deleted and recreated.',params:{resourceId:{type:"string",description:"Cash-in resourceId (parentEntityResourceId from create response)"},accountResourceId:{type:"string",description:"Bank account resourceId (required for update)"},reference:yo,valueDate:go,lines:ec,notes:yr,tags:{type:"array",items:{type:"string"},description:"Tags (string array)"}},required:["resourceId"],group:"cash_entries",readOnly:!1,searchHint:"update cash in receipt entry details",execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{internalNotes:n}};return Zb(e.client,r,i)}},{name:"get_cash_out",description:"Get a cash-out entry by resourceId.",params:{resourceId:{type:"string",description:"Cash-out resourceId"}},required:["resourceId"],group:"cash_entries",readOnly:!0,searchHint:"get cash out payment entry details",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Xb(e.client,t.resourceId)},{name:"update_cash_out",description:'Update an existing cash-out entry (change amount, date, reference, notes, tags, or entry lines). Use when the user says "update", "change", "fix", or "adjust" a cash-out that was just created or found. Do NOT create a new entry \u2014 use this tool instead. NOTE: cash entries created without saveAsDraft:true are ACTIVE (finalized) and cannot be updated \u2014 they must be deleted and recreated.',params:{resourceId:{type:"string",description:"Cash-out resourceId (parentEntityResourceId from create response)"},accountResourceId:{type:"string",description:"Bank account resourceId (required for update)"},reference:yo,valueDate:go,lines:ec,notes:yr,tags:{type:"array",items:{type:"string"},description:"Tags (string array)"}},required:["resourceId"],group:"cash_entries",readOnly:!1,searchHint:"update cash out payment entry details",execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{internalNotes:n}};return Qb(e.client,r,i)}},gt("list_cash_transfers","List cash transfer entries. Paginated.","cash_transfers",(e,t,r)=>e0(e,{limit:r,offset:t}),"list cash transfers between accounts"),{name:"create_cash_transfer",description:`Move money between TWO OF YOUR OWN bank/cash accounts (petty-cash top-up, inter-account, FX between own accounts).
|
|
708
|
+
|
|
709
|
+
NOT for external parties \u2014 use create_cash_in (receiving) / create_cash_out (paying).
|
|
710
|
+
|
|
711
|
+
cashOut = source, cashIn = destination. Each side needs accountResourceId + amount. reference auto-generated if omitted. Do NOT send currency/exchangeRate (derived server-side).`,params:{reference:{type:"string",description:"Reference number"},valueDate:{type:"string",description:"Date (YYYY-MM-DD)"},cashOut:{type:"object",properties:{accountResourceId:{type:"string",description:"Source bank account resourceId"},amount:{type:"number",description:"Transfer amount"}},required:["accountResourceId","amount"]},cashIn:{type:"object",properties:{accountResourceId:{type:"string",description:"Destination bank account resourceId"},amount:{type:"number",description:"Transfer amount"}},required:["accountResourceId","amount"]},tags:{type:"array",items:{type:"string"},description:"Tags (string array)"},saveAsDraft:{type:"boolean",description:"Save as draft (default true)"}},required:["valueDate","cashOut","cashIn"],group:"cash_transfers",readOnly:!1,searchHint:"create cash transfer between bank accounts",execute:async(e,t)=>{let r={...t};return r.reference||(r.reference=`CT-${Date.now()}`),Cf(e.client,r)}},ln("delete_cash_in","Delete (void) a cash-in entry. Uses parentEntityResourceId from create response.","cash_entries",(e,t)=>vs(e,t),"delete void a cash in receipt entry"),ln("delete_cash_out","Delete (void) a cash-out entry. Uses parentEntityResourceId from create response.","cash_entries",(e,t)=>vs(e,t),"delete void a cash out payment entry"),ln("delete_cash_transfer","Delete (void) a cash transfer. Uses parentEntityResourceId from create response.","cash_transfers",(e,t)=>vs(e,t),"delete void a cash transfer between accounts"),gt("list_scheduled_invoices","List scheduled (recurring) invoices. Paginated.","schedulers",(e,t,r)=>X0(e,{limit:r,offset:t}),"list recurring scheduled invoices subscriptions"),gt("list_scheduled_bills","List scheduled (recurring) bills. Paginated.","schedulers",(e,t,r)=>Q0(e,{limit:r,offset:t}),"list recurring scheduled bills subscriptions"),gt("list_scheduled_journals","List scheduled (recurring) journals. Paginated.","schedulers",(e,t,r)=>ev(e,{limit:r,offset:t}),"list recurring scheduled journal entries"),{name:"get_bank_account",description:"Get full bank account details by resourceId.",params:{resourceId:{type:"string",description:"Bank account resourceId"}},required:["resourceId"],group:"bank",readOnly:!0,searchHint:"get bank account details balance by id",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>qc(e.client,t.resourceId)},Rt({name:"search_bank_records",description:"Search bank records for a specific account. Filter by status, date, description, payer, reference, amount range. Call list_bank_accounts first to get accountResourceId.",group:"bank",fields:Yp,defaults:Jp,fetcher:by,pathParam:"accountResourceId",pathParamDescription:"Bank account resourceId (UUID). Call list_bank_accounts first.",searchHint:"find bank records by status date amount description"}),Rt({name:"search_cashflow_transactions",description:"Search cashflow transactions (unified ledger). Filter by type, direction (PAYIN/PAYOUT), status, date, reference, account.",group:"cashflow",fields:Ri,defaults:$i,fetcher:Ss,searchHint:"find cashflow transactions by type direction status"}),gt("list_bookmarks","List organization bookmarks (saved values/settings).","bookmarks",(e,t,r)=>q0(e,{limit:r,offset:t}),"list saved bookmarks reports shortcuts"),{name:"get_bookmark",description:"Get a bookmark by resourceId.",params:{resourceId:{type:"string",description:"Bookmark resourceId"}},required:["resourceId"],group:"bookmarks",readOnly:!0,searchHint:"get bookmark saved report details",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>z0(e.client,t.resourceId)},{name:"create_bookmarks",description:"Create one or more bookmarks. categoryCode must be one of: AUDIT_AND_ASSURANCE, BANKING_AND_FINANCE, BUDGETS_AND_CONTROLS, EMPLOYEES_AND_PAYROLL, EXTERNAL_DOCUMENTS, GENERAL_INFORMATION, OWNERS_AND_DIRECTORS, TAXATION_AND_COMPLIANCE, WORKFLOWS_AND_PROCESSES.",params:{items:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Bookmark name"},value:{type:"string",description:"Bookmark value"},categoryCode:{type:"string",description:"Category code (e.g., GENERAL_INFORMATION)"},datatypeCode:{type:"string",description:"Datatype code (default: TEXT)"}},required:["name","value","categoryCode","datatypeCode"]},description:"Bookmarks to create"}},required:["items"],group:"bookmarks",readOnly:!1,searchHint:"create new bookmark saved report shortcut",execute:async(e,t)=>Pf(e.client,t.items)},{name:"update_bookmark",description:"Update an existing bookmark (name, value, or category). Use when modifying a previously created bookmark.",params:{resourceId:{type:"string",description:"Bookmark resourceId"},name:{type:"string",description:"New name"},value:{type:"string",description:"New value"},categoryCode:{type:"string",description:"New category code"}},required:["resourceId"],group:"bookmarks",readOnly:!1,searchHint:"update bookmark name or configuration",execute:async(e,t)=>{let{resourceId:r,...n}=t;return Y0(e.client,r,n)}},gt("list_org_users","List organization users (team members). Returns name, email, roles.","org_users",(e,t,r)=>J0(e,{limit:r,offset:t}),"list organization users team members"),Rt({name:"search_org_users",description:"Search organization users by name, email, role, status. For OR search (name or email), use filter param.",group:"org_users",fields:ff,defaults:mf,fetcher:G0,searchHint:"find organization users by name email role status"}),{name:"invite_org_user",description:"Invite a new user to the organization.",params:{firstName:{type:"string",description:"First name"},lastName:{type:"string",description:"Last name"},email:{type:"string",description:"Email address"},moduleRoles:{type:"array",items:{type:"object",properties:{moduleName:{type:"string",description:"Module name: ORGANIZATION, USER_MANAGEMENT, ACCOUNTING, SALES, PURCHASES, REPORTS, or FIXED_ASSET"},roleCode:{type:"string",description:"Role code: ADMIN, PREPARER, MEMBER, or NO_ACCESS"}},required:["moduleName","roleCode"]},description:"Module role assignments"}},required:["firstName","lastName","email","moduleRoles"],group:"org_users",readOnly:!1,searchHint:"invite new user to join organization team",execute:async(e,t)=>Nu(e.client,t)},{name:"update_org_user",description:"Update an organization user's module roles.",params:{resourceId:{type:"string",description:"Org user resourceId"},moduleRoles:{type:"array",items:{type:"object",properties:{moduleName:{type:"string",description:"Module name: ORGANIZATION, USER_MANAGEMENT, ACCOUNTING, SALES, PURCHASES, REPORTS, or FIXED_ASSET"},roleCode:{type:"string",description:"Role code: ADMIN, PREPARER, MEMBER, or NO_ACCESS"}},required:["moduleName","roleCode"]}}},required:["resourceId","moduleRoles"],group:"org_users",readOnly:!1,searchHint:"update organization user role permissions",execute:async(e,t)=>V0(e.client,t.resourceId,{moduleRoles:t.moduleRoles})},{name:"remove_org_user",description:"Remove a user from the organization.",params:{resourceId:{type:"string",description:"Org user resourceId"}},required:["resourceId"],group:"org_users",readOnly:!1,searchHint:"remove user from organization team",isDestructive:!0,execute:async(e,t)=>H0(e.client,t.resourceId)},{name:"list_payments",description:"List recent payments across all transaction types. Paginated.",params:{...cR},required:[],group:"payments",readOnly:!0,searchHint:"list payment records transactions with pagination",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>{let r=t.limit,n=t.offset;return r0(e.client,{limit:r??100,offset:n??0})}},Rt({name:"search_payments",description:"Search payments by type, direction (PAYIN/PAYOUT), method, date, reference, account.",group:"payments",fields:qp,defaults:zp,fetcher:xf,searchHint:"find payments by type direction method date account"}),{name:"download_export",description:`Analytical / financial / audit report XLSX. Returns { fileName, fileUrl } (pre-signed, ~5 min).
|
|
712
|
+
|
|
713
|
+
Use this tool (not export_records) for: analysis-* (anomalous-invoices/bills, cashflow-anomalies, gl-journal-audit, exchange-rate-audit, receivables-customer-risk, cash-expense-health); statements (trial-balance, balance-sheet, profit-and-loss, cashflow, general-ledger, cash-balance); aging (ar-report, ap-report); summaries (sales, sales-payments, purchase, purchase-payments, customer-revenue, product-sales, periodic-revenue, supplier-expense, product-purchase, periodic-expense, credit-note, sales-cost-margin); inventory movement (sale-/purchase-inventory-movement); statement-of-account-export.
|
|
714
|
+
|
|
715
|
+
NOT for raw entity dumps (invoices/bills/contacts as rows) \u2014 use export_records.`,params:{exportType:{type:"string",description:"Export type (see description for full list)"},startDate:{type:"string",description:"Period start (YYYY-MM-DD)"},endDate:{type:"string",description:"Period end (YYYY-MM-DD)"},currencyCode:{type:"string",description:"Currency override"},tags:{type:"array",items:{type:"string"},description:"Filter by tags"},contactResourceId:{type:"string",description:"Filter by contact"}},required:["exportType"],group:"exports",readOnly:!0,searchHint:"download data export report CSV XLSX file. Includes anomaly detection (anomalous invoices, anomalous bills, cashflow anomalies), audit analyses (GL journal audit, exchange rate audit), risk analyses (receivables customer risk, cash expense health), plus standard reports (trial balance, P&L, balance sheet, general ledger, AR/AP, sales/purchase summaries, statement of account).",isConcurrencySafe:!0,execute:async(e,t)=>{let{exportType:r,...n}=t;return lv(e.client,r,n)}},{name:"plan_recipe",description:`Offline. Plan an IFRS transaction (schedule + journals) WITHOUT posting. Returns RecipePlan: capsuleType, capsuleName, requiredAccounts, needsContact, steps (journal|bill|invoice|cash-in|cash-out), calculator output.
|
|
716
|
+
|
|
717
|
+
Supported (${Ma.length}): ${Ma.join(", ")}.
|
|
718
|
+
|
|
719
|
+
USE FOR: depreciation (sl/ddb/150db), amortization, ECL, lease (IFRS 16), hire purchase, loan, IAS 37 provisions, deferred revenue, fixed deposits, asset disposal, accrued expenses, leave-accrual, dividends. Never hand-construct.
|
|
720
|
+
|
|
721
|
+
fx-reval EXCEPTION: Jaz auto-handles period-end IAS 21.23 FX translation. fx-reval is VERIFICATION ONLY \u2014 do NOT execute_recipe(recipe: 'fx-reval'), it double-posts.
|
|
722
|
+
|
|
723
|
+
NEXT STEP: call execute_recipe with same params + startDate.
|
|
724
|
+
|
|
725
|
+
ALIASES (file\u2192engine): prepaid-amortization\u2192prepaid-expense, bank-loan\u2192loan, ifrs16-lease\u2192lease, bad-debt-provision\u2192ecl, accrued-expenses\u2192accrued-expense, fx-revaluation\u2192fx-reval, declining-balance\u2192depreciation. Pass the engine name.`,params:{recipe:{type:"string",enum:[...Ma],description:"Recipe type"},amount:{type:"number",description:"Amount (for amortization, accrued-expense, dividend, ecl, provision, fx-reval)"},principal:{type:"number",description:"Principal (for loan, fixed-deposit)"},startDate:{type:"string",description:"Start date YYYY-MM-DD (REQUIRED for blueprint generation \u2014 default to today if user does not specify)"},currency:{type:"string",description:"Currency code (e.g. SGD, USD)"},periods:{type:"number",description:"Number of periods (for amortization, accrued-expense, leave-accrual)"},frequency:{type:"string",enum:["monthly","quarterly","annual"],description:"Frequency (for depreciation, amortization, accrued-expense)"},annualRate:{type:"number",description:"Annual interest/discount rate %"},termMonths:{type:"number",description:"Term in months"},monthlyPayment:{type:"number",description:"Monthly lease payment (for lease)"},usefulLifeMonths:{type:"number",description:"Asset useful life in months (hire purchase)"},cost:{type:"number",description:"Asset cost"},salvageValue:{type:"number",description:"Salvage value"},usefulLifeYears:{type:"number",description:"Useful life in years"},method:{type:"string",enum:["sl","ddb","150db"],description:"Depreciation method"},acquisitionDate:{type:"string",description:"Acquisition date YYYY-MM-DD"},disposalDate:{type:"string",description:"Disposal date YYYY-MM-DD"},proceeds:{type:"number",description:"Disposal proceeds"},bookRate:{type:"number",description:"Original booking exchange rate"},closingRate:{type:"number",description:"Period-end closing exchange rate"},baseCurrency:{type:"string",description:"Base (functional) currency"},buckets:{type:"array",items:{type:"object",properties:{name:{type:"string"},balance:{type:"number"},rate:{type:"number"}},required:["name","balance","rate"]},description:"ECL aging buckets"},existingProvision:{type:"number",description:"Existing ECL provision balance"},compounding:{type:"string",enum:["none","monthly","quarterly","annually"],description:"Compounding method"},employees:{type:"number",description:"Number of employees"},daysPerYear:{type:"number",description:"Leave days per employee per year"},dailyRate:{type:"number",description:"Average daily rate"},declarationDate:{type:"string",description:"Board resolution date YYYY-MM-DD"},paymentDate:{type:"string",description:"Settlement date YYYY-MM-DD"},withholdingRate:{type:"number",description:"Withholding tax rate %"}},required:["recipe"],group:"recipes",readOnly:!0,searchHint:"plan multi-step transaction recipe offline. Covers depreciation (straight-line, DDB, 150DB), amortization, prepaid amortization, deferred revenue, IFRS 16 leases, hire purchase, loan schedules, fixed deposits, FX revaluation, ECL (expected credit loss), IAS 37 provisions, asset disposal, accrued expenses, leave accrual, dividend.",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>{let r=t.recipe,n=xr(r,t);return{...ku(r,n),_nextStep:"Call execute_recipe with the same parameters plus startDate to create all transactions. The execute_recipe tool IS available \u2014 use it now."}}},{name:"execute_recipe",description:`Execute a recipe end-to-end \u2014 calculator + capsule + post all entries in one call. PREFERRED over manual creation (replaces ~20 tool calls). After plan_recipe, ALWAYS use this (not create_journal/create_invoice/create_cash_out).
|
|
726
|
+
|
|
727
|
+
Supported: ${Ma.join(", ")}.
|
|
728
|
+
|
|
729
|
+
Requires startDate. Auto-resolves accounts from CoA. Provide bankAccountName for recipes with cash-in/cash-out steps, contactName for recipes with invoice/bill steps.`,params:{recipe:{type:"string",enum:[...Ma],description:"Recipe type"},amount:{type:"number"},principal:{type:"number"},startDate:{type:"string",description:"Start date YYYY-MM-DD (REQUIRED for execution)"},currency:{type:"string"},periods:{type:"number"},frequency:{type:"string",enum:["monthly","quarterly","annual"]},annualRate:{type:"number"},termMonths:{type:"number"},monthlyPayment:{type:"number"},usefulLifeMonths:{type:"number"},cost:{type:"number"},salvageValue:{type:"number"},usefulLifeYears:{type:"number"},method:{type:"string",enum:["sl","ddb","150db"]},acquisitionDate:{type:"string"},disposalDate:{type:"string"},proceeds:{type:"number"},bookRate:{type:"number"},closingRate:{type:"number"},baseCurrency:{type:"string"},buckets:{type:"array",items:{type:"object",properties:{name:{type:"string"},balance:{type:"number"},rate:{type:"number"}},required:["name","balance","rate"]}},existingProvision:{type:"number"},compounding:{type:"string",enum:["none","monthly","quarterly","annually"]},employees:{type:"number"},daysPerYear:{type:"number"},dailyRate:{type:"number"},declarationDate:{type:"string"},paymentDate:{type:"string"},withholdingRate:{type:"number"},bankAccountName:{type:"string",description:"Bank/cash account name (for cash-in/cash-out steps) \u2014 auto-resolved by fuzzy match"},contactName:{type:"string",description:"Contact name (for invoice/bill steps) \u2014 auto-resolved by fuzzy match"},existingTxnId:{type:"string",description:"Attach to existing transaction \u2014 skip initial step"},referencePrefix:{type:"string",description:"Reference prefix (generates prefix-1, prefix-2, ...)"},finalize:{type:"boolean",description:"Approve transactions immediately (default: drafts)"}},required:["recipe","startDate"],group:"recipes",readOnly:!1,searchHint:"execute transaction recipe capsule blueprint with dated steps. Posts depreciation, amortization, prepaid, deferred revenue, IFRS 16 lease, hire purchase, loan, fixed deposit, FX revaluation, ECL, IAS 37 provision, asset disposal, accrued expense, leave accrual, dividend entries.",maxResultSizeChars:1e5,execute:async(e,t)=>{let r=t.recipe,n=xr(r,t),o=Lf(n);if(!o)throw new Error("No blueprint generated. Ensure startDate is provided.");let i=ku(r,n),s=await EJ(e.client,i.plan.requiredAccounts);if(s.failures.length>0){let u=s.failures.map(l=>`${l.name}${l.candidates.length>0?` (closest: ${l.candidates.join(", ")})`:""}`).join("; ");throw new Error(`Cannot auto-resolve ${s.failures.length} account(s): ${u}. Create them in Jaz first.`)}let a;t.contactName&&(a=(await IJ(e.client,t.contactName)).resourceId);let c;return t.bankAccountName&&(c=(await CJ(e.client,t.bankAccountName)).resourceId),W0(e.client,{blueprint:o,calcType:r,accountMap:s.mapping,bankAccountId:c,contactId:a,existingTxnId:t.existingTxnId,referencePrefix:t.referencePrefix,finalize:t.finalize})}},{name:"create_scheduled_journal",description:"Recurring journal. Use `schedulerEntries` (NOT journalEntries) \u2014 each needs accountResourceId, amount, type (DEBIT|CREDIT), name. Use `repeat` (NOT frequency/interval): WEEKLY|MONTHLY|QUARTERLY|YEARLY. Debits must equal credits. Flat structure \u2014 reference, valueDate, saveAsDraft at top level.\n\nDynamic strings (reference/name/notes): {{Day}}, {{Date}}, {{Date+X}}, {{DateRange:X}}, {{Month}}, {{Month+X}}, {{MonthRange:X}}, {{Year}}, {{Year+X}}.",params:{reference:{type:"string",description:"Journal reference"},valueDate:{type:"string",description:"Template date (YYYY-MM-DD)"},startDate:{type:"string",description:"First occurrence (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence (YYYY-MM-DD, optional)"},repeat:{type:"string",enum:["WEEKLY","MONTHLY","QUARTERLY","YEARLY"],description:"Recurrence interval"},schedulerEntries:{type:"array",items:{type:"object",properties:{accountResourceId:tc,amount:{type:"number"},type:{type:"string",enum:["DEBIT","CREDIT"]},name:{type:"string",description:"Line description"}},required:["accountResourceId","amount","type"]}},notes:{type:"string",description:"Journal notes"}},required:["startDate","repeat","valueDate","schedulerEntries"],group:"schedulers",readOnly:!1,searchHint:"create recurring scheduled journal entry",execute:async(e,t)=>If(e.client,{status:"ACTIVE",startDate:t.startDate,endDate:t.endDate,repeat:t.repeat,valueDate:t.valueDate,schedulerEntries:t.schedulerEntries,reference:t.reference,internalNotes:t.notes})},{name:"create_scheduled_invoice",description:`Recurring invoice. Use for fixed-amount recurrence where you want per-period control over currency / tax / line items. DIFFERENT from subscriptions: no proration, but currency/tax/items can differ per occurrence.
|
|
730
|
+
|
|
731
|
+
CRITICAL: saveAsDraft MUST be false (API rejects INVALID_SALE_STATUS). Use \`repeat\` (NOT frequency/interval): WEEKLY | MONTHLY | QUARTERLY | YEARLY. Each lineItem needs name, unitPrice, quantity, accountResourceId.
|
|
732
|
+
|
|
733
|
+
Dynamic strings (reference/name/notes): {{Day}}, {{Date}}, {{Date+X}}, {{DateRange:X}}, {{Month}}, {{Month+X}}, {{MonthRange:X}}, {{Year}}, {{Year+X}}.`,params:{startDate:{type:"string",description:"First occurrence (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence (YYYY-MM-DD, optional)"},repeat:{type:"string",enum:["WEEKLY","MONTHLY","QUARTERLY","YEARLY"],description:"Recurrence interval"},contactResourceId:{type:"string",description:"Customer contact resourceId"},reference:{type:"string",description:"Invoice reference"},valueDate:{type:"string",description:"Template issue date (YYYY-MM-DD)"},dueDate:{type:"string",description:"Template due date (YYYY-MM-DD)"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string"},unitPrice:{type:"number"},quantity:{type:"number"},accountResourceId:tc,taxProfileResourceId:{type:"string"}},required:["name","unitPrice","quantity","accountResourceId"]}},tag:{type:"string",description:"Tag name"}},required:["startDate","repeat","contactResourceId","reference","valueDate","dueDate","lineItems"],group:"schedulers",readOnly:!1,searchHint:"create recurring scheduled invoice subscription",execute:async(e,t)=>vf(e.client,{status:"ACTIVE",startDate:t.startDate,endDate:t.endDate,repeat:t.repeat,invoice:{reference:t.reference,valueDate:t.valueDate,dueDate:t.dueDate,contactResourceId:t.contactResourceId,lineItems:t.lineItems,tags:t.tag?[t.tag]:void 0,saveAsDraft:!1}})},{name:"create_scheduled_bill",description:`Create a scheduled (recurring) bill. CRITICAL:
|
|
756
734
|
- saveAsDraft MUST be false (API rejects INVALID_PURCHASE_STATUS otherwise).
|
|
757
735
|
- Use repeat (NOT frequency/interval): WEEKLY, MONTHLY, QUARTERLY, YEARLY.
|
|
758
736
|
- Each lineItem needs name, unitPrice, quantity, accountResourceId.
|
|
@@ -763,15 +741,17 @@ Fields per record:
|
|
|
763
741
|
- transactionDate (required): YYYY-MM-DD
|
|
764
742
|
- description, payerOrPayee, reference: optional strings
|
|
765
743
|
|
|
766
|
-
Returns {data: {errors: []}} on success. accountResourceId must be a bank-type CoA account (find via list_bank_accounts).`,params:{accountResourceId:{type:"string",description:"Bank account resourceId (from list_bank_accounts)"},records:{type:"array",items:{type:"object",properties:{amount:{type:"number",description:"Positive = cash-in, negative = cash-out"},transactionDate:{type:"string",description:"Date (YYYY-MM-DD)"},description:{type:"string",description:"Description"},payerOrPayee:{type:"string",description:"Payer or payee name"},reference:{type:"string",description:"Reference"}},required:["amount","transactionDate"]},description:"Array of 1-100 bank records"}},required:["accountResourceId","records"],group:"bank",readOnly:!1,searchHint:"add manual bank transaction records entries",execute:async(e,t)=>vy(e.client,t.accountResourceId,t.records)},{name:"create_bt_from_attachment",description:"Create a business transaction (invoice/bill/credit note) from an uploaded file using AI extraction. Processing is async.",params:{businessTransactionType:{type:"string",enum:["INVOICE","BILL","CUSTOMER_CREDIT_NOTE","SUPPLIER_CREDIT_NOTE"],description:"Type of transaction to create"},sourceUrl:{type:"string",description:"URL of the source file"},attachmentId:{type:"string",description:"Attachment ID (alternative to URL)"}},required:["businessTransactionType"],group:"magic",readOnly:!1,searchHint:"create transaction from attachment AI extraction",execute:async(e,t)=>{if(!t.sourceUrl&&!t.attachmentId)throw new Error("Provide sourceUrl or attachmentId \u2014 one is required.");let r=t.sourceUrl;if(r&&r.includes("api.telegram.org/file/")){let n=await fetch(r,{signal:AbortSignal.timeout(15e3)});if(!n.ok)throw new Error(`Failed to download Telegram file: ${n.status}`);let o=n.headers.get("content-type")??"application/octet-stream",i=await n.arrayBuffer(),s=new Uint8Array(i.slice(0,8)),c=(s[0]===37&&s[1]===80&&s[2]===68&&s[3]===70?"application/pdf":s[0]===255&&s[1]===216?"image/jpeg":s[0]===137&&s[1]===80&&s[2]===78&&s[3]===71?"image/png":s[0]===80&&s[1]===75?"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":null)??o,u=new Blob([i],{type:c}),l=decodeURIComponent(r.split("/").pop()??"file"),f={"application/pdf":".pdf","image/jpeg":".jpg","image/png":".png"}[c];return f&&!l.endsWith(f)&&(l=l.replace(/\.[^.]+$/,"")+f),es(e.client,{businessTransactionType:t.businessTransactionType,sourceFile:u,sourceFileName:l,sourceUrl:r})}return es(e.client,{businessTransactionType:t.businessTransactionType,sourceUrl:r,attachmentId:t.attachmentId})}},{name:"get_magic_workflow_status",description:"Get the current status of specific magic workflow(s) by resourceId(s). Returns workflow details including status, document type, and results.",params:{workflowIds:{type:"array",items:{type:"string"},description:"One or more workflow resourceIds to check"}},required:["workflowIds"],group:"magic",readOnly:!0,searchHint:"check AI extraction workflow status progress",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=t.workflowIds;if(r.length===0)throw new Error("workflowIds must be non-empty");return bd(e.client,{filter:{resourceId:{in:r}},limit:r.length})}},{name:"get_attachments",description:"Get attachments for a business transaction (invoice, bill, journal, credit note).",params:{transactionType:{type:"string",enum:["invoices","bills","journals","scheduled_journals","customer-credit-notes","supplier-credit-notes"],description:"Transaction type"},transactionId:{type:"string",description:"Transaction resourceId"}},required:["transactionType","transactionId"],group:"attachments",readOnly:!0,searchHint:"list attachments files on a transaction",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Mt(e.client,t.transactionType,t.transactionId)},{name:"add_attachment",description:"Add an attachment to a business transaction. Provide sourceUrl (downloads and uploads as file) or attachmentId (links existing).",params:{transactionType:{type:"string",enum:["invoices","bills","journals","scheduled_journals","customer-credit-notes","supplier-credit-notes"],description:"Transaction type"},transactionId:{type:"string",description:"Transaction resourceId"},attachmentId:{type:"string",description:"Attachment ID to link (alternative to sourceUrl)"},sourceUrl:{type:"string",description:"Source file URL \u2014 downloaded and uploaded as multipart file"}},required:["transactionType","transactionId"],group:"attachments",readOnly:!1,searchHint:"upload attach file to a transaction",execute:async(e,t)=>{if(!t.attachmentId&&!t.sourceUrl)throw new Error("Provide attachmentId or sourceUrl \u2014 one is required.");let r,n;if(t.sourceUrl){let o=await fetch(t.sourceUrl);if(!o.ok)throw new Error(`Failed to download ${t.sourceUrl}: ${o.status}`);let i=await o.arrayBuffer(),s=o.headers.get("content-type")??"application/octet-stream";r=new Blob([i],{type:s});try{n=new URL(t.sourceUrl).pathname.split("/").pop()||"attachment"}catch{n="attachment"}}return Lb(e.client,{businessTransactionType:t.transactionType,businessTransactionResourceId:t.transactionId,file:r,fileName:n,attachmentId:t.attachmentId})}},{name:"delete_attachment",description:"Delete an attachment from a business transaction.",params:{transactionType:{type:"string",enum:["invoices","bills","journals","scheduled_journals","customer-credit-notes","supplier-credit-notes"],description:"Transaction type"},transactionId:{type:"string",description:"Transaction resourceId"},attachmentResourceId:{type:"string",description:"Attachment resourceId (from get_attachments response)"}},required:["transactionType","transactionId","attachmentResourceId"],group:"attachments",readOnly:!1,searchHint:"delete remove attachment file from transaction",isDestructive:!0,execute:async(e,t)=>jb(e.client,t.transactionType,t.transactionId,t.attachmentResourceId)},{name:"fetch_attachment_table",description:"Fetch extracted table data from an attachment (OCR/AI extraction result).",params:{attachmentId:{type:"string",description:"Attachment ID"}},required:["attachmentId"],group:"attachments",readOnly:!0,searchHint:"extract table data from attachment image PDF",isConcurrencySafe:!0,execute:async(e,t)=>Mb(e.client,t.attachmentId)},{name:"message_to_pdf",description:"Convert a markdown message to a downloadable PDF document.",params:{markdown:{type:"string",description:"Markdown content to convert to PDF"},title:{type:"string",description:"PDF title (optional)"}},required:["markdown"],group:"exports",readOnly:!0,searchHint:"convert message text to PDF document",isConcurrencySafe:!0,execute:async(e,t)=>E0(e.client,{markdown:t.markdown,title:t.title})},{name:"generate_month_end_blueprint",description:"Generate a month-end close checklist with phases, steps, recipe references, and API calls. Returns a structured JobBlueprint.",params:{period:{type:"string",description:'Period in YYYY-MM format (e.g., "2026-01")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"month-end close checklist phases steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ey({period:t.period,currency:t.currency})},{name:"generate_quarter_end_blueprint",description:"Generate a quarter-end close checklist. Set incremental=true to skip month-end phases (assumes months are already closed).",params:{period:{type:"string",description:'Period in YYYY-QN format (e.g., "2026-Q1")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'},incremental:{type:"boolean",description:"Skip month-end phases (assumes months already closed)"}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"quarter-end close procedures review steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>Pc({period:t.period,currency:t.currency,incremental:t.incremental})},{name:"generate_year_end_blueprint",description:"Generate a year-end close checklist. Set incremental=true to skip quarter/month phases (assumes already closed).",params:{period:{type:"string",description:'Year in YYYY format (e.g., "2025")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'},incremental:{type:"boolean",description:"Skip quarter/month phases (assumes already closed)"}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"year-end close annual procedures checklist",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ty({period:t.period,currency:t.currency,incremental:t.incremental})},{name:"generate_bank_recon_blueprint",description:"Generate a bank reconciliation job checklist \u2014 match bank statement entries to ledger transactions.",params:{account:{type:"string",description:"Specific bank account name or resourceId (optional \u2014 all accounts if omitted)"},period:{type:"string",description:"Period in YYYY-MM format (optional)"},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"close_jobs",readOnly:!0,searchHint:"bank reconciliation procedure checklist steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ry({account:t.account,period:t.period,currency:t.currency})},{name:"generate_gst_vat_blueprint",description:"Generate a GST/VAT filing job checklist \u2014 verify tax transactions, reconcile GST accounts, prepare F5 return.",params:{period:{type:"string",description:'Period in YYYY-QN format (e.g., "2026-Q1")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"GST VAT tax filing preparation checklist",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ny({period:t.period,currency:t.currency})},{name:"generate_payment_run_blueprint",description:"Generate a payment run job checklist \u2014 identify outstanding bills, verify bank details, batch payments.",params:{dueBefore:{type:"string",description:"Pay bills due before this date (YYYY-MM-DD). Defaults to today."},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"payment run batch processing procedure steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>oy({dueBefore:t.dueBefore,currency:t.currency})},{name:"generate_credit_control_blueprint",description:"Generate a credit control job checklist \u2014 chase overdue invoices, send reminders, escalate aged debt.",params:{overdueDays:{type:"number",description:"Minimum days overdue to include (default 30)"},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"credit control collections follow-up procedure",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>iy({overdueDays:t.overdueDays,currency:t.currency})},{name:"generate_supplier_recon_blueprint",description:"Generate a supplier reconciliation job checklist \u2014 match supplier statements to AP ledger.",params:{supplier:{type:"string",description:"Specific supplier name or resourceId (optional \u2014 all suppliers if omitted)"},period:{type:"string",description:"Period in YYYY-MM format (optional)"},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"supplier reconciliation verification procedure steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>sy({supplier:t.supplier,period:t.period,currency:t.currency})},{name:"generate_audit_prep_blueprint",description:"Generate an audit preparation job checklist \u2014 verify completeness, prepare supporting schedules, organize documents.",params:{period:{type:"string",description:'Period in YYYY or YYYY-QN format (e.g., "2025" or "2025-Q4")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"audit preparation documentation checklist steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ay({period:t.period,currency:t.currency})},{name:"generate_fa_review_blueprint",description:"Generate a fixed asset review job checklist \u2014 verify asset register, reconcile depreciation, check disposals.",params:{currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"fixed asset review depreciation check procedure",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>cy({currency:t.currency})},{name:"generate_document_collection_blueprint",description:"Generate a document collection job checklist \u2014 identify missing invoices, receipts, and supporting docs for the period.",params:{currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"document collection gathering compliance checklist",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>uy({currency:t.currency})},{name:"generate_statutory_filing_blueprint",description:"Generate a statutory filing job checklist \u2014 prepare corporate income tax computation, file returns.",params:{ya:{type:"number",description:"Year of Assessment (defaults to current year)"},jurisdiction:{type:"string",description:'Tax jurisdiction code (e.g., "sg"). Defaults to "sg".'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"statutory filing regulatory compliance procedure",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ly({ya:t.ya,jurisdiction:t.jurisdiction,currency:t.currency})},{name:"validate_invoice_draft",description:"Check if an invoice draft is ready to finalize. Returns missing fields, structured validation report, and ready status. Use before finalize_invoice to prevent errors.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"drafts",readOnly:!0,searchHint:"validate invoice draft readiness for finalization",isConcurrencySafe:!0,execute:async(e,t)=>{let r=t.resourceId,n=await io(e.client,r),o=await Mt(e.client,"invoices",r);return Cr(n.data,so,o.data.length)}},{name:"validate_bill_draft",description:"Check if a bill draft is ready to finalize. Returns missing fields, structured validation report, and ready status. Use before finalize_bill to prevent errors.",params:{resourceId:{type:"string",description:"Bill resourceId"}},required:["resourceId"],group:"drafts",readOnly:!0,searchHint:"validate bill draft readiness for finalization",isConcurrencySafe:!0,execute:async(e,t)=>{let r=t.resourceId,n=await to(e.client,r),o=await Mt(e.client,"bills",r);return Cr(n.data,_n,o.data.length)}},{name:"validate_journal_draft",description:"Check if a journal draft is ready to finalize. Returns missing fields (accounts, amounts, date), structured validation, and ready status.",params:{resourceId:{type:"string",description:"Journal resourceId"}},required:["resourceId"],group:"drafts",readOnly:!0,searchHint:"validate journal draft readiness for posting",isConcurrencySafe:!0,execute:async(e,t)=>{let r=await ri(e.client,t.resourceId);return Cr(r.data,Ro,0,"journalEntries")}},{name:"validate_credit_note_draft",description:"Check if a credit note draft (customer or supplier) is ready to finalize. Returns missing fields, structured validation, and ready status.",params:{resourceId:{type:"string",description:"Credit note resourceId"},type:{type:"string",enum:["customer","supplier"],description:'Credit note type: "customer" or "supplier"'}},required:["resourceId","type"],group:"drafts",readOnly:!0,searchHint:"validate credit note draft readiness for finalization",isConcurrencySafe:!0,execute:async(e,t)=>{let r=t.resourceId,n=t.type,o=n==="customer"?await $o(e.client,r):await No(e.client,r),i=n==="customer"?"customer-credit-notes":"supplier-credit-notes",s=await Mt(e.client,i,r);return Cr(o.data,ur,s.data.length)}},gt("list_bank_rules","List bank reconciliation rules (action shortcuts). Shows rule name, action type, and target bank account.","bank_rules",(e,t,r)=>$S(e,{limit:r,offset:t}),"list automatic bank reconciliation rules"),Yn("get_bank_rule","Get full bank rule details including configuration (allocation percentages, accounts, tax settings).","bank_rules",(e,t)=>Um(e,t),"get bank rule details conditions actions"),Rt({name:"search_bank_rules",description:"Search bank rules by name.",group:"bank_rules",fields:hf,defaults:gf,fetcher:NS,searchHint:"find bank rules by name matching criteria"}),{name:"create_bank_rule",description:`Create a bank reconciliation rule. Rules auto-match bank records to transactions during reconciliation. When the user asks to create a bank rule, use this tool directly \u2014 do not only list existing rules.
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
Minimum
|
|
773
|
-
|
|
774
|
-
|
|
744
|
+
Returns {data: {errors: []}} on success. accountResourceId must be a bank-type CoA account (find via list_bank_accounts).`,params:{accountResourceId:{type:"string",description:"Bank account resourceId (from list_bank_accounts)"},records:{type:"array",items:{type:"object",properties:{amount:{type:"number",description:"Positive = cash-in, negative = cash-out"},transactionDate:{type:"string",description:"Date (YYYY-MM-DD)"},description:{type:"string",description:"Description"},payerOrPayee:{type:"string",description:"Payer or payee name"},reference:{type:"string",description:"Reference"}},required:["amount","transactionDate"]},description:"Array of 1-100 bank records"}},required:["accountResourceId","records"],group:"bank",readOnly:!1,searchHint:"add manual bank transaction records entries",execute:async(e,t)=>vy(e.client,t.accountResourceId,t.records)},{name:"create_bt_from_attachment",description:"Create a business transaction (invoice/bill/credit note) from an uploaded file using AI extraction. Processing is async.",params:{businessTransactionType:{type:"string",enum:["INVOICE","BILL","CUSTOMER_CREDIT_NOTE","SUPPLIER_CREDIT_NOTE"],description:"Type of transaction to create"},sourceUrl:{type:"string",description:"URL of the source file"},attachmentId:{type:"string",description:"Attachment ID (alternative to URL)"}},required:["businessTransactionType"],group:"magic",readOnly:!1,searchHint:"create transaction from attachment AI extraction",execute:async(e,t)=>{if(!t.sourceUrl&&!t.attachmentId)throw new Error("Provide sourceUrl or attachmentId \u2014 one is required.");let r=t.sourceUrl;if(r&&r.includes("api.telegram.org/file/")){let n=await fetch(r,{signal:AbortSignal.timeout(15e3)});if(!n.ok)throw new Error(`Failed to download Telegram file: ${n.status}`);let o=n.headers.get("content-type")??"application/octet-stream",i=await n.arrayBuffer(),s=new Uint8Array(i.slice(0,8)),c=(s[0]===37&&s[1]===80&&s[2]===68&&s[3]===70?"application/pdf":s[0]===255&&s[1]===216?"image/jpeg":s[0]===137&&s[1]===80&&s[2]===78&&s[3]===71?"image/png":s[0]===80&&s[1]===75?"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":null)??o,u=new Blob([i],{type:c}),l=decodeURIComponent(r.split("/").pop()??"file"),f={"application/pdf":".pdf","image/jpeg":".jpg","image/png":".png"}[c];return f&&!l.endsWith(f)&&(l=l.replace(/\.[^.]+$/,"")+f),es(e.client,{businessTransactionType:t.businessTransactionType,sourceFile:u,sourceFileName:l,sourceUrl:r})}return es(e.client,{businessTransactionType:t.businessTransactionType,sourceUrl:r,attachmentId:t.attachmentId})}},{name:"get_magic_workflow_status",description:"Get the current status of specific magic workflow(s) by resourceId(s). Returns workflow details including status, document type, and results.",params:{workflowIds:{type:"array",items:{type:"string"},description:"One or more workflow resourceIds to check"}},required:["workflowIds"],group:"magic",readOnly:!0,searchHint:"check AI extraction workflow status progress",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=t.workflowIds;if(r.length===0)throw new Error("workflowIds must be non-empty");return bd(e.client,{filter:{resourceId:{in:r}},limit:r.length})}},{name:"get_attachments",description:"Get attachments for a business transaction (invoice, bill, journal, credit note).",params:{transactionType:{type:"string",enum:["invoices","bills","journals","scheduled_journals","customer-credit-notes","supplier-credit-notes"],description:"Transaction type"},transactionId:{type:"string",description:"Transaction resourceId"}},required:["transactionType","transactionId"],group:"attachments",readOnly:!0,searchHint:"list attachments files on a transaction",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Mt(e.client,t.transactionType,t.transactionId)},{name:"add_attachment",description:"Add an attachment to a business transaction. Provide sourceUrl (downloads and uploads as file) or attachmentId (links existing).",params:{transactionType:{type:"string",enum:["invoices","bills","journals","scheduled_journals","customer-credit-notes","supplier-credit-notes"],description:"Transaction type"},transactionId:{type:"string",description:"Transaction resourceId"},attachmentId:{type:"string",description:"Attachment ID to link (alternative to sourceUrl)"},sourceUrl:{type:"string",description:"Source file URL \u2014 downloaded and uploaded as multipart file"}},required:["transactionType","transactionId"],group:"attachments",readOnly:!1,searchHint:"upload attach file to a transaction",execute:async(e,t)=>{if(!t.attachmentId&&!t.sourceUrl)throw new Error("Provide attachmentId or sourceUrl \u2014 one is required.");let r,n;if(t.sourceUrl){let o=await fetch(t.sourceUrl);if(!o.ok)throw new Error(`Failed to download ${t.sourceUrl}: ${o.status}`);let i=await o.arrayBuffer(),s=o.headers.get("content-type")??"application/octet-stream";r=new Blob([i],{type:s});try{n=new URL(t.sourceUrl).pathname.split("/").pop()||"attachment"}catch{n="attachment"}}return Lb(e.client,{businessTransactionType:t.transactionType,businessTransactionResourceId:t.transactionId,file:r,fileName:n,attachmentId:t.attachmentId})}},{name:"delete_attachment",description:"Delete an attachment from a business transaction.",params:{transactionType:{type:"string",enum:["invoices","bills","journals","scheduled_journals","customer-credit-notes","supplier-credit-notes"],description:"Transaction type"},transactionId:{type:"string",description:"Transaction resourceId"},attachmentResourceId:{type:"string",description:"Attachment resourceId (from get_attachments response)"}},required:["transactionType","transactionId","attachmentResourceId"],group:"attachments",readOnly:!1,searchHint:"delete remove attachment file from transaction",isDestructive:!0,execute:async(e,t)=>jb(e.client,t.transactionType,t.transactionId,t.attachmentResourceId)},{name:"fetch_attachment_table",description:"Fetch extracted table data from an attachment (OCR/AI extraction result).",params:{attachmentId:{type:"string",description:"Attachment ID"}},required:["attachmentId"],group:"attachments",readOnly:!0,searchHint:"extract table data from attachment image PDF",isConcurrencySafe:!0,execute:async(e,t)=>Mb(e.client,t.attachmentId)},{name:"message_to_pdf",description:"Convert a markdown message to a downloadable PDF document.",params:{markdown:{type:"string",description:"Markdown content to convert to PDF"},title:{type:"string",description:"PDF title (optional)"}},required:["markdown"],group:"exports",readOnly:!0,searchHint:"convert message text to PDF document",isConcurrencySafe:!0,execute:async(e,t)=>E0(e.client,{markdown:t.markdown,title:t.title})},{name:"generate_month_end_blueprint",description:"Offline. Generate a month-end close checklist with phases, steps, recipe references, and API calls. Returns a structured JobBlueprint.",params:{period:{type:"string",description:'Period in YYYY-MM format (e.g., "2026-01")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"month-end close checklist phases steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ey({period:t.period,currency:t.currency})},{name:"generate_quarter_end_blueprint",description:"Offline. Generate a quarter-end close checklist. Set incremental=true to skip month-end phases (assumes months are already closed).",params:{period:{type:"string",description:'Period in YYYY-QN format (e.g., "2026-Q1")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'},incremental:{type:"boolean",description:"Skip month-end phases (assumes months already closed)"}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"quarter-end close procedures review steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>Pc({period:t.period,currency:t.currency,incremental:t.incremental})},{name:"generate_year_end_blueprint",description:"Offline. Generate a year-end close checklist. Set incremental=true to skip quarter/month phases (assumes already closed).",params:{period:{type:"string",description:'Year in YYYY format (e.g., "2025")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'},incremental:{type:"boolean",description:"Skip quarter/month phases (assumes already closed)"}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"year-end close annual procedures checklist",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ty({period:t.period,currency:t.currency,incremental:t.incremental})},{name:"generate_bank_recon_blueprint",description:"Offline. Generate a bank reconciliation job checklist \u2014 match bank statement entries to ledger transactions.",params:{account:{type:"string",description:"Specific bank account name or resourceId (optional \u2014 all accounts if omitted)"},period:{type:"string",description:"Period in YYYY-MM format (optional)"},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"close_jobs",readOnly:!0,searchHint:"bank reconciliation procedure checklist steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ry({account:t.account,period:t.period,currency:t.currency})},{name:"generate_gst_vat_blueprint",description:"Offline. Generate a GST/VAT filing job checklist \u2014 verify tax transactions, reconcile GST accounts, prepare F5 return.",params:{period:{type:"string",description:'Period in YYYY-QN format (e.g., "2026-Q1")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"GST VAT tax filing preparation checklist",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ny({period:t.period,currency:t.currency})},{name:"generate_payment_run_blueprint",description:"Offline. Generate a payment run job checklist \u2014 identify outstanding bills, verify bank details, batch payments.",params:{dueBefore:{type:"string",description:"Pay bills due before this date (YYYY-MM-DD). Defaults to today."},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"payment run batch processing procedure steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>oy({dueBefore:t.dueBefore,currency:t.currency})},{name:"generate_credit_control_blueprint",description:"Offline. Generate a credit control job checklist \u2014 chase overdue invoices, send reminders, escalate aged debt.",params:{overdueDays:{type:"number",description:"Minimum days overdue to include (default 30)"},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"credit control collections follow-up procedure",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>iy({overdueDays:t.overdueDays,currency:t.currency})},{name:"generate_supplier_recon_blueprint",description:"Offline. Generate a supplier reconciliation job checklist \u2014 match supplier statements to AP ledger.",params:{supplier:{type:"string",description:"Specific supplier name or resourceId (optional \u2014 all suppliers if omitted)"},period:{type:"string",description:"Period in YYYY-MM format (optional)"},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"supplier reconciliation verification procedure steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>sy({supplier:t.supplier,period:t.period,currency:t.currency})},{name:"generate_audit_prep_blueprint",description:"Offline. Generate an audit preparation job checklist \u2014 verify completeness, prepare supporting schedules, organize documents.",params:{period:{type:"string",description:'Period in YYYY or YYYY-QN format (e.g., "2025" or "2025-Q4")'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:["period"],group:"close_jobs",readOnly:!0,searchHint:"audit preparation documentation checklist steps",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ay({period:t.period,currency:t.currency})},{name:"generate_fa_review_blueprint",description:"Offline. Generate a fixed asset review job checklist \u2014 verify asset register, reconcile depreciation, check disposals.",params:{currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"fixed asset review depreciation check procedure",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>cy({currency:t.currency})},{name:"generate_document_collection_blueprint",description:"Offline. Generate a document collection job checklist \u2014 identify missing invoices, receipts, and supporting docs for the period.",params:{currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"document collection gathering compliance checklist",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>uy({currency:t.currency})},{name:"generate_statutory_filing_blueprint",description:"Offline. Generate a statutory filing job checklist \u2014 prepare corporate income tax computation, file returns.",params:{ya:{type:"number",description:"Year of Assessment (defaults to current year)"},jurisdiction:{type:"string",description:'Tax jurisdiction code (e.g., "sg"). Defaults to "sg".'},currency:{type:"string",description:'Base currency (e.g., "SGD"). Defaults to SGD.'}},required:[],group:"operational_jobs",readOnly:!0,searchHint:"statutory filing regulatory compliance procedure",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>ly({ya:t.ya,jurisdiction:t.jurisdiction,currency:t.currency})},{name:"validate_invoice_draft",description:"Check if an invoice draft is ready to finalize. Returns missing fields, structured validation report, and ready status. Use before finalize_invoice to prevent errors.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"drafts",readOnly:!0,searchHint:"validate invoice draft readiness for finalization",isConcurrencySafe:!0,execute:async(e,t)=>{let r=t.resourceId,n=await io(e.client,r),o=await Mt(e.client,"invoices",r);return Cr(n.data,so,o.data.length)}},{name:"validate_bill_draft",description:"Check if a bill draft is ready to finalize. Returns missing fields, structured validation report, and ready status. Use before finalize_bill to prevent errors.",params:{resourceId:{type:"string",description:"Bill resourceId"}},required:["resourceId"],group:"drafts",readOnly:!0,searchHint:"validate bill draft readiness for finalization",isConcurrencySafe:!0,execute:async(e,t)=>{let r=t.resourceId,n=await to(e.client,r),o=await Mt(e.client,"bills",r);return Cr(n.data,_n,o.data.length)}},{name:"validate_journal_draft",description:"Check if a journal draft is ready to finalize. Returns missing fields (accounts, amounts, date), structured validation, and ready status.",params:{resourceId:{type:"string",description:"Journal resourceId"}},required:["resourceId"],group:"drafts",readOnly:!0,searchHint:"validate journal draft readiness for posting",isConcurrencySafe:!0,execute:async(e,t)=>{let r=await ri(e.client,t.resourceId);return Cr(r.data,Ro,0,"journalEntries")}},{name:"validate_credit_note_draft",description:"Check if a credit note draft (customer or supplier) is ready to finalize. Returns missing fields, structured validation, and ready status.",params:{resourceId:{type:"string",description:"Credit note resourceId"},type:{type:"string",enum:["customer","supplier"],description:'Credit note type: "customer" or "supplier"'}},required:["resourceId","type"],group:"drafts",readOnly:!0,searchHint:"validate credit note draft readiness for finalization",isConcurrencySafe:!0,execute:async(e,t)=>{let r=t.resourceId,n=t.type,o=n==="customer"?await $o(e.client,r):await No(e.client,r),i=n==="customer"?"customer-credit-notes":"supplier-credit-notes",s=await Mt(e.client,i,r);return Cr(o.data,ur,s.data.length)}},gt("list_bank_rules","List bank reconciliation rules (action shortcuts). Shows rule name, action type, and target bank account.","bank_rules",(e,t,r)=>$S(e,{limit:r,offset:t}),"list automatic bank reconciliation rules"),Yn("get_bank_rule","Get full bank rule details including configuration (allocation percentages, accounts, tax settings).","bank_rules",(e,t)=>Um(e,t),"get bank rule details conditions actions"),Rt({name:"search_bank_rules",description:"Search bank rules by name.",group:"bank_rules",fields:hf,defaults:gf,fetcher:NS,searchHint:"find bank rules by name matching criteria"}),{name:"create_bank_rule",description:`Bank reconciliation rule \u2014 auto-matches bank records. Use directly on user request, don't just list existing.
|
|
745
|
+
|
|
746
|
+
Required: name, appliesToReconciliationAccount (bank account UUID, no "ResourceId" suffix), configuration.
|
|
747
|
+
|
|
748
|
+
configuration MUST nest under reconcileWithDirectCashEntry. Inside: reference (REQUIRED), amountAllocationType ("PERCENTAGE" | "FIXED" \u2014 server infers from arrays, don't send "FIXED_AND_PERCENTAGE"), percentageAllocation[] / fixedAllocation[].
|
|
749
|
+
|
|
750
|
+
Minimum: \`{ reconcileWithDirectCashEntry: { amountAllocationType: "PERCENTAGE", reference: "{{bankReference}}", percentageAllocation: [{ organizationAccountResourceId, amount: 100 }] } }\`
|
|
751
|
+
|
|
752
|
+
Optional inside configuration: contactResourceId, internalNotes, tags, currencySettings, taxCurrencySettings, taxInclusion, taxVatApplicable.
|
|
753
|
+
|
|
754
|
+
Dynamic strings (name + reference): {{bankReference}}, {{bankPayee}}, {{bankDescription}}.`,params:{name:{type:"string",description:"Rule name \u2014 supports dynamic strings: {{bankReference}}, {{bankPayee}}, {{bankDescription}}"},appliesToReconciliationAccount:{type:"string",description:"Bank account UUID this rule applies to"},configuration:{type:"object",description:"MUST nest under reconcileWithDirectCashEntry key. reference is REQUIRED. See tool description for full structure."}},required:["name","appliesToReconciliationAccount","configuration"],group:"bank_rules",readOnly:!1,searchHint:"create automatic bank reconciliation rule",execute:async(e,t)=>kS(e.client,t)},{name:"update_bank_rule",description:"Update an existing bank reconciliation rule. FULL REPLACEMENT \u2014 the API replaces the entire rule on update. You MUST provide the complete configuration, appliesToReconciliationAccount, and name every time. Use get_bank_rule first to read the current state, merge your changes, then call this tool with the full payload. Dynamic strings: {{bankReference}}, {{bankPayee}}, {{bankDescription}}.",params:{resourceId:{type:"string",description:"Bank rule resourceId"},name:{type:"string",description:"Rule name \u2014 supports dynamic strings: {{bankReference}}, {{bankPayee}}, {{bankDescription}}"},appliesToReconciliationAccount:{type:"string",description:"Bank account UUID this rule applies to (required for update \u2014 full replacement)"},configuration:{type:"object",description:"Full configuration object \u2014 must nest under reconcileWithDirectCashEntry key (same structure as create). reference is REQUIRED."}},required:["resourceId","name","appliesToReconciliationAccount","configuration"],group:"bank_rules",readOnly:!1,searchHint:"update bank rule conditions actions matching",execute:async(e,t)=>FS(e.client,t.resourceId,{resourceId:t.resourceId,name:t.name,appliesToReconciliationAccount:t.appliesToReconciliationAccount,configuration:t.configuration})},ln("delete_bank_rule","Delete a bank reconciliation rule.","bank_rules",(e,t)=>PS(e,t),"permanently delete a bank reconciliation rule"),{name:"view_auto_reconciliation",description:"Generate auto-reconciliation suggestions for a bank account. READ-ONLY \u2014 does NOT write reconciliations. To execute a reconciliation, use quick_reconcile (bulk async) or apply_bank_rule (rule-driven async) or one of the per-entry reconcile_* tools (sync). Returns magic match suggestions.",params:{bankAccountResourceId:{type:"string",description:"Bank account resourceId"},recommendationType:{type:"string",enum:["MAGIC_MATCH","MAGIC_RECONCILE_WITH_CASH_TRANSFER","MAGIC_RECONCILE_WITH_BANK_RULE","MAGIC_QUICK_RECONCILE"],description:"Type of recommendation to generate"}},required:["recommendationType"],group:"bank",readOnly:!0,searchHint:"view automatic bank reconciliation matches",isConcurrencySafe:!0,execute:async(e,t)=>{try{return await e.client.post("/api/v1/search-magic-reconciliation",{bankAccountResourceId:t.bankAccountResourceId,recommendationType:t.recommendationType})}catch(r){if((r.status??r.response?.status)===404)return{notSupported:!0,reason:"Endpoint /search-magic-reconciliation not available"};throw r}}},gt("list_fixed_assets","List fixed assets. Returns name, reference, type, category, status, purchase amount, net book value.","fixed_assets",(e,t,r)=>LS(e,{limit:r,offset:t}),"list fixed assets with depreciation status"),Yn("get_fixed_asset","Get full fixed asset details including depreciation schedule, accounts, disposal info.","fixed_assets",(e,t)=>jS(e,t),"get fixed asset details depreciation schedule"),Rt({name:"search_fixed_assets",description:"Search fixed assets by name, status, category, tag, type, date, amount range.",group:"fixed_assets",fields:Hp,defaults:Wp,fetcher:MS,searchHint:"find fixed assets by name status category amount"}),{name:"create_fixed_asset",description:`Register a fixed asset linked to an existing purchase transaction (bill or journal).
|
|
775
755
|
- saveAsDraft defaults to true. Set to false to activate \u2014 requires ALL fields below.
|
|
776
756
|
- ACTIVE assets require: purchaseBusinessTransactionType + purchaseBusinessTransactionResourceId
|
|
777
757
|
(links to the bill/journal that recorded the purchase).
|
|
@@ -779,45 +759,57 @@ Dynamic strings for name/reference: {{bankReference}} (e.g., INV-03/01/2025-01),
|
|
|
779
759
|
Use when the asset was acquired before using Jaz, imported from a legacy system, or purchased outside the system.
|
|
780
760
|
No linked purchase transaction needed \u2014 unlike create_fixed_asset which requires a bill/journal reference.
|
|
781
761
|
- bookValueAccumulatedDepreciationAmount: depreciation already incurred before registration
|
|
782
|
-
- All depreciation/account fields same as create_fixed_asset`,params:{name:{type:"string",description:"Asset name"},reference:{type:"string",description:"Asset reference (e.g., FA-000001)"},category:{type:"string",enum:["TANGIBLE","INTANGIBLE"],description:"Asset category"},typeName:{type:"string",description:'Asset type (e.g., "Computers and Electronics", "Furniture and Fixtures")'},typeCode:{type:"string",description:"Asset type code (e.g., COMPUTER_AND_ELECTRONIC, FURNITURE_AND_FIXTURE)"},purchaseAmount:{type:"number",description:"Original purchase cost"},purchaseDate:{type:"string",description:"Original purchase date (YYYY-MM-DD)"},purchaseAssetAccountResourceId:{type:"string",description:"Asset account resourceId"},depreciationMethod:{type:"string",enum:["STRAIGHT_LINE","NO_DEPRECIATION"],description:"Depreciation method"},depreciationStartDate:{type:"string",description:"Depreciation start date (YYYY-MM-DD)"},effectiveLife:{type:"number",description:"Useful life in months"},bookValueAccumulatedDepreciationAmount:{type:"number",description:"Depreciation already accumulated before registration"},depreciableValueResidualAmount:{type:"number",description:"Residual/salvage value"},depreciableValueCostLimitAmount:{type:"number",description:"Cost limit amount"},accumulatedDepreciationAccountResourceId:{type:"string",description:"Accumulated depreciation account resourceId"},depreciationExpenseAccountResourceId:{type:"string",description:"Depreciation expense account resourceId"},internalNotes:{type:"string",description:"Internal notes"},saveAsDraft:{type:"boolean",description:"Save as draft (default true). False = activate immediately."},customFields:un},required:["name","purchaseAmount","purchaseDate","purchaseAssetAccountResourceId","depreciationStartDate"],group:"fixed_assets",readOnly:!1,searchHint:"transfer fixed asset between accounts categories",execute:async(e,t)=>YS(e.client,t)},{name:"undo_fixed_asset_disposal",description:"Undo a fixed asset disposal (discard or sale). Restores the asset to active status. When the user asks to reverse or undo a disposal, use this tool directly.",params:{resourceId:{type:"string",description:"Fixed asset resourceId"}},required:["resourceId"],group:"fixed_assets",readOnly:!1,searchHint:"undo reversal of fixed asset disposal",execute:async(e,t)=>JS(e.client,t.resourceId)},gt("list_subscriptions","List recurring subscriptions. Returns status, interval, next schedule date, amount, transaction type.","subscriptions",(e,t,r)=>VS(e,{limit:r,offset:t}),"list recurring subscriptions billing schedules"),Yn("get_subscription","Get full subscription details including line items, schedule, and payment history.","subscriptions",(e,t)=>zm(e,t),"get subscription recurring billing details"),{name:"create_subscription",description:`
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
- interval: "WEEKLY", "MONTHLY", "QUARTERLY", "YEARLY"
|
|
787
|
-
- reference is REQUIRED (API rejects without it)
|
|
788
|
-
Dynamic strings for reference/line item name/notes: {{Day}}, {{Date}}, {{Date+X}}, {{DateRange:X}}, {{Month}}, {{Month+X}}, {{MonthRange:X}}, {{Year}}, {{Year+X}} \u2014 replaced with values relative to the transaction date (e.g., {{Month}} \u2192 "March", {{Date+7}} \u2192 "16 Mar 2026").`,params:{interval:{type:"string",enum:["WEEKLY","MONTHLY","QUARTERLY","YEARLY"],description:"Billing interval"},startDate:{type:"string",description:"Start date (YYYY-MM-DD)"},endDate:{type:"string",description:"End date (YYYY-MM-DD, optional for ongoing)"},contactResourceId:{type:"string",description:"Customer contact resourceId"},reference:{type:"string",description:"Invoice reference (REQUIRED). Supports dynamic strings: {{Month}}, {{Year}}, etc."},valueDate:{type:"string",description:"Invoice date (YYYY-MM-DD)"},dueDate:{type:"string",description:"Due date (YYYY-MM-DD)"},accountResourceId:{type:"string",description:"Revenue account resourceId (applied to ALL line items \u2014 must be same)"},taxProfileResourceId:{type:"string",description:"Tax profile resourceId (applied to ALL line items \u2014 must be same)"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string"},unitPrice:{type:"number"},quantity:{type:"number"}},required:["name","unitPrice","quantity"]},description:"Line items (name, unitPrice, quantity only \u2014 account/tax set at top level)"}},required:["interval","startDate","contactResourceId","lineItems","accountResourceId","valueDate","dueDate","reference"],group:"subscriptions",readOnly:!1,searchHint:"create new recurring subscription billing schedule",execute:async(e,t)=>{let{interval:r,startDate:n,endDate:o,contactResourceId:i,reference:s,valueDate:a,dueDate:c,accountResourceId:u,taxProfileResourceId:l,lineItems:d}=t,f=d.map(m=>({...m,accountResourceId:u,...l?{taxProfileResourceId:l}:{}})),p={repeat:r,startDate:n,status:"ACTIVE",proratedConfig:{proratedAdjustmentLineText:"Prorated adjustment"},invoice:{contactResourceId:i,reference:s||`SUB-${Date.now()}`,valueDate:a,dueDate:c,lineItems:f,saveAsDraft:!1}};return o&&(p.endDate=o),HS(e.client,p)}},{name:"update_subscription",description:"Update an existing subscription (interval, end date, or transaction template). When the user asks to update a subscription, use this tool directly. NOTE: accountResourceId and taxProfileResourceId on line items are immutable after creation \u2014 to change them, cancel and recreate.",params:{resourceId:{type:"string",description:"Subscription resourceId"},interval:{type:"string",enum:["WEEKLY","MONTHLY","QUARTERLY","YEARLY"]},endDate:{type:"string",description:"New end date (YYYY-MM-DD)"},data:{type:"object",description:"Updated transaction template"}},required:["resourceId"],group:"subscriptions",readOnly:!1,searchHint:"update subscription schedule amount details",execute:async(e,t)=>{let{resourceId:r,...n}=t;return WS(e.client,r,n)}},ln("delete_subscription","Delete a subscription. Removes the recurring schedule.","subscriptions",(e,t)=>ZS(e,t),"permanently delete a subscription schedule"),{name:"cancel_subscription",description:"Cancel an active subscription. Prorates remaining period and stops future billing. Safe to call \u2014 subscriptions can be reactivated after cancellation. Always use this tool when the user asks to cancel a subscription. Must cancel before delete.",params:{resourceId:{type:"string",description:"Subscription resourceId"},cancelDateType:{type:"string",enum:["END_OF_CURRENT_PERIOD","END_OF_LAST_PERIOD","CUSTOM_DATE"],description:"When to end (default: END_OF_CURRENT_PERIOD)"},endDate:{type:"string",description:"Custom cancel date YYYY-MM-DD (only with CUSTOM_DATE)"},proratedAdjustmentLineText:{type:"string",description:'Label for proration line item (default: "Prorated adjustment")'}},required:["resourceId"],group:"subscriptions",readOnly:!1,searchHint:"cancel stop a recurring subscription",isDestructive:!0,execute:async(e,t)=>KS(e.client,t.resourceId,{cancelDateType:t.cancelDateType,endDate:t.endDate,proratedAdjustmentLineText:t.proratedAdjustmentLineText})},Rt({name:"search_scheduled_transactions",description:"Search scheduled transactions (subscriptions, recurring). Filter by type, status, interval, contact.",group:"subscriptions",fields:Zp,defaults:Kp,fetcher:XS,searchHint:"find scheduled recurring transactions by type status"}),{name:"generate_vat_ledger",description:"Generate VAT/GST ledger report showing all tax transactions for the period.",params:{startDate:{type:"string",description:"Start date (YYYY-MM-DD)"},endDate:{type:"string",description:"End date (YYYY-MM-DD)"}},required:["startDate","endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate VAT GST tax ledger report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>m0(e.client,{startDate:t.startDate,endDate:t.endDate})},{name:"generate_equity_movement",description:"Generate equity movement report (statement of changes in equity).",params:{primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},currencyCode:{type:"string",description:'Currency code (e.g., "SGD")'},compareWith:{type:"string",description:'Compare with period (e.g., "PREVIOUS_YEAR")'},compareCount:{type:"number",description:"Number of comparison periods"}},required:["primarySnapshotStartDate","primarySnapshotEndDate"],group:"financial_reports",readOnly:!0,searchHint:"generate equity movement statement report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>h0(e.client,t)},{name:"generate_bank_balance_summary",description:"Generate bank balance summary report \u2014 snapshot of all bank account balances at a point in time.",params:{primarySnapshotDate:{type:"string",description:"Snapshot date (YYYY-MM-DD)"},currencyCode:{type:"string",description:'Currency code (e.g., "SGD")'}},required:["primarySnapshotDate"],group:"operational_reports",readOnly:!0,searchHint:"generate bank account balance summary report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>g0(e.client,{primarySnapshotDate:t.primarySnapshotDate,currencyCode:t.currencyCode})},{name:"generate_bank_recon_summary",description:"Generate bank reconciliation summary for a specific bank account. Essential for month-end close \u2014 call this for each in-scope bank account for the current entity and reporting period. Use for bank recon status, unreconciled items count, or reconciliation summaries.",params:{bankAccountResourceId:{type:"string",description:"Bank account resourceId"},primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},currencyCode:{type:"string",description:"Currency code"},tags:{type:"array",items:{type:"string"},description:"Filter by tags"}},required:["bankAccountResourceId","primarySnapshotStartDate","primarySnapshotEndDate"],group:"operational_reports",readOnly:!0,searchHint:"generate bank reconciliation summary report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>y0(e.client,t)},{name:"generate_bank_recon_details",description:"Generate detailed bank reconciliation report showing matched/unmatched items.",params:{bankAccountResourceId:{type:"string",description:"Bank account resourceId"},primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},filter:{type:"object",description:'Filter criteria (e.g., { status: "UNMATCHED" })'},currencyCode:{type:"string",description:"Currency code"}},required:["bankAccountResourceId","primarySnapshotStartDate","primarySnapshotEndDate","filter"],group:"operational_reports",readOnly:!0,searchHint:"generate bank reconciliation detailed report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>D0(e.client,t)},{name:"generate_fa_summary",description:"Generate fixed assets summary report grouped by account, type, category, or status.",params:{primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},groupBy:{type:"string",enum:["ACCOUNT","TYPE","CATEGORY","STATUS"],description:"Grouping dimension"},currencyCode:{type:"string",description:"Currency code"}},required:["primarySnapshotStartDate","primarySnapshotEndDate","groupBy"],group:"operational_reports",readOnly:!0,searchHint:"generate fixed asset summary depreciation report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>b0(e.client,t)},{name:"generate_fa_recon_summary",description:"Generate fixed assets reconciliation summary \u2014 reconciles asset register with general ledger.",params:{primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},accountResourceIds:{type:"array",items:{type:"string"},description:"Filter by specific asset account IDs"},currencyCode:{type:"string",description:"Currency code"}},required:["primarySnapshotStartDate","primarySnapshotEndDate"],group:"operational_reports",readOnly:!0,searchHint:"generate fixed asset reconciliation report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>v0(e.client,t)},{name:"generate_ar_report",description:"Generate accounts receivable aging report. Shows outstanding invoices grouped by aging buckets. Use this when discussing customer payment allocation, credit control, or AR status \u2014 generate the report to show the full picture.",params:{endDate:{type:"string",description:"Report date (YYYY-MM-DD) \u2014 point-in-time snapshot"}},required:["endDate"],group:"operational_reports",readOnly:!0,searchHint:"generate detailed accounts receivable report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>S0(e.client,{endDate:t.endDate})},{name:"get_ledger_highlights",description:"Get ledger highlights \u2014 summary metadata about the org general ledger: transaction counts by type, date range, active accounts, active currencies, and cross-currency detection. No parameters needed.",params:{},required:[],group:"operational_reports",readOnly:!0,searchHint:"get ledger highlights key metrics for period",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async e=>_0(e.client)},gt("list_contact_groups","List contact groups with their associated contacts. Used to segment customers/suppliers.","contact_groups",(e,t,r)=>QS(e,{limit:r,offset:t}),"list contact groups customer supplier categories"),Yn("get_contact_group","Get contact group details including all associated contacts.","contact_groups",(e,t)=>e_(e,t),"get contact group details members"),Rt({name:"search_contact_groups",description:"Search contact groups by name.",group:"contact_groups",fields:df,defaults:pf,fetcher:t_,searchHint:"find contact groups by name category"}),{name:"create_contact_group",description:'Create a new contact group for segmenting contacts (e.g., "VIP Customers", "Government", "Overdue > 90 Days").',params:{name:{type:"string",description:"Group name"},contactResourceIds:{type:"array",items:{type:"string"},description:"Contact IDs to add to the group"}},required:["name"],group:"contact_groups",readOnly:!1,searchHint:"create new contact group category",execute:async(e,t)=>r_(e.client,{name:t.name,contactResourceIds:t.contactResourceIds})},{name:"update_contact_group",description:"Update a contact group name or members. NOTE: Update endpoint has a known 500 bug on some orgs \u2014 retry or recreate if it fails.",params:{resourceId:{type:"string",description:"Contact group resourceId"},name:{type:"string",description:"New group name"},contactResourceIds:{type:"array",items:{type:"string"},description:"Contact IDs to set as group members (replaces existing)"}},required:["resourceId"],group:"contact_groups",readOnly:!1,searchHint:"update contact group name details",execute:async(e,t)=>n_(e.client,t.resourceId,{name:t.name,contactResourceIds:t.contactResourceIds})},ln("delete_contact_group","Delete a contact group. Does not delete the contacts themselves.","contact_groups",(e,t)=>o_(e,t),"permanently delete a contact group"),gt("list_custom_fields","List custom fields defined for the organization. Custom fields add extra data to invoices, bills, credit notes, and payments.","custom_fields",(e,t,r)=>c_(e,{limit:r,offset:t}),"list custom fields metadata on transactions"),{name:"get_custom_field",description:"Get a custom field by resourceId. Returns full definition including appliesTo flags and list options.",params:{resourceId:{type:"string",description:"Custom field resourceId"}},required:["resourceId"],group:"custom_fields",readOnly:!0,searchHint:"get custom field definition details",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>u_(e.client,t.resourceId)},Rt({name:"search_custom_fields",description:"Search custom fields by name or data type.",group:"custom_fields",fields:uf,defaults:lf,fetcher:l_,searchHint:"find custom fields by name data type"}),{name:"create_custom_field",description:`Create a new custom field. Custom fields appear on transactions (invoices, bills, credit notes, payments).
|
|
762
|
+
- All depreciation/account fields same as create_fixed_asset`,params:{name:{type:"string",description:"Asset name"},reference:{type:"string",description:"Asset reference (e.g., FA-000001)"},category:{type:"string",enum:["TANGIBLE","INTANGIBLE"],description:"Asset category"},typeName:{type:"string",description:'Asset type (e.g., "Computers and Electronics", "Furniture and Fixtures")'},typeCode:{type:"string",description:"Asset type code (e.g., COMPUTER_AND_ELECTRONIC, FURNITURE_AND_FIXTURE)"},purchaseAmount:{type:"number",description:"Original purchase cost"},purchaseDate:{type:"string",description:"Original purchase date (YYYY-MM-DD)"},purchaseAssetAccountResourceId:{type:"string",description:"Asset account resourceId"},depreciationMethod:{type:"string",enum:["STRAIGHT_LINE","NO_DEPRECIATION"],description:"Depreciation method"},depreciationStartDate:{type:"string",description:"Depreciation start date (YYYY-MM-DD)"},effectiveLife:{type:"number",description:"Useful life in months"},bookValueAccumulatedDepreciationAmount:{type:"number",description:"Depreciation already accumulated before registration"},depreciableValueResidualAmount:{type:"number",description:"Residual/salvage value"},depreciableValueCostLimitAmount:{type:"number",description:"Cost limit amount"},accumulatedDepreciationAccountResourceId:{type:"string",description:"Accumulated depreciation account resourceId"},depreciationExpenseAccountResourceId:{type:"string",description:"Depreciation expense account resourceId"},internalNotes:{type:"string",description:"Internal notes"},saveAsDraft:{type:"boolean",description:"Save as draft (default true). False = activate immediately."},customFields:un},required:["name","purchaseAmount","purchaseDate","purchaseAssetAccountResourceId","depreciationStartDate"],group:"fixed_assets",readOnly:!1,searchHint:"transfer fixed asset between accounts categories",execute:async(e,t)=>YS(e.client,t)},{name:"undo_fixed_asset_disposal",description:"Undo a fixed asset disposal (discard or sale). Restores the asset to active status. When the user asks to reverse or undo a disposal, use this tool directly.",params:{resourceId:{type:"string",description:"Fixed asset resourceId"}},required:["resourceId"],group:"fixed_assets",readOnly:!1,searchHint:"undo reversal of fixed asset disposal",execute:async(e,t)=>JS(e.client,t.resourceId)},gt("list_subscriptions","List recurring subscriptions. Returns status, interval, next schedule date, amount, transaction type.","subscriptions",(e,t,r)=>VS(e,{limit:r,offset:t}),"list recurring subscriptions billing schedules"),Yn("get_subscription","Get full subscription details including line items, schedule, and payment history.","subscriptions",(e,t)=>zm(e,t),"get subscription recurring billing details"),{name:"create_subscription",description:`Subscription \u2014 auto-generates invoices on schedule WITH proration. DIFFERENT from scheduled_invoice: subscriptions prorate partial periods (credit notes for mid-period changes), but currency/tax/account are immutable after creation. Use for software licenses, retainers, recurring SaaS. Invoices only (no bills).
|
|
763
|
+
|
|
764
|
+
accountResourceId + taxProfileResourceId apply to ALL line items (immutable). interval: WEEKLY | MONTHLY | QUARTERLY | YEARLY. reference REQUIRED.
|
|
765
|
+
|
|
766
|
+
Dynamic strings (reference/lineItem name/notes): {{Day}}, {{Date}}, {{Date+X}}, {{DateRange:X}}, {{Month}}, {{Month+X}}, {{MonthRange:X}}, {{Year}}, {{Year+X}} \u2014 relative to transaction date.`,params:{interval:{type:"string",enum:["WEEKLY","MONTHLY","QUARTERLY","YEARLY"],description:"Billing interval"},startDate:{type:"string",description:"Start date (YYYY-MM-DD)"},endDate:{type:"string",description:"End date (YYYY-MM-DD, optional for ongoing)"},contactResourceId:{type:"string",description:"Customer contact resourceId"},reference:{type:"string",description:"Invoice reference (REQUIRED). Supports dynamic strings: {{Month}}, {{Year}}, etc."},valueDate:{type:"string",description:"Invoice date (YYYY-MM-DD)"},dueDate:{type:"string",description:"Due date (YYYY-MM-DD)"},accountResourceId:{type:"string",description:"Revenue account resourceId (applied to ALL line items \u2014 must be same)"},taxProfileResourceId:{type:"string",description:"Tax profile resourceId (applied to ALL line items \u2014 must be same)"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string"},unitPrice:{type:"number"},quantity:{type:"number"}},required:["name","unitPrice","quantity"]},description:"Line items (name, unitPrice, quantity only \u2014 account/tax set at top level)"}},required:["interval","startDate","contactResourceId","lineItems","accountResourceId","valueDate","dueDate","reference"],group:"subscriptions",readOnly:!1,searchHint:"create new recurring subscription billing schedule",execute:async(e,t)=>{let{interval:r,startDate:n,endDate:o,contactResourceId:i,reference:s,valueDate:a,dueDate:c,accountResourceId:u,taxProfileResourceId:l,lineItems:d}=t,f=d.map(m=>({...m,accountResourceId:u,...l?{taxProfileResourceId:l}:{}})),p={repeat:r,startDate:n,status:"ACTIVE",proratedConfig:{proratedAdjustmentLineText:"Prorated adjustment"},invoice:{contactResourceId:i,reference:s||`SUB-${Date.now()}`,valueDate:a,dueDate:c,lineItems:f,saveAsDraft:!1}};return o&&(p.endDate=o),HS(e.client,p)}},{name:"update_subscription",description:"Update an existing subscription (interval, end date, or transaction template). When the user asks to update a subscription, use this tool directly. NOTE: accountResourceId and taxProfileResourceId on line items are immutable after creation \u2014 to change them, cancel and recreate.",params:{resourceId:{type:"string",description:"Subscription resourceId"},interval:{type:"string",enum:["WEEKLY","MONTHLY","QUARTERLY","YEARLY"]},endDate:{type:"string",description:"New end date (YYYY-MM-DD)"},data:{type:"object",description:"Updated transaction template"}},required:["resourceId"],group:"subscriptions",readOnly:!1,searchHint:"update subscription schedule amount details",execute:async(e,t)=>{let{resourceId:r,...n}=t;return WS(e.client,r,n)}},ln("delete_subscription","Delete a subscription. Removes the recurring schedule.","subscriptions",(e,t)=>ZS(e,t),"permanently delete a subscription schedule"),{name:"cancel_subscription",description:"Cancel an active subscription. Prorates remaining period and stops future billing. Safe to call \u2014 subscriptions can be reactivated after cancellation. Always use this tool when the user asks to cancel a subscription. Must cancel before delete.",params:{resourceId:{type:"string",description:"Subscription resourceId"},cancelDateType:{type:"string",enum:["END_OF_CURRENT_PERIOD","END_OF_LAST_PERIOD","CUSTOM_DATE"],description:"When to end (default: END_OF_CURRENT_PERIOD)"},endDate:{type:"string",description:"Custom cancel date YYYY-MM-DD (only with CUSTOM_DATE)"},proratedAdjustmentLineText:{type:"string",description:'Label for proration line item (default: "Prorated adjustment")'}},required:["resourceId"],group:"subscriptions",readOnly:!1,searchHint:"cancel stop a recurring subscription",isDestructive:!0,execute:async(e,t)=>KS(e.client,t.resourceId,{cancelDateType:t.cancelDateType,endDate:t.endDate,proratedAdjustmentLineText:t.proratedAdjustmentLineText})},Rt({name:"search_scheduled_transactions",description:"Search scheduled transactions (subscriptions, recurring). Filter by type, status, interval, contact.",group:"subscriptions",fields:Zp,defaults:Kp,fetcher:XS,searchHint:"find scheduled recurring transactions by type status"}),{name:"generate_vat_ledger",description:"Generate VAT/GST ledger report showing all tax transactions for the period.",params:{startDate:{type:"string",description:"Start date (YYYY-MM-DD)"},endDate:{type:"string",description:"End date (YYYY-MM-DD)"}},required:["startDate","endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate VAT GST tax ledger report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>m0(e.client,{startDate:t.startDate,endDate:t.endDate})},{name:"generate_equity_movement",description:"Generate equity movement report (statement of changes in equity).",params:{primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},currencyCode:{type:"string",description:'Currency code (e.g., "SGD")'},compareWith:{type:"string",description:'Compare with period (e.g., "PREVIOUS_YEAR")'},compareCount:{type:"number",description:"Number of comparison periods"}},required:["primarySnapshotStartDate","primarySnapshotEndDate"],group:"financial_reports",readOnly:!0,searchHint:"generate equity movement statement report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>h0(e.client,t)},{name:"generate_bank_balance_summary",description:"Generate bank balance summary report \u2014 snapshot of all bank account balances at a point in time.",params:{primarySnapshotDate:{type:"string",description:"Snapshot date (YYYY-MM-DD)"},currencyCode:{type:"string",description:'Currency code (e.g., "SGD")'}},required:["primarySnapshotDate"],group:"operational_reports",readOnly:!0,searchHint:"generate bank account balance summary report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>g0(e.client,{primarySnapshotDate:t.primarySnapshotDate,currencyCode:t.currencyCode})},{name:"generate_bank_recon_summary",description:"Generate bank reconciliation summary for a specific bank account. Essential for month-end close \u2014 call this for each in-scope bank account for the current entity and reporting period. Use for bank recon status, unreconciled items count, or reconciliation summaries.",params:{bankAccountResourceId:{type:"string",description:"Bank account resourceId"},primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},currencyCode:{type:"string",description:"Currency code"},tags:{type:"array",items:{type:"string"},description:"Filter by tags"}},required:["bankAccountResourceId","primarySnapshotStartDate","primarySnapshotEndDate"],group:"operational_reports",readOnly:!0,searchHint:"generate bank reconciliation summary report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>y0(e.client,t)},{name:"generate_bank_recon_details",description:"Generate detailed bank reconciliation report showing matched/unmatched items.",params:{bankAccountResourceId:{type:"string",description:"Bank account resourceId"},primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},filter:{type:"object",description:'Filter criteria (e.g., { status: "UNMATCHED" })'},currencyCode:{type:"string",description:"Currency code"}},required:["bankAccountResourceId","primarySnapshotStartDate","primarySnapshotEndDate","filter"],group:"operational_reports",readOnly:!0,searchHint:"generate bank reconciliation detailed report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>D0(e.client,t)},{name:"generate_fa_summary",description:"Generate fixed assets summary report grouped by account, type, category, or status.",params:{primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},groupBy:{type:"string",enum:["ACCOUNT","TYPE","CATEGORY","STATUS"],description:"Grouping dimension"},currencyCode:{type:"string",description:"Currency code"}},required:["primarySnapshotStartDate","primarySnapshotEndDate","groupBy"],group:"operational_reports",readOnly:!0,searchHint:"generate fixed asset summary depreciation report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>b0(e.client,t)},{name:"generate_fa_recon_summary",description:"Generate fixed assets reconciliation summary \u2014 reconciles asset register with general ledger.",params:{primarySnapshotStartDate:{type:"string",description:"Period start date (YYYY-MM-DD)"},primarySnapshotEndDate:{type:"string",description:"Period end date (YYYY-MM-DD)"},accountResourceIds:{type:"array",items:{type:"string"},description:"Filter by specific asset account IDs"},currencyCode:{type:"string",description:"Currency code"}},required:["primarySnapshotStartDate","primarySnapshotEndDate"],group:"operational_reports",readOnly:!0,searchHint:"generate fixed asset reconciliation report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>v0(e.client,t)},{name:"generate_ar_report",description:"Generate accounts receivable aging report. Shows outstanding invoices grouped by aging buckets. Use this when discussing customer payment allocation, credit control, or AR status \u2014 generate the report to show the full picture.",params:{endDate:{type:"string",description:"Report date (YYYY-MM-DD) \u2014 point-in-time snapshot"}},required:["endDate"],group:"operational_reports",readOnly:!0,searchHint:"generate detailed accounts receivable report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>S0(e.client,{endDate:t.endDate})},{name:"get_ledger_highlights",description:"Get ledger highlights \u2014 summary metadata about the org general ledger: transaction counts by type, date range, active accounts, active currencies, and cross-currency detection. No parameters needed.",params:{},required:[],group:"operational_reports",readOnly:!0,searchHint:"get ledger highlights key metrics for period",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async e=>_0(e.client)},gt("list_contact_groups","List contact groups with their associated contacts. Used to segment customers/suppliers.","contact_groups",(e,t,r)=>QS(e,{limit:r,offset:t}),"list contact groups customer supplier categories"),Yn("get_contact_group","Get contact group details including all associated contacts.","contact_groups",(e,t)=>e_(e,t),"get contact group details members"),Rt({name:"search_contact_groups",description:"Search contact groups by name.",group:"contact_groups",fields:df,defaults:pf,fetcher:t_,searchHint:"find contact groups by name category"}),{name:"create_contact_group",description:'Create a new contact group for segmenting contacts (e.g., "VIP Customers", "Government", "Overdue > 90 Days").',params:{name:{type:"string",description:"Group name"},contactResourceIds:{type:"array",items:{type:"string"},description:"Contact IDs to add to the group"}},required:["name"],group:"contact_groups",readOnly:!1,searchHint:"create new contact group category",execute:async(e,t)=>r_(e.client,{name:t.name,contactResourceIds:t.contactResourceIds})},{name:"update_contact_group",description:"Update a contact group name or members. NOTE: Update endpoint has a known 500 bug on some orgs \u2014 retry or recreate if it fails.",params:{resourceId:{type:"string",description:"Contact group resourceId"},name:{type:"string",description:"New group name"},contactResourceIds:{type:"array",items:{type:"string"},description:"Contact IDs to set as group members (replaces existing)"}},required:["resourceId"],group:"contact_groups",readOnly:!1,searchHint:"update contact group name details",execute:async(e,t)=>n_(e.client,t.resourceId,{name:t.name,contactResourceIds:t.contactResourceIds})},ln("delete_contact_group","Delete a contact group. Does not delete the contacts themselves.","contact_groups",(e,t)=>o_(e,t),"permanently delete a contact group"),gt("list_custom_fields","List custom fields defined for the organization. Custom fields add extra data to invoices, bills, credit notes, and payments.","custom_fields",(e,t,r)=>c_(e,{limit:r,offset:t}),"list custom fields metadata on transactions"),{name:"get_custom_field",description:"Get a custom field by resourceId. Returns full definition including appliesTo flags and list options.",params:{resourceId:{type:"string",description:"Custom field resourceId"}},required:["resourceId"],group:"custom_fields",readOnly:!0,searchHint:"get custom field definition details",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>u_(e.client,t.resourceId)},Rt({name:"search_custom_fields",description:"Search custom fields by name or data type.",group:"custom_fields",fields:uf,defaults:lf,fetcher:l_,searchHint:"find custom fields by name data type"}),{name:"create_custom_field",description:`Create a new custom field. Custom fields appear on transactions (invoices, bills, credit notes, payments).
|
|
789
767
|
- Use appliesTo to control which transaction types show this field.
|
|
790
768
|
- printOnDocuments controls whether the field appears on PDFs.`,params:{name:{type:"string",description:'Field name (e.g., "PO Number", "Cost Center")'},description:{type:"string",description:"Field description"},printOnDocuments:{type:"boolean",description:"Show on PDF documents (default false)"},appliesTo:{type:"object",description:"Which transaction types: { invoices: true, bills: true, customerCredits: true, supplierCredits: true, payments: true }"},fieldType:{type:"string",description:'Field type (e.g., "TEXT", "NUMBER", "DATE") \u2014 legacy param'},entityType:{type:"string",description:"Entity type \u2014 legacy param"}},required:["name"],group:"custom_fields",readOnly:!1,searchHint:"create new custom field for transactions",execute:async(e,t)=>d_(e.client,t)},{name:"update_custom_field",description:"Update a custom field definition. Can change name, description, printOnDocuments, and appliesTo flags.",params:{resourceId:{type:"string",description:"Custom field resourceId"},name:{type:"string",description:"New field name"},description:{type:"string",description:"New description"},printOnDocuments:{type:"boolean",description:"Show on PDF documents"},appliesTo:{type:"object",description:"Which transaction types: { invoices, bills, customerCredits, supplierCredits, payments }"}},required:["resourceId"],group:"custom_fields",readOnly:!1,searchHint:"update custom field name type settings",execute:async(e,t)=>{let{resourceId:r,...n}=t;return p_(e.client,r,n)}},ln("delete_custom_field","Delete a custom field. Removes it from all future transactions.","custom_fields",(e,t)=>f_(e,t),"permanently delete a custom field definition"),{name:"list_withholding_tax_codes",description:"List withholding tax codes (industry classification codes for PH/SG compliance). Returns full list (no pagination).",params:{},required:[],group:"tax_profiles",readOnly:!0,searchHint:"list withholding tax WHT codes",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>eb(e.client)},Rt({name:"search_tax_profiles",description:"Search tax profiles by name, tax type code, applicability (sale/purchase). Filter appliesToSale/appliesToPurchase to scope by transaction type.",group:"tax_profiles",fields:of,defaults:sf,fetcher:pu,searchHint:"find tax profiles by name type applicability"}),Yn("get_tax_profile","Get full tax profile details including tax rate, type code, and status.","tax_profiles",(e,t)=>XD(e,t),"get tax profile details rate code"),{name:"update_tax_profile",description:"Update an existing tax profile (name, rate, or status).",params:{resourceId:{type:"string",description:"Tax profile resourceId"},name:sR,taxRate:{type:"number"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Status (ACTIVE or INACTIVE)"}},required:["resourceId"],group:"tax_profiles",readOnly:!1,searchHint:"update tax profile name rate details",execute:async(e,t)=>QD(e.client,t.resourceId,{name:t.name,taxRate:t.taxRate,status:t.status})},gt("list_inventory_items","List inventory-tracked items with stock details, COGS accounts, and purchase/sale accounts.","inventory",(e,t,r)=>i_(e,{limit:r,offset:t}),"list inventory items stock levels quantities"),{name:"get_inventory_balance",description:"Get current inventory balance for a specific item \u2014 quantity on hand, average cost, base unit.",params:{itemResourceId:{type:"string",description:"Item resourceId"}},required:["itemResourceId"],group:"inventory",readOnly:!0,searchHint:"get inventory balance stock level for item",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>a_(e.client,t.itemResourceId)},{name:"create_inventory_item",description:"Create a new inventory-tracked item. Requires itemCode, name, costingMethod (FIXED or WAC), cogsResourceId, and account links. Use --input for full JSON body.",params:{itemCode:{type:"string",description:"Unique item code (SKU)"},name:{type:"string",description:"Item name"},unit:{type:"string",description:'Unit of measure (e.g., "pcs", "kg")'},costingMethod:{type:"string",description:"Costing method: FIXED or WAC"},cogsResourceId:{type:"string",description:"COGS account resourceId (required)"},purchaseAccountResourceId:{type:"string",description:"Purchase account resourceId (required if cogsResourceId set)"},saleAccountResourceId:{type:"string",description:"Sale account resourceId (required if cogsResourceId set)"},appliesToSale:{type:"boolean",description:"Whether item applies to sales (required if cogsResourceId set)"},appliesToPurchase:{type:"boolean",description:"Whether item applies to purchases (required if cogsResourceId set)"},blockInsufficientDeductions:{type:"boolean",description:"Block transactions when insufficient stock (default: false)"}},required:["itemCode","name","costingMethod","cogsResourceId"],group:"inventory",readOnly:!1,searchHint:"create new inventory tracked stock item",execute:async(e,t)=>{let r={itemCode:t.itemCode,name:t.name,costingMethod:t.costingMethod,cogsResourceId:t.cogsResourceId,blockInsufficientDeductions:t.blockInsufficientDeductions??!1};return t.unit&&(r.unit=t.unit),t.purchaseAccountResourceId&&(r.purchaseAccountResourceId=t.purchaseAccountResourceId),t.saleAccountResourceId&&(r.saleAccountResourceId=t.saleAccountResourceId),t.appliesToSale!==void 0&&(r.appliesToSale=t.appliesToSale),t.appliesToPurchase!==void 0&&(r.appliesToPurchase=t.appliesToPurchase),s_(e.client,r)}},ln("delete_contact","Delete a contact. Cannot delete contacts with existing transactions.","contacts",(e,t)=>Ry(e,t),"permanently delete a customer supplier contact"),ln("delete_account","Delete a chart of accounts entry. Cannot delete accounts with existing transactions.","accounts",(e,t)=>db(e,t),"permanently delete a chart of accounts entry"),Yn("get_cash_transfer","Get full cash transfer details by resourceId.","cash_transfers",(e,t)=>t0(e,t),"get cash transfer details between accounts"),{name:"download_credit_note_pdf",description:"Download a customer credit note as PDF. Returns a file URL.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"}},required:["resourceId"],group:"customer_credit_notes",readOnly:!0,searchHint:"download customer credit note as PDF file",isConcurrencySafe:!0,execute:async(e,t)=>w0(e.client,t.resourceId)},{name:"get_transaction_summary",description:`Get a complete summary of any transaction \u2014 fetches the transaction, its attachments, and payment history in one call.
|
|
791
769
|
Works for invoices, bills, customer credit notes, supplier credit notes, and journals.`,params:{transactionType:{type:"string",enum:["invoice","bill","customer_credit_note","supplier_credit_note","journal"],description:"Transaction type"},resourceId:{type:"string",description:"Transaction resourceId"}},required:["transactionType","resourceId"],group:"search",readOnly:!0,searchHint:"get aggregated transaction counts totals by status",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=t.transactionType,n=t.resourceId,o=r==="invoice"?io(e.client,n):r==="bill"?to(e.client,n):r==="customer_credit_note"?$o(e.client,n):r==="supplier_credit_note"?No(e.client,n):ri(e.client,n),i=r==="invoice"?"invoices":r==="bill"?"bills":r==="customer_credit_note"?"customer-credit-notes":r==="supplier_credit_note"?"supplier-credit-notes":"journals",[s,a]=await Promise.all([o,Mt(e.client,i,n)]),c;if(r==="invoice"||r==="bill")try{c=await xf(e.client,{filter:{businessTransactionResourceId:{eq:n}},limit:100})}catch{}let u=a.data??[];return{transaction:s.data,attachments:u,attachmentCount:u.length,...c?{payments:c.data,paymentCount:c.totalElements}:{}}}},{name:"bulk_finalize_drafts",description:"Finalize multiple draft transactions in one call. Attempts finalization for each item and returns per-item pass/fail results. Supports invoices, bills, and credit notes.",params:{items:{type:"array",items:{type:"object",properties:{type:{type:"string",enum:["invoice","bill","customer_credit_note","supplier_credit_note"],description:"Transaction type"},resourceId:{type:"string",description:"Transaction resourceId"}},required:["type","resourceId"]},description:"Array of {type, resourceId} to finalize"}},required:["items"],group:"drafts",readOnly:!1,searchHint:"bulk finalize approve multiple draft transactions",isDestructive:!0,execute:async(e,t)=>{let r=t.items,n=[];for(let o of r)try{let i=await Km(e.client,o.type,o.resourceId,{});o.type==="invoice"?await Sf(e.client,o.resourceId,i):o.type==="bill"?await vd(e.client,o.resourceId,i):o.type==="customer_credit_note"?await Tf(e.client,o.resourceId,i):o.type==="supplier_credit_note"&&await Nf(e.client,o.resourceId,i),n.push({...o,success:!0})}catch(i){n.push({...o,success:!1,error:i instanceof Error?i.message:String(i)})}return{total:r.length,succeeded:n.filter(o=>o.success).length,failed:n.filter(o=>!o.success).length,results:n}}},{name:"bulk_invite_org_users",description:`Invite multiple users to the organization in one call. Accepts an array of user objects.
|
|
792
770
|
Each user needs: email, firstName, lastName, moduleRoles. Returns per-user pass/fail results.`,params:{users:{type:"array",items:{type:"object",properties:{email:{type:"string",description:"User email"},firstName:{type:"string",description:"First name"},lastName:{type:"string",description:"Last name"},moduleRoles:{type:"array",items:{type:"object",properties:{moduleName:{type:"string"},roleCode:{type:"string"}}},description:"Module roles to assign"}},required:["email","firstName","lastName"]},description:"Array of users to invite"}},required:["users"],group:"org_users",readOnly:!1,searchHint:"bulk invite multiple users to organization",execute:async(e,t)=>{let r=t.users,n=[];for(let o of r)try{let i=await Nu(e.client,{...o,moduleRoles:o.moduleRoles??[]});n.push({email:o.email,success:!0,resourceId:i.data?.resourceId})}catch(i){n.push({email:o.email,success:!1,error:i instanceof Error?i.message:String(i)})}return{total:r.length,succeeded:n.filter(o=>o.success).length,failed:n.filter(o=>!o.success).length,results:n}}},{name:"bulk_create_contacts",description:`Create multiple contacts in one call. Deduplicates against existing contacts (exact name match).
|
|
793
|
-
Returns per-contact result: created, skipped (duplicate), or failed.`,params:{contacts:{type:"array",items:{type:"object",properties:{billingName:{type:"string",description:"Official billing name"},name:{type:"string",description:"Display name"},email:{type:"string",description:"Primary email"},customer:{type:"boolean",description:"Is a customer"},supplier:{type:"boolean",description:"Is a supplier"}},required:["billingName"]},description:"Array of contacts to create"},skipDuplicates:{type:"boolean",description:"Skip contacts that match existing names (default true)"}},required:["contacts"],group:"contacts",readOnly:!1,searchHint:"bulk create multiple customer supplier contacts",execute:async(e,t)=>{let r=t.contacts,n=t.skipDuplicates??!0,o=[];for(let i of r)try{if(n){let a=await hp(e.client,i.name??i.billingName);if(a){o.push({billingName:i.billingName,status:"skipped",resourceId:a.resourceId});continue}}let s=await Yc(e.client,{billingName:i.billingName,name:i.name??i.billingName,emails:i.email?[i.email]:void 0,customer:i.customer??!0,supplier:i.supplier??!1});o.push({billingName:i.billingName,status:"created",resourceId:s.data.resourceId})}catch(s){o.push({billingName:i.billingName,status:"failed",error:s instanceof Error?s.message:String(s)})}return{total:r.length,created:o.filter(i=>i.status==="created").length,skipped:o.filter(i=>i.status==="skipped").length,failed:o.filter(i=>i.status==="failed").length,results:o}}},{name:"quick_fix_transactions",description:`Bulk-update multiple transactions of the same type
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
Line item attributes by type:
|
|
811
|
-
|
|
812
|
-
-
|
|
813
|
-
|
|
814
|
-
-
|
|
815
|
-
|
|
816
|
-
Response: { updated: string[], failed: [{ resourceId, error, errorCode }] }. On partial failure (HTTP 207), check failed.length.`,params:{entity:{type:"string",enum:[...sl],description:"Transaction type"},lineItemResourceIds:{type:"array",items:{type:"string"},description:"Line item resourceIds to update (ARAP + accounting entities)"},attributes:{type:"object",description:"Fields to update on all specified line items"},schedulerUpdates:{type:"array",items:{type:"object"},description:"Per-scheduler updates: [{ schedulerResourceId, lineItemUpdates: [{ arrayIndex, ...fields }] }]. EXCEPTION: journal-schedules use lineItemResourceId (UUID) instead of arrayIndex."}},required:["entity"],group:"quick_fix",readOnly:!1,searchHint:"bulk update line item accounts tax profiles",execute:async(e,t)=>{let r=t.entity,n=["sale-schedules","purchase-schedules","subscription-schedules","journal-schedules"].includes(r),o={};if(n){if(!t.schedulerUpdates)throw new Error("schedulerUpdates is required for scheduler entities (sale-schedules, purchase-schedules, subscription-schedules, journal-schedules)");o.schedulerUpdates=t.schedulerUpdates}else{if(!t.lineItemResourceIds)throw new Error("lineItemResourceIds is required for non-scheduler entities");o.lineItemResourceIds=t.lineItemResourceIds,o.attributes=t.attributes??{}}return Jm(e.client,r,o)}},gt("list_nano_classifiers","List nano classifiers (tracking categories). Paginated. Nano classifiers tag line items with structured categories.","nano_classifiers",(e,t,r)=>m_(e,{limit:r,offset:t}),"list nano classifiers tracking categories types"),Yn("get_nano_classifier","Get a nano classifier by resourceId. Returns type and all classes.","nano_classifiers",(e,t)=>h_(e,t),"get nano classifier tracking category details"),Rt({name:"search_nano_classifiers",description:"Search nano classifiers (tracking categories) by type name.",group:"nano_classifiers",fields:yf,defaults:Df,fetcher:g_,searchHint:"find nano classifiers tracking categories by type"}),{name:"create_nano_classifier",description:"Create a nano classifier (tracking category). Provide a type name and list of class names. printable defaults to true (NOTE: printable: false is currently rejected by a server bug \u2014 always use true).",params:{type:{type:"string",description:'Classifier type name (e.g., "Department", "Project")'},classes:{type:"array",items:{type:"string"},description:'Class names: ["Sales", "Marketing", "Engineering"]'},printable:{type:"boolean",description:"Show on printed documents (default: true). NOTE: false is rejected by a server bug."}},required:["type","classes"],group:"nano_classifiers",readOnly:!1,searchHint:"create new nano classifier tracking category",execute:async(e,t)=>Gm(e.client,{type:t.type,classes:t.classes,printable:t.printable??!0})},{name:"update_nano_classifier",description:"Update a nano classifier \u2014 change type name, modify classes, or toggle printable.",params:{resourceId:{type:"string",description:"Nano classifier resourceId"},type:{type:"string",description:"New type name"},classes:{type:"array",items:{type:"string"},description:'Updated class names: ["Sales", "Marketing"]'},printable:{type:"boolean",description:"Show on printed documents"}},required:["resourceId"],group:"nano_classifiers",readOnly:!1,searchHint:"update nano classifier classes and settings",execute:async(e,t)=>{let r={};return t.type&&(r.type=t.type),t.classes&&(r.classes=t.classes),t.printable!==void 0&&(r.printable=t.printable),Vm(e.client,t.resourceId,r)}},ln("delete_nano_classifier","Delete a nano classifier.","nano_classifiers",(e,t)=>y_(e,t),"permanently delete a nano classifier type"),{name:"list_invoice_payments",description:"List all payments recorded against an invoice. Returns payment records with amounts, dates, and methods.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"payments",readOnly:!0,searchHint:"list payment records on an invoice",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>$b(e.client,t.resourceId)},{name:"list_invoice_credits",description:"List all credit notes applied to an invoice.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"payments",readOnly:!0,searchHint:"list credit applications on an invoice",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>Nb(e.client,t.resourceId)},{name:"reverse_invoice_credit",description:"Reverse (unapply) a credit note from an invoice. The credit note becomes UNAPPLIED again.",params:{resourceId:{type:"string",description:"Invoice resourceId"},creditResourceId:{type:"string",description:"Credit application resourceId to reverse"}},required:["resourceId","creditResourceId"],group:"payments",readOnly:!1,searchHint:"reverse a credit note application on invoice",isDestructive:!0,execute:async(e,t)=>(await kb(e.client,t.resourceId,t.creditResourceId),{reversed:!0,invoiceId:t.resourceId,creditId:t.creditResourceId})},{name:"list_bill_payments",description:"List all payments recorded against a bill. Returns payment records with amounts, dates, and methods.",params:{resourceId:{type:"string",description:"Bill resourceId"}},required:["resourceId"],group:"payments",readOnly:!0,searchHint:"list payment records on a bill",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>Cy(e.client,t.resourceId)},{name:"list_bill_credits",description:"List all credit notes applied to a bill.",params:{resourceId:{type:"string",description:"Bill resourceId"}},required:["resourceId"],group:"payments",readOnly:!0,searchHint:"list credit applications on a bill",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>xy(e.client,t.resourceId)},{name:"reverse_bill_credit",description:"Reverse (unapply) a supplier credit note from a bill. The credit note becomes UNAPPLIED again.",params:{resourceId:{type:"string",description:"Bill resourceId"},creditResourceId:{type:"string",description:"Credit application resourceId to reverse"}},required:["resourceId","creditResourceId"],group:"payments",readOnly:!1,searchHint:"reverse a credit note application on bill",isDestructive:!0,execute:async(e,t)=>(await Ay(e.client,t.resourceId,t.creditResourceId),{reversed:!0,billId:t.resourceId,creditId:t.creditResourceId})},Yn("get_scheduled_invoice","Get a scheduled (recurring) invoice by resourceId.","schedulers",(e,t)=>tv(e,t),"get scheduled recurring invoice details"),{name:"update_scheduled_invoice",description:"Update a scheduled invoice \u2014 change schedule settings and/or the invoice template.",params:{resourceId:{type:"string",description:"Scheduled invoice resourceId"},repeat:{type:"string",description:"Recurrence: WEEKLY, MONTHLY, QUARTERLY, YEARLY"},startDate:{type:"string",description:"First occurrence date (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence date (YYYY-MM-DD)"},status:{type:"string",description:"Status: ACTIVE or PAUSED"},invoice:{type:"object",description:"Invoice template: { reference, valueDate, dueDate, contactResourceId, lineItems, currency, tag, saveAsDraft }"}},required:["resourceId"],group:"schedulers",readOnly:!1,searchHint:"update recurring scheduled invoice settings",execute:async(e,t)=>{let r={};return t.repeat&&(r.repeat=t.repeat),t.startDate&&(r.startDate=t.startDate),t.endDate&&(r.endDate=t.endDate),t.status&&(r.status=t.status),t.invoice&&(r.invoice=t.invoice),rv(e.client,t.resourceId,r)}},ln("delete_scheduled_invoice","Delete a scheduled (recurring) invoice.","schedulers",(e,t)=>nv(e,t),"delete a recurring scheduled invoice"),Yn("get_scheduled_bill","Get a scheduled (recurring) bill by resourceId.","schedulers",(e,t)=>ov(e,t),"get scheduled recurring bill details"),{name:"update_scheduled_bill",description:"Update a scheduled bill \u2014 change schedule settings and/or the bill template.",params:{resourceId:{type:"string",description:"Scheduled bill resourceId"},repeat:{type:"string",description:"Recurrence: WEEKLY, MONTHLY, QUARTERLY, YEARLY"},startDate:{type:"string",description:"First occurrence date (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence date (YYYY-MM-DD)"},status:{type:"string",description:"Status: ACTIVE or PAUSED"},bill:{type:"object",description:"Bill template: { reference, valueDate, dueDate, contactResourceId, lineItems, currency, tag, saveAsDraft }"}},required:["resourceId"],group:"schedulers",readOnly:!1,searchHint:"update recurring scheduled bill settings",execute:async(e,t)=>{let r={};return t.repeat&&(r.repeat=t.repeat),t.startDate&&(r.startDate=t.startDate),t.endDate&&(r.endDate=t.endDate),t.status&&(r.status=t.status),t.bill&&(r.bill=t.bill),iv(e.client,t.resourceId,r)}},ln("delete_scheduled_bill","Delete a scheduled (recurring) bill.","schedulers",(e,t)=>sv(e,t),"delete a recurring scheduled bill"),Yn("get_scheduled_journal","Get a scheduled (recurring) journal by resourceId.","schedulers",(e,t)=>av(e,t),"get scheduled recurring journal details"),{name:"update_scheduled_journal",description:"Update a scheduled journal \u2014 change schedule settings and/or the journal template.",params:{resourceId:{type:"string",description:"Scheduled journal resourceId"},repeat:{type:"string",description:"Recurrence: WEEKLY, MONTHLY, QUARTERLY, YEARLY"},startDate:{type:"string",description:"First occurrence date (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence date (YYYY-MM-DD)"},status:{type:"string",description:"Status: ACTIVE or PAUSED"},valueDate:{type:"string",description:"Journal date (YYYY-MM-DD)"},schedulerEntries:{type:"array",items:{type:"object"},description:"Journal entries: [{ accountResourceId, type: CREDIT|DEBIT, amount, ... }]"},reference:{type:"string",description:"Journal reference"},notes:{type:"string",description:"Journal notes"}},required:["resourceId"],group:"schedulers",readOnly:!1,searchHint:"update recurring scheduled journal settings",execute:async(e,t)=>{let r={};return t.repeat&&(r.repeat=t.repeat),t.startDate&&(r.startDate=t.startDate),t.endDate&&(r.endDate=t.endDate),t.status&&(r.status=t.status),t.valueDate&&(r.valueDate=t.valueDate),t.schedulerEntries&&(r.schedulerEntries=t.schedulerEntries),t.reference&&(r.reference=t.reference),t.notes&&(r.notes=t.notes),cv(e.client,t.resourceId,r)}},ln("delete_scheduled_journal","Delete a scheduled (recurring) journal.","schedulers",(e,t)=>uv(e,t),"delete a recurring scheduled journal"),Yn("get_payment","Get a specific payment record by resourceId. Returns payment amount, method, date, and reference.","payments",(e,t)=>n0(e,t),"get payment record details by id"),{name:"update_payment",description:"Update a payment record \u2014 correct amount, reference, date, method, or account.",params:{resourceId:{type:"string",description:"Payment resourceId (from invoice/bill paymentRecords)"},paymentAmount:{type:"number",description:"Corrected payment amount (bank currency)"},reference:{type:"string",description:"Payment reference"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},paymentMethod:Zm,accountResourceId:{type:"string",description:"Bank/cash account resourceId"},transactionFee:{type:"number",description:"Transaction fee amount"}},required:["resourceId"],group:"payments",readOnly:!1,searchHint:"update payment amount reference date method",execute:async(e,t)=>{let r={};return t.paymentAmount!==void 0&&(r.paymentAmount=t.paymentAmount),t.reference&&(r.reference=t.reference),t.valueDate&&(r.valueDate=t.valueDate),t.paymentMethod&&(r.paymentMethod=t.paymentMethod),t.accountResourceId&&(r.accountResourceId=t.accountResourceId),t.transactionFee!==void 0&&(r.transactionFee=t.transactionFee),o0(e.client,t.resourceId,r)}},ln("delete_payment","Delete (void) a payment record. The associated invoice/bill balance is restored.","payments",(e,t)=>i0(e,t),"delete void a payment record restore balance"),{name:"get_export_columns",description:"List all exportable columns for an entity type, including their paths and data types. Use paths from this response to build custom column sets for export_records or preview_export_records.",params:{entityType:aR},required:["entityType"],group:"export_records",readOnly:!0,isConcurrencySafe:!0,searchHint:"list export columns fields for entity type",execute:async(e,t)=>v_(e.client,t.entityType)},{name:"preview_export_records",description:"Preview an export before generating the file. Returns totalRecords, up to 10 sample rows, resolved column definitions, and a human-readable filterDescription. Use this to confirm scope before calling export_records. Pass either query OR filter, never both.",params:{entityType:aR,query:TJ,filter:OJ,columns:RJ,sort:$J},required:["entityType"],group:"export_records",readOnly:!0,isConcurrencySafe:!0,searchHint:"preview export records count sample rows filter",execute:async(e,t)=>b_(e.client,{entityType:t.entityType,outputFormat:"XLSX",query:t.query,filter:t.filter,columns:t.columns,sort:t.sort})},{name:"export_records",description:`Generate a raw entity-row XLSX export for one entity type (a list of invoices, bills, contacts, items, journals, bank records, cashflow, fixed assets, etc. \u2014 one row per record, with column selection). Returns a pre-signed download URL (~5 min), file name, and total record count. Pass either query OR filter, never both. Use preview_export_records first to confirm scope.
|
|
817
|
-
|
|
818
|
-
DO NOT use this tool for analytical or audit reports (anomalous invoices, anomalous bills, cashflow anomalies, GL journal audit, exchange rate audit, receivables customer risk, cash expense health), financial statements (trial balance, P&L, balance sheet, cashflow, general ledger), aging (AR/AP report), summary reports (sales-summary, purchase-summary, etc.), or statement of account. Those go through download_export.`,params:{entityType:aR,query:TJ,filter:OJ,columns:RJ,sort:$J},required:["entityType"],group:"export_records",readOnly:!0,isConcurrencySafe:!0,searchHint:"export records download xlsx file url",execute:async(e,t)=>D_(e.client,{entityType:t.entityType,outputFormat:"XLSX",query:t.query,filter:t.filter,columns:t.columns,sort:t.sort})},Rt({name:"search_background_jobs",description:"Search and poll background jobs. ANY operation that returns a jobId (bulk_upsert_contacts, bulk_upsert_items, bank statement import, magic file processing, etc.) can be tracked here. Filter by resourceId (the jobId value) to poll a specific job. Poll until status is SUCCESS, FAILED, or PARTIAL_SUCCESS. Use processedCount/failedCount/totalRecords for progress. IMPORTANT: filter by resourceId field, NOT jobId \u2014 they differ.",group:"background_jobs",fields:Xp,defaults:Qp,fetcher:Hm,searchHint:"poll background job status by jobId type status"}),{name:"bulk_upsert_contacts",description:"Create or update contacts in bulk (max 500 per call). Provide resourceId per contact to update (partial \u2014 omitted fields preserve existing values, including customer/supplier flags). Omit resourceId to create. Returns a jobId \u2014 async; poll search_background_jobs with filter {resourceId:{eq:jobId}} until status is SUCCESS / FAILED / PARTIAL_SUCCESS. Per-row failures live in the background job's errorDetails (NOT failedRows \u2014 that's the sync bulk-upsert pattern). Common 422 cases (whole batch rejected at request level): at least one of `customer` or `supplier` must be true per contact (after defaults+backfill from existing); duplicate emails within a contact's emailList (case-insensitive after trim); payment-terms `value` must be a positive integer when `name` != CUSTOM; duplicate names within the batch (after whitespace+case normalize); when a billingAddress / shippingAddress object is provided, its `addressLine1` field is required.",params:{contacts:{type:"array",description:"Array of contacts to create or update (max 500)",items:{type:"object",properties:{resourceId:{type:"string",description:"Contact resourceId (omit for create, provide UUID for update)"},billingName:{type:"string",description:"Billing name (required for create)"},name:{type:"string",description:"Display name (defaults to billingName)"},emails:{type:"array",items:{type:"string"},description:"Email addresses"},customer:{type:"boolean",description:"Mark as customer"},supplier:{type:"boolean",description:"Mark as supplier"},taxId:{type:"string",description:"Tax ID / GST registration number"},taxIdType:{type:"string",description:"Tax ID type (e.g., GST, VAT)"},registrationNumber:{type:"string",description:"Business registration number"},currencyCode:{type:"string",description:"Default currency code (e.g., SGD)"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Contact status"},paymentTerms:{type:"number",description:"Payment terms in days (e.g., 30 for Net 30)"},notes:{type:"string",description:"Internal notes"},billingAddress:{type:"object",description:"Billing address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}},shippingAddress:{type:"object",description:"Shipping address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}}}}}},required:["contacts"],group:"contacts",readOnly:!1,searchHint:"bulk create update contacts upsert",execute:async(e,t)=>(ar(t.contacts,"contacts"),$y(e.client,t.contacts))},{name:"bulk_upsert_invoices",description:"Create or update invoices in bulk (max 500 per call). FLAT shape: ONE line per invoice via `itemDescription` + `totalAmount` + `invoiceAccountResourceId` at row level. For multi-line invoices use `bulk_upsert_invoice_line_items` instead \u2014 that variant takes nested `lineItems[]`. Natural key: `invoiceReference` (rows sharing one within a batch are MERGED \u2014 last wins). Provide resourceId per invoice to update via UUID; or omit and rely on invoiceReference for upsert. Async \u2014 returns a jobId. Poll search_background_jobs with filter {resourceId:{eq:jobId}} until SUCCESS / FAILED / PARTIAL_SUCCESS; on PARTIAL_SUCCESS read data[0].errorDetails on the same response for per-row failures. Dates are ISO 8601 (YYYY-MM-DD) only \u2014 the dateFormat field was removed.",params:{invoices:{type:"array",description:"Array of invoices to create or update (max 500). Each row needs at least: invoiceReference, contactResourceId, valueDate, totalAmount, invoiceAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string",description:"Optional caller-supplied row index for error reporting"},resourceId:{type:"string",description:"Invoice resourceId (UUID) \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key (e.g., INV-2025-001) \u2014 required"},contactResourceId:{type:"string",description:"Customer contact UUID \u2014 required"},valueDate:{type:"string",description:"Invoice date YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"Due date YYYY-MM-DD"},totalAmount:{type:"number",description:"Total amount (BigDecimal)"},currencyCode:{type:"string",description:"Currency (e.g., SGD)"},invoiceAccountResourceId:{type:"string",description:"Revenue account UUID"},itemDescription:{type:"string",description:"Single-line item description"},internalNotes:{type:"string",description:"Internal notes"},tags:{type:"array",items:{type:"string"},description:"Tag resourceIds"}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk create update invoices upsert import migrate",execute:async(e,t)=>{ar(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),Fb(e.client,r)}},{name:"bulk_upsert_invoice_line_items",description:"Create or update invoices with nested line items in bulk (max 500 invoices per call). Each row carries lineItems[] under its parent invoice (scoped by invoiceReference). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 only.",params:{invoices:{type:"array",description:"Array of invoices with line items (max 500). Each invoice row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string",description:"Invoice resourceId \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"YYYY-MM-DD"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",description:"Line items belonging to this invoice",items:{type:"object",properties:{itemDescription:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string",description:"Unit of measure (pcs, kg, etc.)"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Revenue account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk invoices line items multi-line upsert import",execute:async(e,t)=>{ar(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),Pb(e.client,r)}},{name:"bulk_upsert_bills",description:"Create or update bills in bulk (max 500 per call). FLAT shape: ONE line per bill via `itemDescription` + `totalAmount` + `billAccountResourceId` at row level. For multi-line bills use `bulk_upsert_bill_line_items` instead \u2014 that variant takes nested `lineItems[]`. Natural key: `billReference` (rows sharing one within a batch are MERGED \u2014 last wins). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 only \u2014 dateFormat field was removed.",params:{bills:{type:"array",description:"Array of bills to create or update (max 500). Each row needs at least: billReference, contactResourceId, valueDate, totalAmount, billAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},totalAmount:{type:"number"},currencyCode:{type:"string"},billAccountResourceId:{type:"string",description:"Expense account UUID"},itemDescription:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk create update bills upsert import migrate",execute:async(e,t)=>{ar(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),wy(e.client,r)}},{name:"bulk_upsert_bill_line_items",description:"Create or update bills with nested line items in bulk (max 500 bills per call). Each row carries lineItems[] under its parent bill (scoped by billReference). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures.",params:{bills:{type:"array",description:"Array of bills with line items (max 500). Each bill row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Expense account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk bills line items multi-line upsert import",execute:async(e,t)=>{ar(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),Ty(e.client,r)}},{name:"bulk_upsert_customer_credit_notes",description:"Create or update customer credit notes in bulk (max 500 per call). Natural key: creditNoteReference. Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 only.",params:{customerCreditNotes:{type:"array",description:"Array of customer credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["customerCreditNotes"],group:"customer_credit_notes",readOnly:!1,searchHint:"bulk customer credit notes refund upsert import",execute:async(e,t)=>{ar(t.customerCreditNotes,"customerCreditNotes",500,"customer credit notes");let r=t.customerCreditNotes;return eo(r,["valueDate"]),T0(e.client,r)}},{name:"bulk_upsert_supplier_credit_notes",description:"Create or update supplier credit notes in bulk (max 500 per call). Natural key: creditNoteReference. Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 only.",params:{supplierCreditNotes:{type:"array",description:"Array of supplier credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["supplierCreditNotes"],group:"supplier_credit_notes",readOnly:!1,searchHint:"bulk supplier credit notes refund upsert import",execute:async(e,t)=>{ar(t.supplierCreditNotes,"supplierCreditNotes",500,"supplier credit notes");let r=t.supplierCreditNotes;return eo(r,["valueDate"]),k0(e.client,r)}},{name:"bulk_upsert_journals",description:"Create or update manual journals in bulk (max 500 per call). NATURAL KEY: `journalReference` (NOT `reference` \u2014 every other bulk-upsert uses entityReference, this one is asymmetric). LEGS field: `journalEntries[]` (NOT `entries[]` \u2014 different from `clio journals create` which uses entries). Each leg has `accountResourceId` + `debitAmount` + `creditAmount` (debit + credit must balance per row). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 (YYYY-MM-DD) only \u2014 dateFormat field was removed.",params:{journals:{type:"array",description:"Array of journals to create or update (max 500). Each row has entries[] (debit/credit legs).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},journalReference:{type:"string",description:"Natural key \u2014 required (NOTE: field is `journalReference`, not `reference`)"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},journalEntries:{type:"array",description:"Journal legs (debit + credit amounts must balance) \u2014 field is `journalEntries`, NOT `entries`",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Required"},description:{type:"string"},debitAmount:{type:"number"},creditAmount:{type:"number"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["journals"],group:"journals",readOnly:!1,searchHint:"bulk manual journals upsert import migration",execute:async(e,t)=>{ar(t.journals,"journals");let r=t.journals;return eo(r,["valueDate"]),zb(e.client,r)}},{name:"bulk_upsert_fixed_assets",description:'\u26A0\uFE0F DATE FIELD MISMATCH: bulk-upsert REQUEST uses `valueDate` (not `purchaseDate`); the GET response uses `purchaseDate`. Sending `purchaseDate` returns a cryptic 400 "Invalid request body" with no field detail. Create or update fixed assets in bulk (max 500 per call). Natural key: `reference`. Each row REQUIRED: `reference`, `registrationType` (NEW | TRANSFER). Recommended: `typeCode`, `typeName`, `category` (TANGIBLE | INTANGIBLE), `cost` (or synonym `purchaseAmount`), `valueDate`, `depreciationStartDate`, `effectiveLife` (or synonym `usefulLifeMonths`), `depreciationMethod`, `purchaseAssetAccountResourceId`, `depreciationExpenseAccountResourceId`, `accumulatedDepreciationAccountResourceId`. Account fields must be valid UUIDv4. Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 (YYYY-MM-DD) only.',params:{fixedAssets:{type:"array",description:"Array of fixed assets to create or update (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},reference:{type:"string",description:"Natural key \u2014 required"},registrationType:{type:"string",enum:["NEW","TRANSFER"],description:"NEW = newly acquired, TRANSFER = inherited from prior system \u2014 required"},typeCode:{type:"string",description:"Asset class code (e.g., FURNITURE_AND_FIXTURE)"},typeName:{type:"string",description:'Human label for the typeCode (e.g., "Furniture and Fixtures")'},category:{type:"string",description:"TANGIBLE | INTANGIBLE"},name:{type:"string",description:"Asset name"},valueDate:{type:"string",description:"Acquisition date YYYY-MM-DD (NOTE: bulk uses `valueDate`, the GET response uses `purchaseDate` \u2014 different fields)"},cost:{type:"number",description:"Cost basis (alias for purchaseAmount on the bulk endpoint)"},purchaseAmount:{type:"number",description:"Cost basis (synonym of `cost`)"},currencyCode:{type:"string"},depreciationStartDate:{type:"number",description:'Epoch milliseconds (NOT YYYY-MM-DD \u2014 inconsistent with valueDate which IS YYYY-MM-DD on this same endpoint). Sending YYYY-MM-DD returns generic 400 "Invalid request body" with no detail. Omit to default to valueDate.'},effectiveLife:{type:"number",description:"Useful life in months (alias for usefulLifeMonths)"},usefulLifeMonths:{type:"number",description:"Useful life in months (synonym of effectiveLife)"},depreciationMethod:{type:"string",description:"e.g., STRAIGHT_LINE, DOUBLE_DECLINING_BALANCE"},purchaseAssetAccountResourceId:{type:"string",description:"Asset (PPE) account UUID \u2014 must be valid UUIDv4"},depreciationExpenseAccountResourceId:{type:"string",description:"Depreciation expense account UUID \u2014 must be valid UUIDv4"},accumulatedDepreciationAccountResourceId:{type:"string",description:"Accumulated depreciation account UUID"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}}}}}},required:["fixedAssets"],group:"fixed_assets",readOnly:!1,searchHint:"bulk fixed assets ppe register upsert import migrate",execute:async(e,t)=>{ar(t.fixedAssets,"fixedAssets",500,"fixed assets");let r=t.fixedAssets;return eo(r,["valueDate"]),GS(e.client,r)}},{name:"quick_reconcile",description:"Bulk-reconcile bank statement entries against a list of journals (max 500). Reconciliation mode is hardcoded to QUICK_RECON. Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails. Caller provides bankAccountResourceId + journalsForReconciliation[] (each row: bankStatementEntryResourceId, journalReference, journalAccountResourceId).",params:{bankAccountResourceId:{type:"string",description:"Bank account UUID (the entries belong to this account)"},journalsForReconciliation:{type:"array",description:"Per-row reconciliation instructions (max 500).",items:{type:"object",properties:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},journalReference:{type:"string",description:"Journal reference text \u2014 required"},journalAccountResourceId:{type:"string",description:"Offsetting account UUID (revenue for cash-in, expense for cash-out) \u2014 required"},contactResourceId:{type:"string",description:"Contact UUID"},capsuleResourceId:{type:"string",description:"Capsule UUID"},taxProfileResourceId:{type:"string",description:"Tax profile UUID"},internalNotes:{type:"string"},journalEntryDescription:{type:"string"},tags:{type:"array",items:{type:"string"}},rowIndex:{type:"string",description:"Optional caller-supplied index for error correlation"}}}}},required:["bankAccountResourceId","journalsForReconciliation"],group:"reconciliations",readOnly:!1,searchHint:"bulk reconcile bank statement journals match",execute:async(e,t)=>(ar(t.journalsForReconciliation,"journalsForReconciliation",500,"journals"),I_(e.client,t))},{name:"apply_bank_rule",description:"Apply a pre-configured bank rule (action shortcut) to a batch of bank statement entries (max 500). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId. The rule executes its configured action (e.g. RECONCILE_WITH_DIRECT_CASH_ENTRY) on each entry.",params:{actionShortcutResourceId:{type:"string",description:"Bank rule UUID \u2014 required"},businessTransactionResourceIds:{type:"array",description:"Bank statement entry UUIDs to apply the rule to (max 500). Note: the field is named businessTransactionResourceIds for legacy reasons but accepts bank entry IDs.",items:{type:"string"}}},required:["actionShortcutResourceId","businessTransactionResourceIds"],group:"reconciliations",readOnly:!1,searchHint:"bank rule apply action shortcut bulk reconcile",execute:async(e,t)=>(ar(t.businessTransactionResourceIds,"businessTransactionResourceIds",500,"entries"),C_(e.client,t))},{name:"reconcile_direct_cash_entry",description:"Reconcile a bank statement entry with a single cash-in / cash-out line. Direction (cash-in vs cash-out) is INFERRED from the bank entry sign. Sync \u2014 returns the reconciled entry status. NOT idempotent: calling twice on the same bankStatementEntryResourceId creates duplicate journals. Confirm reconciled-state via view_auto_reconciliation before retrying.",params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID (used to look up the entry) \u2014 required"},reference:{type:"string",description:"Reference for the cash entry \u2014 required"},accountResourceId:{type:"string",description:"Offsetting account UUID (revenue for cash-in, expense for cash-out) \u2014 required"},amount:{type:"number",description:"Amount in source currency. Defaults to bank entry amount if omitted."},description:{type:"string"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"},internalNotes:{type:"string"},bankAccountJournalEntryDescription:{type:"string",description:"Description for the bank-side journal entry"},tags:{type:"array",items:{type:"string"}},taxVatApplicable:{type:"boolean"},taxInclusion:{type:"boolean"},capsuleResourceId:{type:"string"}},required:["bankStatementEntryResourceId","bankAccountResourceId","reference","accountResourceId"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry direct cash in out single line",execute:async(e,t)=>x_(e.client,t)},{name:"reconcile_cash_journal",description:"Reconcile a bank statement entry with a multi-line cashflow journal (multiple cash splits, max 200 lines). Sync \u2014 returns the reconciled entry status. NOT idempotent \u2014 confirm reconciled-state before retrying.",params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},reference:{type:"string",description:"Journal reference \u2014 required"},journalEntries:{type:"array",description:"Cash journal lines (max 200). Each row is one debit OR credit against an account.",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Account UUID \u2014 required"},amount:{type:"number",description:"Amount in source currency \u2014 required (>0)"},description:{type:"string"},taxProfileResourceId:{type:"string"}}}},contactResourceId:{type:"string"},bankAccountJournalEntryDescription:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},taxVatApplicable:{type:"boolean"},taxInclusion:{type:"boolean"},capsuleResourceId:{type:"string"}},required:["bankStatementEntryResourceId","bankAccountResourceId","reference","journalEntries"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry multi line cash journal splits",execute:async(e,t)=>(ar(t.journalEntries,"journalEntries",200,"entries"),A_(e.client,t))},{name:"reconcile_manual_journal",description:'\u26A0\uFE0F CALLER PROVIDES ONLY THE OFFSET LEG(S) \u2014 backend AUTO-ADDS the bank-side leg from the statement entry. Sending both debit AND credit legs \u2192 422 "sum of debit and credit amounts are not equal" (your sides duplicate after the auto-add). Reconcile a bank statement entry with a double-entry manual journal. Sync \u2014 returns the reconciled entry status. valueDate prefills from bank entry if omitted. NOT idempotent.',params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},status:{type:"string",enum:["DRAFT","ACTIVE"],description:"Journal status \u2014 required"},journalEntries:{type:"array",description:"Offset-side journal entries only (max 200). The bank-side leg is auto-added by the API.",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Account UUID \u2014 required"},type:{type:"string",enum:["DEBIT","CREDIT"]},amount:{type:"number",description:"Amount \u2014 required"},description:{type:"string"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}},reference:{type:"string"},valueDate:{type:"string",description:"YYYY-MM-DD. Defaults to bank entry value date."},contactResourceId:{type:"string"},internalNotes:{type:"string"},bankAccountJournalEntryDescription:{type:"string"},taxVatApplicable:{type:"boolean"},taxInclusion:{type:"boolean"},tags:{type:"array",items:{type:"string"}},capsuleResourceId:{type:"string"}},required:["bankStatementEntryResourceId","bankAccountResourceId","status","journalEntries"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry manual journal double entry",execute:async(e,t)=>(ar(t.journalEntries,"journalEntries",200,"entries"),w_(e.client,t))},{name:"reconcile_cash_transfer",description:"Reconcile a bank statement entry with an inter-account transfer. Sync \u2014 returns the reconciled entry status. amount is required only when the counterparty account is in a non-functional currency. NOT idempotent.",params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},accountResourceId:{type:"string",description:"Counterparty cash account UUID \u2014 required"},reference:{type:"string",description:"Transfer reference \u2014 required"},amount:{type:"number",description:"Amount in source currency. Required only for cross-currency transfers."},contactResourceId:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},capsuleResourceId:{type:"string"}},required:["bankStatementEntryResourceId","bankAccountResourceId","accountResourceId","reference"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry transfer between accounts",execute:async(e,t)=>T_(e.client,t)},{name:"reconcile_invoice_receipt",description:'\u26A0\uFE0F BSE must have `paymentDirection: PAYIN` (money in \u2014 AR). Produce via `bank add-records` with a POSITIVE amount (creates `credit_amount > 0` \u2192 PAYIN). Statement-imported BSEs from `bank import` also work. The error code "Invalid business transaction type" (422) is misleadingly named \u2014 the actual gate is direction, not entry type. Create an invoice and auto-reconcile it to a bank statement entry (AR). Sync \u2014 returns the reconciled entry status. valueDate / dueDate / payment amount prefill from the bank entry if omitted. NOT idempotent.',params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},invoiceDetails:{type:"object",description:"The invoice to create. Required.",properties:{reference:{type:"string",description:"Invoice reference \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID"},valueDate:{type:"string",description:"YYYY-MM-DD. Defaults to bank entry value date."},dueDate:{type:"string",description:"YYYY-MM-DD. Defaults to value date."},taxInclusion:{type:"boolean"},isTaxVATApplicable:{type:"boolean"},lineItems:{type:"array",description:"Invoice line items (max 500) \u2014 required",items:{type:"object",properties:{name:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},organizationAccountResourceId:{type:"string",description:"Revenue account UUID"},itemResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}},recordedPayment:{type:"object",description:"Optional. The matching payment record \u2014 auto-built from the bank entry if omitted.",properties:{reference:{type:"string"},valueDate:{type:"string",description:"YYYY-MM-DD. Defaults to bank entry value date."},organizationAccountResourceId:{type:"string"},paymentAmount:{type:"number"},transactionAmount:{type:"number"},paymentMethod:{type:"string",description:"Defaults to BANK_TRANSFER"}}},capsuleResourceId:{type:"string"}}}},required:["bankStatementEntryResourceId","bankAccountResourceId","invoiceDetails"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry invoice receipt AR sale",execute:async(e,t)=>(oR(t.invoiceDetails,"invoiceDetails"),O_(e.client,t))},{name:"reconcile_bill_receipt",description:'\u26A0\uFE0F BSE must have `paymentDirection: PAYOUT` (money out \u2014 AP). Produce via `bank add-records` with a NEGATIVE amount (creates `debit_amount > 0` \u2192 PAYOUT). Statement-imported BSEs from `bank import` also work. The error code "Invalid business transaction type" (422) is misleadingly named \u2014 the actual gate is direction, not entry type. Create a bill and auto-reconcile it to a bank statement entry (AP). Sync \u2014 returns the reconciled entry status. valueDate / dueDate / payment amount prefill from the bank entry if omitted. NOT idempotent.',params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},billDetails:{type:"object",description:"The bill to create. Required.",properties:{reference:{type:"string",description:"Bill reference \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID"},valueDate:{type:"string",description:"YYYY-MM-DD. Defaults to bank entry value date."},dueDate:{type:"string",description:"YYYY-MM-DD. Defaults to value date."},taxInclusion:{type:"boolean"},isTaxVATApplicable:{type:"boolean"},lineItems:{type:"array",description:"Bill line items (max 500) \u2014 required",items:{type:"object",properties:{name:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},organizationAccountResourceId:{type:"string",description:"Expense account UUID"},itemResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}},recordedPayment:{type:"object",description:"Optional. The matching payment record \u2014 auto-built from the bank entry if omitted.",properties:{reference:{type:"string"},valueDate:{type:"string",description:"YYYY-MM-DD"},organizationAccountResourceId:{type:"string"},paymentAmount:{type:"number"},transactionAmount:{type:"number"},paymentMethod:{type:"string",description:"Defaults to BANK_TRANSFER"}}},capsuleResourceId:{type:"string"}}}},required:["bankStatementEntryResourceId","bankAccountResourceId","billDetails"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry bill receipt AP purchase",execute:async(e,t)=>(oR(t.billDetails,"billDetails"),R_(e.client,t))},{name:"validate_drafts",description:'BULK validate \u2014 process up to 500 draft business transactions in ONE call, mixing any combination of invoices, bills, customer credit notes, and supplier credit notes (no per-type tools needed). SYNC: returns per-item errors and display data inline; no state change. Each result also carries `contactSignals` (Mid-7 contact-history insight: cadence, outliers, severity, divergences from the contact\'s modal pattern \u2014 null when the draft has no contact or the contact has no history) and `breakdown` (full Balance-panel payload: line items + trx-level metadata like subtotal, tax, total, balance, exchange rate). Top-level `contactSignalsMeta.unavailable=true` signals the freshness layer was unavailable for the whole batch. USE THIS to score a specific draft against contact history; for stand-alone "what does this contact normally look like?" lookups WITHOUT a draft, use `get_contact_signals` instead. Run before convert_drafts_to_active to surface eligibility issues client-side. btType enum: SALE = invoice, PURCHASE = bill, SALE_CREDIT_NOTE = customer CN, PURCHASE_CREDIT_NOTE = supplier CN. Journals are NOT in this enum.',params:{items:{type:"array",description:"Draft business transaction references (max 500). Mix any btType freely.",items:{type:"object",properties:{btResourceId:{type:"string",description:"Draft BT resource ID (UUID) \u2014 required"},btType:{type:"string",enum:["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"],description:"Required"}}}}},required:["items"],group:"drafts",readOnly:!0,isConcurrencySafe:!0,searchHint:"validate drafts eligibility check before convert promote",execute:async(e,t)=>(al(t.items),S_(e.client,t.items))},{name:"convert_drafts_to_active",description:"BULK promote \u2014 finalize up to 500 draft business transactions to ACTIVE in ONE call, mixing any combination of invoices, bills, and credit notes (no per-type tools needed). ASYNC: returns a jobId \u2014 poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. NOT idempotent: a second call on already-promoted drafts returns 422. Filter the draft list by status: DRAFT before submitting. Pair with validate_drafts for a pre-flight check on large batches.",params:{items:{type:"array",description:"Draft BT references (max 500). Mix any btType.",items:{type:"object",properties:{btResourceId:{type:"string",description:"Draft BT resource ID (UUID) \u2014 required"},btType:{type:"string",enum:["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"],description:"Required"}}}}},required:["items"],group:"drafts",readOnly:!1,searchHint:"convert drafts to active promote finalize bulk",execute:async(e,t)=>(al(t.items),__(e.client,t.items))},{name:"submit_drafts_for_approval",description:"BULK submit \u2014 route up to 500 draft business transactions into the approval workflow in ONE call, mixing any combination of invoices, bills, and credit notes. ASYNC: returns a jobId \u2014 poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. NOT idempotent on drafts that already have an in-flight approval request.",params:{items:{type:"array",description:"Draft BT references (max 500). Mix any btType.",items:{type:"object",properties:{btResourceId:{type:"string",description:"Draft BT resource ID (UUID) \u2014 required"},btType:{type:"string",enum:["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"],description:"Required"}}}}},required:["items"],group:"drafts",readOnly:!1,searchHint:"submit drafts for approval workflow review bulk",execute:async(e,t)=>(al(t.items),E_(e.client,t.items))},{name:"search_help_center",description:`Search the Jaz help center for how-to articles, feature guides, and accounting concepts. Use this for "how do I..." or "what is..." questions about Jaz: bank reconciliation, GST/VAT filing, multi-currency, fixed assets, custom fields, integrations, and so on. Returns top matching articles with title, section, snippet, and source URL.
|
|
819
|
-
|
|
820
|
-
Works without an API key \u2014 bundle ships the help center corpus locally.`,params:{query:{type:"string",description:'Natural-language question or keywords (e.g. "how do I reconcile a bank statement", "set up GST", "multi-currency invoice").'},limit:{type:"number",description:"Maximum number of articles to return (default 3, max 10)."},section:{type:"string",description:'Optional: restrict to a single help-center section slug (e.g. "bank-reconciliations", "invoices").'}},required:["query"],group:"help_center",readOnly:!0,searchHint:"help center docs how to guide article search question",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=String(t.query??"").trim();if(!r)return{error:"Query is required.",hint:"Pass a natural-language question or keywords."};let n=typeof t.limit=="number"&&!Number.isNaN(t.limit)?t.limit:3,o=Math.max(1,Math.min(10,Math.floor(n))),i=typeof t.section=="string"?t.section:void 0;try{let s=Bf();if(i&&!s.sections.some(c=>c.slug===i))return{error:`Unknown section: "${i}".`,available:s.sections.map(c=>c.slug),hint:"Omit the section parameter to search every section, or pick a slug from the available list."};let a=ki(s,r,{limit:o,section:i});return a.length===0?{results:[],hint:"No matching articles. Try broader keywords or rephrase the question."}:{results:a.map(c=>({title:c.article.title,section:c.section.name,sectionSlug:c.section.slug,snippet:c.article.snippet,url:c.article.sourceUrl,score:Math.round(c.score*1e3)/1e3,matchedTerms:c.matchedTerms})),totalArticles:s.articleCount,searchedSections:i?[i]:void 0}}catch(s){return{error:"Help center search failed.",detail:s instanceof Error?s.message:String(s),hint:"The bundled help-center index may be missing or corrupt."}}}},{name:"practice_init",description:"Scaffold the practitioner workspace at ~/Documents/Jaz Practice (or PRACTICE_HOME env override). Creates clients/, templates/, and a starter PRACTICE.md from the firm name. Idempotent on re-run. Filesystem-only. Run once before practice_onboard_client.",params:{firmName:{type:"string",description:"Display name shown on outputs."},defaultBaseCurrency:{type:"string",description:'Default currency for new clients (e.g., "SGD"). Defaults to SGD.'},defaultJurisdiction:{type:"string",description:'ISO-3166 alpha-2 (e.g., "SG"). Defaults to SG.'},defaultJazApiKey:{type:"string",description:"Optional default JAZ_API_KEY for all clients (last in resolution chain after CLIENT.md override and env)."},practiceHome:{type:"string",description:"Optional override for the practice home dir. Defaults to ~/Documents/Jaz Practice or PRACTICE_HOME env."}},required:["firmName"],group:"practice",readOnly:!1,searchHint:"practice init firm setup workspace scaffold",isConcurrencySafe:!1,maxResultSizeChars:5e3,execute:async(e,t)=>{let r=nn(t.practiceHome);Ra(r);let n=$a(r),o=n??{v:1,firm_name:String(t.firmName),default_jaz_api_key:t.defaultJazApiKey,default_base_currency:t.defaultBaseCurrency??"SGD",default_jurisdiction:t.defaultJurisdiction??"SG",materiality_default:1e3,body:"Firm-level defaults that flow into every new client. Changes here apply to NEW clients only."};return n&&(t.firmName&&(o.firm_name=String(t.firmName)),t.defaultBaseCurrency&&(o.default_base_currency=String(t.defaultBaseCurrency)),t.defaultJurisdiction&&(o.default_jurisdiction=String(t.defaultJurisdiction)),t.defaultJazApiKey&&(o.default_jaz_api_key=String(t.defaultJazApiKey))),Ep(r,o),{practiceHome:r,firmName:o.firm_name,defaultBaseCurrency:o.default_base_currency,defaultJurisdiction:o.default_jurisdiction,clientsDir:`${r}/clients`,wasExisting:n!==null}}},{name:"practice_list_clients",description:"List all clients in the practitioner workspace. Returns slugs and last-active engagement per client. Filesystem-only. Use as a dashboard entry point before practice_load_client.",params:{practiceHome:{type:"string",description:"Optional override; defaults to ~/Documents/Jaz Practice."}},required:[],group:"practice",readOnly:!0,searchHint:"practice list clients dashboard",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=nn(t.practiceHome),o=Ap(r).map(i=>{let s=Oi(r,i),a=Fa(r,i);return{slug:i,legalEntityName:s?.legal_entity_name??i,fyEnd:s?.fy_end,baseCurrency:s?.base_currency,gstScheme:s?.gst_scheme,hasJazApiKeyOverride:!!s?.jaz_api_key_override,activeEngagements:a}});return{practiceHome:r,total:o.length,clients:o}}},{name:"practice_load_client",description:"Read a client's CLIENT.md master file. Returns the full record (legal entity, FY, COA mapping notes, banks, recurring accruals, recurring engagements, etc.) plus the list of active engagements. Filesystem-only. Use this to give the agent client context before invoking jaz-jobs blueprints or jaz-recipes recipes.",params:{slug:{type:"string",description:'Client slug (lowercase, hyphenated; e.g., "acme-pte-ltd").'},practiceHome:{type:"string",description:"Optional override."}},required:["slug"],group:"practice",readOnly:!0,searchHint:"practice load client read context CLIENT.md",isConcurrencySafe:!0,maxResultSizeChars:3e4,execute:async(e,t)=>{let r=nn(t.practiceHome),n=String(t.slug);try{Sn(n,"client slug")}catch(s){return{error:s instanceof Error?s.message:String(s)}}let o=Oi(r,n);if(!o)return{error:`Client not found: ${n}`,hint:"Run practice_list_clients to see available slugs, or practice_onboard_client to create a new one."};let i=Fa(r,n).map(s=>{let a=Pa(r,n,s);return a?{slug:s,type:a.type,period:a.period,status:a.status,scope:a.scope_summary}:null}).filter(Boolean);return{client:Cp(o),engagements:i}}},{name:"practice_onboard_client",description:"Scaffold a new client folder and write the initial CLIENT.md. Captures legal entity, FY end, GST scheme, banks, recurring accruals, recurring engagements. Optionally sets a per-client JAZ_API_KEY override for multi-org agencies. Filesystem-only. After this, call practice_create_engagement for the first period.",params:{legalEntityName:{type:"string",description:"Full legal name as registered with ACRA / equivalent."},uen:{type:"string",description:"Singapore UEN if applicable."},registeredAddress:{type:"string",description:"ACRA-registered address."},country:{type:"string",description:"ISO-3166 alpha-2; defaults to PRACTICE.md.default_jurisdiction."},baseCurrency:{type:"string",description:"ISO-4217; defaults to PRACTICE.md.default_base_currency."},fyEnd:{type:"string",description:'MM-DD format (e.g., "12-31"). Drives annual-statutory engagement period boundaries.'},gstScheme:{type:"string",enum:["quarterly","monthly","not-registered"],description:"GST registration cadence; drives quarterly-gst engagement scheduling."},gstRegistrationNumber:{type:"string",description:"Required when gstScheme != not-registered."},corporateTaxBracket:{type:"string",enum:["standard","startup_exemption","partial_exemption"],description:"Drives Form C-S computation path during annual-statutory."},jazApiKeyOverride:{type:"string",description:"Optional per-client API key. Resolution: this override -> PRACTICE.md.default_jaz_api_key -> JAZ_API_KEY env."},jazOrgId:{type:"string",description:"Optional Jaz org UUID. Pinned for tool invocations against this client."},materialityThreshold:{type:"number",description:"In base currency. Defaults to PRACTICE.md.materiality_default."},bankAccounts:{type:"array",description:"Array of {name, currency, account_number_ref?, jaz_resource_id?}. Read by monthly-close before search_bank_records.",items:{type:"object"}},recurringAccruals:{type:"array",description:'Array of {name, gl_account, vendor?, estimation_method?, fixed_amount?}. Drives plan_recipe(name: "accrued-expense") in monthly-close.',items:{type:"object"}},recurringEngagements:{type:"array",description:'Array of {type, cadence}. e.g. [{type: "monthly-close", cadence: "monthly"}]. Drives engagement scheduling.',items:{type:"object"}},keyContacts:{type:"array",description:"Array of {name, role, email?}.",items:{type:"object"}},practiceHome:{type:"string",description:"Optional override."}},required:["legalEntityName","fyEnd","gstScheme"],group:"practice",readOnly:!1,searchHint:"practice onboard new client setup CLIENT.md",isConcurrencySafe:!1,maxResultSizeChars:5e3,execute:async(e,t)=>{let r=nn(t.practiceHome);Ra(r);let n=$a(r);try{let o=wp(r,{legal_entity_name:String(t.legalEntityName),uen:t.uen,registered_address:t.registeredAddress,country:t.country,base_currency:t.baseCurrency,fy_end:String(t.fyEnd),gst_scheme:t.gstScheme,gst_registration_number:t.gstRegistrationNumber,corporate_tax_bracket:t.corporateTaxBracket,jaz_api_key_override:t.jazApiKeyOverride,jaz_org_id:t.jazOrgId,materiality_threshold:t.materialityThreshold,bank_accounts:t.bankAccounts,recurring_accruals:t.recurringAccruals,recurring_engagements:t.recurringEngagements,key_contacts:t.keyContacts},n);return{slug:o.slug,path:o.path,nextStep:"Call practice_create_engagement to scaffold the first engagement (e.g., type: monthly-close for the current period)."}}catch(o){return{error:o instanceof Error?o.message:String(o),hint:"If the slug already exists, choose a different legal_entity_name or remove the existing folder."}}}},{name:"practice_create_engagement",description:"Scaffold a new engagement folder under a client. Creates ENGAGEMENT.md from the type-specific template plus inputs/, workpapers/, deliverables/ subdirs. Filesystem-only. Engagement type drives which jaz-jobs blueprint and jaz-recipes recipes the agent should invoke. period is REQUIRED for monthly-close (YYYY-MM), quarterly-gst (YYYY-QN), and annual-statutory (YYYY) \u2014 only onboarding and adhoc accept free-text or omitted period.",params:{clientSlug:{type:"string",description:"Existing client slug."},type:{type:"string",enum:["monthly-close","quarterly-gst","annual-statutory","onboarding","adhoc"],description:"Engagement type. monthly-close uses generate_month_end_blueprint; quarterly-gst uses generate_gst_vat_blueprint; annual-statutory uses generate_year_end_blueprint + generate_audit_prep_blueprint + generate_statutory_filing_blueprint."},period:{type:"string",description:"Period in the format the type expects. REQUIRED for monthly-close (YYYY-MM, e.g. 2026-03), quarterly-gst (YYYY-QN, e.g. 2026-Q1), annual-statutory (YYYY, e.g. 2026). Free-text or omitted accepted only for onboarding and adhoc. Validated server-side; malformed periods rejected before scaffolding to prevent audit-trail gaps."},scopeSummary:{type:"string",description:"One sentence describing what this engagement produces."},targetCompletionDate:{type:"string",description:"YYYY-MM-DD. Used by practice_list_clients to flag overdue work."},practiceHome:{type:"string",description:"Optional override."}},required:["clientSlug","type"],group:"practice",readOnly:!1,searchHint:"practice create engagement scaffold ENGAGEMENT.md monthly close gst statutory",isConcurrencySafe:!1,maxResultSizeChars:5e3,execute:async(e,t)=>{let r=nn(t.practiceHome),n=String(t.clientSlug);try{Sn(n,"client slug")}catch(s){return{error:s instanceof Error?s.message:String(s)}}let o=Oi(r,n);if(!o)return{error:`Client not found: ${n}`,hint:"Run practice_list_clients or practice_onboard_client first."};let i=t.type;try{Cu(i,t.period)}catch(s){return{error:s instanceof Error?s.message:String(s),hint:"Recurring/statutory engagements require a period: monthly-close=YYYY-MM, quarterly-gst=YYYY-QN, annual-statutory=YYYY."}}try{let s=Op(r,n,{type:i,period:t.period,scope_summary:t.scopeSummary,target_completion_date:t.targetCompletionDate},o.jaz_org_id);return{slug:s.slug,path:s.path,nextStep:"Open ENGAGEMENT.md and follow the type-specific playbook in jaz-practice/references/<type>.md."}}catch(s){return{error:s instanceof Error?s.message:String(s),hint:"If the engagement folder already exists, pick a different period or load the existing one with practice_load_engagement."}}}},{name:"practice_load_engagement",description:"Read an engagement's ENGAGEMENT.md file. Returns scope, status, period, queries, decisions log. Pair with practice_load_client to get full context before driving jaz-jobs / jaz-recipes work.",params:{clientSlug:{type:"string",description:"Client slug."},engagementSlug:{type:"string",description:'Engagement slug (e.g., "monthly-close-2026-03").'},practiceHome:{type:"string",description:"Optional override."}},required:["clientSlug","engagementSlug"],group:"practice",readOnly:!0,searchHint:"practice load engagement read ENGAGEMENT.md context",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=nn(t.practiceHome),n=String(t.clientSlug),o=String(t.engagementSlug);try{Sn(n,"client slug"),Sn(o,"engagement slug")}catch(s){return{error:s instanceof Error?s.message:String(s)}}let i=Pa(r,n,o);return i?{engagement:i}:{error:`Engagement not found: ${n}/${o}`,hint:"Run practice_load_client to see active engagement slugs."}}}];var $_=null;function nSe(){if(!$_){$_=new Map;for(let e of ul)$_.set(e.name,e)}return $_}function N_(e){return nSe().get(e)}function uR(){return ul}function ll(e){return uR().filter(t=>t.group===e)}la();function oSe(e){switch(e){case 401:return"Invalid or missing API key. Run `clio auth add` or set JAZ_API_KEY.";case 403:return"Insufficient permissions for this operation.";case 404:return"Resource not found \u2014 check the resourceId. Use a search/list tool to look it up.";case 409:return"Conflict \u2014 resource may have been modified. Re-fetch and retry.";case 422:return"Validation error \u2014 check field values against the tool description.";case 429:return"Rate limited \u2014 wait a moment and retry.";default:return""}}function PJ(e){if(e instanceof Zi){let r=oSe(e.status);return{error:e.message,status:e.status,endpoint:e.endpoint,...r?{hint:r}:{}}}return{error:e instanceof Error?e.message:String(e)}}function LJ(e,t){if(e.readOnly)return{valid:!0,errors:[]};let r=[];for(let n of e.required){let o=t[n];if(o==null){r.push(`Missing required field: ${n}`);continue}typeof o=="string"&&o.trim()===""&&r.push(`Required field "${n}" is empty`)}for(let[n,o]of Object.entries(t)){if(o==null)continue;let i=e.params[n];if(!i)continue;let s=iSe(n,o,i);s&&r.push(s),i.enum&&typeof o=="string"&&(i.enum.includes(o)||r.push(`Field "${n}" value "${o}" not in allowed values: ${i.enum.join(", ")}`))}return{valid:r.length===0,errors:r}}function iSe(e,t,r){switch(r.type){case"string":if(typeof t!="string")return`Field "${e}" expected string, got ${typeof t}`;break;case"number":if(typeof t!="number"||!Number.isFinite(t))return`Field "${e}" expected finite number, got ${typeof t=="number"?"non-finite":typeof t}`;break;case"boolean":if(typeof t!="boolean")return`Field "${e}" expected boolean, got ${typeof t}`;break;case"array":if(!Array.isArray(t))return`Field "${e}" expected array, got ${typeof t}`;break;case"object":if(typeof t!="object"||Array.isArray(t))return`Field "${e}" expected object, got ${Array.isArray(t)?"array":typeof t}`;break}return null}var dl=[{name:"invoices",description:"Sales invoices (INV/SI). Create, search, get, update, delete, pay, finalize, apply credits, download PDF. Also: receivables, AR, AR aging, billing, overdue invoices, dunning, recurring invoices.",groups:["invoices"]},{name:"customer_credit_notes",description:"Customer credit notes (CN). Create, search, update, delete, finalize, refund, download PDF. Also: sales returns, customer CN.",groups:["customer_credit_notes"]},{name:"bills",description:"Purchase bills (PO/PI). Create, search, get, update, delete, pay, finalize, apply credits. Also: payables, AP, vendor invoices, supplier bills.",groups:["bills"]},{name:"supplier_credit_notes",description:"Supplier credit notes. Create, search, update, delete, finalize, refund. Also: purchase returns, debit notes, supplier CN.",groups:["supplier_credit_notes"]},{name:"journals",description:"Journal entries (JE). Create, search, update, delete manual journals. Also: adjusting entries, accruals, reclassifications, corrections.",groups:["journals"]},{name:"cash_entries",description:"Cash-in receipts and cash-out disbursements for external cash movements. WHEN TO USE: money received from customers/external \u2192 cash-in. Money paid to suppliers/external \u2192 cash-out. For internal account-to-account transfers, use cash_transfers namespace.",groups:["cash_entries"]},{name:"cash_transfers",description:"Cash transfers between your own bank/cash accounts and cashflow transaction search. WHEN TO USE: moving funds between own accounts (main bank \u2192 petty cash, USD \u2192 SGD). For external receipts/payments, use cash_entries namespace.",groups:["cash_transfers"]},{name:"bank_accounts",description:"Bank accounts, bank statement imports (CSV/OFX), bank records search, auto-reconciliation. For unreconciled queries: ALWAYS search bank records with status UNRECONCILED after listing accounts. Also: bank feeds, bank balance.",groups:["bank"]},{name:"bank_rules",description:"Bank reconciliation rules (action shortcuts). Create, search, update, delete bank rules. Configure auto-matching rules for bank records.",groups:["bank_rules"]},{name:"reconciliations",description:"Apply a reconciliation decision to a bank statement entry \u2014 write side. Auto-match and match bank records to invoices, bills, journals, cash entries, or transfers. Distinct from bank_accounts/bank_rules (which configure auto-reconciliation) and view_auto_reconciliation (which queries suggestions). Eight endpoints: quick_reconcile + apply_bank_rule (async, bulk), and direct_cash_entry / cash_journal / manual_journal / cash_transfer / invoice_receipt / bill_receipt (sync, per-entry). Most fields prefill from the bank entry when omitted.",groups:["reconciliations"]},{name:"financial_reports",description:"Core financial statements: trial balance (TB), balance sheet (BS/B/S), profit & loss (PnL/P&L/income statement), cash flow, general ledger (GL), cash balance/position, equity movement, VAT/GST ledger. Also: how profitable, what is the balance.",groups:["financial_reports"]},{name:"operational_reports",description:"Aging and operational reports: aged receivables (AR aging), aged payables (AP aging), AR report, bank balance summary, bank reconciliation reports, fixed asset (FA) summary, FA reconciliation. Data exports (CSV/Excel/XLSX). Anomaly detection and audit analysis: anomalous invoices, anomalous bills, cashflow anomalies, GL journal audit, exchange rate audit, receivables customer risk, cash expense health. Also: overdue analysis, how much owed, suspicious transactions, audit trail.",groups:["operational_reports","exports"]},{name:"contacts",description:"Contacts (customers/suppliers/vendors), contact groups, customer segmentation. Create, search, get, update, delete contacts. Bulk upsert contacts from CSV / spreadsheet imports \u2014 async, returns jobId, poll background_jobs. List/create contact groups.",groups:["contacts","contact_groups"]},{name:"items_and_inventory",description:"Products, services, inventory items. Create, search, get, update, delete items. Check inventory balance. Also: SKU, catalog, stock.",groups:["items","inventory"]},{name:"tags_and_custom_fields",description:"Tags for categorizing transactions. Custom fields for adding metadata (text, date, dropdown). Create, search, delete tags and custom fields.",groups:["tags","custom_fields"]},{name:"nano_classifiers",description:"Nano classifiers (tracking categories/dimensions). List, search, create, update, delete classifiers and their classes. Used for line-item tagging and dimensional reporting. Also: tracking categories, cost centers, departments, projects.",groups:["nano_classifiers"]},{name:"chart_of_accounts",description:"Chart of accounts (COA/GL accounts). Create, search, update accounts. Bookmarks (favorites/shortcuts). Also: ledger codes, account types.",groups:["accounts","bookmarks"]},{name:"currencies",description:"Currencies, exchange rates (FX/forex). List/add org currencies. Set, update, import currency rates. Also: multi-currency, FX rates.",groups:["currencies"]},{name:"tax_profiles",description:"Tax profiles (GST/VAT/sales tax), withholding tax codes (WHT/ATC). Search, create, update tax profiles. List WHT codes.",groups:["tax_profiles"]},{name:"capsules_and_recipes",description:"Capsules (transaction groupings/capsule types). Financial recipes: amortization, depreciation, deferred revenue, IFRS 16 leases, hire purchase, fixed deposits, FX revaluation, loan schedules, ECL/expected credit loss, IAS 37 provisions, asset disposal. Plan and execute recipes. Keywords: calculate, provision, schedule, expected credit loss, revaluation.",groups:["capsules","recipes"]},{name:"scheduled_transactions",description:"Scheduled/recurring invoices, bills, journals. Create scheduled invoices/bills/journals, search scheduled transactions. Also: recurring, auto-generate.",groups:["schedulers"]},{name:"subscriptions",description:"Subscriptions (recurring billing/payment plans). Create, update, cancel, search subscriptions. Also: recurring charges, subscription schedules.",groups:["subscriptions"]},{name:"organization",description:"Organization info (name, currency, country, fiscal year). User management: invite, update, remove, search org users. Bulk invite.",groups:["organization","org_users"]},{name:"document_ai",description:"File attachments, AI document extraction (magic/OCR). Upload/list attachments. Create transactions from PDFs/images (invoice scanning, bill extraction). Track extraction workflows.",groups:["attachments","magic"]},{name:"fixed_assets",description:"Fixed assets (PP&E/property, plant, equipment). Search, create, update, discard, sell, transfer, undo disposal. Also: depreciation, asset register.",groups:["fixed_assets"]},{name:"payments_and_search",description:"Payment records: get, update, delete individual payments. List payments/credits on invoices and bills. Reverse credit applications. Cashflow transaction search. Universal cross-entity search. Also: payment run, batch payment, payment matching, void payment, payment history, credit note applications.",groups:["payments","cashflow","search"]},{name:"quick_fix",description:"Quick Fix: bulk-update multiple transactions or line items in one call. Change dates, contacts, tags, accounts, tax profiles, custom fields across many invoices/bills/journals/credit-notes/cash-entries/schedulers at once. Also: batch update, mass edit.",groups:["quick_fix"]},{name:"export_records",description:"Export records to XLSX. List available columns, preview export scope (row count + sample), generate export file with pre-signed download URL. Supports any entity type: invoices, bills, contacts, items, journals, bank records, cashflow, fixed assets, etc. Pass query (structured search syntax) or filter (JSON), never both.",groups:["export_records"]},{name:"background_jobs",description:"Background job tracking. Poll any async operation by jobId (contacts bulk-upsert, items bulk-upsert, bank import, magic file processing, etc.). Filter by resourceId field to look up a specific job. Poll until status is SUCCESS, FAILED, or PARTIAL_SUCCESS.",groups:["background_jobs"]},{name:"drafts",description:"Draft business transactions \u2014 both local payload validation (invoices, bills, journals, credit notes) AND BULK-FRIENDLY server-side lifecycle: validate_drafts (sync eligibility check), convert_drafts_to_active (async promote to ACTIVE), submit_drafts_for_approval (async route to approval). The lifecycle tools are GENERIC and BULK \u2014 one call accepts up to 500 items mixing any combination of {btResourceId, btType: SALE|PURCHASE|SALE_CREDIT_NOTE|PURCHASE_CREDIT_NOTE}. No need for per-entity tools when promoting/submitting drafts at scale. NOT idempotent on already-promoted drafts.",groups:["drafts"]},{name:"close_procedures",description:"Period-end close checklists: month-end, quarter-end, year-end close. Bank reconciliation job. GST/VAT filing job. Audit preparation. Returns structured blueprints.",groups:["close_jobs"]},{name:"operational_jobs",description:"Operational job checklists: payment runs (incl. batch payment, batch supplier disbursement), credit control/collections, supplier reconciliation, fixed asset review, document collection, statutory filing. Returns structured blueprints.",groups:["operational_jobs"]},{name:"help_center",description:"Search the Jaz help center for how-to articles, feature guides, accounting concepts, and troubleshooting. Returns top matches with title, section, snippet, and source URL. Works without an API key.",groups:["help_center"]},{name:"practice",description:"Practitioner workspace scaffolding: per-client folders, per-engagement files, schemas. Use to onboard new clients (capture legal entity / FY / GST scheme / banks / recurring accruals into CLIENT.md), list active engagements, scaffold a monthly-close / quarterly-gst / annual-statutory engagement, and load client/engagement context before driving accounting work via jaz-jobs blueprints + jaz-recipes. All filesystem-only, offline. Pair with jaz-practice skill for the canonical playbooks.",groups:["practice"]}];function jJ(e,t=5){let r=e.trim().toLowerCase();if(!r)return[];let n=r.split(/[\s_-]+/).filter(i=>i.length>=2);return n.length===0?[]:dl.map(i=>{let s=0,a=i.name.toLowerCase(),c=i.description.toLowerCase();(a===r||a===r.replace(/\s+/g,"_"))&&(s+=5),a.includes(r)&&(s+=3),c.includes(r)&&(s+=1);for(let u of n)a.includes(u)&&(s+=2),c.includes(u)&&(s+=1);return{ns:i,score:s}}).filter(i=>i.score>0).sort((i,s)=>s.score-i.score).slice(0,t).map(i=>i.ns)}function k_(e){let t={type:e.type};if(e.description&&(t.description=e.description),e.enum&&(t.enum=e.enum),e.type==="array"&&e.items&&(t.items=k_(e.items)),e.type==="object"&&e.properties){let r={};for(let[n,o]of Object.entries(e.properties))r[n]=k_(o);t.properties=r,e.required?.length&&(t.required=e.required)}return t}function rc(e,t){let r={};for(let[n,o]of Object.entries(e))r[n]=k_(o);return{type:"object",properties:r,...t.length>0?{required:t}:{}}}function MJ(e){return{name:e.name,description:e.description,input_schema:rc(e.params,e.required),...e.searchHint?{searchHint:e.searchHint}:{}}}function sSe(e){if(typeof e!="string")return e.isDestructive??!1;let t=e;return t.startsWith("delete_")||t.startsWith("pay_")||t.startsWith("finalize_")||t.includes("refund")||t==="remove_org_user"}function BJ(e){if(!e.trim())return{namespaces:dl.map(o=>{let i=o.groups.flatMap(s=>ll(s));return{name:o.name,description:o.description,toolCount:i.length,tools:i.map(s=>s.name)}}),hint:"Call describe_tools with specific tool names to get full schemas before executing."};let t=jJ(e,5);if(t.length===0)return{matches:[],hint:`No tools match "${e}". Try broader terms or call search_tools with empty query to see all namespaces.`};let n=e.toLowerCase().split(/\s+/).filter(Boolean);return{matches:t.map(o=>{let s=o.groups.flatMap(a=>ll(a)).map(a=>{let c=`${a.name} ${a.searchHint??""} ${a.description}`.toLowerCase(),u=n.filter(l=>c.includes(l)).length;return{tool:a,score:u}}).sort((a,c)=>c.score-a.score);return{namespace:o.name,description:o.description,tools:s.map(a=>({name:a.tool.name,description:a.tool.description.split(`
|
|
771
|
+
Returns per-contact result: created, skipped (duplicate), or failed.`,params:{contacts:{type:"array",items:{type:"object",properties:{billingName:{type:"string",description:"Official billing name"},name:{type:"string",description:"Display name"},email:{type:"string",description:"Primary email"},customer:{type:"boolean",description:"Is a customer"},supplier:{type:"boolean",description:"Is a supplier"}},required:["billingName"]},description:"Array of contacts to create"},skipDuplicates:{type:"boolean",description:"Skip contacts that match existing names (default true)"}},required:["contacts"],group:"contacts",readOnly:!1,searchHint:"bulk create multiple customer supplier contacts",execute:async(e,t)=>{let r=t.contacts,n=t.skipDuplicates??!0,o=[];for(let i of r)try{if(n){let a=await hp(e.client,i.name??i.billingName);if(a){o.push({billingName:i.billingName,status:"skipped",resourceId:a.resourceId});continue}}let s=await Yc(e.client,{billingName:i.billingName,name:i.name??i.billingName,emails:i.email?[i.email]:void 0,customer:i.customer??!0,supplier:i.supplier??!1});o.push({billingName:i.billingName,status:"created",resourceId:s.data.resourceId})}catch(s){o.push({billingName:i.billingName,status:"failed",error:s instanceof Error?s.message:String(s)})}return{total:r.length,created:o.filter(i=>i.status==="created").length,skipped:o.filter(i=>i.status==="skipped").length,failed:o.filter(i=>i.status==="failed").length,results:o}}},{name:"quick_fix_transactions",description:`Bulk-update multiple transactions of the same type. Pass entity + resourceIds + attributes \u2014 only included fields change, omitted fields are unchanged.
|
|
772
|
+
|
|
773
|
+
Entities: invoices, bills, customer-credit-notes, supplier-credit-notes, journals, cash-entries, sale-schedules, purchase-schedules, subscription-schedules, journal-schedules.
|
|
774
|
+
|
|
775
|
+
Common attributes (most entities): valueDate, contactResourceId, tags, customFields, capsuleResourceId, currencySettings. Plus per-entity: invoices/bills add dueDate; cash-entries use currencySetting SINGULAR ({rateFunctionalToSource, exchangeToken}); journal-schedules add startDate/endDate/interval. Full per-entity attribute matrix: see jaz-api SKILL.md Rule 107.
|
|
776
|
+
|
|
777
|
+
Tags: string[] max 50 items, max 50 chars each.
|
|
778
|
+
|
|
779
|
+
Response: { updated: string[], failed: [{ resourceId, error, errorCode }] }. HTTP 207 = partial \u2014 check failed.length, retry only failed resourceIds.`,params:{entity:{type:"string",enum:[...sl],description:"Transaction type to update"},resourceIds:{type:"array",items:{type:"string"},description:"Array of transaction resourceIds to update"},attributes:{type:"object",description:'REQUIRED object with fields to update. Only included fields are changed, omitted fields left unchanged. Example: { "valueDate": "2026-03-15", "tags": ["Q1"] }. See tool description for per-entity attribute list.'}},required:["entity","resourceIds"],group:"quick_fix",readOnly:!1,searchHint:"bulk update transactions account tag contact",execute:async(e,t)=>{let r=new Set(["entity","resourceIds","attributes"]),n=t.attributes??{};for(let[o,i]of Object.entries(t))r.has(o)||(n={...n,[o]:i});return Ym(e.client,t.entity,{resourceIds:t.resourceIds,attributes:n})}},{name:"quick_fix_line_items",description:`Bulk-update line items across transactions. Only included fields change.
|
|
780
|
+
|
|
781
|
+
Request patterns:
|
|
782
|
+
- ARAP + accounting (invoices, bills, CNs, journals, cash-entries): lineItemResourceIds + attributes.
|
|
783
|
+
- Sale/purchase/subscription schedules (Pattern C): schedulerUpdates with arrayIndex (zero-based) per line.
|
|
784
|
+
- Journal schedules (Pattern D): schedulerUpdates with lineItemResourceId (UUID), NOT arrayIndex.
|
|
785
|
+
|
|
786
|
+
Common line attributes: name, quantity, unit, unitPrice, discount, organizationAccountResourceId, taxProfileResourceId, classifierConfig. Purchase entities add withholdingTax. Journals/cash-entries use amount + description instead of unit/unitPrice. Full per-entity attribute matrix: see jaz-api SKILL.md Rule 107.
|
|
787
|
+
|
|
788
|
+
Response: { updated: string[], failed: [{ resourceId, error, errorCode }] }. HTTP 207 = partial.`,params:{entity:{type:"string",enum:[...sl],description:"Transaction type"},lineItemResourceIds:{type:"array",items:{type:"string"},description:"Line item resourceIds to update (ARAP + accounting entities)"},attributes:{type:"object",description:"Fields to update on all specified line items"},schedulerUpdates:{type:"array",items:{type:"object"},description:"Per-scheduler updates: [{ schedulerResourceId, lineItemUpdates: [{ arrayIndex, ...fields }] }]. EXCEPTION: journal-schedules use lineItemResourceId (UUID) instead of arrayIndex."}},required:["entity"],group:"quick_fix",readOnly:!1,searchHint:"bulk update line item accounts tax profiles",execute:async(e,t)=>{let r=t.entity,n=["sale-schedules","purchase-schedules","subscription-schedules","journal-schedules"].includes(r),o={};if(n){if(!t.schedulerUpdates)throw new Error("schedulerUpdates is required for scheduler entities (sale-schedules, purchase-schedules, subscription-schedules, journal-schedules)");o.schedulerUpdates=t.schedulerUpdates}else{if(!t.lineItemResourceIds)throw new Error("lineItemResourceIds is required for non-scheduler entities");o.lineItemResourceIds=t.lineItemResourceIds,o.attributes=t.attributes??{}}return Jm(e.client,r,o)}},gt("list_nano_classifiers","List nano classifiers (tracking categories). Paginated. Nano classifiers tag line items with structured categories.","nano_classifiers",(e,t,r)=>m_(e,{limit:r,offset:t}),"list nano classifiers tracking categories types"),Yn("get_nano_classifier","Get a nano classifier by resourceId. Returns type and all classes.","nano_classifiers",(e,t)=>h_(e,t),"get nano classifier tracking category details"),Rt({name:"search_nano_classifiers",description:"Search nano classifiers (tracking categories) by type name.",group:"nano_classifiers",fields:yf,defaults:Df,fetcher:g_,searchHint:"find nano classifiers tracking categories by type"}),{name:"create_nano_classifier",description:"Create a nano classifier (tracking category). Provide a type name and list of class names. printable defaults to true (NOTE: printable: false is currently rejected by a server bug \u2014 always use true).",params:{type:{type:"string",description:'Classifier type name (e.g., "Department", "Project")'},classes:{type:"array",items:{type:"string"},description:'Class names: ["Sales", "Marketing", "Engineering"]'},printable:{type:"boolean",description:"Show on printed documents (default: true). NOTE: false is rejected by a server bug."}},required:["type","classes"],group:"nano_classifiers",readOnly:!1,searchHint:"create new nano classifier tracking category",execute:async(e,t)=>Gm(e.client,{type:t.type,classes:t.classes,printable:t.printable??!0})},{name:"update_nano_classifier",description:"Update a nano classifier \u2014 change type name, modify classes, or toggle printable.",params:{resourceId:{type:"string",description:"Nano classifier resourceId"},type:{type:"string",description:"New type name"},classes:{type:"array",items:{type:"string"},description:'Updated class names: ["Sales", "Marketing"]'},printable:{type:"boolean",description:"Show on printed documents"}},required:["resourceId"],group:"nano_classifiers",readOnly:!1,searchHint:"update nano classifier classes and settings",execute:async(e,t)=>{let r={};return t.type&&(r.type=t.type),t.classes&&(r.classes=t.classes),t.printable!==void 0&&(r.printable=t.printable),Vm(e.client,t.resourceId,r)}},ln("delete_nano_classifier","Delete a nano classifier.","nano_classifiers",(e,t)=>y_(e,t),"permanently delete a nano classifier type"),{name:"list_invoice_payments",description:"List all payments recorded against an invoice. Returns payment records with amounts, dates, and methods.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"payments",readOnly:!0,searchHint:"list payment records on an invoice",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>$b(e.client,t.resourceId)},{name:"list_invoice_credits",description:"List all credit notes applied to an invoice.",params:{resourceId:{type:"string",description:"Invoice resourceId"}},required:["resourceId"],group:"payments",readOnly:!0,searchHint:"list credit applications on an invoice",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>Nb(e.client,t.resourceId)},{name:"reverse_invoice_credit",description:"Reverse (unapply) a credit note from an invoice. The credit note becomes UNAPPLIED again.",params:{resourceId:{type:"string",description:"Invoice resourceId"},creditResourceId:{type:"string",description:"Credit application resourceId to reverse"}},required:["resourceId","creditResourceId"],group:"payments",readOnly:!1,searchHint:"reverse a credit note application on invoice",isDestructive:!0,execute:async(e,t)=>(await kb(e.client,t.resourceId,t.creditResourceId),{reversed:!0,invoiceId:t.resourceId,creditId:t.creditResourceId})},{name:"list_bill_payments",description:"List all payments recorded against a bill. Returns payment records with amounts, dates, and methods.",params:{resourceId:{type:"string",description:"Bill resourceId"}},required:["resourceId"],group:"payments",readOnly:!0,searchHint:"list payment records on a bill",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>Cy(e.client,t.resourceId)},{name:"list_bill_credits",description:"List all credit notes applied to a bill.",params:{resourceId:{type:"string",description:"Bill resourceId"}},required:["resourceId"],group:"payments",readOnly:!0,searchHint:"list credit applications on a bill",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>xy(e.client,t.resourceId)},{name:"reverse_bill_credit",description:"Reverse (unapply) a supplier credit note from a bill. The credit note becomes UNAPPLIED again.",params:{resourceId:{type:"string",description:"Bill resourceId"},creditResourceId:{type:"string",description:"Credit application resourceId to reverse"}},required:["resourceId","creditResourceId"],group:"payments",readOnly:!1,searchHint:"reverse a credit note application on bill",isDestructive:!0,execute:async(e,t)=>(await Ay(e.client,t.resourceId,t.creditResourceId),{reversed:!0,billId:t.resourceId,creditId:t.creditResourceId})},Yn("get_scheduled_invoice","Get a scheduled (recurring) invoice by resourceId.","schedulers",(e,t)=>tv(e,t),"get scheduled recurring invoice details"),{name:"update_scheduled_invoice",description:"Update a scheduled invoice \u2014 change schedule settings and/or the invoice template.",params:{resourceId:{type:"string",description:"Scheduled invoice resourceId"},repeat:{type:"string",description:"Recurrence: WEEKLY, MONTHLY, QUARTERLY, YEARLY"},startDate:{type:"string",description:"First occurrence date (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence date (YYYY-MM-DD)"},status:{type:"string",description:"Status: ACTIVE or PAUSED"},invoice:{type:"object",description:"Invoice template: { reference, valueDate, dueDate, contactResourceId, lineItems, currency, tag, saveAsDraft }"}},required:["resourceId"],group:"schedulers",readOnly:!1,searchHint:"update recurring scheduled invoice settings",execute:async(e,t)=>{let r={};return t.repeat&&(r.repeat=t.repeat),t.startDate&&(r.startDate=t.startDate),t.endDate&&(r.endDate=t.endDate),t.status&&(r.status=t.status),t.invoice&&(r.invoice=t.invoice),rv(e.client,t.resourceId,r)}},ln("delete_scheduled_invoice","Delete a scheduled (recurring) invoice.","schedulers",(e,t)=>nv(e,t),"delete a recurring scheduled invoice"),Yn("get_scheduled_bill","Get a scheduled (recurring) bill by resourceId.","schedulers",(e,t)=>ov(e,t),"get scheduled recurring bill details"),{name:"update_scheduled_bill",description:"Update a scheduled bill \u2014 change schedule settings and/or the bill template.",params:{resourceId:{type:"string",description:"Scheduled bill resourceId"},repeat:{type:"string",description:"Recurrence: WEEKLY, MONTHLY, QUARTERLY, YEARLY"},startDate:{type:"string",description:"First occurrence date (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence date (YYYY-MM-DD)"},status:{type:"string",description:"Status: ACTIVE or PAUSED"},bill:{type:"object",description:"Bill template: { reference, valueDate, dueDate, contactResourceId, lineItems, currency, tag, saveAsDraft }"}},required:["resourceId"],group:"schedulers",readOnly:!1,searchHint:"update recurring scheduled bill settings",execute:async(e,t)=>{let r={};return t.repeat&&(r.repeat=t.repeat),t.startDate&&(r.startDate=t.startDate),t.endDate&&(r.endDate=t.endDate),t.status&&(r.status=t.status),t.bill&&(r.bill=t.bill),iv(e.client,t.resourceId,r)}},ln("delete_scheduled_bill","Delete a scheduled (recurring) bill.","schedulers",(e,t)=>sv(e,t),"delete a recurring scheduled bill"),Yn("get_scheduled_journal","Get a scheduled (recurring) journal by resourceId.","schedulers",(e,t)=>av(e,t),"get scheduled recurring journal details"),{name:"update_scheduled_journal",description:"Update a scheduled journal \u2014 change schedule settings and/or the journal template.",params:{resourceId:{type:"string",description:"Scheduled journal resourceId"},repeat:{type:"string",description:"Recurrence: WEEKLY, MONTHLY, QUARTERLY, YEARLY"},startDate:{type:"string",description:"First occurrence date (YYYY-MM-DD)"},endDate:{type:"string",description:"Last occurrence date (YYYY-MM-DD)"},status:{type:"string",description:"Status: ACTIVE or PAUSED"},valueDate:{type:"string",description:"Journal date (YYYY-MM-DD)"},schedulerEntries:{type:"array",items:{type:"object"},description:"Journal entries: [{ accountResourceId, type: CREDIT|DEBIT, amount, ... }]"},reference:{type:"string",description:"Journal reference"},notes:{type:"string",description:"Journal notes"}},required:["resourceId"],group:"schedulers",readOnly:!1,searchHint:"update recurring scheduled journal settings",execute:async(e,t)=>{let r={};return t.repeat&&(r.repeat=t.repeat),t.startDate&&(r.startDate=t.startDate),t.endDate&&(r.endDate=t.endDate),t.status&&(r.status=t.status),t.valueDate&&(r.valueDate=t.valueDate),t.schedulerEntries&&(r.schedulerEntries=t.schedulerEntries),t.reference&&(r.reference=t.reference),t.notes&&(r.notes=t.notes),cv(e.client,t.resourceId,r)}},ln("delete_scheduled_journal","Delete a scheduled (recurring) journal.","schedulers",(e,t)=>uv(e,t),"delete a recurring scheduled journal"),Yn("get_payment","Get a specific payment record by resourceId. Returns payment amount, method, date, and reference.","payments",(e,t)=>n0(e,t),"get payment record details by id"),{name:"update_payment",description:"Update a payment record \u2014 correct amount, reference, date, method, or account.",params:{resourceId:{type:"string",description:"Payment resourceId (from invoice/bill paymentRecords)"},paymentAmount:{type:"number",description:"Corrected payment amount (bank currency)"},reference:{type:"string",description:"Payment reference"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},paymentMethod:Zm,accountResourceId:{type:"string",description:"Bank/cash account resourceId"},transactionFee:{type:"number",description:"Transaction fee amount"}},required:["resourceId"],group:"payments",readOnly:!1,searchHint:"update payment amount reference date method",execute:async(e,t)=>{let r={};return t.paymentAmount!==void 0&&(r.paymentAmount=t.paymentAmount),t.reference&&(r.reference=t.reference),t.valueDate&&(r.valueDate=t.valueDate),t.paymentMethod&&(r.paymentMethod=t.paymentMethod),t.accountResourceId&&(r.accountResourceId=t.accountResourceId),t.transactionFee!==void 0&&(r.transactionFee=t.transactionFee),o0(e.client,t.resourceId,r)}},ln("delete_payment","Delete (void) a payment record. The associated invoice/bill balance is restored.","payments",(e,t)=>i0(e,t),"delete void a payment record restore balance"),{name:"get_export_columns",description:"List all exportable columns for an entity type, including their paths and data types. Use paths from this response to build custom column sets for export_records or preview_export_records.",params:{entityType:aR},required:["entityType"],group:"export_records",readOnly:!0,isConcurrencySafe:!0,searchHint:"list export columns fields for entity type",execute:async(e,t)=>v_(e.client,t.entityType)},{name:"preview_export_records",description:"Preview an export before generating the file. Returns totalRecords, up to 10 sample rows, resolved column definitions, and a human-readable filterDescription. Use this to confirm scope before calling export_records. Pass either query OR filter, never both.",params:{entityType:aR,query:TJ,filter:OJ,columns:RJ,sort:$J},required:["entityType"],group:"export_records",readOnly:!0,isConcurrencySafe:!0,searchHint:"preview export records count sample rows filter",execute:async(e,t)=>b_(e.client,{entityType:t.entityType,outputFormat:"XLSX",query:t.query,filter:t.filter,columns:t.columns,sort:t.sort})},{name:"export_records",description:`Raw entity-row XLSX export for one entity type (invoices/bills/contacts/items/journals/bank records/cashflow/fixed assets \u2014 one row per record, with column selection). Returns pre-signed download URL (~5 min), fileName, totalCount. Pass query OR filter, never both. Use preview_export_records first to confirm scope.
|
|
789
|
+
|
|
790
|
+
DO NOT use this for analytical / audit reports, financial statements, aging, summary reports, or statement-of-account \u2014 those go through download_export.`,params:{entityType:aR,query:TJ,filter:OJ,columns:RJ,sort:$J},required:["entityType"],group:"export_records",readOnly:!0,isConcurrencySafe:!0,searchHint:"export records download xlsx file url",execute:async(e,t)=>D_(e.client,{entityType:t.entityType,outputFormat:"XLSX",query:t.query,filter:t.filter,columns:t.columns,sort:t.sort})},Rt({name:"search_background_jobs",description:"Search and poll background jobs. ANY operation that returns a jobId (bulk_upsert_contacts, bulk_upsert_items, bank statement import, magic file processing, etc.) can be tracked here. Filter by resourceId (the jobId value) to poll a specific job. Poll until status is SUCCESS, FAILED, or PARTIAL_SUCCESS. Use processedCount/failedCount/totalRecords for progress. IMPORTANT: filter by resourceId field, NOT jobId \u2014 they differ.",group:"background_jobs",fields:Xp,defaults:Qp,fetcher:Hm,searchHint:"poll background job status by jobId type status"}),{name:"bulk_upsert_contacts",description:`Bulk create/update contacts (max 500). resourceId per row \u2192 update (partial; omitted fields preserve existing). Omit resourceId \u2192 create. ASYNC: returns jobId \u2192 poll search_background_jobs(filter:{resourceId:{eq:jobId}}) until SUCCESS / FAILED / PARTIAL_SUCCESS. Per-row failures in background job's errorDetails (NOT failedRows \u2014 that's the sync pattern).
|
|
791
|
+
|
|
792
|
+
Whole-batch 422 (validate before submit): (1) each contact must have at least one of customer:true OR supplier:true (after defaults + backfill from existing); (2) emailList unique within a contact (case-insensitive after trim); (3) paymentTerms.value must be positive integer when paymentTerms.name != "CUSTOM"; (4) no duplicate names within batch (after whitespace+case normalize); (5) billingAddress / shippingAddress: addressLine1 required when address object provided.
|
|
793
|
+
|
|
794
|
+
On PARTIAL_SUCCESS: succeeded rows are committed; inspect errorDetails[].rowIndex and re-submit only failed rows.`,params:{contacts:{type:"array",description:"Array of contacts to create or update (max 500)",items:{type:"object",properties:{resourceId:{type:"string",description:"Contact resourceId (omit for create, provide UUID for update)"},billingName:{type:"string",description:"Billing name (required for create)"},name:{type:"string",description:"Display name (defaults to billingName)"},emails:{type:"array",items:{type:"string"},description:"Email addresses"},customer:{type:"boolean",description:"Mark as customer"},supplier:{type:"boolean",description:"Mark as supplier"},taxId:{type:"string",description:"Tax ID / GST registration number"},taxIdType:{type:"string",description:"Tax ID type (e.g., GST, VAT)"},registrationNumber:{type:"string",description:"Business registration number"},currencyCode:{type:"string",description:"Default currency code (e.g., SGD)"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Contact status"},paymentTerms:{type:"number",description:"Payment terms in days (e.g., 30 for Net 30)"},notes:{type:"string",description:"Internal notes"},billingAddress:{type:"object",description:"Billing address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}},shippingAddress:{type:"object",description:"Shipping address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}}}}}},required:["contacts"],group:"contacts",readOnly:!1,searchHint:"bulk create update contacts upsert",execute:async(e,t)=>(ar(t.contacts,"contacts"),$y(e.client,t.contacts))},{name:"bulk_upsert_invoices",description:`Bulk create/update invoices (max 500). FLAT shape \u2014 ONE line per invoice via itemDescription + totalAmount + invoiceAccountResourceId at row level. For multi-line, use bulk_upsert_invoice_line_items (nested lineItems[]).
|
|
795
|
+
|
|
796
|
+
Natural key: invoiceReference (rows sharing one within a batch are MERGED \u2014 last wins). resourceId per row \u2192 update by UUID; omit \u2192 upsert by invoiceReference.
|
|
797
|
+
|
|
798
|
+
ASYNC: returns jobId \u2192 poll search_background_jobs(filter:{resourceId:{eq:jobId}}); PARTIAL_SUCCESS \u2192 data[0].errorDetails. Dates ISO 8601 (YYYY-MM-DD); dateFormat field removed.`,params:{invoices:{type:"array",description:"Array of invoices to create or update (max 500). Each row needs at least: invoiceReference, contactResourceId, valueDate, totalAmount, invoiceAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string",description:"Optional caller-supplied row index for error reporting"},resourceId:{type:"string",description:"Invoice resourceId (UUID) \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key (e.g., INV-2025-001) \u2014 required"},contactResourceId:{type:"string",description:"Customer contact UUID \u2014 required"},valueDate:{type:"string",description:"Invoice date YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"Due date YYYY-MM-DD"},totalAmount:{type:"number",description:"Total amount (BigDecimal)"},currencyCode:{type:"string",description:"Currency (e.g., SGD)"},invoiceAccountResourceId:{type:"string",description:"Revenue account UUID"},itemDescription:{type:"string",description:"Single-line item description"},internalNotes:{type:"string",description:"Internal notes"},tags:{type:"array",items:{type:"string"},description:"Tag resourceIds"}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk create update invoices upsert import migrate",execute:async(e,t)=>{ar(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),Fb(e.client,r)}},{name:"bulk_upsert_invoice_line_items",description:"Create or update invoices with nested line items in bulk (max 500 invoices per call). Each row carries lineItems[] under its parent invoice (scoped by invoiceReference). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 only.",params:{invoices:{type:"array",description:"Array of invoices with line items (max 500). Each invoice row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string",description:"Invoice resourceId \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"YYYY-MM-DD"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",description:"Line items belonging to this invoice",items:{type:"object",properties:{itemDescription:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string",description:"Unit of measure (pcs, kg, etc.)"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Revenue account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk invoices line items multi-line upsert import",execute:async(e,t)=>{ar(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),Pb(e.client,r)}},{name:"bulk_upsert_bills",description:"Create or update bills in bulk (max 500 per call). FLAT shape: ONE line per bill via `itemDescription` + `totalAmount` + `billAccountResourceId` at row level. For multi-line bills use `bulk_upsert_bill_line_items` instead \u2014 that variant takes nested `lineItems[]`. Natural key: `billReference` (rows sharing one within a batch are MERGED \u2014 last wins). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 only \u2014 dateFormat field was removed.",params:{bills:{type:"array",description:"Array of bills to create or update (max 500). Each row needs at least: billReference, contactResourceId, valueDate, totalAmount, billAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},totalAmount:{type:"number"},currencyCode:{type:"string"},billAccountResourceId:{type:"string",description:"Expense account UUID"},itemDescription:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk create update bills upsert import migrate",execute:async(e,t)=>{ar(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),wy(e.client,r)}},{name:"bulk_upsert_bill_line_items",description:"Create or update bills with nested line items in bulk (max 500 bills per call). Each row carries lineItems[] under its parent bill (scoped by billReference). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures.",params:{bills:{type:"array",description:"Array of bills with line items (max 500). Each bill row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Expense account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk bills line items multi-line upsert import",execute:async(e,t)=>{ar(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),Ty(e.client,r)}},{name:"bulk_upsert_customer_credit_notes",description:"Create or update customer credit notes in bulk (max 500 per call). Natural key: creditNoteReference. Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 only.",params:{customerCreditNotes:{type:"array",description:"Array of customer credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["customerCreditNotes"],group:"customer_credit_notes",readOnly:!1,searchHint:"bulk customer credit notes refund upsert import",execute:async(e,t)=>{ar(t.customerCreditNotes,"customerCreditNotes",500,"customer credit notes");let r=t.customerCreditNotes;return eo(r,["valueDate"]),T0(e.client,r)}},{name:"bulk_upsert_supplier_credit_notes",description:"Create or update supplier credit notes in bulk (max 500 per call). Natural key: creditNoteReference. Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 only.",params:{supplierCreditNotes:{type:"array",description:"Array of supplier credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["supplierCreditNotes"],group:"supplier_credit_notes",readOnly:!1,searchHint:"bulk supplier credit notes refund upsert import",execute:async(e,t)=>{ar(t.supplierCreditNotes,"supplierCreditNotes",500,"supplier credit notes");let r=t.supplierCreditNotes;return eo(r,["valueDate"]),k0(e.client,r)}},{name:"bulk_upsert_journals",description:"Create or update manual journals in bulk (max 500 per call). NATURAL KEY: `journalReference` (NOT `reference` \u2014 every other bulk-upsert uses entityReference, this one is asymmetric). LEGS field: `journalEntries[]` (NOT `entries[]` \u2014 different from `clio journals create` which uses entries). Each leg has `accountResourceId` + `debitAmount` + `creditAmount` (debit + credit must balance per row). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. Dates are ISO 8601 (YYYY-MM-DD) only \u2014 dateFormat field was removed.",params:{journals:{type:"array",description:"Array of journals to create or update (max 500). Each row has entries[] (debit/credit legs).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},journalReference:{type:"string",description:"Natural key \u2014 required (NOTE: field is `journalReference`, not `reference`)"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},journalEntries:{type:"array",description:"Journal legs (debit + credit amounts must balance) \u2014 field is `journalEntries`, NOT `entries`",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Required"},description:{type:"string"},debitAmount:{type:"number"},creditAmount:{type:"number"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["journals"],group:"journals",readOnly:!1,searchHint:"bulk manual journals upsert import migration",execute:async(e,t)=>{ar(t.journals,"journals");let r=t.journals;return eo(r,["valueDate"]),zb(e.client,r)}},{name:"bulk_upsert_fixed_assets",description:`Bulk create/update fixed assets (max 500). Natural key: reference.
|
|
799
|
+
|
|
800
|
+
\u26A0\uFE0F DATE FIELD MISMATCH: REQUEST uses valueDate (NOT purchaseDate); GET response uses purchaseDate. Sending purchaseDate \u2192 cryptic 400 "Invalid request body".
|
|
801
|
+
|
|
802
|
+
Required per row: reference, registrationType (NEW | TRANSFER). Recommended: typeCode, typeName, category (TANGIBLE | INTANGIBLE), cost (synonym: purchaseAmount), valueDate, depreciationStartDate, effectiveLife (synonym: usefulLifeMonths), depreciationMethod, purchaseAssetAccountResourceId, depreciationExpenseAccountResourceId, accumulatedDepreciationAccountResourceId. Account fields = UUIDv4.
|
|
803
|
+
|
|
804
|
+
ASYNC: returns jobId \u2192 poll search_background_jobs(filter:{resourceId:{eq:jobId}}); on PARTIAL_SUCCESS read data[0].errorDetails. Dates ISO 8601 (YYYY-MM-DD).`,params:{fixedAssets:{type:"array",description:"Array of fixed assets to create or update (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},reference:{type:"string",description:"Natural key \u2014 required"},registrationType:{type:"string",enum:["NEW","TRANSFER"],description:"NEW = newly acquired, TRANSFER = inherited from prior system \u2014 required"},typeCode:{type:"string",description:"Asset class code (e.g., FURNITURE_AND_FIXTURE)"},typeName:{type:"string",description:'Human label for the typeCode (e.g., "Furniture and Fixtures")'},category:{type:"string",description:"TANGIBLE | INTANGIBLE"},name:{type:"string",description:"Asset name"},valueDate:{type:"string",description:"Acquisition date YYYY-MM-DD (NOTE: bulk uses `valueDate`, the GET response uses `purchaseDate` \u2014 different fields)"},cost:{type:"number",description:"Cost basis (alias for purchaseAmount on the bulk endpoint)"},purchaseAmount:{type:"number",description:"Cost basis (synonym of `cost`)"},currencyCode:{type:"string"},depreciationStartDate:{type:"number",description:'Epoch milliseconds (NOT YYYY-MM-DD \u2014 inconsistent with valueDate which IS YYYY-MM-DD on this same endpoint). Sending YYYY-MM-DD returns generic 400 "Invalid request body" with no detail. Omit to default to valueDate.'},effectiveLife:{type:"number",description:"Useful life in months (alias for usefulLifeMonths)"},usefulLifeMonths:{type:"number",description:"Useful life in months (synonym of effectiveLife)"},depreciationMethod:{type:"string",description:"e.g., STRAIGHT_LINE, DOUBLE_DECLINING_BALANCE"},purchaseAssetAccountResourceId:{type:"string",description:"Asset (PPE) account UUID \u2014 must be valid UUIDv4"},depreciationExpenseAccountResourceId:{type:"string",description:"Depreciation expense account UUID \u2014 must be valid UUIDv4"},accumulatedDepreciationAccountResourceId:{type:"string",description:"Accumulated depreciation account UUID"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}}}}}},required:["fixedAssets"],group:"fixed_assets",readOnly:!1,searchHint:"bulk fixed assets ppe register upsert import migrate",execute:async(e,t)=>{ar(t.fixedAssets,"fixedAssets",500,"fixed assets");let r=t.fixedAssets;return eo(r,["valueDate"]),GS(e.client,r)}},{name:"quick_reconcile",description:"Bulk-reconcile bank statement entries against a list of journals (max 500). Reconciliation mode is hardcoded to QUICK_RECON. Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails. Caller provides bankAccountResourceId + journalsForReconciliation[] (each row: bankStatementEntryResourceId, journalReference, journalAccountResourceId).",params:{bankAccountResourceId:{type:"string",description:"Bank account UUID (the entries belong to this account)"},journalsForReconciliation:{type:"array",description:"Per-row reconciliation instructions (max 500).",items:{type:"object",properties:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},journalReference:{type:"string",description:"Journal reference text \u2014 required"},journalAccountResourceId:{type:"string",description:"Offsetting account UUID (revenue for cash-in, expense for cash-out) \u2014 required"},contactResourceId:{type:"string",description:"Contact UUID"},capsuleResourceId:{type:"string",description:"Capsule UUID"},taxProfileResourceId:{type:"string",description:"Tax profile UUID"},internalNotes:{type:"string"},journalEntryDescription:{type:"string"},tags:{type:"array",items:{type:"string"}},rowIndex:{type:"string",description:"Optional caller-supplied index for error correlation"}}}}},required:["bankAccountResourceId","journalsForReconciliation"],group:"reconciliations",readOnly:!1,searchHint:"bulk reconcile bank statement journals match",execute:async(e,t)=>(ar(t.journalsForReconciliation,"journalsForReconciliation",500,"journals"),I_(e.client,t))},{name:"apply_bank_rule",description:"Apply a pre-configured bank rule (action shortcut) to a batch of bank statement entries (max 500). Async \u2014 returns a jobId. Poll search_background_jobs filtered by resourceId. The rule executes its configured action (e.g. RECONCILE_WITH_DIRECT_CASH_ENTRY) on each entry.",params:{actionShortcutResourceId:{type:"string",description:"Bank rule UUID \u2014 required"},businessTransactionResourceIds:{type:"array",description:"Bank statement entry UUIDs to apply the rule to (max 500). Note: the field is named businessTransactionResourceIds for legacy reasons but accepts bank entry IDs.",items:{type:"string"}}},required:["actionShortcutResourceId","businessTransactionResourceIds"],group:"reconciliations",readOnly:!1,searchHint:"bank rule apply action shortcut bulk reconcile",execute:async(e,t)=>(ar(t.businessTransactionResourceIds,"businessTransactionResourceIds",500,"entries"),C_(e.client,t))},{name:"reconcile_direct_cash_entry",description:"Reconcile a bank statement entry with a single cash-in / cash-out line. Direction (cash-in vs cash-out) is INFERRED from the bank entry sign. Sync \u2014 returns the reconciled entry status. NOT idempotent: calling twice on the same bankStatementEntryResourceId creates duplicate journals. Confirm reconciled-state via view_auto_reconciliation before retrying.",params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID (used to look up the entry) \u2014 required"},reference:{type:"string",description:"Reference for the cash entry \u2014 required"},accountResourceId:{type:"string",description:"Offsetting account UUID (revenue for cash-in, expense for cash-out) \u2014 required"},amount:{type:"number",description:"Amount in source currency. Defaults to bank entry amount if omitted."},description:{type:"string"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"},internalNotes:{type:"string"},bankAccountJournalEntryDescription:{type:"string",description:"Description for the bank-side journal entry"},tags:{type:"array",items:{type:"string"}},taxVatApplicable:{type:"boolean"},taxInclusion:{type:"boolean"},capsuleResourceId:{type:"string"}},required:["bankStatementEntryResourceId","bankAccountResourceId","reference","accountResourceId"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry direct cash in out single line",execute:async(e,t)=>x_(e.client,t)},{name:"reconcile_cash_journal",description:"Reconcile a bank statement entry with a multi-line cashflow journal (multiple cash splits, max 200 lines). Sync \u2014 returns the reconciled entry status. NOT idempotent \u2014 confirm reconciled-state before retrying.",params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},reference:{type:"string",description:"Journal reference \u2014 required"},journalEntries:{type:"array",description:"Cash journal lines (max 200). Each row is one debit OR credit against an account.",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Account UUID \u2014 required"},amount:{type:"number",description:"Amount in source currency \u2014 required (>0)"},description:{type:"string"},taxProfileResourceId:{type:"string"}}}},contactResourceId:{type:"string"},bankAccountJournalEntryDescription:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},taxVatApplicable:{type:"boolean"},taxInclusion:{type:"boolean"},capsuleResourceId:{type:"string"}},required:["bankStatementEntryResourceId","bankAccountResourceId","reference","journalEntries"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry multi line cash journal splits",execute:async(e,t)=>(ar(t.journalEntries,"journalEntries",200,"entries"),A_(e.client,t))},{name:"reconcile_manual_journal",description:'\u26A0\uFE0F CALLER PROVIDES ONLY THE OFFSET LEG(S) \u2014 backend AUTO-ADDS the bank-side leg from the statement entry. Sending both debit AND credit legs \u2192 422 "sum of debit and credit amounts are not equal" (your sides duplicate after the auto-add). Reconcile a bank statement entry with a double-entry manual journal. Sync \u2014 returns the reconciled entry status. valueDate prefills from bank entry if omitted. NOT idempotent.',params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},status:{type:"string",enum:["DRAFT","ACTIVE"],description:"Journal status \u2014 required"},journalEntries:{type:"array",description:"Offset-side journal entries only (max 200). The bank-side leg is auto-added by the API.",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Account UUID \u2014 required"},type:{type:"string",enum:["DEBIT","CREDIT"]},amount:{type:"number",description:"Amount \u2014 required"},description:{type:"string"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}},reference:{type:"string"},valueDate:{type:"string",description:"YYYY-MM-DD. Defaults to bank entry value date."},contactResourceId:{type:"string"},internalNotes:{type:"string"},bankAccountJournalEntryDescription:{type:"string"},taxVatApplicable:{type:"boolean"},taxInclusion:{type:"boolean"},tags:{type:"array",items:{type:"string"}},capsuleResourceId:{type:"string"}},required:["bankStatementEntryResourceId","bankAccountResourceId","status","journalEntries"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry manual journal double entry",execute:async(e,t)=>(ar(t.journalEntries,"journalEntries",200,"entries"),w_(e.client,t))},{name:"reconcile_cash_transfer",description:"Reconcile a bank statement entry with an inter-account transfer. Sync \u2014 returns the reconciled entry status. amount is required only when the counterparty account is in a non-functional currency. NOT idempotent.",params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},accountResourceId:{type:"string",description:"Counterparty cash account UUID \u2014 required"},reference:{type:"string",description:"Transfer reference \u2014 required"},amount:{type:"number",description:"Amount in source currency. Required only for cross-currency transfers."},contactResourceId:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},capsuleResourceId:{type:"string"}},required:["bankStatementEntryResourceId","bankAccountResourceId","accountResourceId","reference"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry transfer between accounts",execute:async(e,t)=>T_(e.client,t)},{name:"reconcile_invoice_receipt",description:'\u26A0\uFE0F BSE must have `paymentDirection: PAYIN` (money in \u2014 AR). Produce via `bank add-records` with a POSITIVE amount (creates `credit_amount > 0` \u2192 PAYIN). Statement-imported BSEs from `bank import` also work. The error code "Invalid business transaction type" (422) is misleadingly named \u2014 the actual gate is direction, not entry type. Create an invoice and auto-reconcile it to a bank statement entry (AR). Sync \u2014 returns the reconciled entry status. valueDate / dueDate / payment amount prefill from the bank entry if omitted. NOT idempotent.',params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},invoiceDetails:{type:"object",description:"The invoice to create. Required.",properties:{reference:{type:"string",description:"Invoice reference \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID"},valueDate:{type:"string",description:"YYYY-MM-DD. Defaults to bank entry value date."},dueDate:{type:"string",description:"YYYY-MM-DD. Defaults to value date."},taxInclusion:{type:"boolean"},isTaxVATApplicable:{type:"boolean"},lineItems:{type:"array",description:"Invoice line items (max 500) \u2014 required",items:{type:"object",properties:{name:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},organizationAccountResourceId:{type:"string",description:"Revenue account UUID"},itemResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}},recordedPayment:{type:"object",description:"Optional. The matching payment record \u2014 auto-built from the bank entry if omitted.",properties:{reference:{type:"string"},valueDate:{type:"string",description:"YYYY-MM-DD. Defaults to bank entry value date."},organizationAccountResourceId:{type:"string"},paymentAmount:{type:"number"},transactionAmount:{type:"number"},paymentMethod:{type:"string",description:"Defaults to BANK_TRANSFER"}}},capsuleResourceId:{type:"string"}}}},required:["bankStatementEntryResourceId","bankAccountResourceId","invoiceDetails"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry invoice receipt AR sale",execute:async(e,t)=>(oR(t.invoiceDetails,"invoiceDetails"),O_(e.client,t))},{name:"reconcile_bill_receipt",description:'\u26A0\uFE0F BSE must have `paymentDirection: PAYOUT` (money out \u2014 AP). Produce via `bank add-records` with a NEGATIVE amount (creates `debit_amount > 0` \u2192 PAYOUT). Statement-imported BSEs from `bank import` also work. The error code "Invalid business transaction type" (422) is misleadingly named \u2014 the actual gate is direction, not entry type. Create a bill and auto-reconcile it to a bank statement entry (AP). Sync \u2014 returns the reconciled entry status. valueDate / dueDate / payment amount prefill from the bank entry if omitted. NOT idempotent.',params:{bankStatementEntryResourceId:{type:"string",description:"Bank entry UUID \u2014 required"},bankAccountResourceId:{type:"string",description:"Bank account UUID \u2014 required"},billDetails:{type:"object",description:"The bill to create. Required.",properties:{reference:{type:"string",description:"Bill reference \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID"},valueDate:{type:"string",description:"YYYY-MM-DD. Defaults to bank entry value date."},dueDate:{type:"string",description:"YYYY-MM-DD. Defaults to value date."},taxInclusion:{type:"boolean"},isTaxVATApplicable:{type:"boolean"},lineItems:{type:"array",description:"Bill line items (max 500) \u2014 required",items:{type:"object",properties:{name:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},organizationAccountResourceId:{type:"string",description:"Expense account UUID"},itemResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}},recordedPayment:{type:"object",description:"Optional. The matching payment record \u2014 auto-built from the bank entry if omitted.",properties:{reference:{type:"string"},valueDate:{type:"string",description:"YYYY-MM-DD"},organizationAccountResourceId:{type:"string"},paymentAmount:{type:"number"},transactionAmount:{type:"number"},paymentMethod:{type:"string",description:"Defaults to BANK_TRANSFER"}}},capsuleResourceId:{type:"string"}}}},required:["bankStatementEntryResourceId","bankAccountResourceId","billDetails"],group:"reconciliations",readOnly:!1,searchHint:"reconcile bank entry bill receipt AP purchase",execute:async(e,t)=>(oR(t.billDetails,"billDetails"),R_(e.client,t))},{name:"validate_drafts",description:`BULK validate up to 500 draft business transactions in ONE call, mixing any btType. SYNC \u2014 returns per-item errors + display data; no state change. Run before convert_drafts_to_active.
|
|
805
|
+
|
|
806
|
+
btType enum: SALE = invoice, PURCHASE = bill, SALE_CREDIT_NOTE = customer CN, PURCHASE_CREDIT_NOTE = supplier CN. Journals NOT in this enum.
|
|
807
|
+
|
|
808
|
+
Each result carries contactSignals (Mid-7: cadence, outliers, severity, divergences from contact's modal pattern; null if no contact / no history) and breakdown (Balance-panel payload: line items + subtotal/tax/total/balance/exchange rate). Top-level contactSignalsMeta.unavailable=true \u2192 freshness layer offline for whole batch.
|
|
809
|
+
|
|
810
|
+
USE THIS to score a specific draft against contact history. For stand-alone "what does this contact normally look like?" without a draft \u2192 use get_contact_signals.`,params:{items:{type:"array",description:"Draft business transaction references (max 500). Mix any btType freely.",items:{type:"object",properties:{btResourceId:{type:"string",description:"Draft BT resource ID (UUID) \u2014 required"},btType:{type:"string",enum:["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"],description:"Required"}}}}},required:["items"],group:"drafts",readOnly:!0,isConcurrencySafe:!0,searchHint:"validate drafts eligibility check before convert promote",execute:async(e,t)=>(al(t.items),S_(e.client,t.items))},{name:"convert_drafts_to_active",description:"BULK promote \u2014 finalize up to 500 draft business transactions to ACTIVE in ONE call, mixing any combination of invoices, bills, and credit notes (no per-type tools needed). ASYNC: returns a jobId \u2014 poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. NOT idempotent: a second call on already-promoted drafts returns 422. Filter the draft list by status: DRAFT before submitting. Pair with validate_drafts for a pre-flight check on large batches.",params:{items:{type:"array",description:"Draft BT references (max 500). Mix any btType.",items:{type:"object",properties:{btResourceId:{type:"string",description:"Draft BT resource ID (UUID) \u2014 required"},btType:{type:"string",enum:["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"],description:"Required"}}}}},required:["items"],group:"drafts",readOnly:!1,searchHint:"convert drafts to active promote finalize bulk",execute:async(e,t)=>(al(t.items),__(e.client,t.items))},{name:"submit_drafts_for_approval",description:"BULK submit \u2014 route up to 500 draft business transactions into the approval workflow in ONE call, mixing any combination of invoices, bills, and credit notes. ASYNC: returns a jobId \u2014 poll search_background_jobs filtered by resourceId; on PARTIAL_SUCCESS read data[0].errorDetails for per-row failures. NOT idempotent on drafts that already have an in-flight approval request.",params:{items:{type:"array",description:"Draft BT references (max 500). Mix any btType.",items:{type:"object",properties:{btResourceId:{type:"string",description:"Draft BT resource ID (UUID) \u2014 required"},btType:{type:"string",enum:["SALE","PURCHASE","SALE_CREDIT_NOTE","PURCHASE_CREDIT_NOTE"],description:"Required"}}}}},required:["items"],group:"drafts",readOnly:!1,searchHint:"submit drafts for approval workflow review bulk",execute:async(e,t)=>(al(t.items),E_(e.client,t.items))},{name:"search_help_center",description:`Offline. Search the Jaz help center for how-to articles, feature guides, and accounting concepts. Use this for "how do I..." or "what is..." questions about Jaz: bank reconciliation, GST/VAT filing, multi-currency, fixed assets, custom fields, integrations, and so on. Returns top matching articles with title, section, snippet, and source URL.
|
|
811
|
+
|
|
812
|
+
Works without an API key \u2014 bundle ships the help center corpus locally.`,params:{query:{type:"string",description:'Natural-language question or keywords (e.g. "how do I reconcile a bank statement", "set up GST", "multi-currency invoice").'},limit:{type:"number",description:"Maximum number of articles to return (default 3, max 10)."},section:{type:"string",description:'Optional: restrict to a single help-center section slug (e.g. "bank-reconciliations", "invoices").'}},required:["query"],group:"help_center",readOnly:!0,searchHint:"help center docs how to guide article search question",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=String(t.query??"").trim();if(!r)return{error:"Query is required.",hint:"Pass a natural-language question or keywords."};let n=typeof t.limit=="number"&&!Number.isNaN(t.limit)?t.limit:3,o=Math.max(1,Math.min(10,Math.floor(n))),i=typeof t.section=="string"?t.section:void 0;try{let s=Bf();if(i&&!s.sections.some(c=>c.slug===i))return{error:`Unknown section: "${i}".`,available:s.sections.map(c=>c.slug),hint:"Omit the section parameter to search every section, or pick a slug from the available list."};let a=ki(s,r,{limit:o,section:i});return a.length===0?{results:[],hint:"No matching articles. Try broader keywords or rephrase the question."}:{results:a.map(c=>({title:c.article.title,section:c.section.name,sectionSlug:c.section.slug,snippet:c.article.snippet,url:c.article.sourceUrl,score:Math.round(c.score*1e3)/1e3,matchedTerms:c.matchedTerms})),totalArticles:s.articleCount,searchedSections:i?[i]:void 0}}catch(s){return{error:"Help center search failed.",detail:s instanceof Error?s.message:String(s),hint:"The bundled help-center index may be missing or corrupt."}}}},{name:"practice_init",description:"Offline. Scaffold the practitioner workspace at ~/Documents/Jaz Practice (or PRACTICE_HOME env override). Creates clients/, templates/, and a starter PRACTICE.md from the firm name. Idempotent on re-run. Filesystem-only. Run once before practice_onboard_client.",params:{firmName:{type:"string",description:"Display name shown on outputs."},defaultBaseCurrency:{type:"string",description:'Default currency for new clients (e.g., "SGD"). Defaults to SGD.'},defaultJurisdiction:{type:"string",description:'ISO-3166 alpha-2 (e.g., "SG"). Defaults to SG.'},defaultJazApiKey:{type:"string",description:"Optional default JAZ_API_KEY for all clients (last in resolution chain after CLIENT.md override and env)."},practiceHome:{type:"string",description:"Optional override for the practice home dir. Defaults to ~/Documents/Jaz Practice or PRACTICE_HOME env."}},required:["firmName"],group:"practice",readOnly:!1,searchHint:"practice init firm setup workspace scaffold",isConcurrencySafe:!1,maxResultSizeChars:5e3,execute:async(e,t)=>{let r=nn(t.practiceHome);Ra(r);let n=$a(r),o=n??{v:1,firm_name:String(t.firmName),default_jaz_api_key:t.defaultJazApiKey,default_base_currency:t.defaultBaseCurrency??"SGD",default_jurisdiction:t.defaultJurisdiction??"SG",materiality_default:1e3,body:"Firm-level defaults that flow into every new client. Changes here apply to NEW clients only."};return n&&(t.firmName&&(o.firm_name=String(t.firmName)),t.defaultBaseCurrency&&(o.default_base_currency=String(t.defaultBaseCurrency)),t.defaultJurisdiction&&(o.default_jurisdiction=String(t.defaultJurisdiction)),t.defaultJazApiKey&&(o.default_jaz_api_key=String(t.defaultJazApiKey))),Ep(r,o),{practiceHome:r,firmName:o.firm_name,defaultBaseCurrency:o.default_base_currency,defaultJurisdiction:o.default_jurisdiction,clientsDir:`${r}/clients`,wasExisting:n!==null}}},{name:"practice_list_clients",description:"Offline. List all clients in the practitioner workspace. Returns slugs and last-active engagement per client. Filesystem-only. Use as a dashboard entry point before practice_load_client.",params:{practiceHome:{type:"string",description:"Optional override; defaults to ~/Documents/Jaz Practice."}},required:[],group:"practice",readOnly:!0,searchHint:"practice list clients dashboard",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=nn(t.practiceHome),o=Ap(r).map(i=>{let s=Oi(r,i),a=Fa(r,i);return{slug:i,legalEntityName:s?.legal_entity_name??i,fyEnd:s?.fy_end,baseCurrency:s?.base_currency,gstScheme:s?.gst_scheme,hasJazApiKeyOverride:!!s?.jaz_api_key_override,activeEngagements:a}});return{practiceHome:r,total:o.length,clients:o}}},{name:"practice_load_client",description:"Offline. Read a client's CLIENT.md master file. Returns the full record (legal entity, FY, COA mapping notes, banks, recurring accruals, recurring engagements, etc.) plus the list of active engagements. Filesystem-only. Use this to give the agent client context before invoking jaz-jobs blueprints or jaz-recipes recipes.",params:{slug:{type:"string",description:'Client slug (lowercase, hyphenated; e.g., "acme-pte-ltd").'},practiceHome:{type:"string",description:"Optional override."}},required:["slug"],group:"practice",readOnly:!0,searchHint:"practice load client read context CLIENT.md",isConcurrencySafe:!0,maxResultSizeChars:3e4,execute:async(e,t)=>{let r=nn(t.practiceHome),n=String(t.slug);try{Sn(n,"client slug")}catch(s){return{error:s instanceof Error?s.message:String(s)}}let o=Oi(r,n);if(!o)return{error:`Client not found: ${n}`,hint:"Run practice_list_clients to see available slugs, or practice_onboard_client to create a new one."};let i=Fa(r,n).map(s=>{let a=Pa(r,n,s);return a?{slug:s,type:a.type,period:a.period,status:a.status,scope:a.scope_summary}:null}).filter(Boolean);return{client:Cp(o),engagements:i}}},{name:"practice_onboard_client",description:"Offline. Scaffold a new client folder and write the initial CLIENT.md. Captures legal entity, FY end, GST scheme, banks, recurring accruals, recurring engagements. Optionally sets a per-client JAZ_API_KEY override for multi-org agencies. Filesystem-only. After this, call practice_create_engagement for the first period.",params:{legalEntityName:{type:"string",description:"Full legal name as registered with ACRA / equivalent."},uen:{type:"string",description:"Singapore UEN if applicable."},registeredAddress:{type:"string",description:"ACRA-registered address."},country:{type:"string",description:"ISO-3166 alpha-2; defaults to PRACTICE.md.default_jurisdiction."},baseCurrency:{type:"string",description:"ISO-4217; defaults to PRACTICE.md.default_base_currency."},fyEnd:{type:"string",description:'MM-DD format (e.g., "12-31"). Drives annual-statutory engagement period boundaries.'},gstScheme:{type:"string",enum:["quarterly","monthly","not-registered"],description:"GST registration cadence; drives quarterly-gst engagement scheduling."},gstRegistrationNumber:{type:"string",description:"Required when gstScheme != not-registered."},corporateTaxBracket:{type:"string",enum:["standard","startup_exemption","partial_exemption"],description:"Drives Form C-S computation path during annual-statutory."},jazApiKeyOverride:{type:"string",description:"Optional per-client API key. Resolution: this override -> PRACTICE.md.default_jaz_api_key -> JAZ_API_KEY env."},jazOrgId:{type:"string",description:"Optional Jaz org UUID. Pinned for tool invocations against this client."},materialityThreshold:{type:"number",description:"In base currency. Defaults to PRACTICE.md.materiality_default."},bankAccounts:{type:"array",description:"Array of {name, currency, account_number_ref?, jaz_resource_id?}. Read by monthly-close before search_bank_records.",items:{type:"object"}},recurringAccruals:{type:"array",description:'Array of {name, gl_account, vendor?, estimation_method?, fixed_amount?}. Drives plan_recipe(name: "accrued-expense") in monthly-close.',items:{type:"object"}},recurringEngagements:{type:"array",description:'Array of {type, cadence}. e.g. [{type: "monthly-close", cadence: "monthly"}]. Drives engagement scheduling.',items:{type:"object"}},keyContacts:{type:"array",description:"Array of {name, role, email?}.",items:{type:"object"}},practiceHome:{type:"string",description:"Optional override."}},required:["legalEntityName","fyEnd","gstScheme"],group:"practice",readOnly:!1,searchHint:"practice onboard new client setup CLIENT.md",isConcurrencySafe:!1,maxResultSizeChars:5e3,execute:async(e,t)=>{let r=nn(t.practiceHome);Ra(r);let n=$a(r);try{let o=wp(r,{legal_entity_name:String(t.legalEntityName),uen:t.uen,registered_address:t.registeredAddress,country:t.country,base_currency:t.baseCurrency,fy_end:String(t.fyEnd),gst_scheme:t.gstScheme,gst_registration_number:t.gstRegistrationNumber,corporate_tax_bracket:t.corporateTaxBracket,jaz_api_key_override:t.jazApiKeyOverride,jaz_org_id:t.jazOrgId,materiality_threshold:t.materialityThreshold,bank_accounts:t.bankAccounts,recurring_accruals:t.recurringAccruals,recurring_engagements:t.recurringEngagements,key_contacts:t.keyContacts},n);return{slug:o.slug,path:o.path,nextStep:"Call practice_create_engagement to scaffold the first engagement (e.g., type: monthly-close for the current period)."}}catch(o){return{error:o instanceof Error?o.message:String(o),hint:"If the slug already exists, choose a different legal_entity_name or remove the existing folder."}}}},{name:"practice_create_engagement",description:"Offline. Scaffold a new engagement folder under a client. Creates ENGAGEMENT.md from the type-specific template plus inputs/, workpapers/, deliverables/ subdirs. Filesystem-only. Engagement type drives which jaz-jobs blueprint and jaz-recipes recipes the agent should invoke. period is REQUIRED for monthly-close (YYYY-MM), quarterly-gst (YYYY-QN), and annual-statutory (YYYY) \u2014 only onboarding and adhoc accept free-text or omitted period.",params:{clientSlug:{type:"string",description:"Existing client slug."},type:{type:"string",enum:["monthly-close","quarterly-gst","annual-statutory","onboarding","adhoc"],description:"Engagement type. monthly-close uses generate_month_end_blueprint; quarterly-gst uses generate_gst_vat_blueprint; annual-statutory uses generate_year_end_blueprint + generate_audit_prep_blueprint + generate_statutory_filing_blueprint."},period:{type:"string",description:"Period in the format the type expects. REQUIRED for monthly-close (YYYY-MM, e.g. 2026-03), quarterly-gst (YYYY-QN, e.g. 2026-Q1), annual-statutory (YYYY, e.g. 2026). Free-text or omitted accepted only for onboarding and adhoc. Validated server-side; malformed periods rejected before scaffolding to prevent audit-trail gaps."},scopeSummary:{type:"string",description:"One sentence describing what this engagement produces."},targetCompletionDate:{type:"string",description:"YYYY-MM-DD. Used by practice_list_clients to flag overdue work."},practiceHome:{type:"string",description:"Optional override."}},required:["clientSlug","type"],group:"practice",readOnly:!1,searchHint:"practice create engagement scaffold ENGAGEMENT.md monthly close gst statutory",isConcurrencySafe:!1,maxResultSizeChars:5e3,execute:async(e,t)=>{let r=nn(t.practiceHome),n=String(t.clientSlug);try{Sn(n,"client slug")}catch(s){return{error:s instanceof Error?s.message:String(s)}}let o=Oi(r,n);if(!o)return{error:`Client not found: ${n}`,hint:"Run practice_list_clients or practice_onboard_client first."};let i=t.type;try{Cu(i,t.period)}catch(s){return{error:s instanceof Error?s.message:String(s),hint:"Recurring/statutory engagements require a period: monthly-close=YYYY-MM, quarterly-gst=YYYY-QN, annual-statutory=YYYY."}}try{let s=Op(r,n,{type:i,period:t.period,scope_summary:t.scopeSummary,target_completion_date:t.targetCompletionDate},o.jaz_org_id);return{slug:s.slug,path:s.path,nextStep:"Open ENGAGEMENT.md and follow the type-specific playbook in jaz-practice/references/<type>.md."}}catch(s){return{error:s instanceof Error?s.message:String(s),hint:"If the engagement folder already exists, pick a different period or load the existing one with practice_load_engagement."}}}},{name:"practice_load_engagement",description:"Offline. Read an engagement's ENGAGEMENT.md file. Returns scope, status, period, queries, decisions log. Pair with practice_load_client to get full context before driving jaz-jobs / jaz-recipes work.",params:{clientSlug:{type:"string",description:"Client slug."},engagementSlug:{type:"string",description:'Engagement slug (e.g., "monthly-close-2026-03").'},practiceHome:{type:"string",description:"Optional override."}},required:["clientSlug","engagementSlug"],group:"practice",readOnly:!0,searchHint:"practice load engagement read ENGAGEMENT.md context",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>{let r=nn(t.practiceHome),n=String(t.clientSlug),o=String(t.engagementSlug);try{Sn(n,"client slug"),Sn(o,"engagement slug")}catch(s){return{error:s instanceof Error?s.message:String(s)}}let i=Pa(r,n,o);return i?{engagement:i}:{error:`Engagement not found: ${n}/${o}`,hint:"Run practice_load_client to see active engagement slugs."}}}];var $_=null;function nSe(){if(!$_){$_=new Map;for(let e of ul)$_.set(e.name,e)}return $_}function N_(e){return nSe().get(e)}function uR(){return ul}function ll(e){return uR().filter(t=>t.group===e)}la();function oSe(e){switch(e){case 401:return"Invalid or missing API key. Run `clio auth add` or set JAZ_API_KEY.";case 403:return"Insufficient permissions for this operation.";case 404:return"Resource not found \u2014 check the resourceId. Use a search/list tool to look it up.";case 409:return"Conflict \u2014 resource may have been modified. Re-fetch and retry.";case 422:return"Validation error \u2014 check field values against the tool description.";case 429:return"Rate limited \u2014 wait a moment and retry.";default:return""}}function PJ(e){if(e instanceof Zi){let r=oSe(e.status);return{error:e.message,status:e.status,endpoint:e.endpoint,...r?{hint:r}:{}}}return{error:e instanceof Error?e.message:String(e)}}function LJ(e,t){if(e.readOnly)return{valid:!0,errors:[]};let r=[];for(let n of e.required){let o=t[n];if(o==null){r.push(`Missing required field: ${n}`);continue}typeof o=="string"&&o.trim()===""&&r.push(`Required field "${n}" is empty`)}for(let[n,o]of Object.entries(t)){if(o==null)continue;let i=e.params[n];if(!i)continue;let s=iSe(n,o,i);s&&r.push(s),i.enum&&typeof o=="string"&&(i.enum.includes(o)||r.push(`Field "${n}" value "${o}" not in allowed values: ${i.enum.join(", ")}`))}return{valid:r.length===0,errors:r}}function iSe(e,t,r){switch(r.type){case"string":if(typeof t!="string")return`Field "${e}" expected string, got ${typeof t}`;break;case"number":if(typeof t!="number"||!Number.isFinite(t))return`Field "${e}" expected finite number, got ${typeof t=="number"?"non-finite":typeof t}`;break;case"boolean":if(typeof t!="boolean")return`Field "${e}" expected boolean, got ${typeof t}`;break;case"array":if(!Array.isArray(t))return`Field "${e}" expected array, got ${typeof t}`;break;case"object":if(typeof t!="object"||Array.isArray(t))return`Field "${e}" expected object, got ${Array.isArray(t)?"array":typeof t}`;break}return null}var dl=[{name:"invoices",description:"Sales invoices (INV/SI). Create, search, get, update, delete, pay, finalize, apply credits, download PDF. Also: receivables, AR, AR aging, billing, overdue invoices, dunning, recurring invoices.",groups:["invoices"]},{name:"customer_credit_notes",description:"Customer credit notes (CN). Create, search, update, delete, finalize, refund, download PDF. Also: sales returns, customer CN.",groups:["customer_credit_notes"]},{name:"bills",description:"Purchase bills (PO/PI). Create, search, get, update, delete, pay, finalize, apply credits. Also: payables, AP, vendor invoices, supplier bills.",groups:["bills"]},{name:"supplier_credit_notes",description:"Supplier credit notes. Create, search, update, delete, finalize, refund. Also: purchase returns, debit notes, supplier CN.",groups:["supplier_credit_notes"]},{name:"journals",description:"Journal entries (JE). Create, search, update, delete manual journals. Also: adjusting entries, accruals, reclassifications, corrections.",groups:["journals"]},{name:"cash_entries",description:"Cash-in receipts and cash-out disbursements for external cash movements. WHEN TO USE: money received from customers/external \u2192 cash-in. Money paid to suppliers/external \u2192 cash-out. For internal account-to-account transfers, use cash_transfers namespace.",groups:["cash_entries"]},{name:"cash_transfers",description:"Cash transfers between your own bank/cash accounts and cashflow transaction search. WHEN TO USE: moving funds between own accounts (main bank \u2192 petty cash, USD \u2192 SGD). For external receipts/payments, use cash_entries namespace.",groups:["cash_transfers"]},{name:"bank_accounts",description:"Bank accounts, bank statement imports (CSV/OFX), bank records search, auto-reconciliation. For unreconciled queries: ALWAYS search bank records with status UNRECONCILED after listing accounts. Also: bank feeds, bank balance.",groups:["bank"]},{name:"bank_rules",description:"Bank reconciliation rules (action shortcuts). Create, search, update, delete bank rules. Configure auto-matching rules for bank records.",groups:["bank_rules"]},{name:"reconciliations",description:"Apply a reconciliation decision to a bank statement entry \u2014 write side. Auto-match and match bank records to invoices, bills, journals, cash entries, or transfers. Distinct from bank_accounts/bank_rules (which configure auto-reconciliation) and view_auto_reconciliation (which queries suggestions). Eight endpoints: quick_reconcile + apply_bank_rule (async, bulk), and direct_cash_entry / cash_journal / manual_journal / cash_transfer / invoice_receipt / bill_receipt (sync, per-entry). Most fields prefill from the bank entry when omitted.",groups:["reconciliations"]},{name:"financial_reports",description:"Core financial statements: trial balance (TB), balance sheet (BS/B/S), profit & loss (PnL/P&L/income statement), cash flow, general ledger (GL), cash balance/position, equity movement, VAT/GST ledger. Also: how profitable, what is the balance.",groups:["financial_reports"]},{name:"operational_reports",description:"Aging and operational reports: aged receivables (AR aging), aged payables (AP aging), AR report, bank balance summary, bank reconciliation reports, fixed asset (FA) summary, FA reconciliation. Data exports (CSV/Excel/XLSX). Anomaly detection and audit analysis: anomalous invoices, anomalous bills, cashflow anomalies, GL journal audit, exchange rate audit, receivables customer risk, cash expense health. Also: overdue analysis, how much owed, suspicious transactions, audit trail.",groups:["operational_reports","exports"]},{name:"contacts",description:"Contacts (customers/suppliers/vendors), contact groups, customer segmentation. Create, search, get, update, delete contacts. Bulk upsert contacts from CSV / spreadsheet imports \u2014 async, returns jobId, poll background_jobs. List/create contact groups.",groups:["contacts","contact_groups"]},{name:"items_and_inventory",description:"Products, services, inventory items. Create, search, get, update, delete items. Check inventory balance. Also: SKU, catalog, stock.",groups:["items","inventory"]},{name:"tags_and_custom_fields",description:"Tags for categorizing transactions. Custom fields for adding metadata (text, date, dropdown). Create, search, delete tags and custom fields.",groups:["tags","custom_fields"]},{name:"nano_classifiers",description:"Nano classifiers (tracking categories/dimensions). List, search, create, update, delete classifiers and their classes. Used for line-item tagging and dimensional reporting. Also: tracking categories, cost centers, departments, projects.",groups:["nano_classifiers"]},{name:"chart_of_accounts",description:"Chart of accounts (COA/GL accounts). Create, search, update accounts. Bookmarks (favorites/shortcuts). Also: ledger codes, account types.",groups:["accounts","bookmarks"]},{name:"currencies",description:"Currencies, exchange rates (FX/forex). List/add org currencies. Set, update, import currency rates. Also: multi-currency, FX rates.",groups:["currencies"]},{name:"tax_profiles",description:"Tax profiles (GST/VAT/sales tax), withholding tax codes (WHT/ATC). Search, create, update tax profiles. List WHT codes.",groups:["tax_profiles"]},{name:"capsules_and_recipes",description:"Capsules (transaction groupings/capsule types). Financial recipes: amortization, depreciation, deferred revenue, IFRS 16 leases, hire purchase, fixed deposits, FX revaluation, loan schedules, ECL/expected credit loss, IAS 37 provisions, asset disposal. Plan and execute recipes. Keywords: calculate, provision, schedule, expected credit loss, revaluation.",groups:["capsules","recipes"]},{name:"scheduled_transactions",description:"Scheduled/recurring invoices, bills, journals. Create scheduled invoices/bills/journals, search scheduled transactions. Also: recurring, auto-generate.",groups:["schedulers"]},{name:"subscriptions",description:"Subscriptions (recurring billing/payment plans). Create, update, cancel, search subscriptions. Also: recurring charges, subscription schedules.",groups:["subscriptions"]},{name:"organization",description:"Organization info (name, currency, country, fiscal year). User management: invite, update, remove, search org users. Bulk invite.",groups:["organization","org_users"]},{name:"document_ai",description:"File attachments, AI document extraction (magic/OCR). Upload/list attachments. Create transactions from PDFs/images (invoice scanning, bill extraction). Track extraction workflows.",groups:["attachments","magic"]},{name:"fixed_assets",description:"Fixed assets (PP&E/property, plant, equipment). Search, create, update, discard, sell, transfer, undo disposal. Also: depreciation, asset register.",groups:["fixed_assets"]},{name:"payments_and_search",description:"Payment records: get, update, delete individual payments. List payments/credits on invoices and bills. Reverse credit applications. Cashflow transaction search. Universal cross-entity search. Also: payment run, batch payment, payment matching, void payment, payment history, credit note applications.",groups:["payments","cashflow","search"]},{name:"quick_fix",description:"Quick Fix: bulk-update multiple transactions or line items in one call. Change dates, contacts, tags, accounts, tax profiles, custom fields across many invoices/bills/journals/credit-notes/cash-entries/schedulers at once. Also: batch update, mass edit.",groups:["quick_fix"]},{name:"export_records",description:"Export records to XLSX. List available columns, preview export scope (row count + sample), generate export file with pre-signed download URL. Supports any entity type: invoices, bills, contacts, items, journals, bank records, cashflow, fixed assets, etc. Pass query (structured search syntax) or filter (JSON), never both.",groups:["export_records"]},{name:"background_jobs",description:"Background job tracking. Poll any async operation by jobId (contacts bulk-upsert, items bulk-upsert, bank import, magic file processing, etc.). Filter by resourceId field to look up a specific job. Poll until status is SUCCESS, FAILED, or PARTIAL_SUCCESS.",groups:["background_jobs"]},{name:"drafts",description:"Draft business transactions \u2014 both local payload validation (invoices, bills, journals, credit notes) AND BULK-FRIENDLY server-side lifecycle: validate_drafts (sync eligibility check), convert_drafts_to_active (async promote to ACTIVE), submit_drafts_for_approval (async route to approval). The lifecycle tools are GENERIC and BULK \u2014 one call accepts up to 500 items mixing any combination of {btResourceId, btType: SALE|PURCHASE|SALE_CREDIT_NOTE|PURCHASE_CREDIT_NOTE}. No need for per-entity tools when promoting/submitting drafts at scale. NOT idempotent on already-promoted drafts.",groups:["drafts"]},{name:"close_procedures",description:"Period-end close checklists: month-end, quarter-end, year-end close. Bank reconciliation job. GST/VAT filing job. Audit preparation. Returns structured blueprints.",groups:["close_jobs"]},{name:"operational_jobs",description:"Operational job checklists: payment runs (incl. batch payment, batch supplier disbursement), credit control/collections, supplier reconciliation, fixed asset review, document collection, statutory filing. Returns structured blueprints.",groups:["operational_jobs"]},{name:"help_center",description:"Search the Jaz help center for how-to articles, feature guides, accounting concepts, and troubleshooting. Returns top matches with title, section, snippet, and source URL. Works without an API key.",groups:["help_center"]},{name:"practice",description:"Practitioner workspace scaffolding: per-client folders, per-engagement files, schemas. Use to onboard new clients (capture legal entity / FY / GST scheme / banks / recurring accruals into CLIENT.md), list active engagements, scaffold a monthly-close / quarterly-gst / annual-statutory engagement, and load client/engagement context before driving accounting work via jaz-jobs blueprints + jaz-recipes. All filesystem-only, offline. Pair with jaz-practice skill for the canonical playbooks.",groups:["practice"]}];function jJ(e,t=5){let r=e.trim().toLowerCase();if(!r)return[];let n=r.split(/[\s_-]+/).filter(i=>i.length>=2);return n.length===0?[]:dl.map(i=>{let s=0,a=i.name.toLowerCase(),c=i.description.toLowerCase();(a===r||a===r.replace(/\s+/g,"_"))&&(s+=5),a.includes(r)&&(s+=3),c.includes(r)&&(s+=1);for(let u of n)a.includes(u)&&(s+=2),c.includes(u)&&(s+=1);return{ns:i,score:s}}).filter(i=>i.score>0).sort((i,s)=>s.score-i.score).slice(0,t).map(i=>i.ns)}function k_(e){let t={type:e.type};if(e.description&&(t.description=e.description),e.enum&&(t.enum=e.enum),e.type==="array"&&e.items&&(t.items=k_(e.items)),e.type==="object"&&e.properties){let r={};for(let[n,o]of Object.entries(e.properties))r[n]=k_(o);t.properties=r,e.required?.length&&(t.required=e.required)}return t}function rc(e,t){let r={};for(let[n,o]of Object.entries(e))r[n]=k_(o);return{type:"object",properties:r,...t.length>0?{required:t}:{}}}function MJ(e){return{name:e.name,description:e.description,input_schema:rc(e.params,e.required),...e.searchHint?{searchHint:e.searchHint}:{}}}function sSe(e){if(typeof e!="string")return e.isDestructive??!1;let t=e;return t.startsWith("delete_")||t.startsWith("pay_")||t.startsWith("finalize_")||t.includes("refund")||t==="remove_org_user"}function BJ(e){if(!e.trim())return{namespaces:dl.map(o=>{let i=o.groups.flatMap(s=>ll(s));return{name:o.name,description:o.description,toolCount:i.length,tools:i.map(s=>s.name)}}),hint:"Call describe_tools with specific tool names to get full schemas before executing."};let t=jJ(e,5);if(t.length===0)return{matches:[],hint:`No tools match "${e}". Try broader terms or call search_tools with empty query to see all namespaces.`};let n=e.toLowerCase().split(/\s+/).filter(Boolean);return{matches:t.map(o=>{let s=o.groups.flatMap(a=>ll(a)).map(a=>{let c=`${a.name} ${a.searchHint??""} ${a.description}`.toLowerCase(),u=n.filter(l=>c.includes(l)).length;return{tool:a,score:u}}).sort((a,c)=>c.score-a.score);return{namespace:o.name,description:o.description,tools:s.map(a=>({name:a.tool.name,description:a.tool.description.split(`
|
|
821
813
|
`)[0],...a.tool.searchHint?{searchHint:a.tool.searchHint}:{}}))}}),hint:"Call describe_tools with the tool names you need, then execute_tool to run them."}}var aSe={name:"search_tools",description:"Search for available Jaz accounting tools by keyword. Returns matching tool namespaces with tool names and descriptions. Call with empty query to list all namespaces. ALWAYS call this first to discover what tools are available.",inputSchema:rc({query:{type:"string",description:'Search keyword (e.g. "invoice", "bank recon", "depreciation"). Empty string lists all namespaces.'}},[])};function UJ(e){if(!Array.isArray(e)||!e.every(n=>typeof n=="string"))return{error:"Invalid `tools` parameter. Expected string[]."};if(e.length===0)return{error:"Provide at least one tool name. Use search_tools first to discover tool names."};let t=[],r=[];for(let n of e){let o=N_(n);if(!o){r.push(n);continue}t.push({...MJ(o),readOnly:o.readOnly,isDestructive:o.isDestructive??!1,isConcurrencySafe:o.isConcurrencySafe??!1,destructiveHint:!o.readOnly&&sSe(o),group:o.group})}return{tools:t,...r.length>0?{notFound:r,hint:`Tools not found: ${r.join(", ")}. Use search_tools to find correct names.`}:{}}}var cSe={name:"describe_tools",description:"Get full JSON Schema (parameters, types, required fields) for specific tools. Call this after search_tools to get the exact input format before calling execute_tool.",inputSchema:rc({tools:{type:"array",items:{type:"string"},description:'Tool names to describe (e.g. ["create_invoice", "search_contacts"])'}},["tools"])},uSe={name:"execute_tool",description:"Execute a Jaz accounting tool. Call describe_tools first to get the required parameters. Pass the tool name and its arguments.",inputSchema:rc({tool:{type:"string",description:'Tool name (e.g. "create_invoice")'},arguments:{type:"object",description:"Tool arguments (see describe_tools for schema)"},org_id:{type:"string",description:"Organization ID (UUID). Required in multi-org mode (PAT or multiple API keys). Call list_organizations to get available IDs."}},["tool"])},qJ={name:"list_organizations",description:"List organizations available to the current authentication. Returns org names and resource IDs for use as org_id in execute_tool calls.",inputSchema:rc({},[])},lR=[aSe,cSe,uSe];Ed();la();import{readFileSync as lSe,readdirSync as dSe,statSync as pSe}from"node:fs";import{dirname as YJ,join as ks,relative as fSe}from"node:path";import{fileURLToPath as JJ}from"node:url";function mSe(e,t){let r;try{r=pSe(e)}catch{return[]}if(!r.isDirectory())return[];let n=[],o=20,i=(s,a)=>{if(a>o)return;let c;try{c=dSe(s,{withFileTypes:!0})}catch{return}for(let u of c){let l=ks(s,u.name);if(u.isDirectory())i(l,a+1);else if(u.isFile()&&u.name.endsWith(".md")){let d=fSe(e,l).split(/[\\/]/).join("/");(!t||!t(d))&&n.push(d)}}};return i(e,0),n.sort()}function zJ(e){let t=e.fileFilter??(()=>!0);return mSe(e.rootDir,n=>!t(n)).map(n=>{let o=e.uriPathBuilder?e.uriPathBuilder(n):n.replace(/\.md$/,"");return{uri:`${e.uriPrefix}/${o}`,name:e.nameBuilder(n),description:e.descriptionBuilder?.(n),mimeType:"text/markdown",filePath:ks(e.rootDir,n)}})}function hSe(){let e=JJ(import.meta.url),t=YJ(e);return Hw([ks(t,"..","..","..","assets","skills"),ks(t,"..","..","..","..","assets","skills"),ks(t,"skills")])}function gSe(){let e=JJ(import.meta.url),t=YJ(e);return Hw([ks(t,"..","..","..","help-center-mirror"),ks(t,"..","..","..","assets","skills","api","help-center-mirror"),ks(t,"help-center-mirror")])}var ySe=["api","cli","conversion","jobs","transaction-recipes"],DSe={api:"Jaz REST API rules: every endpoint, field name, error code, production gotchas.",cli:"Jaz CLI commands, auth, calculators, jobs.",conversion:"Migration from Xero, QuickBooks, Sage, MYOB, or Excel exports into Jaz.",jobs:"12 recurring accounting workflow playbooks (close, reconciliation, GST/VAT, etc.).","transaction-recipes":"16 IFRS-compliant transaction recipes plus 13 financial calculators."};function bSe(e){if(e.includes("/help-center-mirror/"))return!1;let t=e.split("/")[0];return ySe.includes(t)}function vSe(e){let t=e.split("/"),r=t[0];if(t.length===2&&t[1]==="SKILL.md")return`Jaz ${r} skill`;if(t[1]==="references"){let n=t.slice(2).join("/").replace(/\.md$/,"");return`Jaz ${r} reference: ${n}`}return`Jaz ${r}: ${e}`}function SSe(e){let t=e.split("/")[0];return DSe[t]}function _Se(e){return!e.includes("/")}function ESe(e){return`Jaz help center: ${e.replace(/\.md$/,"").split("-").map(n=>n[0]?.toUpperCase()+n.slice(1)).join(" ")}`}var dR=null,pR=null;function fR(){if(dR)return dR;let e=hSe(),t=gSe(),r=[];return e&&r.push(...zJ({rootDir:e,uriPrefix:"jaz://skill",fileFilter:bSe,nameBuilder:vSe,descriptionBuilder:SSe,uriPathBuilder:n=>{let o=n.split("/");return o.length===2&&o[1]==="SKILL.md"?o[0]:n.replace(/\.md$/,"")}})),t&&r.push(...zJ({rootDir:t,uriPrefix:"jaz://help-center",fileFilter:_Se,nameBuilder:ESe,descriptionBuilder:()=>"Jaz help center article. Same corpus search_help_center indexes."})),dR=r,pR=new Map(r.map(n=>[n.uri,n])),r}function GJ(e){pR||fR();let t=pR.get(e);if(!t)throw new Error(`Resource not found: ${e}`);let r=lSe(t.filePath,"utf-8");return{mimeType:t.mimeType,text:r}}var ISe=new Set(["close_jobs","operational_jobs","help_center"]),VJ="Calculators, blueprints, and help center search work without an account.",HJ="Get an API key or token from jaz.ai";function mR(e,t){return!!(ISe.has(e)||e==="recipes"&&t==="plan_recipe")}function CSe(e,t){return new Dn({mode:"pat",token:e,orgId:t})}async function WJ(e,t=5e3){let r=new Map,n=[],o=a=>Promise.race([a,new Promise(c=>setTimeout(()=>c(null),t))]),i=e.map(a=>({auth:a,client:new Dn(a)})),s=i[0]?.client??null;return await Promise.all(i.map(async({auth:a,client:c})=>{try{let u=await o(Pn(c));if(u)r.set(u.resourceId,{name:u.name,resourceId:u.resourceId,currency:u.currency,client:c});else{let l=a.mode==="direct"?"api-key":a.mode;n.push(`Org lookup returned empty (${l}).`)}}catch(u){let l=a.mode==="direct"?"api-key":a.mode;n.push(`Org lookup failed (${l}): ${u instanceof Error?u.message:"unknown"}`)}})),{orgMap:r,primaryClient:s,errors:n}}function ZJ(e){e.command("mcp").description("Start MCP stdio server for Claude Code / Cowork").option("--api-key <key>","API key, PAT, or comma-separated keys (overrides stored/env)").action(async t=>{let r=[];try{r=UC(t.apiKey)}catch(b){let S=b instanceof Error?b.message:String(b);process.stderr.write(`jaz-ai: ${S} (continuing in offline mode)
|
|
822
814
|
`)}let n=e.version()??"0.0.0",o=new Map,i=null,s=r.length>1||r[0]?.mode==="pat";if(r.length>0){let b=await WJ(r);o=b.orgMap,i=b.primaryClient;for(let S of b.errors)process.stderr.write(`warning: ${S}
|
|
823
815
|
`)}let a="",c="";if(o.size>1){let b=[...o.values()].map(S=>`${S.name} (${S.currency})`);a=`Connected to ${o.size} organizations: ${b.join(", ")}.`,c=`${o.size} orgs`}else if(o.size===1){let b=[...o.values()][0];a=`Connected to: ${b.name} (${b.currency}).`,c=b.name}else if(i){let b=dd();if(b){let S=Xn(b);S?.orgName&&(a=`Connected to: ${S.orgName} (${S.currency}).`,c=`${S.orgName} (${b})`)}}let u=dl.map(b=>b.name).join(", "),l=i?"All API tools hit api.getjaz.com using the configured credentials.":`${HJ} to bring Jaz into Claude for real accounting and finance work. ${VJ}`,d=s&&o.size>0?["","MULTI-ORG MODE:",`You have access to ${o.size} organization(s):`,...[...o.values()].map(b=>` - ${b.name} (org_id: ${b.resourceId}, ${b.currency})`),"","RULES:","1. Every execute_tool call for API tools MUST include org_id.","2. If the user mentions an org by name, match it to the org_id above.",`3. If the user hasn't specified an org, ask: "Which organization?"`,"4. Once the user picks an org, use it for all subsequent calls until they say otherwise.",'5. If the user says "switch to [org]", update the active org for subsequent calls.','6. Always confirm the org on the first tool call: "Using [Org Name]."','7. For cross-org queries (e.g. "compare Acme and Beta"), make separate execute_tool calls with different org_ids.',"8. Call list_organizations to refresh the org list if needed."]:[],f=[`Jaz accounting platform \u2014 ${ul.length} tools across ${dl.length} namespaces.`,a,"","WORKFLOW: search_tools \u2192 describe_tools \u2192 execute_tool.","1. Call search_tools with a keyword to find relevant tools.","2. Call describe_tools with tool names to get full parameter schemas.","3. Call execute_tool with the tool name and arguments to run it.","",`Namespaces: ${u}.`,"","Key API rules (apply to all tools):","- All IDs are `resourceId` (never `id`).","- All transaction dates are `valueDate` (not issueDate/invoiceDate/date). Format: YYYY-MM-DD.","- Line item text field is `name` (not `description`).","- `saveAsDraft` defaults to false \u2014 omitting it finalizes the transaction.","- Response dates are epoch milliseconds (convert with new Date(ms)).","- Pagination: use `limit`/`offset` (not page/size). Search sort is required when offset present.","- Create responses return only `{ resourceId }` \u2014 GET the full entity after creation.","","Offline tools (no auth needed): close-procedure blueprints (close_procedures, operational_jobs), plan_recipe calculator, and search_help_center for the Jaz help center.",l,...d].filter(b=>b!==void 0).join(`
|