@commandable/mcp 0.12.0 → 0.12.1
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/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{DRfk9W3W.js → B6ti3873.js} +1 -1
- package/.output/public/_nuxt/{VvnbcAzZ.js → BZ8athzM.js} +1 -1
- package/.output/public/_nuxt/{DSWYWRXT.js → BuJvZwTh.js} +9 -9
- package/.output/public/_nuxt/{D9wFDhac.js → CiSdBjBt.js} +1 -1
- package/.output/public/_nuxt/{BD6mASiY.js → D_Ecm3JY.js} +1 -1
- package/.output/public/_nuxt/{CjAs3eBq.js → Vt66r6sN.js} +1 -1
- package/.output/public/_nuxt/{BUmYUDQu.js → bOjQRRUc.js} +3 -3
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/6152dcdc-6d3b-4e0a-8c56-4584c72c8765.json +1 -0
- package/.output/server/chunks/build/{_id_-DA3Q8jun.mjs → _id_-BIPuj6eI.mjs} +4 -4
- package/.output/server/chunks/build/{_id_-DA3Q8jun.mjs.map → _id_-BIPuj6eI.mjs.map} +1 -1
- package/.output/server/chunks/build/client.precomputed.mjs +1 -1
- package/.output/server/chunks/build/{error-404-D1k2kWid.mjs → error-404-BHlLSgAJ.mjs} +1 -1
- package/.output/server/chunks/build/error-404-BHlLSgAJ.mjs.map +1 -0
- package/.output/server/chunks/build/{error-500-D2K2rAfl.mjs → error-500-D4rqaBv3.mjs} +1 -1
- package/.output/server/chunks/build/error-500-D4rqaBv3.mjs.map +1 -0
- package/.output/server/chunks/build/{fetch-aDh21opM.mjs → fetch-DJGu_p4i.mjs} +1 -1
- package/.output/server/chunks/build/fetch-DJGu_p4i.mjs.map +1 -0
- package/.output/server/chunks/build/{index-ycGPozML.mjs → index-DUjkeeyt.mjs} +1 -1
- package/.output/server/chunks/build/index-DUjkeeyt.mjs.map +1 -0
- package/.output/server/chunks/build/{index-F5lAFSQk.mjs → index-DvzWme19.mjs} +4 -4
- package/.output/server/chunks/build/index-DvzWme19.mjs.map +1 -0
- package/.output/server/chunks/build/server.mjs +5 -5
- package/.output/server/chunks/nitro/nitro.mjs +3008 -213
- package/.output/server/package.json +1 -1
- package/package.json +2 -2
- package/.output/public/_nuxt/builds/meta/886deef4-f3b5-464c-b4e2-11735eb5272e.json +0 -1
- package/.output/server/chunks/build/error-404-D1k2kWid.mjs.map +0 -1
- package/.output/server/chunks/build/error-500-D2K2rAfl.mjs.map +0 -1
- package/.output/server/chunks/build/fetch-aDh21opM.mjs.map +0 -1
- package/.output/server/chunks/build/index-F5lAFSQk.mjs.map +0 -1
- package/.output/server/chunks/build/index-ycGPozML.mjs.map +0 -1
|
@@ -4431,7 +4431,7 @@ function _expandFromEnv(value) {
|
|
|
4431
4431
|
const _inlineRuntimeConfig = {
|
|
4432
4432
|
"app": {
|
|
4433
4433
|
"baseURL": "/",
|
|
4434
|
-
"buildId": "
|
|
4434
|
+
"buildId": "6152dcdc-6d3b-4e0a-8c56-4584c72c8765",
|
|
4435
4435
|
"buildAssetsDir": "/_nuxt/",
|
|
4436
4436
|
"cdnURL": ""
|
|
4437
4437
|
},
|
|
@@ -4900,7 +4900,7 @@ async function errorHandler(error, event) {
|
|
|
4900
4900
|
|
|
4901
4901
|
const script = "\"use strict\";(()=>{const t=window,e=document.documentElement,c=[\"dark\",\"light\"],n=getStorageValue(\"localStorage\",\"nuxt-color-mode\")||\"system\";let i=n===\"system\"?u():n;const r=e.getAttribute(\"data-color-mode-forced\");r&&(i=r),l(i),t[\"__NUXT_COLOR_MODE__\"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=\"\"+o+\"\",a=\"\";e.classList?e.classList.add(s):e.className+=\" \"+s,a&&e.setAttribute(\"data-\"+a,o)}function d(o){const s=\"\"+o+\"\",a=\"\";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,\"g\"),\"\"),a&&e.removeAttribute(\"data-\"+a)}function f(o){return t.matchMedia(\"(prefers-color-scheme\"+o+\")\")}function u(){if(t.matchMedia&&f(\"\").media!==\"not all\"){for(const o of c)if(f(\":\"+o).matches)return o}return\"light\"}})();function getStorageValue(t,e){switch(t){case\"localStorage\":return window.localStorage.getItem(e);case\"sessionStorage\":return window.sessionStorage.getItem(e);case\"cookie\":return getCookie(e);default:return null}}function getCookie(t){const c=(\"; \"+window.document.cookie).split(\"; \"+t+\"=\");if(c.length===2)return c.pop()?.split(\";\").shift()}";
|
|
4902
4902
|
|
|
4903
|
-
const
|
|
4903
|
+
const _zUuxVGgAOQhH7E5atfn9Ptf95wF4esqexnSnzyTPmK8 = (function(nitro) {
|
|
4904
4904
|
nitro.hooks.hook("render:html", (htmlContext) => {
|
|
4905
4905
|
htmlContext.head.push(`<script>${script}<\/script>`);
|
|
4906
4906
|
});
|
|
@@ -9058,12 +9058,20 @@ const GENERATED_INTEGRATIONS = {
|
|
|
9058
9058
|
},
|
|
9059
9059
|
{
|
|
9060
9060
|
"name": "read_email",
|
|
9061
|
-
"description": "Read an email by message ID and return a flat, decoded result with subject, from, to, cc, date, snippet, body text, labelIds, and
|
|
9061
|
+
"description": "Read an email by message ID and return a flat, decoded result with subject, from, to, cc, date, snippet, body text, labelIds, threadId, and attachment metadata. Use this for reading email content -- it handles base64 decoding and header extraction automatically. To extract an attachment's readable file content, use read_attachment_content with an attachmentId or filename from this result. For raw API access or advanced format options, use get_message instead.",
|
|
9062
9062
|
"inputSchema": "schemas/read_email.json",
|
|
9063
9063
|
"handler": "handlers/read_email.js",
|
|
9064
9064
|
"scope": "read",
|
|
9065
9065
|
"toolset": "email"
|
|
9066
9066
|
},
|
|
9067
|
+
{
|
|
9068
|
+
"name": "read_attachment_content",
|
|
9069
|
+
"description": "Read and extract the content of a Gmail message attachment into agent-friendly text. Use read_email first to discover attachmentId, filename, mimeType, and size. Supports PDFs, Office files, CSV, text, HTML, and other formats supported by Commandable file processing. Provide attachmentId when possible; filename can be used as a fallback.",
|
|
9070
|
+
"inputSchema": "schemas/read_attachment_content.json",
|
|
9071
|
+
"handler": "handlers/read_attachment_content.js",
|
|
9072
|
+
"scope": "read",
|
|
9073
|
+
"toolset": "email"
|
|
9074
|
+
},
|
|
9067
9075
|
{
|
|
9068
9076
|
"name": "get_message",
|
|
9069
9077
|
"description": "Get the raw Gmail message resource by message ID. Returns the full nested payload including base64url-encoded body parts and all headers. For most use cases, prefer read_email which decodes the response into a flat readable format. Use format='minimal' for lightweight ID+threadId+labelIds only, format='metadata' with metadataHeaders for specific headers only.",
|
|
@@ -9242,7 +9250,7 @@ const GENERATED_INTEGRATIONS = {
|
|
|
9242
9250
|
}
|
|
9243
9251
|
]
|
|
9244
9252
|
},
|
|
9245
|
-
"usageGuide": "## Gmail search query syntax\n\nGmail's `q` parameter supports a powerful search language. Key operators:\n\n- `is:unread` / `is:read` \u2014 filter by read status\n- `is:starred`, `is:important` \u2014 filter by markers\n- `from:user@example.com` \u2014 sender filter\n- `to:user@example.com`, `cc:user@example.com` \u2014 recipient filters\n- `subject:keyword` \u2014 subject line search\n- `has:attachment` \u2014 messages with attachments\n- `filename:report.pdf` \u2014 specific attachment filename\n- `label:INBOX` \u2014 filter by label (use label name or ID)\n- `after:2024/01/01`, `before:2024/12/31` \u2014 date range (YYYY/MM/DD)\n- `newer_than:7d`, `older_than:1y` \u2014 relative time (d=days, m=months, y=years)\n- `in:sent`, `in:drafts`, `in:trash`, `in:spam` \u2014 folder filters\n- `larger:5M`, `smaller:1M` \u2014 size filters\n\nCombine operators with spaces (implicit AND): `from:alice is:unread has:attachment`\n\n## Recommended workflows\n\n**Reading emails:**\n1. Use `list_messages` with a `q` query to find relevant message IDs\n2. Use `read_email` on each ID to get decoded subject, from, to, date, and
|
|
9253
|
+
"usageGuide": "## Gmail search query syntax\n\nGmail's `q` parameter supports a powerful search language. Key operators:\n\n- `is:unread` / `is:read` \u2014 filter by read status\n- `is:starred`, `is:important` \u2014 filter by markers\n- `from:user@example.com` \u2014 sender filter\n- `to:user@example.com`, `cc:user@example.com` \u2014 recipient filters\n- `subject:keyword` \u2014 subject line search\n- `has:attachment` \u2014 messages with attachments\n- `filename:report.pdf` \u2014 specific attachment filename\n- `label:INBOX` \u2014 filter by label (use label name or ID)\n- `after:2024/01/01`, `before:2024/12/31` \u2014 date range (YYYY/MM/DD)\n- `newer_than:7d`, `older_than:1y` \u2014 relative time (d=days, m=months, y=years)\n- `in:sent`, `in:drafts`, `in:trash`, `in:spam` \u2014 folder filters\n- `larger:5M`, `smaller:1M` \u2014 size filters\n\nCombine operators with spaces (implicit AND): `from:alice is:unread has:attachment`\n\n## Recommended workflows\n\n**Reading emails:**\n1. Use `list_messages` with a `q` query to find relevant message IDs\n2. Use `read_email` on each ID to get decoded subject, from, to, date, body text, and attachment metadata\n3. For raw access or advanced format options, use `get_message` with `format='full'`\n\n**Reading attachments:**\n1. Use `list_messages` with `has:attachment` or `filename:report.pdf` to find messages with attachments\n2. Use `read_email` to inspect the `attachments` array and find the attachment ID, filename, MIME type, and size\n3. Use `read_attachment_content` with the message ID and either `attachmentId` or `filename` to extract readable file content\n\n**Searching for threads:**\n1. Use `list_threads` with `q` to find conversation threads\n2. Use `get_thread` to retrieve all messages in a conversation at once\n\n**Sending email:**\n- Use `send_email` for the vast majority of cases -- it accepts plain `to`, `subject`, `body` fields\n- Use `create_draft_email` + `send_draft` when you want to create a draft for review before sending\n\n**Replying to an email:**\n1. Get the original message with `read_email` to obtain its `threadId` and `id`\n2. Call `send_email` with `replyToMessageId` = original message `id` and `threadId` = original `threadId`\n3. The reply will appear in the same conversation thread\n\n## Label IDs\n\nSystem label IDs (always uppercase): `INBOX`, `UNREAD`, `STARRED`, `IMPORTANT`, `SENT`, `DRAFT`, `SPAM`, `TRASH`, `CATEGORY_PERSONAL`, `CATEGORY_SOCIAL`, `CATEGORY_PROMOTIONS`, `CATEGORY_UPDATES`, `CATEGORY_FORUMS`\n\nUser-created labels have auto-generated IDs. Use `list_labels` to discover them.\n\n## Archiving and organizing\n\n- Archive a message: `modify_message` with `removeLabelIds=['INBOX']`\n- Mark as read: `modify_message` with `removeLabelIds=['UNREAD']`\n- Star a message: `modify_message` with `addLabelIds=['STARRED']`\n- Apply a label: `modify_message` with `addLabelIds=['<labelId>']`\n- Use `modify_thread` to apply the same operation to all messages in a thread at once\n",
|
|
9246
9254
|
"variants": {
|
|
9247
9255
|
"variants": {
|
|
9248
9256
|
"service_account": {
|
|
@@ -9382,7 +9390,7 @@ const GENERATED_INTEGRATIONS = {
|
|
|
9382
9390
|
},
|
|
9383
9391
|
{
|
|
9384
9392
|
"name": "read_email",
|
|
9385
|
-
"description": "Read an email by message ID and return a flat, decoded result with subject, from, to, cc, date, snippet, body text, labelIds, and
|
|
9393
|
+
"description": "Read an email by message ID and return a flat, decoded result with subject, from, to, cc, date, snippet, body text, labelIds, threadId, and attachment metadata. Use this for reading email content -- it handles base64 decoding and header extraction automatically. To extract an attachment's readable file content, use read_attachment_content with an attachmentId or filename from this result. For raw API access or advanced format options, use get_message instead.",
|
|
9386
9394
|
"inputSchema": {
|
|
9387
9395
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
9388
9396
|
"type": "object",
|
|
@@ -9401,7 +9409,62 @@ const GENERATED_INTEGRATIONS = {
|
|
|
9401
9409
|
},
|
|
9402
9410
|
"additionalProperties": false
|
|
9403
9411
|
},
|
|
9404
|
-
"handlerCode": "async (input) => {\n const userId = encodeURIComponent(input.userId || 'me')\n const messageId = encodeURIComponent(input.messageId)\n const res = await integration.fetch(`/users/${userId}/messages/${messageId}?format=full`)\n const msg = await res.json()\n\n const getHeader = (name) => {\n const h = (msg.payload?.headers || []).find(h => h.name.toLowerCase() === name.toLowerCase())\n return h?.value || ''\n }\n\n const decodeBase64url = (data) => {\n if (!data) return ''\n try {\n return decodeURIComponent(escape(atob(data.replace(/-/g, '+').replace(/_/g, '/'))))\n }\n catch {\n return ''\n }\n }\n\n // Recursively extract text body, preferring text/plain over text/html\n const extractBody = (part) => {\n if (!part) return ''\n if (part.mimeType === 'text/plain' && part.body?.data)\n return decodeBase64url(part.body.data)\n if (part.parts) {\n // Depth-first: try text/plain first across all parts\n for (const p of part.parts) {\n if (p.mimeType === 'text/plain' && p.body?.data)\n return decodeBase64url(p.body.data)\n }\n // Recurse into nested multipart\n for (const p of part.parts) {\n const text = extractBody(p)\n if (text) return text\n }\n }\n if (part.mimeType === 'text/html' && part.body?.data)\n return decodeBase64url(part.body.data)\n return ''\n }\n\n return {\n id: msg.id,\n threadId: msg.threadId,\n labelIds: msg.labelIds || [],\n subject: getHeader('Subject'),\n from: getHeader('From'),\n to: getHeader('To'),\n cc: getHeader('Cc'),\n date: getHeader('Date'),\n snippet: msg.snippet || '',\n body: extractBody(msg.payload),\n }\n}",
|
|
9412
|
+
"handlerCode": "async (input) => {\n const userId = encodeURIComponent(input.userId || 'me')\n const messageId = encodeURIComponent(input.messageId)\n const res = await integration.fetch(`/users/${userId}/messages/${messageId}?format=full`)\n const msg = await res.json()\n\n const getHeader = (name) => {\n const h = (msg.payload?.headers || []).find(h => h.name.toLowerCase() === name.toLowerCase())\n return h?.value || ''\n }\n\n const decodeBase64url = (data) => {\n if (!data) return ''\n try {\n return decodeURIComponent(escape(atob(data.replace(/-/g, '+').replace(/_/g, '/'))))\n }\n catch {\n return ''\n }\n }\n\n // Recursively extract text body, preferring text/plain over text/html\n const extractBody = (part) => {\n if (!part) return ''\n if (part.mimeType === 'text/plain' && part.body?.data)\n return decodeBase64url(part.body.data)\n if (part.parts) {\n // Depth-first: try text/plain first across all parts\n for (const p of part.parts) {\n if (p.mimeType === 'text/plain' && p.body?.data)\n return decodeBase64url(p.body.data)\n }\n // Recurse into nested multipart\n for (const p of part.parts) {\n const text = extractBody(p)\n if (text) return text\n }\n }\n if (part.mimeType === 'text/html' && part.body?.data)\n return decodeBase64url(part.body.data)\n return ''\n }\n\n const collectAttachments = (part, out = []) => {\n if (!part) return out\n if (part.body?.attachmentId) {\n out.push({\n attachmentId: part.body.attachmentId,\n filename: part.filename || '',\n mimeType: part.mimeType || '',\n size: part.body?.size || 0,\n partId: part.partId || '',\n })\n }\n if (Array.isArray(part.parts)) {\n for (const child of part.parts)\n collectAttachments(child, out)\n }\n return out\n }\n\n return {\n id: msg.id,\n threadId: msg.threadId,\n labelIds: msg.labelIds || [],\n subject: getHeader('Subject'),\n from: getHeader('From'),\n to: getHeader('To'),\n cc: getHeader('Cc'),\n date: getHeader('Date'),\n snippet: msg.snippet || '',\n body: extractBody(msg.payload),\n attachments: collectAttachments(msg.payload),\n }\n}",
|
|
9413
|
+
"scope": "read",
|
|
9414
|
+
"toolset": "email"
|
|
9415
|
+
},
|
|
9416
|
+
{
|
|
9417
|
+
"name": "read_attachment_content",
|
|
9418
|
+
"description": "Read and extract the content of a Gmail message attachment into agent-friendly text. Use read_email first to discover attachmentId, filename, mimeType, and size. Supports PDFs, Office files, CSV, text, HTML, and other formats supported by Commandable file processing. Provide attachmentId when possible; filename can be used as a fallback.",
|
|
9419
|
+
"inputSchema": {
|
|
9420
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
9421
|
+
"type": "object",
|
|
9422
|
+
"required": [
|
|
9423
|
+
"messageId"
|
|
9424
|
+
],
|
|
9425
|
+
"anyOf": [
|
|
9426
|
+
{
|
|
9427
|
+
"required": [
|
|
9428
|
+
"attachmentId"
|
|
9429
|
+
]
|
|
9430
|
+
},
|
|
9431
|
+
{
|
|
9432
|
+
"required": [
|
|
9433
|
+
"filename"
|
|
9434
|
+
]
|
|
9435
|
+
}
|
|
9436
|
+
],
|
|
9437
|
+
"properties": {
|
|
9438
|
+
"userId": {
|
|
9439
|
+
"type": "string",
|
|
9440
|
+
"description": "User email or 'me'. Defaults to 'me'."
|
|
9441
|
+
},
|
|
9442
|
+
"messageId": {
|
|
9443
|
+
"type": "string",
|
|
9444
|
+
"description": "Gmail message ID. Obtain from list_messages or read_email."
|
|
9445
|
+
},
|
|
9446
|
+
"attachmentId": {
|
|
9447
|
+
"type": "string",
|
|
9448
|
+
"description": "Gmail attachment ID from read_email's attachments array. Preferred when available."
|
|
9449
|
+
},
|
|
9450
|
+
"filename": {
|
|
9451
|
+
"type": "string",
|
|
9452
|
+
"description": "Attachment filename from read_email's attachments array. Used to resolve the attachment when attachmentId is not provided."
|
|
9453
|
+
},
|
|
9454
|
+
"mimeType": {
|
|
9455
|
+
"type": "string",
|
|
9456
|
+
"description": "Optional MIME type override. Defaults to the MIME type from the matching message part."
|
|
9457
|
+
},
|
|
9458
|
+
"previewPages": {
|
|
9459
|
+
"type": "integer",
|
|
9460
|
+
"minimum": 1,
|
|
9461
|
+
"maximum": 10,
|
|
9462
|
+
"description": "Number of pages to render as images and return alongside the text (PDF only). Omit or set to 0 to skip. Useful for visually checking signatures, logos, or layout."
|
|
9463
|
+
}
|
|
9464
|
+
},
|
|
9465
|
+
"additionalProperties": false
|
|
9466
|
+
},
|
|
9467
|
+
"handlerCode": "async (input) => {\n const userId = encodeURIComponent(input.userId || 'me')\n const messageId = encodeURIComponent(input.messageId)\n\n const collectAttachments = (part, out = []) => {\n if (!part) return out\n if (part.body?.attachmentId) {\n out.push({\n attachmentId: part.body.attachmentId,\n filename: part.filename || '',\n mimeType: part.mimeType || '',\n size: part.body?.size || 0,\n partId: part.partId || '',\n })\n }\n if (Array.isArray(part.parts)) {\n for (const child of part.parts)\n collectAttachments(child, out)\n }\n return out\n }\n\n const toBase64 = (value) => {\n const raw = String(value || '').replace(/-/g, '+').replace(/_/g, '/')\n return raw.padEnd(Math.ceil(raw.length / 4) * 4, '=')\n }\n\n const messageRes = await integration.fetch(`/users/${userId}/messages/${messageId}?format=full`)\n if (!messageRes.ok)\n throw new Error(`Failed to fetch Gmail message (${messageRes.status}).`)\n const message = await messageRes.json()\n const attachments = collectAttachments(message.payload)\n\n const requestedAttachmentId = String(input.attachmentId || '')\n const requestedFilename = String(input.filename || '').toLowerCase()\n const found = requestedAttachmentId\n ? attachments.find(item => item.attachmentId === requestedAttachmentId)\n : attachments.find(item => item.filename.toLowerCase() === requestedFilename)\n const match = found || (requestedAttachmentId\n ? {\n attachmentId: requestedAttachmentId,\n filename: input.filename || '',\n mimeType: input.mimeType || '',\n size: 0,\n partId: '',\n }\n : null)\n\n if (!match) {\n return {\n messageId: input.messageId,\n attachmentId: input.attachmentId || null,\n filename: input.filename || null,\n content: null,\n message: 'Attachment not found on this Gmail message. Use read_email to inspect available attachments.',\n attachments,\n }\n }\n\n const attachmentId = encodeURIComponent(match.attachmentId)\n const attachmentRes = await integration.fetch(`/users/${userId}/messages/${messageId}/attachments/${attachmentId}`)\n if (!attachmentRes.ok)\n throw new Error(`Failed to fetch Gmail attachment (${attachmentRes.status}).`)\n const attachment = await attachmentRes.json()\n\n if (!attachment?.data) {\n return {\n messageId: input.messageId,\n attachmentId: match.attachmentId,\n filename: match.filename,\n mimeType: input.mimeType || match.mimeType || null,\n size: match.size,\n content: null,\n message: 'Gmail attachment response did not include file data.',\n }\n }\n\n const mimeType = input.mimeType || match.mimeType || 'application/octet-stream'\n const extracted = await utils.extractFileContent({\n auth: false,\n source: `data:${mimeType};base64,${toBase64(attachment.data)}`,\n previewPages: input.previewPages || 0,\n })\n\n return {\n messageId: input.messageId,\n attachmentId: match.attachmentId,\n filename: match.filename,\n mimeType,\n size: match.size || attachment.size || 0,\n partId: match.partId,\n ...extracted,\n }\n}",
|
|
9405
9468
|
"scope": "read",
|
|
9406
9469
|
"toolset": "email"
|
|
9407
9470
|
},
|
|
@@ -9769,7 +9832,7 @@ const GENERATED_INTEGRATIONS = {
|
|
|
9769
9832
|
],
|
|
9770
9833
|
"additionalProperties": false
|
|
9771
9834
|
},
|
|
9772
|
-
"handlerCode": "async (input) => {\n const userId = encodeURIComponent(input.userId || 'me')\n const body = {}\n if (input.draftId)\n body.id = input.draftId\n if (input.raw) {\n body.message = { raw: input.raw }\n if (input.threadId)\n body.message.threadId = input.threadId\n if (Array.isArray(input.labelIds))\n body.message.labelIds = input.labelIds\n }\n const res = await integration.fetch(`/users/${userId}/drafts/send`, { method: 'POST', body })\n return await res.json()\n}",
|
|
9835
|
+
"handlerCode": "async (input) => {\n const userId = encodeURIComponent(input.userId || 'me')\n if (input.raw && !input.draftId) {\n const message = { raw: input.raw }\n if (input.threadId)\n message.threadId = input.threadId\n if (Array.isArray(input.labelIds))\n message.labelIds = input.labelIds\n const res = await integration.fetch(`/users/${userId}/messages/send`, { method: 'POST', body: message })\n return await res.json()\n }\n\n const body = {}\n if (input.draftId)\n body.id = input.draftId\n if (input.raw) {\n body.message = { raw: input.raw }\n if (input.threadId)\n body.message.threadId = input.threadId\n if (Array.isArray(input.labelIds))\n body.message.labelIds = input.labelIds\n }\n const res = await integration.fetch(`/users/${userId}/drafts/send`, { method: 'POST', body })\n return await res.json()\n}",
|
|
9773
9836
|
"scope": "write",
|
|
9774
9837
|
"toolset": "email"
|
|
9775
9838
|
},
|
|
@@ -10666,7 +10729,8 @@ const GENERATED_INTEGRATIONS = {
|
|
|
10666
10729
|
},
|
|
10667
10730
|
"preprocess": "google_service_account",
|
|
10668
10731
|
"healthCheck": {
|
|
10669
|
-
"
|
|
10732
|
+
"path": "/about?fields=user",
|
|
10733
|
+
"description": "Validates that the service account can mint a Google access token and call the Drive API."
|
|
10670
10734
|
}
|
|
10671
10735
|
},
|
|
10672
10736
|
"oauth_token": {
|
|
@@ -10691,7 +10755,8 @@ const GENERATED_INTEGRATIONS = {
|
|
|
10691
10755
|
}
|
|
10692
10756
|
},
|
|
10693
10757
|
"healthCheck": {
|
|
10694
|
-
"
|
|
10758
|
+
"path": "/about?fields=user",
|
|
10759
|
+
"description": "Validates that the OAuth token can call the Drive API."
|
|
10695
10760
|
}
|
|
10696
10761
|
}
|
|
10697
10762
|
},
|
|
@@ -15980,7 +16045,8 @@ const GENERATED_INTEGRATIONS = {
|
|
|
15980
16045
|
}
|
|
15981
16046
|
},
|
|
15982
16047
|
"healthCheck": {
|
|
15983
|
-
"
|
|
16048
|
+
"path": "/sites?search=*&$top=1",
|
|
16049
|
+
"description": "Validates that app credentials can obtain a Microsoft Graph token and read SharePoint sites."
|
|
15984
16050
|
}
|
|
15985
16051
|
}
|
|
15986
16052
|
},
|
|
@@ -16474,7 +16540,8 @@ const GENERATED_INTEGRATIONS = {
|
|
|
16474
16540
|
}
|
|
16475
16541
|
},
|
|
16476
16542
|
"healthCheck": {
|
|
16477
|
-
"
|
|
16543
|
+
"path": "/sites?search=*&$top=1",
|
|
16544
|
+
"description": "Validates that app credentials can obtain a Microsoft Graph token and read SharePoint sites."
|
|
16478
16545
|
}
|
|
16479
16546
|
}
|
|
16480
16547
|
},
|
|
@@ -17793,7 +17860,7 @@ const GENERATED_INTEGRATIONS = {
|
|
|
17793
17860
|
"name": "Trello",
|
|
17794
17861
|
"version": "0.1.0",
|
|
17795
17862
|
"baseUrl": "https://api.trello.com/1",
|
|
17796
|
-
"variantLabel": "Single
|
|
17863
|
+
"variantLabel": "Single Board",
|
|
17797
17864
|
"variantConfig": [
|
|
17798
17865
|
{
|
|
17799
17866
|
"key": "board",
|
|
@@ -18641,58 +18708,2752 @@ const GENERATED_INTEGRATIONS = {
|
|
|
18641
18708
|
}
|
|
18642
18709
|
],
|
|
18643
18710
|
"variantOwnerType": "trello"
|
|
18644
|
-
}
|
|
18645
|
-
|
|
18646
|
-
|
|
18647
|
-
|
|
18648
|
-
|
|
18649
|
-
|
|
18650
|
-
|
|
18651
|
-
|
|
18652
|
-
|
|
18653
|
-
|
|
18654
|
-
|
|
18655
|
-
|
|
18656
|
-
|
|
18657
|
-
|
|
18658
|
-
|
|
18659
|
-
|
|
18660
|
-
|
|
18661
|
-
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
18665
|
-
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
|
|
18670
|
-
|
|
18671
|
-
|
|
18711
|
+
},
|
|
18712
|
+
"xero": {
|
|
18713
|
+
"manifest": {
|
|
18714
|
+
"name": "xero",
|
|
18715
|
+
"version": "0.1.0",
|
|
18716
|
+
"baseUrl": "https://api.xero.com",
|
|
18717
|
+
"toolsets": {
|
|
18718
|
+
"accounting": {
|
|
18719
|
+
"label": "Accounting",
|
|
18720
|
+
"description": "Work with Xero contacts, items, invoices, payments, bank transactions, journals, and attachments"
|
|
18721
|
+
},
|
|
18722
|
+
"reports": {
|
|
18723
|
+
"label": "Reports",
|
|
18724
|
+
"description": "Read Xero financial reports such as profit and loss, balance sheet, trial balance, and aged reports"
|
|
18725
|
+
}
|
|
18726
|
+
},
|
|
18727
|
+
"tools": [
|
|
18728
|
+
{
|
|
18729
|
+
"name": "list_connections",
|
|
18730
|
+
"description": "List Xero tenant connections available to the current token. Use this for public OAuth integrations to discover tenantId values; Custom Connections are single-organisation and usually do not require tenantId.",
|
|
18731
|
+
"inputSchema": "schemas/empty.json",
|
|
18732
|
+
"handler": "handlers/list_connections.js",
|
|
18733
|
+
"scope": "read"
|
|
18734
|
+
},
|
|
18735
|
+
{
|
|
18736
|
+
"name": "get_organisation",
|
|
18737
|
+
"description": "Get the connected Xero organisation profile and settings. For public OAuth, provide tenantId from list_connections; for Custom Connections omit tenantId.",
|
|
18738
|
+
"inputSchema": "schemas/tenant_optional.json",
|
|
18739
|
+
"handler": "handlers/get_organisation.js",
|
|
18740
|
+
"scope": "read"
|
|
18741
|
+
},
|
|
18742
|
+
{
|
|
18743
|
+
"name": "list_accounts",
|
|
18744
|
+
"description": "List chart of accounts with account IDs, codes, names, types, status, and tax type. Use this before creating payments, bank transactions, or journals.",
|
|
18745
|
+
"inputSchema": "schemas/list_accounts.json",
|
|
18746
|
+
"handler": "handlers/list_accounts.js",
|
|
18747
|
+
"scope": "read"
|
|
18748
|
+
},
|
|
18749
|
+
{
|
|
18750
|
+
"name": "list_tax_rates",
|
|
18751
|
+
"description": "List tax rates available in the connected organisation. Use this to discover valid tax type values for invoice, item, and bank transaction lines.",
|
|
18752
|
+
"inputSchema": "schemas/tenant_optional.json",
|
|
18753
|
+
"handler": "handlers/list_tax_rates.js",
|
|
18754
|
+
"scope": "read"
|
|
18755
|
+
},
|
|
18756
|
+
{
|
|
18757
|
+
"name": "list_tracking_categories",
|
|
18758
|
+
"description": "List tracking categories and active options. Use this before adding tracking to invoice, journal, or bank transaction lines.",
|
|
18759
|
+
"inputSchema": "schemas/tenant_optional.json",
|
|
18760
|
+
"handler": "handlers/list_tracking_categories.js",
|
|
18761
|
+
"scope": "read"
|
|
18762
|
+
},
|
|
18763
|
+
{
|
|
18764
|
+
"name": "list_contact_groups",
|
|
18765
|
+
"description": "List contact groups, or provide contactGroupId to fetch one group with contacts. Use this when users ask about Xero customer/supplier groupings.",
|
|
18766
|
+
"inputSchema": "schemas/contact_group_list.json",
|
|
18767
|
+
"handler": "handlers/list_contact_groups.js",
|
|
18768
|
+
"scope": "read",
|
|
18769
|
+
"toolset": "accounting"
|
|
18770
|
+
},
|
|
18771
|
+
{
|
|
18772
|
+
"name": "create_tracking_category",
|
|
18773
|
+
"description": "Create a tracking category. Use list_tracking_categories first to avoid duplicates.",
|
|
18774
|
+
"inputSchema": "schemas/tracking_category_write.json",
|
|
18775
|
+
"handler": "handlers/create_tracking_category.js",
|
|
18776
|
+
"scope": "write",
|
|
18777
|
+
"toolset": "accounting"
|
|
18778
|
+
},
|
|
18779
|
+
{
|
|
18780
|
+
"name": "create_tracking_options",
|
|
18781
|
+
"description": "Create up to 10 tracking options in a tracking category. Get trackingCategoryId from list_tracking_categories.",
|
|
18782
|
+
"inputSchema": "schemas/tracking_options_write.json",
|
|
18783
|
+
"handler": "handlers/create_tracking_options.js",
|
|
18784
|
+
"scope": "write",
|
|
18785
|
+
"toolset": "accounting"
|
|
18786
|
+
},
|
|
18787
|
+
{
|
|
18788
|
+
"name": "update_tracking_category",
|
|
18789
|
+
"description": "Rename or archive a tracking category. Get trackingCategoryId from list_tracking_categories.",
|
|
18790
|
+
"inputSchema": "schemas/tracking_category_write.json",
|
|
18791
|
+
"handler": "handlers/update_tracking_category.js",
|
|
18792
|
+
"scope": "write",
|
|
18793
|
+
"toolset": "accounting"
|
|
18794
|
+
},
|
|
18795
|
+
{
|
|
18796
|
+
"name": "update_tracking_options",
|
|
18797
|
+
"description": "Rename or archive a tracking option. Get trackingCategoryId and trackingOptionId from list_tracking_categories.",
|
|
18798
|
+
"inputSchema": "schemas/tracking_options_write.json",
|
|
18799
|
+
"handler": "handlers/update_tracking_options.js",
|
|
18800
|
+
"scope": "write",
|
|
18801
|
+
"toolset": "accounting"
|
|
18802
|
+
},
|
|
18803
|
+
{
|
|
18804
|
+
"name": "list_currencies",
|
|
18805
|
+
"description": "List currencies configured in the connected Xero organisation.",
|
|
18806
|
+
"inputSchema": "schemas/tenant_optional.json",
|
|
18807
|
+
"handler": "handlers/list_currencies.js",
|
|
18808
|
+
"scope": "read"
|
|
18809
|
+
},
|
|
18810
|
+
{
|
|
18811
|
+
"name": "list_contacts",
|
|
18812
|
+
"description": "List contacts with compact identity and balance fields. Filter with where/order/page when needed; use get_contact for full details before updating.",
|
|
18813
|
+
"inputSchema": "schemas/list_records.json",
|
|
18814
|
+
"handler": "handlers/list_contacts.js",
|
|
18815
|
+
"scope": "read",
|
|
18816
|
+
"toolset": "accounting"
|
|
18817
|
+
},
|
|
18818
|
+
{
|
|
18819
|
+
"name": "get_contact",
|
|
18820
|
+
"description": "Get a Xero contact by contactId. Use this before update_contact to avoid overwriting important fields.",
|
|
18821
|
+
"inputSchema": "schemas/id_record.json",
|
|
18822
|
+
"handler": "handlers/get_contact.js",
|
|
18823
|
+
"scope": "read",
|
|
18824
|
+
"toolset": "accounting"
|
|
18825
|
+
},
|
|
18826
|
+
{
|
|
18827
|
+
"name": "create_contact",
|
|
18828
|
+
"description": "Create a contact from flat fields. Use extraFields only for advanced Xero fields; returns a compact summary and Xero link when available.",
|
|
18829
|
+
"inputSchema": "schemas/contact_write.json",
|
|
18830
|
+
"handler": "handlers/create_contact.js",
|
|
18831
|
+
"scope": "write",
|
|
18832
|
+
"toolset": "accounting"
|
|
18833
|
+
},
|
|
18834
|
+
{
|
|
18835
|
+
"name": "update_contact",
|
|
18836
|
+
"description": "Update a contact by contactId. Provide only fields to change; use get_contact first when preserving existing values matters.",
|
|
18837
|
+
"inputSchema": "schemas/contact_write.json",
|
|
18838
|
+
"handler": "handlers/update_contact.js",
|
|
18839
|
+
"scope": "write",
|
|
18840
|
+
"toolset": "accounting"
|
|
18841
|
+
},
|
|
18842
|
+
{
|
|
18843
|
+
"name": "list_items",
|
|
18844
|
+
"description": "List inventory/service items with IDs, codes, names, status, and sale/purchase details. Use get_item for full details.",
|
|
18845
|
+
"inputSchema": "schemas/list_records.json",
|
|
18846
|
+
"handler": "handlers/list_items.js",
|
|
18847
|
+
"scope": "read",
|
|
18848
|
+
"toolset": "accounting"
|
|
18849
|
+
},
|
|
18850
|
+
{
|
|
18851
|
+
"name": "get_item",
|
|
18852
|
+
"description": "Get a Xero item by itemId.",
|
|
18853
|
+
"inputSchema": "schemas/id_record.json",
|
|
18854
|
+
"handler": "handlers/get_item.js",
|
|
18855
|
+
"scope": "read",
|
|
18856
|
+
"toolset": "accounting"
|
|
18857
|
+
},
|
|
18858
|
+
{
|
|
18859
|
+
"name": "create_item",
|
|
18860
|
+
"description": "Create an item from flat fields. Use extraFields only for advanced Xero fields.",
|
|
18861
|
+
"inputSchema": "schemas/item_write.json",
|
|
18862
|
+
"handler": "handlers/create_item.js",
|
|
18863
|
+
"scope": "write",
|
|
18864
|
+
"toolset": "accounting"
|
|
18865
|
+
},
|
|
18866
|
+
{
|
|
18867
|
+
"name": "update_item",
|
|
18868
|
+
"description": "Update an item by itemId. Provide only fields to change.",
|
|
18869
|
+
"inputSchema": "schemas/item_write.json",
|
|
18870
|
+
"handler": "handlers/update_item.js",
|
|
18871
|
+
"scope": "write",
|
|
18872
|
+
"toolset": "accounting"
|
|
18873
|
+
},
|
|
18874
|
+
{
|
|
18875
|
+
"name": "list_invoices",
|
|
18876
|
+
"description": "List invoices with compact totals, status, contact, dates, and invoice number. Prefer explicit filters like status, contactIds, invoiceNumbers, fromDate/toDate; use get_invoice for line items.",
|
|
18877
|
+
"inputSchema": "schemas/list_records.json",
|
|
18878
|
+
"handler": "handlers/list_invoices.js",
|
|
18879
|
+
"scope": "read",
|
|
18880
|
+
"toolset": "accounting"
|
|
18881
|
+
},
|
|
18882
|
+
{
|
|
18883
|
+
"name": "get_invoice",
|
|
18884
|
+
"description": "Get an invoice by invoiceId, including line items and payment summary.",
|
|
18885
|
+
"inputSchema": "schemas/id_record.json",
|
|
18886
|
+
"handler": "handlers/get_invoice.js",
|
|
18887
|
+
"scope": "read",
|
|
18888
|
+
"toolset": "accounting"
|
|
18889
|
+
},
|
|
18890
|
+
{
|
|
18891
|
+
"name": "create_invoice",
|
|
18892
|
+
"description": "Create an invoice or bill from flat fields. Get contactId from list_contacts, accountCode from list_accounts, taxType from list_tax_rates, and tracking from list_tracking_categories. Returns a compact summary and Xero link.",
|
|
18893
|
+
"inputSchema": "schemas/invoice_write.json",
|
|
18894
|
+
"handler": "handlers/create_invoice.js",
|
|
18895
|
+
"scope": "write",
|
|
18896
|
+
"toolset": "accounting"
|
|
18897
|
+
},
|
|
18898
|
+
{
|
|
18899
|
+
"name": "update_invoice",
|
|
18900
|
+
"description": "Update an invoice by invoiceId. Use this for draft changes or allowed status transitions; prefer get_invoice first.",
|
|
18901
|
+
"inputSchema": "schemas/invoice_write.json",
|
|
18902
|
+
"handler": "handlers/update_invoice.js",
|
|
18903
|
+
"scope": "write",
|
|
18904
|
+
"toolset": "accounting"
|
|
18905
|
+
},
|
|
18906
|
+
{
|
|
18907
|
+
"name": "list_credit_notes",
|
|
18908
|
+
"description": "List credit notes with compact status, contact, date, total, and remaining credit fields.",
|
|
18909
|
+
"inputSchema": "schemas/list_records.json",
|
|
18910
|
+
"handler": "handlers/list_credit_notes.js",
|
|
18911
|
+
"scope": "read",
|
|
18912
|
+
"toolset": "accounting"
|
|
18913
|
+
},
|
|
18914
|
+
{
|
|
18915
|
+
"name": "create_credit_note",
|
|
18916
|
+
"description": "Create a credit note from flat fields. Get contactId from list_contacts, accountCode from list_accounts, and taxType from list_tax_rates. Returns a compact summary and Xero link.",
|
|
18917
|
+
"inputSchema": "schemas/credit_note_write.json",
|
|
18918
|
+
"handler": "handlers/create_credit_note.js",
|
|
18919
|
+
"scope": "write",
|
|
18920
|
+
"toolset": "accounting"
|
|
18921
|
+
},
|
|
18922
|
+
{
|
|
18923
|
+
"name": "list_quotes",
|
|
18924
|
+
"description": "List quotes with compact quote number, status, contact, dates, and totals.",
|
|
18925
|
+
"inputSchema": "schemas/list_records.json",
|
|
18926
|
+
"handler": "handlers/list_quotes.js",
|
|
18927
|
+
"scope": "read",
|
|
18928
|
+
"toolset": "accounting"
|
|
18929
|
+
},
|
|
18930
|
+
{
|
|
18931
|
+
"name": "create_quote",
|
|
18932
|
+
"description": "Create a quote from flat fields. Get contactId from list_contacts, accountCode from list_accounts, and taxType from list_tax_rates. Returns a compact summary and Xero link.",
|
|
18933
|
+
"inputSchema": "schemas/quote_write.json",
|
|
18934
|
+
"handler": "handlers/create_quote.js",
|
|
18935
|
+
"scope": "write",
|
|
18936
|
+
"toolset": "accounting"
|
|
18937
|
+
},
|
|
18938
|
+
{
|
|
18939
|
+
"name": "list_purchase_orders",
|
|
18940
|
+
"description": "List purchase orders with compact purchase order number, status, contact, delivery date, and totals.",
|
|
18941
|
+
"inputSchema": "schemas/list_records.json",
|
|
18942
|
+
"handler": "handlers/list_purchase_orders.js",
|
|
18943
|
+
"scope": "read",
|
|
18944
|
+
"toolset": "accounting"
|
|
18945
|
+
},
|
|
18946
|
+
{
|
|
18947
|
+
"name": "create_purchase_order",
|
|
18948
|
+
"description": "Create a purchase order from flat fields. Get supplier contactId from list_contacts and line account/tax values from list_accounts/list_tax_rates.",
|
|
18949
|
+
"inputSchema": "schemas/purchase_order_write.json",
|
|
18950
|
+
"handler": "handlers/create_purchase_order.js",
|
|
18951
|
+
"scope": "write",
|
|
18952
|
+
"toolset": "accounting"
|
|
18953
|
+
},
|
|
18954
|
+
{
|
|
18955
|
+
"name": "list_payments",
|
|
18956
|
+
"description": "List payments with compact payment ID, date, amount, status, account, and invoice references.",
|
|
18957
|
+
"inputSchema": "schemas/list_records.json",
|
|
18958
|
+
"handler": "handlers/list_payments.js",
|
|
18959
|
+
"scope": "read",
|
|
18960
|
+
"toolset": "accounting"
|
|
18961
|
+
},
|
|
18962
|
+
{
|
|
18963
|
+
"name": "create_payment",
|
|
18964
|
+
"description": "Create a payment against an invoice. Use get_invoice for invoiceId/amount due and list_accounts for the payment accountId. Returns a compact summary and Xero link.",
|
|
18965
|
+
"inputSchema": "schemas/payment_write.json",
|
|
18966
|
+
"handler": "handlers/create_payment.js",
|
|
18967
|
+
"scope": "write",
|
|
18968
|
+
"toolset": "accounting"
|
|
18969
|
+
},
|
|
18970
|
+
{
|
|
18971
|
+
"name": "list_bank_transactions",
|
|
18972
|
+
"description": "List bank transactions with compact type, status, contact, date, total, and bank account details.",
|
|
18973
|
+
"inputSchema": "schemas/list_records.json",
|
|
18974
|
+
"handler": "handlers/list_bank_transactions.js",
|
|
18975
|
+
"scope": "read",
|
|
18976
|
+
"toolset": "accounting"
|
|
18977
|
+
},
|
|
18978
|
+
{
|
|
18979
|
+
"name": "create_bank_transaction",
|
|
18980
|
+
"description": "Create a spend or receive bank transaction. Use list_accounts for valid bank/account codes and tax rates before calling this.",
|
|
18981
|
+
"inputSchema": "schemas/bank_transaction_write.json",
|
|
18982
|
+
"handler": "handlers/create_bank_transaction.js",
|
|
18983
|
+
"scope": "write",
|
|
18984
|
+
"toolset": "accounting"
|
|
18985
|
+
},
|
|
18986
|
+
{
|
|
18987
|
+
"name": "list_manual_journals",
|
|
18988
|
+
"description": "List manual journals with compact status, narration, date, journal ID, and line count.",
|
|
18989
|
+
"inputSchema": "schemas/list_records.json",
|
|
18990
|
+
"handler": "handlers/list_manual_journals.js",
|
|
18991
|
+
"scope": "read",
|
|
18992
|
+
"toolset": "accounting"
|
|
18993
|
+
},
|
|
18994
|
+
{
|
|
18995
|
+
"name": "create_manual_journal",
|
|
18996
|
+
"description": "Create a manual journal. Use this carefully; discover account codes with list_accounts and prefer DRAFT when supported by the organisation workflow.",
|
|
18997
|
+
"inputSchema": "schemas/manual_journal_write.json",
|
|
18998
|
+
"handler": "handlers/create_manual_journal.js",
|
|
18999
|
+
"scope": "write",
|
|
19000
|
+
"toolset": "accounting"
|
|
19001
|
+
},
|
|
19002
|
+
{
|
|
19003
|
+
"name": "list_attachments",
|
|
19004
|
+
"description": "List attachments for a supported Xero resource such as Invoices, Contacts, BankTransactions, CreditNotes, PurchaseOrders, or ManualJournals.",
|
|
19005
|
+
"inputSchema": "schemas/attachments.json",
|
|
19006
|
+
"handler": "handlers/list_attachments.js",
|
|
19007
|
+
"scope": "read",
|
|
19008
|
+
"toolset": "accounting"
|
|
19009
|
+
},
|
|
19010
|
+
{
|
|
19011
|
+
"name": "read_attachment_content",
|
|
19012
|
+
"description": "Extract readable text from an attachment on a supported Xero resource. Uses the shared file extractor for PDFs, Office files, CSV, text, HTML, and similar formats.",
|
|
19013
|
+
"inputSchema": "schemas/read_attachment_content.json",
|
|
19014
|
+
"handler": "handlers/read_attachment_content.js",
|
|
19015
|
+
"scope": "read",
|
|
19016
|
+
"toolset": "accounting"
|
|
19017
|
+
},
|
|
19018
|
+
{
|
|
19019
|
+
"name": "get_profit_and_loss",
|
|
19020
|
+
"description": "Get the Profit and Loss report for a date range or period. Returns Xero's report rows plus helper metadata for the query used.",
|
|
19021
|
+
"inputSchema": "schemas/report_profit_and_loss.json",
|
|
19022
|
+
"handler": "handlers/get_profit_and_loss.js",
|
|
19023
|
+
"scope": "read",
|
|
19024
|
+
"toolset": "reports"
|
|
19025
|
+
},
|
|
19026
|
+
{
|
|
19027
|
+
"name": "get_balance_sheet",
|
|
19028
|
+
"description": "Get the Balance Sheet report for a date or period. Use this for financial position summaries.",
|
|
19029
|
+
"inputSchema": "schemas/report_balance_sheet.json",
|
|
19030
|
+
"handler": "handlers/get_balance_sheet.js",
|
|
19031
|
+
"scope": "read",
|
|
19032
|
+
"toolset": "reports"
|
|
19033
|
+
},
|
|
19034
|
+
{
|
|
19035
|
+
"name": "get_trial_balance",
|
|
19036
|
+
"description": "Get the Trial Balance report at a point in time.",
|
|
19037
|
+
"inputSchema": "schemas/report_date.json",
|
|
19038
|
+
"handler": "handlers/get_trial_balance.js",
|
|
19039
|
+
"scope": "read",
|
|
19040
|
+
"toolset": "reports"
|
|
19041
|
+
},
|
|
19042
|
+
{
|
|
19043
|
+
"name": "get_bank_summary",
|
|
19044
|
+
"description": "Get the Bank Summary report for a date range.",
|
|
19045
|
+
"inputSchema": "schemas/report_date_range.json",
|
|
19046
|
+
"handler": "handlers/get_bank_summary.js",
|
|
19047
|
+
"scope": "read",
|
|
19048
|
+
"toolset": "reports"
|
|
19049
|
+
},
|
|
19050
|
+
{
|
|
19051
|
+
"name": "get_aged_payables_by_contact",
|
|
19052
|
+
"description": "Get the Aged Payables by Contact report for a supplier contact. Provide contactId from list_contacts.",
|
|
19053
|
+
"inputSchema": "schemas/report_aged_by_contact.json",
|
|
19054
|
+
"handler": "handlers/get_aged_payables_by_contact.js",
|
|
19055
|
+
"scope": "read",
|
|
19056
|
+
"toolset": "reports"
|
|
19057
|
+
},
|
|
19058
|
+
{
|
|
19059
|
+
"name": "get_aged_receivables_by_contact",
|
|
19060
|
+
"description": "Get the Aged Receivables by Contact report for a customer contact. Provide contactId from list_contacts.",
|
|
19061
|
+
"inputSchema": "schemas/report_aged_by_contact.json",
|
|
19062
|
+
"handler": "handlers/get_aged_receivables_by_contact.js",
|
|
19063
|
+
"scope": "read",
|
|
19064
|
+
"toolset": "reports"
|
|
19065
|
+
},
|
|
19066
|
+
{
|
|
19067
|
+
"name": "get_budget_summary",
|
|
19068
|
+
"description": "Get the Budget Summary report for a date range and period count.",
|
|
19069
|
+
"inputSchema": "schemas/report_budget_summary.json",
|
|
19070
|
+
"handler": "handlers/get_budget_summary.js",
|
|
19071
|
+
"scope": "read",
|
|
19072
|
+
"toolset": "reports"
|
|
19073
|
+
}
|
|
19074
|
+
]
|
|
18672
19075
|
},
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18680
|
-
|
|
18681
|
-
|
|
18682
|
-
|
|
18683
|
-
|
|
18684
|
-
|
|
18685
|
-
|
|
18686
|
-
|
|
18687
|
-
|
|
18688
|
-
|
|
18689
|
-
|
|
18690
|
-
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
|
|
18694
|
-
|
|
18695
|
-
|
|
19076
|
+
"usageGuide": "## Authentication and tenants\n\nCustom Connections are single-organisation connections. Omit `tenantId` for those tools unless Xero explicitly gives you one. Public OAuth integrations can connect to multiple organisations; call `list_connections`, choose the intended tenant, then pass that `tenantId` to Accounting API tools.\n\n## Recommended workflows\n\n- Discovery before writes: call `get_organisation`, `list_accounts`, `list_tax_rates`, and `list_tracking_categories` before creating invoices, payments, bank transactions, or journals.\n- Contacts and items: use `list_contacts`/`get_contact` and `list_items`/`get_item` to find IDs before referencing them from invoices or payments.\n- Invoices: create draft invoices first where possible, then use `get_invoice` to inspect Xero's calculated totals and validation state before updating status.\n- Payments: call `get_invoice` and `list_accounts` first so the payment amount and account reference are valid.\n- Reports: report tools require the matching granular report scope. If Xero returns insufficient scope, reconnect the Xero app with the report scope listed in the tool description or credential hint.\n\n## Query filters\n\nXero list endpoints accept API-specific `where` and `order` expressions. Keep filters narrow and prefer `page` pagination over unbounded reads. Date fields should use ISO dates (`YYYY-MM-DD`) unless the Xero endpoint documents another format.\n\n## Payroll\n\nPayroll APIs are regional and not enabled for every organisation. Verify the demo company region and payroll scopes in the Xero developer portal before adding payroll tools to a live workflow. This integration currently ships Accounting API tools first.\n",
|
|
19077
|
+
"variants": {
|
|
19078
|
+
"variants": {
|
|
19079
|
+
"custom_connection": {
|
|
19080
|
+
"label": "Custom Connection",
|
|
19081
|
+
"schema": {
|
|
19082
|
+
"type": "object",
|
|
19083
|
+
"properties": {
|
|
19084
|
+
"clientId": {
|
|
19085
|
+
"type": "string",
|
|
19086
|
+
"title": "Client ID",
|
|
19087
|
+
"description": "Xero app client ID for a Custom Connection."
|
|
19088
|
+
},
|
|
19089
|
+
"clientSecret": {
|
|
19090
|
+
"type": "string",
|
|
19091
|
+
"title": "Client Secret",
|
|
19092
|
+
"description": "Xero app client secret for the Custom Connection.",
|
|
19093
|
+
"format": "password"
|
|
19094
|
+
}
|
|
19095
|
+
},
|
|
19096
|
+
"required": [
|
|
19097
|
+
"clientId",
|
|
19098
|
+
"clientSecret"
|
|
19099
|
+
],
|
|
19100
|
+
"additionalProperties": false
|
|
19101
|
+
},
|
|
19102
|
+
"preprocess": {
|
|
19103
|
+
"type": "handler",
|
|
19104
|
+
"handlerCode": "async (creds, utils) => {\n const clientId = String(creds?.clientId || '').trim()\n const clientSecret = String(creds?.clientSecret || '').trim()\n\n if (!clientId)\n throw new Error('Missing clientId')\n if (!clientSecret)\n throw new Error('Missing clientSecret')\n\n const response = await utils.tokenFetch('https://identity.xero.com/connect/token', {\n method: 'POST',\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: clientId,\n client_secret: clientSecret,\n }),\n })\n\n const data = await response.json()\n if (!response.ok) {\n const message = typeof data?.error_description === 'string'\n ? data.error_description\n : (typeof data?.error === 'string' ? data.error : `Token request failed with status ${response.status}`)\n throw new Error(message)\n }\n\n const token = typeof data?.access_token === 'string' ? data.access_token : ''\n if (!token)\n throw new Error('Xero token response did not include access_token')\n\n return {\n token,\n expiresIn: data?.expires_in,\n }\n}",
|
|
19105
|
+
"allowedOrigins": [
|
|
19106
|
+
"https://identity.xero.com"
|
|
19107
|
+
]
|
|
19108
|
+
},
|
|
19109
|
+
"injection": {
|
|
19110
|
+
"headers": {
|
|
19111
|
+
"Authorization": "Bearer {{token}}",
|
|
19112
|
+
"Accept": "application/json"
|
|
19113
|
+
}
|
|
19114
|
+
},
|
|
19115
|
+
"healthCheck": {
|
|
19116
|
+
"path": "/connections",
|
|
19117
|
+
"description": "Validates that the Custom Connection credentials can obtain a Xero access token."
|
|
19118
|
+
}
|
|
19119
|
+
}
|
|
19120
|
+
},
|
|
19121
|
+
"default": "custom_connection"
|
|
19122
|
+
},
|
|
19123
|
+
"hint": "1. Go to https://developer.xero.com/ and sign in with your free Xero developer account.\n2. Open My Apps, create an app, and choose a Custom Connection when testing against the Xero demo company.\n3. Authorise the Custom Connection for the demo company. Demo-company Custom Connections can be used for development testing without charge.\n4. Copy the Client ID and Client Secret into Commandable.\n5. Ensure the app is authorised for the Accounting API scopes used by this integration.\n6. For future public OAuth apps, use `offline_access`, store refresh tokens securely, and select a tenant from the `/connections` response before calling tenant-scoped Accounting API tools.",
|
|
19124
|
+
"hintsByVariant": {},
|
|
19125
|
+
"tools": [
|
|
19126
|
+
{
|
|
19127
|
+
"name": "list_connections",
|
|
19128
|
+
"description": "List Xero tenant connections available to the current token. Use this for public OAuth integrations to discover tenantId values; Custom Connections are single-organisation and usually do not require tenantId.",
|
|
19129
|
+
"inputSchema": {
|
|
19130
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19131
|
+
"type": "object",
|
|
19132
|
+
"properties": {},
|
|
19133
|
+
"additionalProperties": false
|
|
19134
|
+
},
|
|
19135
|
+
"handlerCode": "async () => {\n const res = await integration.get('/connections')\n const data = await res.json()\n const connections = Array.isArray(data) ? data : []\n\n return {\n connections: connections.map(connection => ({\n id: connection.id,\n tenantId: connection.tenantId,\n tenantName: connection.tenantName,\n tenantType: connection.tenantType,\n createdDateUtc: connection.createdDateUtc,\n updatedDateUtc: connection.updatedDateUtc,\n })),\n note: 'For public OAuth, pass tenantId to tenant-scoped tools. Custom Connections are single-organisation and may not need this tool.',\n }\n}",
|
|
19136
|
+
"scope": "read"
|
|
19137
|
+
},
|
|
19138
|
+
{
|
|
19139
|
+
"name": "get_organisation",
|
|
19140
|
+
"description": "Get the connected Xero organisation profile and settings. For public OAuth, provide tenantId from list_connections; for Custom Connections omit tenantId.",
|
|
19141
|
+
"inputSchema": {
|
|
19142
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19143
|
+
"type": "object",
|
|
19144
|
+
"properties": {
|
|
19145
|
+
"tenantId": {
|
|
19146
|
+
"type": "string",
|
|
19147
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19148
|
+
}
|
|
19149
|
+
},
|
|
19150
|
+
"additionalProperties": false
|
|
19151
|
+
},
|
|
19152
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const res = await integration.get('/api.xro/2.0/Organisation', { headers })\n const data = await res.json()\n const organisations = Array.isArray(data?.Organisations) ? data.Organisations : []\n\n return {\n organisations: organisations.map(org => ({\n organisationId: org.OrganisationID,\n name: org.Name,\n legalName: org.LegalName,\n paysTax: org.PaysTax,\n version: org.Version,\n organisationType: org.OrganisationType,\n baseCurrency: org.BaseCurrency,\n countryCode: org.CountryCode,\n shortCode: org.ShortCode,\n timezone: org.Timezone,\n financialYearEndDay: org.FinancialYearEndDay,\n financialYearEndMonth: org.FinancialYearEndMonth,\n salesTaxBasis: org.SalesTaxBasis,\n salesTaxPeriod: org.SalesTaxPeriod,\n defaultSalesTax: org.DefaultSalesTax,\n defaultPurchasesTax: org.DefaultPurchasesTax,\n })),\n }\n}",
|
|
19153
|
+
"scope": "read"
|
|
19154
|
+
},
|
|
19155
|
+
{
|
|
19156
|
+
"name": "list_accounts",
|
|
19157
|
+
"description": "List chart of accounts with account IDs, codes, names, types, status, and tax type. Use this before creating payments, bank transactions, or journals.",
|
|
19158
|
+
"inputSchema": {
|
|
19159
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19160
|
+
"type": "object",
|
|
19161
|
+
"properties": {
|
|
19162
|
+
"tenantId": {
|
|
19163
|
+
"type": "string",
|
|
19164
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19165
|
+
},
|
|
19166
|
+
"where": {
|
|
19167
|
+
"type": "string",
|
|
19168
|
+
"description": 'Xero where filter expression, e.g. Status=="ACTIVE".'
|
|
19169
|
+
},
|
|
19170
|
+
"order": {
|
|
19171
|
+
"type": "string",
|
|
19172
|
+
"description": "Xero order expression, e.g. Code ASC."
|
|
19173
|
+
}
|
|
19174
|
+
},
|
|
19175
|
+
"additionalProperties": false
|
|
19176
|
+
},
|
|
19177
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n const path = `/api.xro/2.0/Accounts${params.toString() ? `?${params}` : ''}`\n const res = await integration.get(path, { headers })\n const data = await res.json()\n const accounts = Array.isArray(data?.Accounts) ? data.Accounts : []\n\n return {\n accounts: accounts.map(account => ({\n accountId: account.AccountID,\n code: account.Code,\n name: account.Name,\n type: account.Type,\n class: account.Class,\n status: account.Status,\n taxType: account.TaxType,\n enablePaymentsToAccount: account.EnablePaymentsToAccount,\n bankAccountNumber: account.BankAccountNumber,\n currencyCode: account.CurrencyCode,\n })),\n count: accounts.length,\n }\n}",
|
|
19178
|
+
"scope": "read"
|
|
19179
|
+
},
|
|
19180
|
+
{
|
|
19181
|
+
"name": "list_tax_rates",
|
|
19182
|
+
"description": "List tax rates available in the connected organisation. Use this to discover valid tax type values for invoice, item, and bank transaction lines.",
|
|
19183
|
+
"inputSchema": {
|
|
19184
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19185
|
+
"type": "object",
|
|
19186
|
+
"properties": {
|
|
19187
|
+
"tenantId": {
|
|
19188
|
+
"type": "string",
|
|
19189
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19190
|
+
}
|
|
19191
|
+
},
|
|
19192
|
+
"additionalProperties": false
|
|
19193
|
+
},
|
|
19194
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const res = await integration.get('/api.xro/2.0/TaxRates', { headers })\n const data = await res.json()\n const taxRates = Array.isArray(data?.TaxRates) ? data.TaxRates : []\n\n return {\n taxRates: taxRates.map(rate => ({\n name: rate.Name,\n taxType: rate.TaxType,\n status: rate.Status,\n displayTaxRate: rate.DisplayTaxRate,\n effectiveRate: rate.EffectiveRate,\n canApplyToAssets: rate.CanApplyToAssets,\n canApplyToEquity: rate.CanApplyToEquity,\n canApplyToExpenses: rate.CanApplyToExpenses,\n canApplyToLiabilities: rate.CanApplyToLiabilities,\n canApplyToRevenue: rate.CanApplyToRevenue,\n })),\n count: taxRates.length,\n }\n}",
|
|
19195
|
+
"scope": "read"
|
|
19196
|
+
},
|
|
19197
|
+
{
|
|
19198
|
+
"name": "list_tracking_categories",
|
|
19199
|
+
"description": "List tracking categories and active options. Use this before adding tracking to invoice, journal, or bank transaction lines.",
|
|
19200
|
+
"inputSchema": {
|
|
19201
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19202
|
+
"type": "object",
|
|
19203
|
+
"properties": {
|
|
19204
|
+
"tenantId": {
|
|
19205
|
+
"type": "string",
|
|
19206
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19207
|
+
}
|
|
19208
|
+
},
|
|
19209
|
+
"additionalProperties": false
|
|
19210
|
+
},
|
|
19211
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const res = await integration.get('/api.xro/2.0/TrackingCategories', { headers })\n const data = await res.json()\n const categories = Array.isArray(data?.TrackingCategories) ? data.TrackingCategories : []\n\n return {\n trackingCategories: categories.map(category => ({\n trackingCategoryId: category.TrackingCategoryID,\n name: category.Name,\n status: category.Status,\n options: Array.isArray(category.Options)\n ? category.Options.map(option => ({\n trackingOptionId: option.TrackingOptionID,\n name: option.Name,\n status: option.Status,\n }))\n : [],\n })),\n count: categories.length,\n }\n}",
|
|
19212
|
+
"scope": "read"
|
|
19213
|
+
},
|
|
19214
|
+
{
|
|
19215
|
+
"name": "list_contact_groups",
|
|
19216
|
+
"description": "List contact groups, or provide contactGroupId to fetch one group with contacts. Use this when users ask about Xero customer/supplier groupings.",
|
|
19217
|
+
"inputSchema": {
|
|
19218
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19219
|
+
"type": "object",
|
|
19220
|
+
"properties": {
|
|
19221
|
+
"tenantId": {
|
|
19222
|
+
"type": "string",
|
|
19223
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19224
|
+
},
|
|
19225
|
+
"contactGroupId": {
|
|
19226
|
+
"type": "string",
|
|
19227
|
+
"description": "Optional contact group ID to retrieve one group with contacts."
|
|
19228
|
+
}
|
|
19229
|
+
},
|
|
19230
|
+
"additionalProperties": false
|
|
19231
|
+
},
|
|
19232
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const path = input.contactGroupId\n ? `/api.xro/2.0/ContactGroups/${encodeURIComponent(input.contactGroupId)}`\n : '/api.xro/2.0/ContactGroups'\n const res = await integration.get(path, { headers })\n const data = await res.json()\n const contactGroups = Array.isArray(data?.ContactGroups) ? data.ContactGroups : []\n\n return {\n contactGroups: contactGroups.map(group => ({\n contactGroupId: group.ContactGroupID,\n name: group.Name,\n status: group.Status,\n contacts: Array.isArray(group.Contacts)\n ? group.Contacts.map(contact => ({\n contactId: contact.ContactID,\n name: contact.Name,\n emailAddress: contact.EmailAddress,\n }))\n : [],\n })),\n }\n}",
|
|
19233
|
+
"scope": "read",
|
|
19234
|
+
"toolset": "accounting"
|
|
19235
|
+
},
|
|
19236
|
+
{
|
|
19237
|
+
"name": "create_tracking_category",
|
|
19238
|
+
"description": "Create a tracking category. Use list_tracking_categories first to avoid duplicates.",
|
|
19239
|
+
"inputSchema": {
|
|
19240
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19241
|
+
"type": "object",
|
|
19242
|
+
"properties": {
|
|
19243
|
+
"tenantId": {
|
|
19244
|
+
"type": "string",
|
|
19245
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19246
|
+
},
|
|
19247
|
+
"trackingCategoryId": {
|
|
19248
|
+
"type": "string",
|
|
19249
|
+
"description": "Required for update_tracking_category. Get from list_tracking_categories."
|
|
19250
|
+
},
|
|
19251
|
+
"name": {
|
|
19252
|
+
"type": "string",
|
|
19253
|
+
"description": "Tracking category name."
|
|
19254
|
+
},
|
|
19255
|
+
"status": {
|
|
19256
|
+
"type": "string",
|
|
19257
|
+
"enum": [
|
|
19258
|
+
"ACTIVE",
|
|
19259
|
+
"ARCHIVED"
|
|
19260
|
+
],
|
|
19261
|
+
"description": "Optional status for update_tracking_category."
|
|
19262
|
+
}
|
|
19263
|
+
},
|
|
19264
|
+
"additionalProperties": false
|
|
19265
|
+
},
|
|
19266
|
+
"handlerCode": "async (input) => {\n if (!input.name)\n throw new Error('name is required for create_tracking_category')\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const res = await integration.put('/api.xro/2.0/TrackingCategories', { Name: input.name }, { headers })\n const data = await res.json()\n const category = Array.isArray(data?.TrackingCategories) ? data.TrackingCategories[0] : null\n\n return {\n trackingCategory: category\n ? {\n trackingCategoryId: category.TrackingCategoryID,\n name: category.Name,\n status: category.Status,\n options: Array.isArray(category.Options)\n ? category.Options.map(option => ({\n trackingOptionId: option.TrackingOptionID,\n name: option.Name,\n status: option.Status,\n }))\n : [],\n }\n : null,\n }\n}",
|
|
19267
|
+
"scope": "write",
|
|
19268
|
+
"toolset": "accounting"
|
|
19269
|
+
},
|
|
19270
|
+
{
|
|
19271
|
+
"name": "create_tracking_options",
|
|
19272
|
+
"description": "Create up to 10 tracking options in a tracking category. Get trackingCategoryId from list_tracking_categories.",
|
|
19273
|
+
"inputSchema": {
|
|
19274
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19275
|
+
"type": "object",
|
|
19276
|
+
"properties": {
|
|
19277
|
+
"tenantId": {
|
|
19278
|
+
"type": "string",
|
|
19279
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19280
|
+
},
|
|
19281
|
+
"trackingCategoryId": {
|
|
19282
|
+
"type": "string",
|
|
19283
|
+
"description": "Tracking category ID from list_tracking_categories."
|
|
19284
|
+
},
|
|
19285
|
+
"optionNames": {
|
|
19286
|
+
"type": "array",
|
|
19287
|
+
"description": "Names of tracking options to create. Maximum 10 per call.",
|
|
19288
|
+
"items": {
|
|
19289
|
+
"type": "string"
|
|
19290
|
+
},
|
|
19291
|
+
"minItems": 1,
|
|
19292
|
+
"maxItems": 10
|
|
19293
|
+
},
|
|
19294
|
+
"trackingOptionId": {
|
|
19295
|
+
"type": "string",
|
|
19296
|
+
"description": "Required for update_tracking_options when updating one existing option."
|
|
19297
|
+
},
|
|
19298
|
+
"name": {
|
|
19299
|
+
"type": "string",
|
|
19300
|
+
"description": "New option name for update_tracking_options."
|
|
19301
|
+
},
|
|
19302
|
+
"status": {
|
|
19303
|
+
"type": "string",
|
|
19304
|
+
"enum": [
|
|
19305
|
+
"ACTIVE",
|
|
19306
|
+
"ARCHIVED"
|
|
19307
|
+
],
|
|
19308
|
+
"description": "Optional option status for update_tracking_options."
|
|
19309
|
+
}
|
|
19310
|
+
},
|
|
19311
|
+
"additionalProperties": false
|
|
19312
|
+
},
|
|
19313
|
+
"handlerCode": "async (input) => {\n if (!input.trackingCategoryId)\n throw new Error('trackingCategoryId is required for create_tracking_options')\n if (!Array.isArray(input.optionNames) || !input.optionNames.length)\n throw new Error('optionNames is required for create_tracking_options')\n if (input.optionNames.length > 10)\n throw new Error('create_tracking_options accepts at most 10 optionNames per call')\n\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const created = []\n for (const optionName of input.optionNames) {\n const res = await integration.put(\n `/api.xro/2.0/TrackingCategories/${encodeURIComponent(input.trackingCategoryId)}/Options`,\n { Name: optionName },\n { headers },\n )\n const data = await res.json()\n const option = Array.isArray(data?.Options) ? data.Options[0] : null\n if (option) {\n created.push({\n trackingOptionId: option.TrackingOptionID,\n name: option.Name,\n status: option.Status,\n })\n }\n }\n\n return {\n createdCount: created.length,\n requestedCount: input.optionNames.length,\n trackingOptions: created,\n }\n}",
|
|
19314
|
+
"scope": "write",
|
|
19315
|
+
"toolset": "accounting"
|
|
19316
|
+
},
|
|
19317
|
+
{
|
|
19318
|
+
"name": "update_tracking_category",
|
|
19319
|
+
"description": "Rename or archive a tracking category. Get trackingCategoryId from list_tracking_categories.",
|
|
19320
|
+
"inputSchema": {
|
|
19321
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19322
|
+
"type": "object",
|
|
19323
|
+
"properties": {
|
|
19324
|
+
"tenantId": {
|
|
19325
|
+
"type": "string",
|
|
19326
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19327
|
+
},
|
|
19328
|
+
"trackingCategoryId": {
|
|
19329
|
+
"type": "string",
|
|
19330
|
+
"description": "Required for update_tracking_category. Get from list_tracking_categories."
|
|
19331
|
+
},
|
|
19332
|
+
"name": {
|
|
19333
|
+
"type": "string",
|
|
19334
|
+
"description": "Tracking category name."
|
|
19335
|
+
},
|
|
19336
|
+
"status": {
|
|
19337
|
+
"type": "string",
|
|
19338
|
+
"enum": [
|
|
19339
|
+
"ACTIVE",
|
|
19340
|
+
"ARCHIVED"
|
|
19341
|
+
],
|
|
19342
|
+
"description": "Optional status for update_tracking_category."
|
|
19343
|
+
}
|
|
19344
|
+
},
|
|
19345
|
+
"additionalProperties": false
|
|
19346
|
+
},
|
|
19347
|
+
"handlerCode": "async (input) => {\n if (!input.trackingCategoryId)\n throw new Error('trackingCategoryId is required for update_tracking_category')\n if (!input.name && !input.status)\n throw new Error('Provide name or status for update_tracking_category')\n\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const body = {\n ...(input.name ? { Name: input.name } : {}),\n ...(input.status ? { Status: input.status } : {}),\n }\n const res = await integration.post(\n `/api.xro/2.0/TrackingCategories/${encodeURIComponent(input.trackingCategoryId)}`,\n body,\n { headers },\n )\n const data = await res.json()\n const category = Array.isArray(data?.TrackingCategories) ? data.TrackingCategories[0] : null\n\n return {\n trackingCategory: category\n ? {\n trackingCategoryId: category.TrackingCategoryID,\n name: category.Name,\n status: category.Status,\n options: Array.isArray(category.Options)\n ? category.Options.map(option => ({\n trackingOptionId: option.TrackingOptionID,\n name: option.Name,\n status: option.Status,\n }))\n : [],\n }\n : null,\n }\n}",
|
|
19348
|
+
"scope": "write",
|
|
19349
|
+
"toolset": "accounting"
|
|
19350
|
+
},
|
|
19351
|
+
{
|
|
19352
|
+
"name": "update_tracking_options",
|
|
19353
|
+
"description": "Rename or archive a tracking option. Get trackingCategoryId and trackingOptionId from list_tracking_categories.",
|
|
19354
|
+
"inputSchema": {
|
|
19355
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19356
|
+
"type": "object",
|
|
19357
|
+
"properties": {
|
|
19358
|
+
"tenantId": {
|
|
19359
|
+
"type": "string",
|
|
19360
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19361
|
+
},
|
|
19362
|
+
"trackingCategoryId": {
|
|
19363
|
+
"type": "string",
|
|
19364
|
+
"description": "Tracking category ID from list_tracking_categories."
|
|
19365
|
+
},
|
|
19366
|
+
"optionNames": {
|
|
19367
|
+
"type": "array",
|
|
19368
|
+
"description": "Names of tracking options to create. Maximum 10 per call.",
|
|
19369
|
+
"items": {
|
|
19370
|
+
"type": "string"
|
|
19371
|
+
},
|
|
19372
|
+
"minItems": 1,
|
|
19373
|
+
"maxItems": 10
|
|
19374
|
+
},
|
|
19375
|
+
"trackingOptionId": {
|
|
19376
|
+
"type": "string",
|
|
19377
|
+
"description": "Required for update_tracking_options when updating one existing option."
|
|
19378
|
+
},
|
|
19379
|
+
"name": {
|
|
19380
|
+
"type": "string",
|
|
19381
|
+
"description": "New option name for update_tracking_options."
|
|
19382
|
+
},
|
|
19383
|
+
"status": {
|
|
19384
|
+
"type": "string",
|
|
19385
|
+
"enum": [
|
|
19386
|
+
"ACTIVE",
|
|
19387
|
+
"ARCHIVED"
|
|
19388
|
+
],
|
|
19389
|
+
"description": "Optional option status for update_tracking_options."
|
|
19390
|
+
}
|
|
19391
|
+
},
|
|
19392
|
+
"additionalProperties": false
|
|
19393
|
+
},
|
|
19394
|
+
"handlerCode": "async (input) => {\n if (!input.trackingCategoryId)\n throw new Error('trackingCategoryId is required for update_tracking_options')\n if (!input.trackingOptionId)\n throw new Error('trackingOptionId is required for update_tracking_options')\n if (!input.name && !input.status)\n throw new Error('Provide name or status for update_tracking_options')\n\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const body = {\n ...(input.name ? { Name: input.name } : {}),\n ...(input.status ? { Status: input.status } : {}),\n }\n const res = await integration.post(\n `/api.xro/2.0/TrackingCategories/${encodeURIComponent(input.trackingCategoryId)}/Options/${encodeURIComponent(input.trackingOptionId)}`,\n body,\n { headers },\n )\n const data = await res.json()\n const option = Array.isArray(data?.Options) ? data.Options[0] : null\n\n return {\n trackingOption: option\n ? {\n trackingOptionId: option.TrackingOptionID,\n name: option.Name,\n status: option.Status,\n }\n : null,\n }\n}",
|
|
19395
|
+
"scope": "write",
|
|
19396
|
+
"toolset": "accounting"
|
|
19397
|
+
},
|
|
19398
|
+
{
|
|
19399
|
+
"name": "list_currencies",
|
|
19400
|
+
"description": "List currencies configured in the connected Xero organisation.",
|
|
19401
|
+
"inputSchema": {
|
|
19402
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19403
|
+
"type": "object",
|
|
19404
|
+
"properties": {
|
|
19405
|
+
"tenantId": {
|
|
19406
|
+
"type": "string",
|
|
19407
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19408
|
+
}
|
|
19409
|
+
},
|
|
19410
|
+
"additionalProperties": false
|
|
19411
|
+
},
|
|
19412
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const res = await integration.get('/api.xro/2.0/Currencies', { headers })\n const data = await res.json()\n const currencies = Array.isArray(data?.Currencies) ? data.Currencies : []\n\n return {\n currencies: currencies.map(currency => ({\n code: currency.Code,\n description: currency.Description,\n })),\n count: currencies.length,\n }\n}",
|
|
19413
|
+
"scope": "read"
|
|
19414
|
+
},
|
|
19415
|
+
{
|
|
19416
|
+
"name": "list_contacts",
|
|
19417
|
+
"description": "List contacts with compact identity and balance fields. Filter with where/order/page when needed; use get_contact for full details before updating.",
|
|
19418
|
+
"inputSchema": {
|
|
19419
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19420
|
+
"type": "object",
|
|
19421
|
+
"properties": {
|
|
19422
|
+
"tenantId": {
|
|
19423
|
+
"type": "string",
|
|
19424
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19425
|
+
},
|
|
19426
|
+
"page": {
|
|
19427
|
+
"type": "integer",
|
|
19428
|
+
"minimum": 1,
|
|
19429
|
+
"description": "Xero page number for paginated endpoints."
|
|
19430
|
+
},
|
|
19431
|
+
"where": {
|
|
19432
|
+
"type": "string",
|
|
19433
|
+
"description": 'Advanced Xero where filter expression, e.g. Status=="AUTHORISED". Prefer the explicit filter fields when available.'
|
|
19434
|
+
},
|
|
19435
|
+
"order": {
|
|
19436
|
+
"type": "string",
|
|
19437
|
+
"description": "Xero order expression, e.g. UpdatedDateUTC DESC."
|
|
19438
|
+
},
|
|
19439
|
+
"modifiedAfter": {
|
|
19440
|
+
"type": "string",
|
|
19441
|
+
"description": "Only include records modified after this RFC3339 timestamp."
|
|
19442
|
+
},
|
|
19443
|
+
"status": {
|
|
19444
|
+
"type": "string",
|
|
19445
|
+
"description": "Convenience status filter for endpoints that support a Status query parameter."
|
|
19446
|
+
},
|
|
19447
|
+
"contactIds": {
|
|
19448
|
+
"type": "array",
|
|
19449
|
+
"description": "Filter invoices/transactions to one or more contact IDs from list_contacts.",
|
|
19450
|
+
"items": {
|
|
19451
|
+
"type": "string"
|
|
19452
|
+
}
|
|
19453
|
+
},
|
|
19454
|
+
"invoiceNumbers": {
|
|
19455
|
+
"type": "array",
|
|
19456
|
+
"description": "Filter invoices by invoice number. For invoices, line items are returned by Xero when invoice numbers are supplied.",
|
|
19457
|
+
"items": {
|
|
19458
|
+
"type": "string"
|
|
19459
|
+
}
|
|
19460
|
+
},
|
|
19461
|
+
"fromDate": {
|
|
19462
|
+
"type": "string",
|
|
19463
|
+
"description": "Convenience start date filter in YYYY-MM-DD format for date-based resources."
|
|
19464
|
+
},
|
|
19465
|
+
"toDate": {
|
|
19466
|
+
"type": "string",
|
|
19467
|
+
"description": "Convenience end date filter in YYYY-MM-DD format for date-based resources."
|
|
19468
|
+
},
|
|
19469
|
+
"includeArchived": {
|
|
19470
|
+
"type": "boolean",
|
|
19471
|
+
"description": "Whether to include archived records when the endpoint supports it."
|
|
19472
|
+
}
|
|
19473
|
+
},
|
|
19474
|
+
"additionalProperties": false
|
|
19475
|
+
},
|
|
19476
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.page) params.set('page', String(input.page))\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n if (input.modifiedAfter) params.set('If-Modified-Since', input.modifiedAfter)\n if (input.includeArchived !== undefined) params.set('includeArchived', String(input.includeArchived))\n const res = await integration.get(`/api.xro/2.0/Contacts${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const contacts = Array.isArray(data?.Contacts) ? data.Contacts : []\n\n return {\n contacts: contacts.map(contact => ({\n contactId: contact.ContactID,\n name: contact.Name,\n emailAddress: contact.EmailAddress,\n contactStatus: contact.ContactStatus,\n isSupplier: contact.IsSupplier,\n isCustomer: contact.IsCustomer,\n balances: contact.Balances,\n updatedDateUtc: contact.UpdatedDateUTC,\n })),\n count: contacts.length,\n page: input.page || 1,\n next: contacts.length ? 'Call list_contacts with the next page number to continue.' : null,\n }\n}",
|
|
19477
|
+
"scope": "read",
|
|
19478
|
+
"toolset": "accounting"
|
|
19479
|
+
},
|
|
19480
|
+
{
|
|
19481
|
+
"name": "get_contact",
|
|
19482
|
+
"description": "Get a Xero contact by contactId. Use this before update_contact to avoid overwriting important fields.",
|
|
19483
|
+
"inputSchema": {
|
|
19484
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19485
|
+
"type": "object",
|
|
19486
|
+
"properties": {
|
|
19487
|
+
"tenantId": {
|
|
19488
|
+
"type": "string",
|
|
19489
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19490
|
+
},
|
|
19491
|
+
"id": {
|
|
19492
|
+
"type": "string",
|
|
19493
|
+
"description": "Xero resource ID."
|
|
19494
|
+
}
|
|
19495
|
+
},
|
|
19496
|
+
"required": [
|
|
19497
|
+
"id"
|
|
19498
|
+
],
|
|
19499
|
+
"additionalProperties": false
|
|
19500
|
+
},
|
|
19501
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const res = await integration.get(`/api.xro/2.0/Contacts/${encodeURIComponent(input.id)}`, { headers })\n const data = await res.json()\n const contacts = Array.isArray(data?.Contacts) ? data.Contacts : []\n const contact = contacts[0] || null\n\n return {\n contact: contact\n ? {\n contactId: contact.ContactID,\n name: contact.Name,\n emailAddress: contact.EmailAddress,\n firstName: contact.FirstName,\n lastName: contact.LastName,\n contactStatus: contact.ContactStatus,\n isSupplier: contact.IsSupplier,\n isCustomer: contact.IsCustomer,\n balances: contact.Balances,\n phones: contact.Phones,\n addresses: contact.Addresses,\n updatedDateUtc: contact.UpdatedDateUTC,\n }\n : null,\n }\n}",
|
|
19502
|
+
"scope": "read",
|
|
19503
|
+
"toolset": "accounting"
|
|
19504
|
+
},
|
|
19505
|
+
{
|
|
19506
|
+
"name": "create_contact",
|
|
19507
|
+
"description": "Create a contact from flat fields. Use extraFields only for advanced Xero fields; returns a compact summary and Xero link when available.",
|
|
19508
|
+
"inputSchema": {
|
|
19509
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19510
|
+
"type": "object",
|
|
19511
|
+
"properties": {
|
|
19512
|
+
"tenantId": {
|
|
19513
|
+
"type": "string",
|
|
19514
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19515
|
+
},
|
|
19516
|
+
"contactId": {
|
|
19517
|
+
"type": "string",
|
|
19518
|
+
"description": "Required for update_contact."
|
|
19519
|
+
},
|
|
19520
|
+
"name": {
|
|
19521
|
+
"type": "string",
|
|
19522
|
+
"description": "Contact name."
|
|
19523
|
+
},
|
|
19524
|
+
"emailAddress": {
|
|
19525
|
+
"type": "string",
|
|
19526
|
+
"description": "Primary email address."
|
|
19527
|
+
},
|
|
19528
|
+
"firstName": {
|
|
19529
|
+
"type": "string"
|
|
19530
|
+
},
|
|
19531
|
+
"lastName": {
|
|
19532
|
+
"type": "string"
|
|
19533
|
+
},
|
|
19534
|
+
"extraFields": {
|
|
19535
|
+
"type": "object",
|
|
19536
|
+
"description": "Additional Xero Contact fields. Values here override common fields.",
|
|
19537
|
+
"additionalProperties": true
|
|
19538
|
+
}
|
|
19539
|
+
},
|
|
19540
|
+
"additionalProperties": false
|
|
19541
|
+
},
|
|
19542
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const getShortCode = async () => {\n try {\n const orgRes = await integration.get('/api.xro/2.0/Organisation', { headers })\n const orgData = await orgRes.json()\n return Array.isArray(orgData?.Organisations) ? orgData.Organisations[0]?.ShortCode : ''\n }\n catch {\n return ''\n }\n }\n const summarizeContact = async (contact) => {\n const contactId = contact?.ContactID || ''\n const shortCode = contactId ? await getShortCode() : ''\n return {\n contactId,\n name: contact?.Name,\n emailAddress: contact?.EmailAddress,\n contactStatus: contact?.ContactStatus,\n isCustomer: contact?.IsCustomer,\n isSupplier: contact?.IsSupplier,\n xeroUrl: shortCode && contactId ? `https://go.xero.com/app/${encodeURIComponent(shortCode)}/contacts/contact/${encodeURIComponent(contactId)}` : null,\n }\n }\n const contact = {\n ...(input.name ? { Name: input.name } : {}),\n ...(input.emailAddress ? { EmailAddress: input.emailAddress } : {}),\n ...(input.firstName ? { FirstName: input.firstName } : {}),\n ...(input.lastName ? { LastName: input.lastName } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post('/api.xro/2.0/Contacts', { Contacts: [contact] }, { headers })\n const data = await res.json()\n const created = Array.isArray(data?.Contacts) ? data.Contacts[0] : null\n return {\n contact: created ? await summarizeContact(created) : null,\n }\n}",
|
|
19543
|
+
"scope": "write",
|
|
19544
|
+
"toolset": "accounting"
|
|
19545
|
+
},
|
|
19546
|
+
{
|
|
19547
|
+
"name": "update_contact",
|
|
19548
|
+
"description": "Update a contact by contactId. Provide only fields to change; use get_contact first when preserving existing values matters.",
|
|
19549
|
+
"inputSchema": {
|
|
19550
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19551
|
+
"type": "object",
|
|
19552
|
+
"properties": {
|
|
19553
|
+
"tenantId": {
|
|
19554
|
+
"type": "string",
|
|
19555
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19556
|
+
},
|
|
19557
|
+
"contactId": {
|
|
19558
|
+
"type": "string",
|
|
19559
|
+
"description": "Required for update_contact."
|
|
19560
|
+
},
|
|
19561
|
+
"name": {
|
|
19562
|
+
"type": "string",
|
|
19563
|
+
"description": "Contact name."
|
|
19564
|
+
},
|
|
19565
|
+
"emailAddress": {
|
|
19566
|
+
"type": "string",
|
|
19567
|
+
"description": "Primary email address."
|
|
19568
|
+
},
|
|
19569
|
+
"firstName": {
|
|
19570
|
+
"type": "string"
|
|
19571
|
+
},
|
|
19572
|
+
"lastName": {
|
|
19573
|
+
"type": "string"
|
|
19574
|
+
},
|
|
19575
|
+
"extraFields": {
|
|
19576
|
+
"type": "object",
|
|
19577
|
+
"description": "Additional Xero Contact fields. Values here override common fields.",
|
|
19578
|
+
"additionalProperties": true
|
|
19579
|
+
}
|
|
19580
|
+
},
|
|
19581
|
+
"additionalProperties": false
|
|
19582
|
+
},
|
|
19583
|
+
"handlerCode": "async (input) => {\n if (!input.contactId)\n throw new Error('contactId is required for update_contact')\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const getShortCode = async () => {\n try {\n const orgRes = await integration.get('/api.xro/2.0/Organisation', { headers })\n const orgData = await orgRes.json()\n return Array.isArray(orgData?.Organisations) ? orgData.Organisations[0]?.ShortCode : ''\n }\n catch {\n return ''\n }\n }\n const summarizeContact = async (contact) => {\n const contactId = contact?.ContactID || ''\n const shortCode = contactId ? await getShortCode() : ''\n return {\n contactId,\n name: contact?.Name,\n emailAddress: contact?.EmailAddress,\n contactStatus: contact?.ContactStatus,\n isCustomer: contact?.IsCustomer,\n isSupplier: contact?.IsSupplier,\n xeroUrl: shortCode && contactId ? `https://go.xero.com/app/${encodeURIComponent(shortCode)}/contacts/contact/${encodeURIComponent(contactId)}` : null,\n }\n }\n const contact = {\n ContactID: input.contactId,\n ...(input.name ? { Name: input.name } : {}),\n ...(input.emailAddress ? { EmailAddress: input.emailAddress } : {}),\n ...(input.firstName ? { FirstName: input.firstName } : {}),\n ...(input.lastName ? { LastName: input.lastName } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post(`/api.xro/2.0/Contacts/${encodeURIComponent(input.contactId)}`, { Contacts: [contact] }, { headers })\n const data = await res.json()\n const updated = Array.isArray(data?.Contacts) ? data.Contacts[0] : null\n return {\n contact: updated ? await summarizeContact(updated) : null,\n }\n}",
|
|
19584
|
+
"scope": "write",
|
|
19585
|
+
"toolset": "accounting"
|
|
19586
|
+
},
|
|
19587
|
+
{
|
|
19588
|
+
"name": "list_items",
|
|
19589
|
+
"description": "List inventory/service items with IDs, codes, names, status, and sale/purchase details. Use get_item for full details.",
|
|
19590
|
+
"inputSchema": {
|
|
19591
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19592
|
+
"type": "object",
|
|
19593
|
+
"properties": {
|
|
19594
|
+
"tenantId": {
|
|
19595
|
+
"type": "string",
|
|
19596
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19597
|
+
},
|
|
19598
|
+
"page": {
|
|
19599
|
+
"type": "integer",
|
|
19600
|
+
"minimum": 1,
|
|
19601
|
+
"description": "Xero page number for paginated endpoints."
|
|
19602
|
+
},
|
|
19603
|
+
"where": {
|
|
19604
|
+
"type": "string",
|
|
19605
|
+
"description": 'Advanced Xero where filter expression, e.g. Status=="AUTHORISED". Prefer the explicit filter fields when available.'
|
|
19606
|
+
},
|
|
19607
|
+
"order": {
|
|
19608
|
+
"type": "string",
|
|
19609
|
+
"description": "Xero order expression, e.g. UpdatedDateUTC DESC."
|
|
19610
|
+
},
|
|
19611
|
+
"modifiedAfter": {
|
|
19612
|
+
"type": "string",
|
|
19613
|
+
"description": "Only include records modified after this RFC3339 timestamp."
|
|
19614
|
+
},
|
|
19615
|
+
"status": {
|
|
19616
|
+
"type": "string",
|
|
19617
|
+
"description": "Convenience status filter for endpoints that support a Status query parameter."
|
|
19618
|
+
},
|
|
19619
|
+
"contactIds": {
|
|
19620
|
+
"type": "array",
|
|
19621
|
+
"description": "Filter invoices/transactions to one or more contact IDs from list_contacts.",
|
|
19622
|
+
"items": {
|
|
19623
|
+
"type": "string"
|
|
19624
|
+
}
|
|
19625
|
+
},
|
|
19626
|
+
"invoiceNumbers": {
|
|
19627
|
+
"type": "array",
|
|
19628
|
+
"description": "Filter invoices by invoice number. For invoices, line items are returned by Xero when invoice numbers are supplied.",
|
|
19629
|
+
"items": {
|
|
19630
|
+
"type": "string"
|
|
19631
|
+
}
|
|
19632
|
+
},
|
|
19633
|
+
"fromDate": {
|
|
19634
|
+
"type": "string",
|
|
19635
|
+
"description": "Convenience start date filter in YYYY-MM-DD format for date-based resources."
|
|
19636
|
+
},
|
|
19637
|
+
"toDate": {
|
|
19638
|
+
"type": "string",
|
|
19639
|
+
"description": "Convenience end date filter in YYYY-MM-DD format for date-based resources."
|
|
19640
|
+
},
|
|
19641
|
+
"includeArchived": {
|
|
19642
|
+
"type": "boolean",
|
|
19643
|
+
"description": "Whether to include archived records when the endpoint supports it."
|
|
19644
|
+
}
|
|
19645
|
+
},
|
|
19646
|
+
"additionalProperties": false
|
|
19647
|
+
},
|
|
19648
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.page) params.set('page', String(input.page))\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n if (input.modifiedAfter) params.set('If-Modified-Since', input.modifiedAfter)\n const res = await integration.get(`/api.xro/2.0/Items${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const items = Array.isArray(data?.Items) ? data.Items : []\n\n return {\n items: items.map(item => ({\n itemId: item.ItemID,\n code: item.Code,\n name: item.Name,\n description: item.Description,\n isTrackedAsInventory: item.IsTrackedAsInventory,\n isSold: item.IsSold,\n isPurchased: item.IsPurchased,\n salesDetails: item.SalesDetails,\n purchaseDetails: item.PurchaseDetails,\n updatedDateUtc: item.UpdatedDateUTC,\n })),\n count: items.length,\n page: input.page || 1,\n }\n}",
|
|
19649
|
+
"scope": "read",
|
|
19650
|
+
"toolset": "accounting"
|
|
19651
|
+
},
|
|
19652
|
+
{
|
|
19653
|
+
"name": "get_item",
|
|
19654
|
+
"description": "Get a Xero item by itemId.",
|
|
19655
|
+
"inputSchema": {
|
|
19656
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19657
|
+
"type": "object",
|
|
19658
|
+
"properties": {
|
|
19659
|
+
"tenantId": {
|
|
19660
|
+
"type": "string",
|
|
19661
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19662
|
+
},
|
|
19663
|
+
"id": {
|
|
19664
|
+
"type": "string",
|
|
19665
|
+
"description": "Xero resource ID."
|
|
19666
|
+
}
|
|
19667
|
+
},
|
|
19668
|
+
"required": [
|
|
19669
|
+
"id"
|
|
19670
|
+
],
|
|
19671
|
+
"additionalProperties": false
|
|
19672
|
+
},
|
|
19673
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const res = await integration.get(`/api.xro/2.0/Items/${encodeURIComponent(input.id)}`, { headers })\n const data = await res.json()\n const item = Array.isArray(data?.Items) ? data.Items[0] : null\n return {\n item: item\n ? {\n itemId: item.ItemID,\n code: item.Code,\n name: item.Name,\n description: item.Description,\n purchaseDescription: item.PurchaseDescription,\n isTrackedAsInventory: item.IsTrackedAsInventory,\n isSold: item.IsSold,\n isPurchased: item.IsPurchased,\n salesDetails: item.SalesDetails,\n purchaseDetails: item.PurchaseDetails,\n updatedDateUtc: item.UpdatedDateUTC,\n }\n : null,\n }\n}",
|
|
19674
|
+
"scope": "read",
|
|
19675
|
+
"toolset": "accounting"
|
|
19676
|
+
},
|
|
19677
|
+
{
|
|
19678
|
+
"name": "create_item",
|
|
19679
|
+
"description": "Create an item from flat fields. Use extraFields only for advanced Xero fields.",
|
|
19680
|
+
"inputSchema": {
|
|
19681
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19682
|
+
"type": "object",
|
|
19683
|
+
"properties": {
|
|
19684
|
+
"tenantId": {
|
|
19685
|
+
"type": "string",
|
|
19686
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19687
|
+
},
|
|
19688
|
+
"itemId": {
|
|
19689
|
+
"type": "string",
|
|
19690
|
+
"description": "Required for update_item."
|
|
19691
|
+
},
|
|
19692
|
+
"code": {
|
|
19693
|
+
"type": "string",
|
|
19694
|
+
"description": "Item code."
|
|
19695
|
+
},
|
|
19696
|
+
"name": {
|
|
19697
|
+
"type": "string",
|
|
19698
|
+
"description": "Item name."
|
|
19699
|
+
},
|
|
19700
|
+
"description": {
|
|
19701
|
+
"type": "string",
|
|
19702
|
+
"description": "Sales description."
|
|
19703
|
+
},
|
|
19704
|
+
"extraFields": {
|
|
19705
|
+
"type": "object",
|
|
19706
|
+
"description": "Additional Xero Item fields. Values here override common fields.",
|
|
19707
|
+
"additionalProperties": true
|
|
19708
|
+
}
|
|
19709
|
+
},
|
|
19710
|
+
"additionalProperties": false
|
|
19711
|
+
},
|
|
19712
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const summarizeItem = item => ({\n itemId: item?.ItemID,\n code: item?.Code,\n name: item?.Name,\n description: item?.Description,\n isSold: item?.IsSold,\n isPurchased: item?.IsPurchased,\n })\n const item = {\n ...(input.code ? { Code: input.code } : {}),\n ...(input.name ? { Name: input.name } : {}),\n ...(input.description ? { Description: input.description } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post('/api.xro/2.0/Items', { Items: [item] }, { headers })\n const data = await res.json()\n const created = Array.isArray(data?.Items) ? data.Items[0] : null\n return {\n item: created ? summarizeItem(created) : null,\n }\n}",
|
|
19713
|
+
"scope": "write",
|
|
19714
|
+
"toolset": "accounting"
|
|
19715
|
+
},
|
|
19716
|
+
{
|
|
19717
|
+
"name": "update_item",
|
|
19718
|
+
"description": "Update an item by itemId. Provide only fields to change.",
|
|
19719
|
+
"inputSchema": {
|
|
19720
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19721
|
+
"type": "object",
|
|
19722
|
+
"properties": {
|
|
19723
|
+
"tenantId": {
|
|
19724
|
+
"type": "string",
|
|
19725
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19726
|
+
},
|
|
19727
|
+
"itemId": {
|
|
19728
|
+
"type": "string",
|
|
19729
|
+
"description": "Required for update_item."
|
|
19730
|
+
},
|
|
19731
|
+
"code": {
|
|
19732
|
+
"type": "string",
|
|
19733
|
+
"description": "Item code."
|
|
19734
|
+
},
|
|
19735
|
+
"name": {
|
|
19736
|
+
"type": "string",
|
|
19737
|
+
"description": "Item name."
|
|
19738
|
+
},
|
|
19739
|
+
"description": {
|
|
19740
|
+
"type": "string",
|
|
19741
|
+
"description": "Sales description."
|
|
19742
|
+
},
|
|
19743
|
+
"extraFields": {
|
|
19744
|
+
"type": "object",
|
|
19745
|
+
"description": "Additional Xero Item fields. Values here override common fields.",
|
|
19746
|
+
"additionalProperties": true
|
|
19747
|
+
}
|
|
19748
|
+
},
|
|
19749
|
+
"additionalProperties": false
|
|
19750
|
+
},
|
|
19751
|
+
"handlerCode": "async (input) => {\n if (!input.itemId)\n throw new Error('itemId is required for update_item')\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const summarizeItem = item => ({\n itemId: item?.ItemID,\n code: item?.Code,\n name: item?.Name,\n description: item?.Description,\n isSold: item?.IsSold,\n isPurchased: item?.IsPurchased,\n })\n const item = {\n ItemID: input.itemId,\n ...(input.code ? { Code: input.code } : {}),\n ...(input.name ? { Name: input.name } : {}),\n ...(input.description ? { Description: input.description } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post(`/api.xro/2.0/Items/${encodeURIComponent(input.itemId)}`, { Items: [item] }, { headers })\n const data = await res.json()\n const updated = Array.isArray(data?.Items) ? data.Items[0] : null\n return {\n item: updated ? summarizeItem(updated) : null,\n }\n}",
|
|
19752
|
+
"scope": "write",
|
|
19753
|
+
"toolset": "accounting"
|
|
19754
|
+
},
|
|
19755
|
+
{
|
|
19756
|
+
"name": "list_invoices",
|
|
19757
|
+
"description": "List invoices with compact totals, status, contact, dates, and invoice number. Prefer explicit filters like status, contactIds, invoiceNumbers, fromDate/toDate; use get_invoice for line items.",
|
|
19758
|
+
"inputSchema": {
|
|
19759
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19760
|
+
"type": "object",
|
|
19761
|
+
"properties": {
|
|
19762
|
+
"tenantId": {
|
|
19763
|
+
"type": "string",
|
|
19764
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19765
|
+
},
|
|
19766
|
+
"page": {
|
|
19767
|
+
"type": "integer",
|
|
19768
|
+
"minimum": 1,
|
|
19769
|
+
"description": "Xero page number for paginated endpoints."
|
|
19770
|
+
},
|
|
19771
|
+
"where": {
|
|
19772
|
+
"type": "string",
|
|
19773
|
+
"description": 'Advanced Xero where filter expression, e.g. Status=="AUTHORISED". Prefer the explicit filter fields when available.'
|
|
19774
|
+
},
|
|
19775
|
+
"order": {
|
|
19776
|
+
"type": "string",
|
|
19777
|
+
"description": "Xero order expression, e.g. UpdatedDateUTC DESC."
|
|
19778
|
+
},
|
|
19779
|
+
"modifiedAfter": {
|
|
19780
|
+
"type": "string",
|
|
19781
|
+
"description": "Only include records modified after this RFC3339 timestamp."
|
|
19782
|
+
},
|
|
19783
|
+
"status": {
|
|
19784
|
+
"type": "string",
|
|
19785
|
+
"description": "Convenience status filter for endpoints that support a Status query parameter."
|
|
19786
|
+
},
|
|
19787
|
+
"contactIds": {
|
|
19788
|
+
"type": "array",
|
|
19789
|
+
"description": "Filter invoices/transactions to one or more contact IDs from list_contacts.",
|
|
19790
|
+
"items": {
|
|
19791
|
+
"type": "string"
|
|
19792
|
+
}
|
|
19793
|
+
},
|
|
19794
|
+
"invoiceNumbers": {
|
|
19795
|
+
"type": "array",
|
|
19796
|
+
"description": "Filter invoices by invoice number. For invoices, line items are returned by Xero when invoice numbers are supplied.",
|
|
19797
|
+
"items": {
|
|
19798
|
+
"type": "string"
|
|
19799
|
+
}
|
|
19800
|
+
},
|
|
19801
|
+
"fromDate": {
|
|
19802
|
+
"type": "string",
|
|
19803
|
+
"description": "Convenience start date filter in YYYY-MM-DD format for date-based resources."
|
|
19804
|
+
},
|
|
19805
|
+
"toDate": {
|
|
19806
|
+
"type": "string",
|
|
19807
|
+
"description": "Convenience end date filter in YYYY-MM-DD format for date-based resources."
|
|
19808
|
+
},
|
|
19809
|
+
"includeArchived": {
|
|
19810
|
+
"type": "boolean",
|
|
19811
|
+
"description": "Whether to include archived records when the endpoint supports it."
|
|
19812
|
+
}
|
|
19813
|
+
},
|
|
19814
|
+
"additionalProperties": false
|
|
19815
|
+
},
|
|
19816
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.page) params.set('page', String(input.page))\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n if (input.status) params.set('Statuses', input.status)\n if (Array.isArray(input.contactIds) && input.contactIds.length) params.set('ContactIDs', input.contactIds.join(','))\n if (Array.isArray(input.invoiceNumbers) && input.invoiceNumbers.length) params.set('InvoiceNumbers', input.invoiceNumbers.join(','))\n if (input.modifiedAfter) params.set('If-Modified-Since', input.modifiedAfter)\n const res = await integration.get(`/api.xro/2.0/Invoices${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const invoices = Array.isArray(data?.Invoices) ? data.Invoices : []\n\n return {\n invoices: invoices.map(invoice => ({\n invoiceId: invoice.InvoiceID,\n invoiceNumber: invoice.InvoiceNumber,\n type: invoice.Type,\n status: invoice.Status,\n contact: invoice.Contact ? { contactId: invoice.Contact.ContactID, name: invoice.Contact.Name } : null,\n date: invoice.DateString || invoice.Date,\n dueDate: invoice.DueDateString || invoice.DueDate,\n currencyCode: invoice.CurrencyCode,\n total: invoice.Total,\n amountDue: invoice.AmountDue,\n amountPaid: invoice.AmountPaid,\n updatedDateUtc: invoice.UpdatedDateUTC,\n })),\n count: invoices.length,\n page: input.page || 1,\n }\n}",
|
|
19817
|
+
"scope": "read",
|
|
19818
|
+
"toolset": "accounting"
|
|
19819
|
+
},
|
|
19820
|
+
{
|
|
19821
|
+
"name": "get_invoice",
|
|
19822
|
+
"description": "Get an invoice by invoiceId, including line items and payment summary.",
|
|
19823
|
+
"inputSchema": {
|
|
19824
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19825
|
+
"type": "object",
|
|
19826
|
+
"properties": {
|
|
19827
|
+
"tenantId": {
|
|
19828
|
+
"type": "string",
|
|
19829
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19830
|
+
},
|
|
19831
|
+
"id": {
|
|
19832
|
+
"type": "string",
|
|
19833
|
+
"description": "Xero resource ID."
|
|
19834
|
+
}
|
|
19835
|
+
},
|
|
19836
|
+
"required": [
|
|
19837
|
+
"id"
|
|
19838
|
+
],
|
|
19839
|
+
"additionalProperties": false
|
|
19840
|
+
},
|
|
19841
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const res = await integration.get(`/api.xro/2.0/Invoices/${encodeURIComponent(input.id)}`, { headers })\n const data = await res.json()\n const invoice = Array.isArray(data?.Invoices) ? data.Invoices[0] : null\n const lineItems = Array.isArray(invoice?.LineItems)\n ? invoice.LineItems.map(line => ({\n lineItemId: line.LineItemID,\n description: line.Description,\n quantity: line.Quantity,\n unitAmount: line.UnitAmount,\n accountCode: line.AccountCode,\n taxType: line.TaxType,\n itemCode: line.ItemCode,\n lineAmount: line.LineAmount,\n tracking: line.Tracking,\n }))\n : []\n return {\n invoice: invoice\n ? {\n invoiceId: invoice.InvoiceID,\n invoiceNumber: invoice.InvoiceNumber,\n type: invoice.Type,\n status: invoice.Status,\n contact: invoice.Contact ? { contactId: invoice.Contact.ContactID, name: invoice.Contact.Name } : null,\n date: invoice.DateString || invoice.Date,\n dueDate: invoice.DueDateString || invoice.DueDate,\n currencyCode: invoice.CurrencyCode,\n subTotal: invoice.SubTotal,\n totalTax: invoice.TotalTax,\n total: invoice.Total,\n amountDue: invoice.AmountDue,\n amountPaid: invoice.AmountPaid,\n amountCredited: invoice.AmountCredited,\n reference: invoice.Reference,\n lineItems,\n payments: invoice.Payments,\n updatedDateUtc: invoice.UpdatedDateUTC,\n }\n : null,\n }\n}",
|
|
19842
|
+
"scope": "read",
|
|
19843
|
+
"toolset": "accounting"
|
|
19844
|
+
},
|
|
19845
|
+
{
|
|
19846
|
+
"name": "create_invoice",
|
|
19847
|
+
"description": "Create an invoice or bill from flat fields. Get contactId from list_contacts, accountCode from list_accounts, taxType from list_tax_rates, and tracking from list_tracking_categories. Returns a compact summary and Xero link.",
|
|
19848
|
+
"inputSchema": {
|
|
19849
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19850
|
+
"type": "object",
|
|
19851
|
+
"definitions": {
|
|
19852
|
+
"tracking": {
|
|
19853
|
+
"type": "object",
|
|
19854
|
+
"properties": {
|
|
19855
|
+
"name": {
|
|
19856
|
+
"type": "string",
|
|
19857
|
+
"description": "Tracking category name from list_tracking_categories."
|
|
19858
|
+
},
|
|
19859
|
+
"option": {
|
|
19860
|
+
"type": "string",
|
|
19861
|
+
"description": "Tracking option name from list_tracking_categories."
|
|
19862
|
+
},
|
|
19863
|
+
"trackingCategoryId": {
|
|
19864
|
+
"type": "string",
|
|
19865
|
+
"description": "Tracking category ID from list_tracking_categories."
|
|
19866
|
+
}
|
|
19867
|
+
},
|
|
19868
|
+
"required": [
|
|
19869
|
+
"name",
|
|
19870
|
+
"option"
|
|
19871
|
+
],
|
|
19872
|
+
"additionalProperties": false
|
|
19873
|
+
},
|
|
19874
|
+
"lineItem": {
|
|
19875
|
+
"type": "object",
|
|
19876
|
+
"properties": {
|
|
19877
|
+
"description": {
|
|
19878
|
+
"type": "string",
|
|
19879
|
+
"description": "Line item description."
|
|
19880
|
+
},
|
|
19881
|
+
"quantity": {
|
|
19882
|
+
"type": "number",
|
|
19883
|
+
"description": "Line item quantity."
|
|
19884
|
+
},
|
|
19885
|
+
"unitAmount": {
|
|
19886
|
+
"type": "number",
|
|
19887
|
+
"description": "Price per unit."
|
|
19888
|
+
},
|
|
19889
|
+
"accountCode": {
|
|
19890
|
+
"type": "string",
|
|
19891
|
+
"description": "Account code from list_accounts."
|
|
19892
|
+
},
|
|
19893
|
+
"taxType": {
|
|
19894
|
+
"type": "string",
|
|
19895
|
+
"description": "Tax type from list_tax_rates."
|
|
19896
|
+
},
|
|
19897
|
+
"itemCode": {
|
|
19898
|
+
"type": "string",
|
|
19899
|
+
"description": "Optional item code from list_items."
|
|
19900
|
+
},
|
|
19901
|
+
"tracking": {
|
|
19902
|
+
"type": "array",
|
|
19903
|
+
"description": "Optional tracking categories. Use only when requested by the user.",
|
|
19904
|
+
"items": {
|
|
19905
|
+
"$ref": "#/definitions/tracking"
|
|
19906
|
+
},
|
|
19907
|
+
"maxItems": 2
|
|
19908
|
+
}
|
|
19909
|
+
},
|
|
19910
|
+
"required": [
|
|
19911
|
+
"description",
|
|
19912
|
+
"quantity",
|
|
19913
|
+
"unitAmount",
|
|
19914
|
+
"accountCode",
|
|
19915
|
+
"taxType"
|
|
19916
|
+
],
|
|
19917
|
+
"additionalProperties": false
|
|
19918
|
+
}
|
|
19919
|
+
},
|
|
19920
|
+
"properties": {
|
|
19921
|
+
"tenantId": {
|
|
19922
|
+
"type": "string",
|
|
19923
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
19924
|
+
},
|
|
19925
|
+
"invoiceId": {
|
|
19926
|
+
"type": "string",
|
|
19927
|
+
"description": "Required for update_invoice."
|
|
19928
|
+
},
|
|
19929
|
+
"contactId": {
|
|
19930
|
+
"type": "string",
|
|
19931
|
+
"description": "Contact ID from list_contacts."
|
|
19932
|
+
},
|
|
19933
|
+
"lineItems": {
|
|
19934
|
+
"type": "array",
|
|
19935
|
+
"description": "Invoice line items. Use list_accounts and list_tax_rates to discover accountCode and taxType values.",
|
|
19936
|
+
"items": {
|
|
19937
|
+
"$ref": "#/definitions/lineItem"
|
|
19938
|
+
},
|
|
19939
|
+
"minItems": 1
|
|
19940
|
+
},
|
|
19941
|
+
"type": {
|
|
19942
|
+
"type": "string",
|
|
19943
|
+
"enum": [
|
|
19944
|
+
"ACCREC",
|
|
19945
|
+
"ACCPAY"
|
|
19946
|
+
],
|
|
19947
|
+
"description": "ACCREC creates a sales/customer invoice. ACCPAY creates a purchase/supplier bill."
|
|
19948
|
+
},
|
|
19949
|
+
"reference": {
|
|
19950
|
+
"type": "string",
|
|
19951
|
+
"description": "Optional reference for the invoice or bill."
|
|
19952
|
+
},
|
|
19953
|
+
"date": {
|
|
19954
|
+
"type": "string",
|
|
19955
|
+
"description": "Invoice date in YYYY-MM-DD format. Defaults to today when omitted."
|
|
19956
|
+
},
|
|
19957
|
+
"dueDate": {
|
|
19958
|
+
"type": "string",
|
|
19959
|
+
"description": "Due date in YYYY-MM-DD format."
|
|
19960
|
+
},
|
|
19961
|
+
"status": {
|
|
19962
|
+
"type": "string",
|
|
19963
|
+
"enum": [
|
|
19964
|
+
"DRAFT",
|
|
19965
|
+
"SUBMITTED",
|
|
19966
|
+
"AUTHORISED"
|
|
19967
|
+
],
|
|
19968
|
+
"description": "Invoice status. Prefer DRAFT unless the user explicitly asks otherwise."
|
|
19969
|
+
},
|
|
19970
|
+
"extraFields": {
|
|
19971
|
+
"type": "object",
|
|
19972
|
+
"description": "Advanced Xero Invoice fields to merge into the generated invoice object.",
|
|
19973
|
+
"additionalProperties": true
|
|
19974
|
+
}
|
|
19975
|
+
},
|
|
19976
|
+
"additionalProperties": false
|
|
19977
|
+
},
|
|
19978
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const today = new Date().toISOString().slice(0, 10)\n const defaultDueDate = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10)\n const mapTracking = tracking => Array.isArray(tracking)\n ? tracking.map(item => ({\n Name: item.name,\n Option: item.option,\n ...(item.trackingCategoryId ? { TrackingCategoryID: item.trackingCategoryId } : {}),\n }))\n : undefined\n const mapLineItem = item => ({\n Description: item.description,\n Quantity: item.quantity,\n UnitAmount: item.unitAmount,\n AccountCode: item.accountCode,\n TaxType: item.taxType,\n ...(item.itemCode ? { ItemCode: item.itemCode } : {}),\n ...(item.tracking ? { Tracking: mapTracking(item.tracking) } : {}),\n })\n const getShortCode = async () => {\n try {\n const orgRes = await integration.get('/api.xro/2.0/Organisation', { headers })\n const orgData = await orgRes.json()\n return Array.isArray(orgData?.Organisations) ? orgData.Organisations[0]?.ShortCode : ''\n }\n catch {\n return ''\n }\n }\n const summarizeInvoice = async (invoice) => {\n const invoiceId = invoice?.InvoiceID || ''\n const shortCode = invoiceId ? await getShortCode() : ''\n const isBill = invoice?.Type === 'ACCPAY'\n return {\n invoiceId,\n invoiceNumber: invoice?.InvoiceNumber,\n type: invoice?.Type,\n status: invoice?.Status,\n contact: invoice?.Contact ? { contactId: invoice.Contact.ContactID, name: invoice.Contact.Name } : null,\n date: invoice?.DateString || invoice?.Date,\n dueDate: invoice?.DueDateString || invoice?.DueDate,\n currencyCode: invoice?.CurrencyCode,\n total: invoice?.Total,\n amountDue: invoice?.AmountDue,\n lineItemCount: Array.isArray(invoice?.LineItems) ? invoice.LineItems.length : undefined,\n xeroUrl: shortCode && invoiceId\n ? (isBill\n ? `https://go.xero.com/organisationlogin/default.aspx?shortcode=${encodeURIComponent(shortCode)}&redirecturl=/AccountsPayable/Edit.aspx?InvoiceID=${encodeURIComponent(invoiceId)}`\n : `https://go.xero.com/app/${encodeURIComponent(shortCode)}/invoicing/view/${encodeURIComponent(invoiceId)}`)\n : null,\n }\n }\n if (!input.contactId)\n throw new Error('contactId is required for create_invoice')\n if (!Array.isArray(input.lineItems) || !input.lineItems.length)\n throw new Error('lineItems is required for create_invoice')\n const invoice = {\n Type: input.type || 'ACCREC',\n Contact: { ContactID: input.contactId },\n LineItems: input.lineItems.map(mapLineItem),\n Date: input.date || today,\n DueDate: input.dueDate || defaultDueDate,\n Status: input.status || 'DRAFT',\n ...(input.reference ? { Reference: input.reference } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post('/api.xro/2.0/Invoices', { Invoices: [invoice] }, { headers })\n const data = await res.json()\n const created = Array.isArray(data?.Invoices) ? data.Invoices[0] : null\n return {\n invoice: created ? await summarizeInvoice(created) : null,\n }\n}",
|
|
19979
|
+
"scope": "write",
|
|
19980
|
+
"toolset": "accounting"
|
|
19981
|
+
},
|
|
19982
|
+
{
|
|
19983
|
+
"name": "update_invoice",
|
|
19984
|
+
"description": "Update an invoice by invoiceId. Use this for draft changes or allowed status transitions; prefer get_invoice first.",
|
|
19985
|
+
"inputSchema": {
|
|
19986
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
19987
|
+
"type": "object",
|
|
19988
|
+
"definitions": {
|
|
19989
|
+
"tracking": {
|
|
19990
|
+
"type": "object",
|
|
19991
|
+
"properties": {
|
|
19992
|
+
"name": {
|
|
19993
|
+
"type": "string",
|
|
19994
|
+
"description": "Tracking category name from list_tracking_categories."
|
|
19995
|
+
},
|
|
19996
|
+
"option": {
|
|
19997
|
+
"type": "string",
|
|
19998
|
+
"description": "Tracking option name from list_tracking_categories."
|
|
19999
|
+
},
|
|
20000
|
+
"trackingCategoryId": {
|
|
20001
|
+
"type": "string",
|
|
20002
|
+
"description": "Tracking category ID from list_tracking_categories."
|
|
20003
|
+
}
|
|
20004
|
+
},
|
|
20005
|
+
"required": [
|
|
20006
|
+
"name",
|
|
20007
|
+
"option"
|
|
20008
|
+
],
|
|
20009
|
+
"additionalProperties": false
|
|
20010
|
+
},
|
|
20011
|
+
"lineItem": {
|
|
20012
|
+
"type": "object",
|
|
20013
|
+
"properties": {
|
|
20014
|
+
"description": {
|
|
20015
|
+
"type": "string",
|
|
20016
|
+
"description": "Line item description."
|
|
20017
|
+
},
|
|
20018
|
+
"quantity": {
|
|
20019
|
+
"type": "number",
|
|
20020
|
+
"description": "Line item quantity."
|
|
20021
|
+
},
|
|
20022
|
+
"unitAmount": {
|
|
20023
|
+
"type": "number",
|
|
20024
|
+
"description": "Price per unit."
|
|
20025
|
+
},
|
|
20026
|
+
"accountCode": {
|
|
20027
|
+
"type": "string",
|
|
20028
|
+
"description": "Account code from list_accounts."
|
|
20029
|
+
},
|
|
20030
|
+
"taxType": {
|
|
20031
|
+
"type": "string",
|
|
20032
|
+
"description": "Tax type from list_tax_rates."
|
|
20033
|
+
},
|
|
20034
|
+
"itemCode": {
|
|
20035
|
+
"type": "string",
|
|
20036
|
+
"description": "Optional item code from list_items."
|
|
20037
|
+
},
|
|
20038
|
+
"tracking": {
|
|
20039
|
+
"type": "array",
|
|
20040
|
+
"description": "Optional tracking categories. Use only when requested by the user.",
|
|
20041
|
+
"items": {
|
|
20042
|
+
"$ref": "#/definitions/tracking"
|
|
20043
|
+
},
|
|
20044
|
+
"maxItems": 2
|
|
20045
|
+
}
|
|
20046
|
+
},
|
|
20047
|
+
"required": [
|
|
20048
|
+
"description",
|
|
20049
|
+
"quantity",
|
|
20050
|
+
"unitAmount",
|
|
20051
|
+
"accountCode",
|
|
20052
|
+
"taxType"
|
|
20053
|
+
],
|
|
20054
|
+
"additionalProperties": false
|
|
20055
|
+
}
|
|
20056
|
+
},
|
|
20057
|
+
"properties": {
|
|
20058
|
+
"tenantId": {
|
|
20059
|
+
"type": "string",
|
|
20060
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20061
|
+
},
|
|
20062
|
+
"invoiceId": {
|
|
20063
|
+
"type": "string",
|
|
20064
|
+
"description": "Required for update_invoice."
|
|
20065
|
+
},
|
|
20066
|
+
"contactId": {
|
|
20067
|
+
"type": "string",
|
|
20068
|
+
"description": "Contact ID from list_contacts."
|
|
20069
|
+
},
|
|
20070
|
+
"lineItems": {
|
|
20071
|
+
"type": "array",
|
|
20072
|
+
"description": "Invoice line items. Use list_accounts and list_tax_rates to discover accountCode and taxType values.",
|
|
20073
|
+
"items": {
|
|
20074
|
+
"$ref": "#/definitions/lineItem"
|
|
20075
|
+
},
|
|
20076
|
+
"minItems": 1
|
|
20077
|
+
},
|
|
20078
|
+
"type": {
|
|
20079
|
+
"type": "string",
|
|
20080
|
+
"enum": [
|
|
20081
|
+
"ACCREC",
|
|
20082
|
+
"ACCPAY"
|
|
20083
|
+
],
|
|
20084
|
+
"description": "ACCREC creates a sales/customer invoice. ACCPAY creates a purchase/supplier bill."
|
|
20085
|
+
},
|
|
20086
|
+
"reference": {
|
|
20087
|
+
"type": "string",
|
|
20088
|
+
"description": "Optional reference for the invoice or bill."
|
|
20089
|
+
},
|
|
20090
|
+
"date": {
|
|
20091
|
+
"type": "string",
|
|
20092
|
+
"description": "Invoice date in YYYY-MM-DD format. Defaults to today when omitted."
|
|
20093
|
+
},
|
|
20094
|
+
"dueDate": {
|
|
20095
|
+
"type": "string",
|
|
20096
|
+
"description": "Due date in YYYY-MM-DD format."
|
|
20097
|
+
},
|
|
20098
|
+
"status": {
|
|
20099
|
+
"type": "string",
|
|
20100
|
+
"enum": [
|
|
20101
|
+
"DRAFT",
|
|
20102
|
+
"SUBMITTED",
|
|
20103
|
+
"AUTHORISED"
|
|
20104
|
+
],
|
|
20105
|
+
"description": "Invoice status. Prefer DRAFT unless the user explicitly asks otherwise."
|
|
20106
|
+
},
|
|
20107
|
+
"extraFields": {
|
|
20108
|
+
"type": "object",
|
|
20109
|
+
"description": "Advanced Xero Invoice fields to merge into the generated invoice object.",
|
|
20110
|
+
"additionalProperties": true
|
|
20111
|
+
}
|
|
20112
|
+
},
|
|
20113
|
+
"additionalProperties": false
|
|
20114
|
+
},
|
|
20115
|
+
"handlerCode": "async (input) => {\n if (!input.invoiceId)\n throw new Error('invoiceId is required for update_invoice')\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const mapTracking = tracking => Array.isArray(tracking)\n ? tracking.map(item => ({\n Name: item.name,\n Option: item.option,\n ...(item.trackingCategoryId ? { TrackingCategoryID: item.trackingCategoryId } : {}),\n }))\n : undefined\n const mapLineItem = item => ({\n Description: item.description,\n Quantity: item.quantity,\n UnitAmount: item.unitAmount,\n AccountCode: item.accountCode,\n TaxType: item.taxType,\n ...(item.itemCode ? { ItemCode: item.itemCode } : {}),\n ...(item.tracking ? { Tracking: mapTracking(item.tracking) } : {}),\n })\n const getShortCode = async () => {\n try {\n const orgRes = await integration.get('/api.xro/2.0/Organisation', { headers })\n const orgData = await orgRes.json()\n return Array.isArray(orgData?.Organisations) ? orgData.Organisations[0]?.ShortCode : ''\n }\n catch {\n return ''\n }\n }\n const summarizeInvoice = async (invoice) => {\n const invoiceId = invoice?.InvoiceID || ''\n const shortCode = invoiceId ? await getShortCode() : ''\n const isBill = invoice?.Type === 'ACCPAY'\n return {\n invoiceId,\n invoiceNumber: invoice?.InvoiceNumber,\n type: invoice?.Type,\n status: invoice?.Status,\n contact: invoice?.Contact ? { contactId: invoice.Contact.ContactID, name: invoice.Contact.Name } : null,\n date: invoice?.DateString || invoice?.Date,\n dueDate: invoice?.DueDateString || invoice?.DueDate,\n total: invoice?.Total,\n amountDue: invoice?.AmountDue,\n lineItemCount: Array.isArray(invoice?.LineItems) ? invoice.LineItems.length : undefined,\n xeroUrl: shortCode && invoiceId\n ? (isBill\n ? `https://go.xero.com/organisationlogin/default.aspx?shortcode=${encodeURIComponent(shortCode)}&redirecturl=/AccountsPayable/Edit.aspx?InvoiceID=${encodeURIComponent(invoiceId)}`\n : `https://go.xero.com/app/${encodeURIComponent(shortCode)}/invoicing/view/${encodeURIComponent(invoiceId)}`)\n : null,\n }\n }\n const invoice = {\n InvoiceID: input.invoiceId,\n ...(input.contactId ? { Contact: { ContactID: input.contactId } } : {}),\n ...(Array.isArray(input.lineItems) ? { LineItems: input.lineItems.map(mapLineItem) } : {}),\n ...(input.type ? { Type: input.type } : {}),\n ...(input.reference ? { Reference: input.reference } : {}),\n ...(input.date ? { Date: input.date } : {}),\n ...(input.dueDate ? { DueDate: input.dueDate } : {}),\n ...(input.status ? { Status: input.status } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post(`/api.xro/2.0/Invoices/${encodeURIComponent(input.invoiceId)}`, { Invoices: [invoice] }, { headers })\n const data = await res.json()\n const updated = Array.isArray(data?.Invoices) ? data.Invoices[0] : null\n return {\n invoice: updated ? await summarizeInvoice(updated) : null,\n }\n}",
|
|
20116
|
+
"scope": "write",
|
|
20117
|
+
"toolset": "accounting"
|
|
20118
|
+
},
|
|
20119
|
+
{
|
|
20120
|
+
"name": "list_credit_notes",
|
|
20121
|
+
"description": "List credit notes with compact status, contact, date, total, and remaining credit fields.",
|
|
20122
|
+
"inputSchema": {
|
|
20123
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20124
|
+
"type": "object",
|
|
20125
|
+
"properties": {
|
|
20126
|
+
"tenantId": {
|
|
20127
|
+
"type": "string",
|
|
20128
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20129
|
+
},
|
|
20130
|
+
"page": {
|
|
20131
|
+
"type": "integer",
|
|
20132
|
+
"minimum": 1,
|
|
20133
|
+
"description": "Xero page number for paginated endpoints."
|
|
20134
|
+
},
|
|
20135
|
+
"where": {
|
|
20136
|
+
"type": "string",
|
|
20137
|
+
"description": 'Advanced Xero where filter expression, e.g. Status=="AUTHORISED". Prefer the explicit filter fields when available.'
|
|
20138
|
+
},
|
|
20139
|
+
"order": {
|
|
20140
|
+
"type": "string",
|
|
20141
|
+
"description": "Xero order expression, e.g. UpdatedDateUTC DESC."
|
|
20142
|
+
},
|
|
20143
|
+
"modifiedAfter": {
|
|
20144
|
+
"type": "string",
|
|
20145
|
+
"description": "Only include records modified after this RFC3339 timestamp."
|
|
20146
|
+
},
|
|
20147
|
+
"status": {
|
|
20148
|
+
"type": "string",
|
|
20149
|
+
"description": "Convenience status filter for endpoints that support a Status query parameter."
|
|
20150
|
+
},
|
|
20151
|
+
"contactIds": {
|
|
20152
|
+
"type": "array",
|
|
20153
|
+
"description": "Filter invoices/transactions to one or more contact IDs from list_contacts.",
|
|
20154
|
+
"items": {
|
|
20155
|
+
"type": "string"
|
|
20156
|
+
}
|
|
20157
|
+
},
|
|
20158
|
+
"invoiceNumbers": {
|
|
20159
|
+
"type": "array",
|
|
20160
|
+
"description": "Filter invoices by invoice number. For invoices, line items are returned by Xero when invoice numbers are supplied.",
|
|
20161
|
+
"items": {
|
|
20162
|
+
"type": "string"
|
|
20163
|
+
}
|
|
20164
|
+
},
|
|
20165
|
+
"fromDate": {
|
|
20166
|
+
"type": "string",
|
|
20167
|
+
"description": "Convenience start date filter in YYYY-MM-DD format for date-based resources."
|
|
20168
|
+
},
|
|
20169
|
+
"toDate": {
|
|
20170
|
+
"type": "string",
|
|
20171
|
+
"description": "Convenience end date filter in YYYY-MM-DD format for date-based resources."
|
|
20172
|
+
},
|
|
20173
|
+
"includeArchived": {
|
|
20174
|
+
"type": "boolean",
|
|
20175
|
+
"description": "Whether to include archived records when the endpoint supports it."
|
|
20176
|
+
}
|
|
20177
|
+
},
|
|
20178
|
+
"additionalProperties": false
|
|
20179
|
+
},
|
|
20180
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.page) params.set('page', String(input.page))\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n if (input.status) params.set('Statuses', input.status)\n if (input.modifiedAfter) params.set('If-Modified-Since', input.modifiedAfter)\n const res = await integration.get(`/api.xro/2.0/CreditNotes${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const creditNotes = Array.isArray(data?.CreditNotes) ? data.CreditNotes : []\n return {\n creditNotes: creditNotes.map(note => ({\n creditNoteId: note.CreditNoteID,\n creditNoteNumber: note.CreditNoteNumber,\n type: note.Type,\n status: note.Status,\n contact: note.Contact ? { contactId: note.Contact.ContactID, name: note.Contact.Name } : null,\n date: note.DateString || note.Date,\n total: note.Total,\n remainingCredit: note.RemainingCredit,\n updatedDateUtc: note.UpdatedDateUTC,\n })),\n count: creditNotes.length,\n page: input.page || 1,\n }\n}",
|
|
20181
|
+
"scope": "read",
|
|
20182
|
+
"toolset": "accounting"
|
|
20183
|
+
},
|
|
20184
|
+
{
|
|
20185
|
+
"name": "create_credit_note",
|
|
20186
|
+
"description": "Create a credit note from flat fields. Get contactId from list_contacts, accountCode from list_accounts, and taxType from list_tax_rates. Returns a compact summary and Xero link.",
|
|
20187
|
+
"inputSchema": {
|
|
20188
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20189
|
+
"type": "object",
|
|
20190
|
+
"definitions": {
|
|
20191
|
+
"lineItem": {
|
|
20192
|
+
"type": "object",
|
|
20193
|
+
"properties": {
|
|
20194
|
+
"description": {
|
|
20195
|
+
"type": "string"
|
|
20196
|
+
},
|
|
20197
|
+
"quantity": {
|
|
20198
|
+
"type": "number"
|
|
20199
|
+
},
|
|
20200
|
+
"unitAmount": {
|
|
20201
|
+
"type": "number"
|
|
20202
|
+
},
|
|
20203
|
+
"accountCode": {
|
|
20204
|
+
"type": "string",
|
|
20205
|
+
"description": "Account code from list_accounts."
|
|
20206
|
+
},
|
|
20207
|
+
"taxType": {
|
|
20208
|
+
"type": "string",
|
|
20209
|
+
"description": "Tax type from list_tax_rates."
|
|
20210
|
+
}
|
|
20211
|
+
},
|
|
20212
|
+
"required": [
|
|
20213
|
+
"description",
|
|
20214
|
+
"quantity",
|
|
20215
|
+
"unitAmount",
|
|
20216
|
+
"accountCode",
|
|
20217
|
+
"taxType"
|
|
20218
|
+
],
|
|
20219
|
+
"additionalProperties": false
|
|
20220
|
+
}
|
|
20221
|
+
},
|
|
20222
|
+
"properties": {
|
|
20223
|
+
"tenantId": {
|
|
20224
|
+
"type": "string",
|
|
20225
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20226
|
+
},
|
|
20227
|
+
"contactId": {
|
|
20228
|
+
"type": "string",
|
|
20229
|
+
"description": "Contact ID from list_contacts."
|
|
20230
|
+
},
|
|
20231
|
+
"lineItems": {
|
|
20232
|
+
"type": "array",
|
|
20233
|
+
"items": {
|
|
20234
|
+
"$ref": "#/definitions/lineItem"
|
|
20235
|
+
},
|
|
20236
|
+
"minItems": 1
|
|
20237
|
+
},
|
|
20238
|
+
"type": {
|
|
20239
|
+
"type": "string",
|
|
20240
|
+
"enum": [
|
|
20241
|
+
"ACCRECCREDIT",
|
|
20242
|
+
"ACCPAYCREDIT"
|
|
20243
|
+
],
|
|
20244
|
+
"description": "ACCRECCREDIT for customer credit notes, ACCPAYCREDIT for supplier credit notes."
|
|
20245
|
+
},
|
|
20246
|
+
"reference": {
|
|
20247
|
+
"type": "string"
|
|
20248
|
+
},
|
|
20249
|
+
"date": {
|
|
20250
|
+
"type": "string",
|
|
20251
|
+
"description": "Credit note date in YYYY-MM-DD format."
|
|
20252
|
+
},
|
|
20253
|
+
"status": {
|
|
20254
|
+
"type": "string",
|
|
20255
|
+
"enum": [
|
|
20256
|
+
"DRAFT",
|
|
20257
|
+
"SUBMITTED",
|
|
20258
|
+
"AUTHORISED"
|
|
20259
|
+
],
|
|
20260
|
+
"description": "Prefer DRAFT unless the user explicitly asks otherwise."
|
|
20261
|
+
},
|
|
20262
|
+
"extraFields": {
|
|
20263
|
+
"type": "object",
|
|
20264
|
+
"description": "Advanced Xero CreditNote fields to merge into the generated object.",
|
|
20265
|
+
"additionalProperties": true
|
|
20266
|
+
}
|
|
20267
|
+
},
|
|
20268
|
+
"required": [
|
|
20269
|
+
"contactId",
|
|
20270
|
+
"lineItems"
|
|
20271
|
+
],
|
|
20272
|
+
"additionalProperties": false
|
|
20273
|
+
},
|
|
20274
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const today = new Date().toISOString().slice(0, 10)\n const mapLineItem = item => ({\n Description: item.description,\n Quantity: item.quantity,\n UnitAmount: item.unitAmount,\n AccountCode: item.accountCode,\n TaxType: item.taxType,\n })\n const getShortCode = async () => {\n try {\n const orgRes = await integration.get('/api.xro/2.0/Organisation', { headers })\n const orgData = await orgRes.json()\n return Array.isArray(orgData?.Organisations) ? orgData.Organisations[0]?.ShortCode : ''\n }\n catch {\n return ''\n }\n }\n const summarizeCreditNote = async (note) => {\n const creditNoteId = note?.CreditNoteID || ''\n const shortCode = creditNoteId ? await getShortCode() : ''\n return {\n creditNoteId,\n creditNoteNumber: note?.CreditNoteNumber,\n type: note?.Type,\n status: note?.Status,\n contact: note?.Contact ? { contactId: note.Contact.ContactID, name: note.Contact.Name } : null,\n date: note?.DateString || note?.Date,\n total: note?.Total,\n remainingCredit: note?.RemainingCredit,\n xeroUrl: shortCode && creditNoteId ? `https://go.xero.com/organisationlogin/default.aspx?shortcode=${encodeURIComponent(shortCode)}&redirecturl=/AccountsPayable/ViewCreditNote.aspx?creditNoteID=${encodeURIComponent(creditNoteId)}` : null,\n }\n }\n const creditNote = {\n Type: input.type || 'ACCRECCREDIT',\n Contact: { ContactID: input.contactId },\n LineItems: input.lineItems.map(mapLineItem),\n Date: input.date || today,\n Status: input.status || 'DRAFT',\n ...(input.reference ? { Reference: input.reference } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post('/api.xro/2.0/CreditNotes', { CreditNotes: [creditNote] }, { headers })\n const data = await res.json()\n const created = Array.isArray(data?.CreditNotes) ? data.CreditNotes[0] : null\n return {\n creditNote: created ? await summarizeCreditNote(created) : null,\n }\n}",
|
|
20275
|
+
"scope": "write",
|
|
20276
|
+
"toolset": "accounting"
|
|
20277
|
+
},
|
|
20278
|
+
{
|
|
20279
|
+
"name": "list_quotes",
|
|
20280
|
+
"description": "List quotes with compact quote number, status, contact, dates, and totals.",
|
|
20281
|
+
"inputSchema": {
|
|
20282
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20283
|
+
"type": "object",
|
|
20284
|
+
"properties": {
|
|
20285
|
+
"tenantId": {
|
|
20286
|
+
"type": "string",
|
|
20287
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20288
|
+
},
|
|
20289
|
+
"page": {
|
|
20290
|
+
"type": "integer",
|
|
20291
|
+
"minimum": 1,
|
|
20292
|
+
"description": "Xero page number for paginated endpoints."
|
|
20293
|
+
},
|
|
20294
|
+
"where": {
|
|
20295
|
+
"type": "string",
|
|
20296
|
+
"description": 'Advanced Xero where filter expression, e.g. Status=="AUTHORISED". Prefer the explicit filter fields when available.'
|
|
20297
|
+
},
|
|
20298
|
+
"order": {
|
|
20299
|
+
"type": "string",
|
|
20300
|
+
"description": "Xero order expression, e.g. UpdatedDateUTC DESC."
|
|
20301
|
+
},
|
|
20302
|
+
"modifiedAfter": {
|
|
20303
|
+
"type": "string",
|
|
20304
|
+
"description": "Only include records modified after this RFC3339 timestamp."
|
|
20305
|
+
},
|
|
20306
|
+
"status": {
|
|
20307
|
+
"type": "string",
|
|
20308
|
+
"description": "Convenience status filter for endpoints that support a Status query parameter."
|
|
20309
|
+
},
|
|
20310
|
+
"contactIds": {
|
|
20311
|
+
"type": "array",
|
|
20312
|
+
"description": "Filter invoices/transactions to one or more contact IDs from list_contacts.",
|
|
20313
|
+
"items": {
|
|
20314
|
+
"type": "string"
|
|
20315
|
+
}
|
|
20316
|
+
},
|
|
20317
|
+
"invoiceNumbers": {
|
|
20318
|
+
"type": "array",
|
|
20319
|
+
"description": "Filter invoices by invoice number. For invoices, line items are returned by Xero when invoice numbers are supplied.",
|
|
20320
|
+
"items": {
|
|
20321
|
+
"type": "string"
|
|
20322
|
+
}
|
|
20323
|
+
},
|
|
20324
|
+
"fromDate": {
|
|
20325
|
+
"type": "string",
|
|
20326
|
+
"description": "Convenience start date filter in YYYY-MM-DD format for date-based resources."
|
|
20327
|
+
},
|
|
20328
|
+
"toDate": {
|
|
20329
|
+
"type": "string",
|
|
20330
|
+
"description": "Convenience end date filter in YYYY-MM-DD format for date-based resources."
|
|
20331
|
+
},
|
|
20332
|
+
"includeArchived": {
|
|
20333
|
+
"type": "boolean",
|
|
20334
|
+
"description": "Whether to include archived records when the endpoint supports it."
|
|
20335
|
+
}
|
|
20336
|
+
},
|
|
20337
|
+
"additionalProperties": false
|
|
20338
|
+
},
|
|
20339
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.page) params.set('page', String(input.page))\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n if (input.status) params.set('Statuses', input.status)\n if (input.modifiedAfter) params.set('If-Modified-Since', input.modifiedAfter)\n const res = await integration.get(`/api.xro/2.0/Quotes${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const quotes = Array.isArray(data?.Quotes) ? data.Quotes : []\n return {\n quotes: quotes.map(quote => ({\n quoteId: quote.QuoteID,\n quoteNumber: quote.QuoteNumber,\n status: quote.Status,\n contact: quote.Contact ? { contactId: quote.Contact.ContactID, name: quote.Contact.Name } : null,\n date: quote.DateString || quote.Date,\n expiryDate: quote.ExpiryDateString || quote.ExpiryDate,\n total: quote.Total,\n currencyCode: quote.CurrencyCode,\n updatedDateUtc: quote.UpdatedDateUTC,\n })),\n count: quotes.length,\n page: input.page || 1,\n }\n}",
|
|
20340
|
+
"scope": "read",
|
|
20341
|
+
"toolset": "accounting"
|
|
20342
|
+
},
|
|
20343
|
+
{
|
|
20344
|
+
"name": "create_quote",
|
|
20345
|
+
"description": "Create a quote from flat fields. Get contactId from list_contacts, accountCode from list_accounts, and taxType from list_tax_rates. Returns a compact summary and Xero link.",
|
|
20346
|
+
"inputSchema": {
|
|
20347
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20348
|
+
"type": "object",
|
|
20349
|
+
"definitions": {
|
|
20350
|
+
"lineItem": {
|
|
20351
|
+
"type": "object",
|
|
20352
|
+
"properties": {
|
|
20353
|
+
"description": {
|
|
20354
|
+
"type": "string"
|
|
20355
|
+
},
|
|
20356
|
+
"quantity": {
|
|
20357
|
+
"type": "number"
|
|
20358
|
+
},
|
|
20359
|
+
"unitAmount": {
|
|
20360
|
+
"type": "number"
|
|
20361
|
+
},
|
|
20362
|
+
"accountCode": {
|
|
20363
|
+
"type": "string",
|
|
20364
|
+
"description": "Account code from list_accounts."
|
|
20365
|
+
},
|
|
20366
|
+
"taxType": {
|
|
20367
|
+
"type": "string",
|
|
20368
|
+
"description": "Tax type from list_tax_rates."
|
|
20369
|
+
},
|
|
20370
|
+
"itemCode": {
|
|
20371
|
+
"type": "string",
|
|
20372
|
+
"description": "Optional item code from list_items."
|
|
20373
|
+
}
|
|
20374
|
+
},
|
|
20375
|
+
"required": [
|
|
20376
|
+
"description",
|
|
20377
|
+
"quantity",
|
|
20378
|
+
"unitAmount",
|
|
20379
|
+
"accountCode",
|
|
20380
|
+
"taxType"
|
|
20381
|
+
],
|
|
20382
|
+
"additionalProperties": false
|
|
20383
|
+
}
|
|
20384
|
+
},
|
|
20385
|
+
"properties": {
|
|
20386
|
+
"tenantId": {
|
|
20387
|
+
"type": "string",
|
|
20388
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20389
|
+
},
|
|
20390
|
+
"contactId": {
|
|
20391
|
+
"type": "string",
|
|
20392
|
+
"description": "Contact ID from list_contacts."
|
|
20393
|
+
},
|
|
20394
|
+
"lineItems": {
|
|
20395
|
+
"type": "array",
|
|
20396
|
+
"items": {
|
|
20397
|
+
"$ref": "#/definitions/lineItem"
|
|
20398
|
+
},
|
|
20399
|
+
"minItems": 1
|
|
20400
|
+
},
|
|
20401
|
+
"reference": {
|
|
20402
|
+
"type": "string"
|
|
20403
|
+
},
|
|
20404
|
+
"quoteNumber": {
|
|
20405
|
+
"type": "string"
|
|
20406
|
+
},
|
|
20407
|
+
"date": {
|
|
20408
|
+
"type": "string",
|
|
20409
|
+
"description": "Quote date in YYYY-MM-DD format."
|
|
20410
|
+
},
|
|
20411
|
+
"expiryDate": {
|
|
20412
|
+
"type": "string",
|
|
20413
|
+
"description": "Expiry date in YYYY-MM-DD format."
|
|
20414
|
+
},
|
|
20415
|
+
"title": {
|
|
20416
|
+
"type": "string"
|
|
20417
|
+
},
|
|
20418
|
+
"summary": {
|
|
20419
|
+
"type": "string"
|
|
20420
|
+
},
|
|
20421
|
+
"terms": {
|
|
20422
|
+
"type": "string"
|
|
20423
|
+
},
|
|
20424
|
+
"status": {
|
|
20425
|
+
"type": "string",
|
|
20426
|
+
"enum": [
|
|
20427
|
+
"DRAFT",
|
|
20428
|
+
"SENT",
|
|
20429
|
+
"ACCEPTED",
|
|
20430
|
+
"DECLINED"
|
|
20431
|
+
],
|
|
20432
|
+
"description": "Prefer DRAFT unless the user explicitly asks otherwise."
|
|
20433
|
+
},
|
|
20434
|
+
"extraFields": {
|
|
20435
|
+
"type": "object",
|
|
20436
|
+
"description": "Advanced Xero Quote fields to merge into the generated object.",
|
|
20437
|
+
"additionalProperties": true
|
|
20438
|
+
}
|
|
20439
|
+
},
|
|
20440
|
+
"required": [
|
|
20441
|
+
"contactId",
|
|
20442
|
+
"lineItems"
|
|
20443
|
+
],
|
|
20444
|
+
"additionalProperties": false
|
|
20445
|
+
},
|
|
20446
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const today = new Date().toISOString().slice(0, 10)\n const mapLineItem = item => ({\n Description: item.description,\n Quantity: item.quantity,\n UnitAmount: item.unitAmount,\n AccountCode: item.accountCode,\n TaxType: item.taxType,\n ...(item.itemCode ? { ItemCode: item.itemCode } : {}),\n })\n const getShortCode = async () => {\n try {\n const orgRes = await integration.get('/api.xro/2.0/Organisation', { headers })\n const orgData = await orgRes.json()\n return Array.isArray(orgData?.Organisations) ? orgData.Organisations[0]?.ShortCode : ''\n }\n catch {\n return ''\n }\n }\n const summarizeQuote = async (quote) => {\n const quoteId = quote?.QuoteID || ''\n const shortCode = quoteId ? await getShortCode() : ''\n return {\n quoteId,\n quoteNumber: quote?.QuoteNumber,\n status: quote?.Status,\n contact: quote?.Contact ? { contactId: quote.Contact.ContactID, name: quote.Contact.Name } : null,\n date: quote?.DateString || quote?.Date,\n expiryDate: quote?.ExpiryDateString || quote?.ExpiryDate,\n total: quote?.Total,\n xeroUrl: shortCode && quoteId ? `https://go.xero.com/app/${encodeURIComponent(shortCode)}/quotes/view/${encodeURIComponent(quoteId)}` : null,\n }\n }\n const quote = {\n Contact: { ContactID: input.contactId },\n LineItems: input.lineItems.map(mapLineItem),\n Date: input.date || today,\n Status: input.status || 'DRAFT',\n ...(input.expiryDate ? { ExpiryDate: input.expiryDate } : {}),\n ...(input.reference ? { Reference: input.reference } : {}),\n ...(input.quoteNumber ? { QuoteNumber: input.quoteNumber } : {}),\n ...(input.title ? { Title: input.title } : {}),\n ...(input.summary ? { Summary: input.summary } : {}),\n ...(input.terms ? { Terms: input.terms } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post('/api.xro/2.0/Quotes', { Quotes: [quote] }, { headers })\n const data = await res.json()\n const created = Array.isArray(data?.Quotes) ? data.Quotes[0] : null\n return {\n quote: created ? await summarizeQuote(created) : null,\n }\n}",
|
|
20447
|
+
"scope": "write",
|
|
20448
|
+
"toolset": "accounting"
|
|
20449
|
+
},
|
|
20450
|
+
{
|
|
20451
|
+
"name": "list_purchase_orders",
|
|
20452
|
+
"description": "List purchase orders with compact purchase order number, status, contact, delivery date, and totals.",
|
|
20453
|
+
"inputSchema": {
|
|
20454
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20455
|
+
"type": "object",
|
|
20456
|
+
"properties": {
|
|
20457
|
+
"tenantId": {
|
|
20458
|
+
"type": "string",
|
|
20459
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20460
|
+
},
|
|
20461
|
+
"page": {
|
|
20462
|
+
"type": "integer",
|
|
20463
|
+
"minimum": 1,
|
|
20464
|
+
"description": "Xero page number for paginated endpoints."
|
|
20465
|
+
},
|
|
20466
|
+
"where": {
|
|
20467
|
+
"type": "string",
|
|
20468
|
+
"description": 'Advanced Xero where filter expression, e.g. Status=="AUTHORISED". Prefer the explicit filter fields when available.'
|
|
20469
|
+
},
|
|
20470
|
+
"order": {
|
|
20471
|
+
"type": "string",
|
|
20472
|
+
"description": "Xero order expression, e.g. UpdatedDateUTC DESC."
|
|
20473
|
+
},
|
|
20474
|
+
"modifiedAfter": {
|
|
20475
|
+
"type": "string",
|
|
20476
|
+
"description": "Only include records modified after this RFC3339 timestamp."
|
|
20477
|
+
},
|
|
20478
|
+
"status": {
|
|
20479
|
+
"type": "string",
|
|
20480
|
+
"description": "Convenience status filter for endpoints that support a Status query parameter."
|
|
20481
|
+
},
|
|
20482
|
+
"contactIds": {
|
|
20483
|
+
"type": "array",
|
|
20484
|
+
"description": "Filter invoices/transactions to one or more contact IDs from list_contacts.",
|
|
20485
|
+
"items": {
|
|
20486
|
+
"type": "string"
|
|
20487
|
+
}
|
|
20488
|
+
},
|
|
20489
|
+
"invoiceNumbers": {
|
|
20490
|
+
"type": "array",
|
|
20491
|
+
"description": "Filter invoices by invoice number. For invoices, line items are returned by Xero when invoice numbers are supplied.",
|
|
20492
|
+
"items": {
|
|
20493
|
+
"type": "string"
|
|
20494
|
+
}
|
|
20495
|
+
},
|
|
20496
|
+
"fromDate": {
|
|
20497
|
+
"type": "string",
|
|
20498
|
+
"description": "Convenience start date filter in YYYY-MM-DD format for date-based resources."
|
|
20499
|
+
},
|
|
20500
|
+
"toDate": {
|
|
20501
|
+
"type": "string",
|
|
20502
|
+
"description": "Convenience end date filter in YYYY-MM-DD format for date-based resources."
|
|
20503
|
+
},
|
|
20504
|
+
"includeArchived": {
|
|
20505
|
+
"type": "boolean",
|
|
20506
|
+
"description": "Whether to include archived records when the endpoint supports it."
|
|
20507
|
+
}
|
|
20508
|
+
},
|
|
20509
|
+
"additionalProperties": false
|
|
20510
|
+
},
|
|
20511
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.page) params.set('page', String(input.page))\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n if (input.status) params.set('Statuses', input.status)\n if (input.modifiedAfter) params.set('If-Modified-Since', input.modifiedAfter)\n const res = await integration.get(`/api.xro/2.0/PurchaseOrders${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const purchaseOrders = Array.isArray(data?.PurchaseOrders) ? data.PurchaseOrders : []\n return {\n purchaseOrders: purchaseOrders.map(po => ({\n purchaseOrderId: po.PurchaseOrderID,\n purchaseOrderNumber: po.PurchaseOrderNumber,\n status: po.Status,\n contact: po.Contact ? { contactId: po.Contact.ContactID, name: po.Contact.Name } : null,\n date: po.DateString || po.Date,\n deliveryDate: po.DeliveryDateString || po.DeliveryDate,\n total: po.Total,\n currencyCode: po.CurrencyCode,\n updatedDateUtc: po.UpdatedDateUTC,\n })),\n count: purchaseOrders.length,\n page: input.page || 1,\n }\n}",
|
|
20512
|
+
"scope": "read",
|
|
20513
|
+
"toolset": "accounting"
|
|
20514
|
+
},
|
|
20515
|
+
{
|
|
20516
|
+
"name": "create_purchase_order",
|
|
20517
|
+
"description": "Create a purchase order from flat fields. Get supplier contactId from list_contacts and line account/tax values from list_accounts/list_tax_rates.",
|
|
20518
|
+
"inputSchema": {
|
|
20519
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20520
|
+
"type": "object",
|
|
20521
|
+
"definitions": {
|
|
20522
|
+
"lineItem": {
|
|
20523
|
+
"type": "object",
|
|
20524
|
+
"properties": {
|
|
20525
|
+
"description": {
|
|
20526
|
+
"type": "string"
|
|
20527
|
+
},
|
|
20528
|
+
"quantity": {
|
|
20529
|
+
"type": "number"
|
|
20530
|
+
},
|
|
20531
|
+
"unitAmount": {
|
|
20532
|
+
"type": "number"
|
|
20533
|
+
},
|
|
20534
|
+
"accountCode": {
|
|
20535
|
+
"type": "string",
|
|
20536
|
+
"description": "Account code from list_accounts."
|
|
20537
|
+
},
|
|
20538
|
+
"taxType": {
|
|
20539
|
+
"type": "string",
|
|
20540
|
+
"description": "Tax type from list_tax_rates."
|
|
20541
|
+
},
|
|
20542
|
+
"itemCode": {
|
|
20543
|
+
"type": "string",
|
|
20544
|
+
"description": "Optional item code from list_items."
|
|
20545
|
+
}
|
|
20546
|
+
},
|
|
20547
|
+
"required": [
|
|
20548
|
+
"description",
|
|
20549
|
+
"quantity",
|
|
20550
|
+
"unitAmount",
|
|
20551
|
+
"accountCode",
|
|
20552
|
+
"taxType"
|
|
20553
|
+
],
|
|
20554
|
+
"additionalProperties": false
|
|
20555
|
+
}
|
|
20556
|
+
},
|
|
20557
|
+
"properties": {
|
|
20558
|
+
"tenantId": {
|
|
20559
|
+
"type": "string",
|
|
20560
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20561
|
+
},
|
|
20562
|
+
"contactId": {
|
|
20563
|
+
"type": "string",
|
|
20564
|
+
"description": "Supplier contact ID from list_contacts."
|
|
20565
|
+
},
|
|
20566
|
+
"lineItems": {
|
|
20567
|
+
"type": "array",
|
|
20568
|
+
"items": {
|
|
20569
|
+
"$ref": "#/definitions/lineItem"
|
|
20570
|
+
},
|
|
20571
|
+
"minItems": 1
|
|
20572
|
+
},
|
|
20573
|
+
"date": {
|
|
20574
|
+
"type": "string",
|
|
20575
|
+
"description": "Purchase order date in YYYY-MM-DD format."
|
|
20576
|
+
},
|
|
20577
|
+
"deliveryDate": {
|
|
20578
|
+
"type": "string",
|
|
20579
|
+
"description": "Delivery date in YYYY-MM-DD format."
|
|
20580
|
+
},
|
|
20581
|
+
"reference": {
|
|
20582
|
+
"type": "string"
|
|
20583
|
+
},
|
|
20584
|
+
"status": {
|
|
20585
|
+
"type": "string",
|
|
20586
|
+
"enum": [
|
|
20587
|
+
"DRAFT",
|
|
20588
|
+
"SUBMITTED",
|
|
20589
|
+
"AUTHORISED",
|
|
20590
|
+
"BILLED"
|
|
20591
|
+
],
|
|
20592
|
+
"description": "Prefer DRAFT unless the user explicitly asks otherwise."
|
|
20593
|
+
},
|
|
20594
|
+
"extraFields": {
|
|
20595
|
+
"type": "object",
|
|
20596
|
+
"description": "Advanced Xero PurchaseOrder fields to merge into the generated object.",
|
|
20597
|
+
"additionalProperties": true
|
|
20598
|
+
}
|
|
20599
|
+
},
|
|
20600
|
+
"required": [
|
|
20601
|
+
"contactId",
|
|
20602
|
+
"lineItems"
|
|
20603
|
+
],
|
|
20604
|
+
"additionalProperties": false
|
|
20605
|
+
},
|
|
20606
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const today = new Date().toISOString().slice(0, 10)\n const mapLineItem = item => ({\n Description: item.description,\n Quantity: item.quantity,\n UnitAmount: item.unitAmount,\n AccountCode: item.accountCode,\n TaxType: item.taxType,\n ...(item.itemCode ? { ItemCode: item.itemCode } : {}),\n })\n const summarizePurchaseOrder = po => ({\n purchaseOrderId: po?.PurchaseOrderID,\n purchaseOrderNumber: po?.PurchaseOrderNumber,\n status: po?.Status,\n contact: po?.Contact ? { contactId: po.Contact.ContactID, name: po.Contact.Name } : null,\n date: po?.DateString || po?.Date,\n deliveryDate: po?.DeliveryDateString || po?.DeliveryDate,\n total: po?.Total,\n lineItemCount: Array.isArray(po?.LineItems) ? po.LineItems.length : undefined,\n })\n const purchaseOrder = {\n Contact: { ContactID: input.contactId },\n LineItems: input.lineItems.map(mapLineItem),\n Date: input.date || today,\n Status: input.status || 'DRAFT',\n ...(input.deliveryDate ? { DeliveryDate: input.deliveryDate } : {}),\n ...(input.reference ? { Reference: input.reference } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post('/api.xro/2.0/PurchaseOrders', { PurchaseOrders: [purchaseOrder] }, { headers })\n const data = await res.json()\n const created = Array.isArray(data?.PurchaseOrders) ? data.PurchaseOrders[0] : null\n return {\n purchaseOrder: created ? summarizePurchaseOrder(created) : null,\n }\n}",
|
|
20607
|
+
"scope": "write",
|
|
20608
|
+
"toolset": "accounting"
|
|
20609
|
+
},
|
|
20610
|
+
{
|
|
20611
|
+
"name": "list_payments",
|
|
20612
|
+
"description": "List payments with compact payment ID, date, amount, status, account, and invoice references.",
|
|
20613
|
+
"inputSchema": {
|
|
20614
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20615
|
+
"type": "object",
|
|
20616
|
+
"properties": {
|
|
20617
|
+
"tenantId": {
|
|
20618
|
+
"type": "string",
|
|
20619
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20620
|
+
},
|
|
20621
|
+
"page": {
|
|
20622
|
+
"type": "integer",
|
|
20623
|
+
"minimum": 1,
|
|
20624
|
+
"description": "Xero page number for paginated endpoints."
|
|
20625
|
+
},
|
|
20626
|
+
"where": {
|
|
20627
|
+
"type": "string",
|
|
20628
|
+
"description": 'Advanced Xero where filter expression, e.g. Status=="AUTHORISED". Prefer the explicit filter fields when available.'
|
|
20629
|
+
},
|
|
20630
|
+
"order": {
|
|
20631
|
+
"type": "string",
|
|
20632
|
+
"description": "Xero order expression, e.g. UpdatedDateUTC DESC."
|
|
20633
|
+
},
|
|
20634
|
+
"modifiedAfter": {
|
|
20635
|
+
"type": "string",
|
|
20636
|
+
"description": "Only include records modified after this RFC3339 timestamp."
|
|
20637
|
+
},
|
|
20638
|
+
"status": {
|
|
20639
|
+
"type": "string",
|
|
20640
|
+
"description": "Convenience status filter for endpoints that support a Status query parameter."
|
|
20641
|
+
},
|
|
20642
|
+
"contactIds": {
|
|
20643
|
+
"type": "array",
|
|
20644
|
+
"description": "Filter invoices/transactions to one or more contact IDs from list_contacts.",
|
|
20645
|
+
"items": {
|
|
20646
|
+
"type": "string"
|
|
20647
|
+
}
|
|
20648
|
+
},
|
|
20649
|
+
"invoiceNumbers": {
|
|
20650
|
+
"type": "array",
|
|
20651
|
+
"description": "Filter invoices by invoice number. For invoices, line items are returned by Xero when invoice numbers are supplied.",
|
|
20652
|
+
"items": {
|
|
20653
|
+
"type": "string"
|
|
20654
|
+
}
|
|
20655
|
+
},
|
|
20656
|
+
"fromDate": {
|
|
20657
|
+
"type": "string",
|
|
20658
|
+
"description": "Convenience start date filter in YYYY-MM-DD format for date-based resources."
|
|
20659
|
+
},
|
|
20660
|
+
"toDate": {
|
|
20661
|
+
"type": "string",
|
|
20662
|
+
"description": "Convenience end date filter in YYYY-MM-DD format for date-based resources."
|
|
20663
|
+
},
|
|
20664
|
+
"includeArchived": {
|
|
20665
|
+
"type": "boolean",
|
|
20666
|
+
"description": "Whether to include archived records when the endpoint supports it."
|
|
20667
|
+
}
|
|
20668
|
+
},
|
|
20669
|
+
"additionalProperties": false
|
|
20670
|
+
},
|
|
20671
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.page) params.set('page', String(input.page))\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n if (input.fromDate || input.toDate) {\n const clauses = []\n if (input.fromDate) clauses.push(`Date >= DateTime(${input.fromDate.replace(/-/g, ',')})`)\n if (input.toDate) clauses.push(`Date <= DateTime(${input.toDate.replace(/-/g, ',')})`)\n params.set('where', input.where ? `${input.where}&&${clauses.join('&&')}` : clauses.join('&&'))\n }\n if (input.modifiedAfter) params.set('If-Modified-Since', input.modifiedAfter)\n const res = await integration.get(`/api.xro/2.0/Payments${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const payments = Array.isArray(data?.Payments) ? data.Payments : []\n return {\n payments: payments.map(payment => ({\n paymentId: payment.PaymentID,\n status: payment.Status,\n date: payment.DateString || payment.Date,\n amount: payment.Amount,\n currencyRate: payment.CurrencyRate,\n account: payment.Account ? { accountId: payment.Account.AccountID, code: payment.Account.Code, name: payment.Account.Name } : null,\n invoice: payment.Invoice ? { invoiceId: payment.Invoice.InvoiceID, invoiceNumber: payment.Invoice.InvoiceNumber } : null,\n updatedDateUtc: payment.UpdatedDateUTC,\n })),\n count: payments.length,\n page: input.page || 1,\n }\n}",
|
|
20672
|
+
"scope": "read",
|
|
20673
|
+
"toolset": "accounting"
|
|
20674
|
+
},
|
|
20675
|
+
{
|
|
20676
|
+
"name": "create_payment",
|
|
20677
|
+
"description": "Create a payment against an invoice. Use get_invoice for invoiceId/amount due and list_accounts for the payment accountId. Returns a compact summary and Xero link.",
|
|
20678
|
+
"inputSchema": {
|
|
20679
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20680
|
+
"type": "object",
|
|
20681
|
+
"properties": {
|
|
20682
|
+
"tenantId": {
|
|
20683
|
+
"type": "string",
|
|
20684
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20685
|
+
},
|
|
20686
|
+
"invoiceId": {
|
|
20687
|
+
"type": "string",
|
|
20688
|
+
"description": "Invoice ID from list_invoices or get_invoice."
|
|
20689
|
+
},
|
|
20690
|
+
"accountId": {
|
|
20691
|
+
"type": "string",
|
|
20692
|
+
"description": "Payment account ID from list_accounts."
|
|
20693
|
+
},
|
|
20694
|
+
"amount": {
|
|
20695
|
+
"type": "number",
|
|
20696
|
+
"description": "Payment amount."
|
|
20697
|
+
},
|
|
20698
|
+
"date": {
|
|
20699
|
+
"type": "string",
|
|
20700
|
+
"description": "Payment date in YYYY-MM-DD format. Defaults to today when omitted."
|
|
20701
|
+
},
|
|
20702
|
+
"reference": {
|
|
20703
|
+
"type": "string",
|
|
20704
|
+
"description": "Optional payment reference."
|
|
20705
|
+
},
|
|
20706
|
+
"extraFields": {
|
|
20707
|
+
"type": "object",
|
|
20708
|
+
"description": "Advanced Xero Payment fields to merge into the generated payment object.",
|
|
20709
|
+
"additionalProperties": true
|
|
20710
|
+
}
|
|
20711
|
+
},
|
|
20712
|
+
"required": [
|
|
20713
|
+
"invoiceId",
|
|
20714
|
+
"accountId",
|
|
20715
|
+
"amount"
|
|
20716
|
+
],
|
|
20717
|
+
"additionalProperties": false
|
|
20718
|
+
},
|
|
20719
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const today = new Date().toISOString().slice(0, 10)\n const getShortCode = async () => {\n try {\n const orgRes = await integration.get('/api.xro/2.0/Organisation', { headers })\n const orgData = await orgRes.json()\n return Array.isArray(orgData?.Organisations) ? orgData.Organisations[0]?.ShortCode : ''\n }\n catch {\n return ''\n }\n }\n const summarizePayment = async (payment) => {\n const paymentId = payment?.PaymentID || ''\n const shortCode = paymentId ? await getShortCode() : ''\n return {\n paymentId,\n status: payment?.Status,\n date: payment?.DateString || payment?.Date,\n amount: payment?.Amount,\n reference: payment?.Reference,\n account: payment?.Account ? { accountId: payment.Account.AccountID, code: payment.Account.Code, name: payment.Account.Name } : null,\n invoice: payment?.Invoice ? { invoiceId: payment.Invoice.InvoiceID, invoiceNumber: payment.Invoice.InvoiceNumber } : null,\n xeroUrl: shortCode && paymentId ? `https://go.xero.com/organisationlogin/default.aspx?shortcode=${encodeURIComponent(shortCode)}&redirecturl=/Bank/ViewTransaction.aspx?bankTransactionID=${encodeURIComponent(paymentId)}` : null,\n }\n }\n const payment = {\n Invoice: { InvoiceID: input.invoiceId },\n Account: { AccountID: input.accountId },\n Amount: input.amount,\n Date: input.date || today,\n ...(input.reference ? { Reference: input.reference } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post('/api.xro/2.0/Payments', { Payments: [payment] }, { headers })\n const data = await res.json()\n const created = Array.isArray(data?.Payments) ? data.Payments[0] : null\n return {\n payment: created ? await summarizePayment(created) : null,\n }\n}",
|
|
20720
|
+
"scope": "write",
|
|
20721
|
+
"toolset": "accounting"
|
|
20722
|
+
},
|
|
20723
|
+
{
|
|
20724
|
+
"name": "list_bank_transactions",
|
|
20725
|
+
"description": "List bank transactions with compact type, status, contact, date, total, and bank account details.",
|
|
20726
|
+
"inputSchema": {
|
|
20727
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20728
|
+
"type": "object",
|
|
20729
|
+
"properties": {
|
|
20730
|
+
"tenantId": {
|
|
20731
|
+
"type": "string",
|
|
20732
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20733
|
+
},
|
|
20734
|
+
"page": {
|
|
20735
|
+
"type": "integer",
|
|
20736
|
+
"minimum": 1,
|
|
20737
|
+
"description": "Xero page number for paginated endpoints."
|
|
20738
|
+
},
|
|
20739
|
+
"where": {
|
|
20740
|
+
"type": "string",
|
|
20741
|
+
"description": 'Advanced Xero where filter expression, e.g. Status=="AUTHORISED". Prefer the explicit filter fields when available.'
|
|
20742
|
+
},
|
|
20743
|
+
"order": {
|
|
20744
|
+
"type": "string",
|
|
20745
|
+
"description": "Xero order expression, e.g. UpdatedDateUTC DESC."
|
|
20746
|
+
},
|
|
20747
|
+
"modifiedAfter": {
|
|
20748
|
+
"type": "string",
|
|
20749
|
+
"description": "Only include records modified after this RFC3339 timestamp."
|
|
20750
|
+
},
|
|
20751
|
+
"status": {
|
|
20752
|
+
"type": "string",
|
|
20753
|
+
"description": "Convenience status filter for endpoints that support a Status query parameter."
|
|
20754
|
+
},
|
|
20755
|
+
"contactIds": {
|
|
20756
|
+
"type": "array",
|
|
20757
|
+
"description": "Filter invoices/transactions to one or more contact IDs from list_contacts.",
|
|
20758
|
+
"items": {
|
|
20759
|
+
"type": "string"
|
|
20760
|
+
}
|
|
20761
|
+
},
|
|
20762
|
+
"invoiceNumbers": {
|
|
20763
|
+
"type": "array",
|
|
20764
|
+
"description": "Filter invoices by invoice number. For invoices, line items are returned by Xero when invoice numbers are supplied.",
|
|
20765
|
+
"items": {
|
|
20766
|
+
"type": "string"
|
|
20767
|
+
}
|
|
20768
|
+
},
|
|
20769
|
+
"fromDate": {
|
|
20770
|
+
"type": "string",
|
|
20771
|
+
"description": "Convenience start date filter in YYYY-MM-DD format for date-based resources."
|
|
20772
|
+
},
|
|
20773
|
+
"toDate": {
|
|
20774
|
+
"type": "string",
|
|
20775
|
+
"description": "Convenience end date filter in YYYY-MM-DD format for date-based resources."
|
|
20776
|
+
},
|
|
20777
|
+
"includeArchived": {
|
|
20778
|
+
"type": "boolean",
|
|
20779
|
+
"description": "Whether to include archived records when the endpoint supports it."
|
|
20780
|
+
}
|
|
20781
|
+
},
|
|
20782
|
+
"additionalProperties": false
|
|
20783
|
+
},
|
|
20784
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.page) params.set('page', String(input.page))\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n if (input.status) params.set('Statuses', input.status)\n if (input.modifiedAfter) params.set('If-Modified-Since', input.modifiedAfter)\n const res = await integration.get(`/api.xro/2.0/BankTransactions${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const bankTransactions = Array.isArray(data?.BankTransactions) ? data.BankTransactions : []\n return {\n bankTransactions: bankTransactions.map(txn => ({\n bankTransactionId: txn.BankTransactionID,\n type: txn.Type,\n status: txn.Status,\n contact: txn.Contact ? { contactId: txn.Contact.ContactID, name: txn.Contact.Name } : null,\n bankAccount: txn.BankAccount ? { accountId: txn.BankAccount.AccountID, code: txn.BankAccount.Code, name: txn.BankAccount.Name } : null,\n date: txn.DateString || txn.Date,\n total: txn.Total,\n currencyCode: txn.CurrencyCode,\n updatedDateUtc: txn.UpdatedDateUTC,\n })),\n count: bankTransactions.length,\n page: input.page || 1,\n }\n}",
|
|
20785
|
+
"scope": "read",
|
|
20786
|
+
"toolset": "accounting"
|
|
20787
|
+
},
|
|
20788
|
+
{
|
|
20789
|
+
"name": "create_bank_transaction",
|
|
20790
|
+
"description": "Create a spend or receive bank transaction. Use list_accounts for valid bank/account codes and tax rates before calling this.",
|
|
20791
|
+
"inputSchema": {
|
|
20792
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20793
|
+
"type": "object",
|
|
20794
|
+
"definitions": {
|
|
20795
|
+
"lineItem": {
|
|
20796
|
+
"type": "object",
|
|
20797
|
+
"properties": {
|
|
20798
|
+
"description": {
|
|
20799
|
+
"type": "string",
|
|
20800
|
+
"description": "Line item description."
|
|
20801
|
+
},
|
|
20802
|
+
"quantity": {
|
|
20803
|
+
"type": "number"
|
|
20804
|
+
},
|
|
20805
|
+
"unitAmount": {
|
|
20806
|
+
"type": "number"
|
|
20807
|
+
},
|
|
20808
|
+
"accountCode": {
|
|
20809
|
+
"type": "string",
|
|
20810
|
+
"description": "Account code from list_accounts."
|
|
20811
|
+
},
|
|
20812
|
+
"taxType": {
|
|
20813
|
+
"type": "string",
|
|
20814
|
+
"description": "Tax type from list_tax_rates."
|
|
20815
|
+
}
|
|
20816
|
+
},
|
|
20817
|
+
"required": [
|
|
20818
|
+
"description",
|
|
20819
|
+
"quantity",
|
|
20820
|
+
"unitAmount",
|
|
20821
|
+
"accountCode",
|
|
20822
|
+
"taxType"
|
|
20823
|
+
],
|
|
20824
|
+
"additionalProperties": false
|
|
20825
|
+
}
|
|
20826
|
+
},
|
|
20827
|
+
"properties": {
|
|
20828
|
+
"tenantId": {
|
|
20829
|
+
"type": "string",
|
|
20830
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20831
|
+
},
|
|
20832
|
+
"type": {
|
|
20833
|
+
"type": "string",
|
|
20834
|
+
"enum": [
|
|
20835
|
+
"RECEIVE",
|
|
20836
|
+
"SPEND"
|
|
20837
|
+
],
|
|
20838
|
+
"description": "RECEIVE for money received, SPEND for money spent."
|
|
20839
|
+
},
|
|
20840
|
+
"bankAccountId": {
|
|
20841
|
+
"type": "string",
|
|
20842
|
+
"description": "Bank account ID from list_accounts."
|
|
20843
|
+
},
|
|
20844
|
+
"contactId": {
|
|
20845
|
+
"type": "string",
|
|
20846
|
+
"description": "Contact ID from list_contacts."
|
|
20847
|
+
},
|
|
20848
|
+
"lineItems": {
|
|
20849
|
+
"type": "array",
|
|
20850
|
+
"description": "Bank transaction line items.",
|
|
20851
|
+
"items": {
|
|
20852
|
+
"$ref": "#/definitions/lineItem"
|
|
20853
|
+
},
|
|
20854
|
+
"minItems": 1
|
|
20855
|
+
},
|
|
20856
|
+
"reference": {
|
|
20857
|
+
"type": "string"
|
|
20858
|
+
},
|
|
20859
|
+
"date": {
|
|
20860
|
+
"type": "string",
|
|
20861
|
+
"description": "Transaction date in YYYY-MM-DD format."
|
|
20862
|
+
},
|
|
20863
|
+
"status": {
|
|
20864
|
+
"type": "string",
|
|
20865
|
+
"enum": [
|
|
20866
|
+
"DRAFT",
|
|
20867
|
+
"AUTHORISED"
|
|
20868
|
+
],
|
|
20869
|
+
"description": "Prefer DRAFT unless the user explicitly asks to authorise."
|
|
20870
|
+
},
|
|
20871
|
+
"extraFields": {
|
|
20872
|
+
"type": "object",
|
|
20873
|
+
"description": "Advanced Xero BankTransaction fields to merge into the generated object.",
|
|
20874
|
+
"additionalProperties": true
|
|
20875
|
+
}
|
|
20876
|
+
},
|
|
20877
|
+
"required": [
|
|
20878
|
+
"type",
|
|
20879
|
+
"bankAccountId",
|
|
20880
|
+
"contactId",
|
|
20881
|
+
"lineItems"
|
|
20882
|
+
],
|
|
20883
|
+
"additionalProperties": false
|
|
20884
|
+
},
|
|
20885
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const today = new Date().toISOString().slice(0, 10)\n const mapLineItem = item => ({\n Description: item.description,\n Quantity: item.quantity,\n UnitAmount: item.unitAmount,\n AccountCode: item.accountCode,\n TaxType: item.taxType,\n })\n const summarizeBankTransaction = txn => ({\n bankTransactionId: txn?.BankTransactionID,\n type: txn?.Type,\n status: txn?.Status,\n contact: txn?.Contact ? { contactId: txn.Contact.ContactID, name: txn.Contact.Name } : null,\n bankAccount: txn?.BankAccount ? { accountId: txn.BankAccount.AccountID, code: txn.BankAccount.Code, name: txn.BankAccount.Name } : null,\n date: txn?.DateString || txn?.Date,\n reference: txn?.Reference,\n total: txn?.Total,\n lineItemCount: Array.isArray(txn?.LineItems) ? txn.LineItems.length : undefined,\n xeroUrl: txn?.BankAccount?.AccountID && txn?.BankTransactionID\n ? `https://go.xero.com/Bank/ViewTransaction.aspx?bankTransactionID=${encodeURIComponent(txn.BankTransactionID)}&accountID=${encodeURIComponent(txn.BankAccount.AccountID)}`\n : null,\n })\n const bankTransaction = {\n Type: input.type,\n BankAccount: { AccountID: input.bankAccountId },\n Contact: { ContactID: input.contactId },\n LineItems: input.lineItems.map(mapLineItem),\n Date: input.date || today,\n Status: input.status || 'DRAFT',\n ...(input.reference ? { Reference: input.reference } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post('/api.xro/2.0/BankTransactions', { BankTransactions: [bankTransaction] }, { headers })\n const data = await res.json()\n const created = Array.isArray(data?.BankTransactions) ? data.BankTransactions[0] : null\n return {\n bankTransaction: created ? summarizeBankTransaction(created) : null,\n }\n}",
|
|
20886
|
+
"scope": "write",
|
|
20887
|
+
"toolset": "accounting"
|
|
20888
|
+
},
|
|
20889
|
+
{
|
|
20890
|
+
"name": "list_manual_journals",
|
|
20891
|
+
"description": "List manual journals with compact status, narration, date, journal ID, and line count.",
|
|
20892
|
+
"inputSchema": {
|
|
20893
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20894
|
+
"type": "object",
|
|
20895
|
+
"properties": {
|
|
20896
|
+
"tenantId": {
|
|
20897
|
+
"type": "string",
|
|
20898
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20899
|
+
},
|
|
20900
|
+
"page": {
|
|
20901
|
+
"type": "integer",
|
|
20902
|
+
"minimum": 1,
|
|
20903
|
+
"description": "Xero page number for paginated endpoints."
|
|
20904
|
+
},
|
|
20905
|
+
"where": {
|
|
20906
|
+
"type": "string",
|
|
20907
|
+
"description": 'Advanced Xero where filter expression, e.g. Status=="AUTHORISED". Prefer the explicit filter fields when available.'
|
|
20908
|
+
},
|
|
20909
|
+
"order": {
|
|
20910
|
+
"type": "string",
|
|
20911
|
+
"description": "Xero order expression, e.g. UpdatedDateUTC DESC."
|
|
20912
|
+
},
|
|
20913
|
+
"modifiedAfter": {
|
|
20914
|
+
"type": "string",
|
|
20915
|
+
"description": "Only include records modified after this RFC3339 timestamp."
|
|
20916
|
+
},
|
|
20917
|
+
"status": {
|
|
20918
|
+
"type": "string",
|
|
20919
|
+
"description": "Convenience status filter for endpoints that support a Status query parameter."
|
|
20920
|
+
},
|
|
20921
|
+
"contactIds": {
|
|
20922
|
+
"type": "array",
|
|
20923
|
+
"description": "Filter invoices/transactions to one or more contact IDs from list_contacts.",
|
|
20924
|
+
"items": {
|
|
20925
|
+
"type": "string"
|
|
20926
|
+
}
|
|
20927
|
+
},
|
|
20928
|
+
"invoiceNumbers": {
|
|
20929
|
+
"type": "array",
|
|
20930
|
+
"description": "Filter invoices by invoice number. For invoices, line items are returned by Xero when invoice numbers are supplied.",
|
|
20931
|
+
"items": {
|
|
20932
|
+
"type": "string"
|
|
20933
|
+
}
|
|
20934
|
+
},
|
|
20935
|
+
"fromDate": {
|
|
20936
|
+
"type": "string",
|
|
20937
|
+
"description": "Convenience start date filter in YYYY-MM-DD format for date-based resources."
|
|
20938
|
+
},
|
|
20939
|
+
"toDate": {
|
|
20940
|
+
"type": "string",
|
|
20941
|
+
"description": "Convenience end date filter in YYYY-MM-DD format for date-based resources."
|
|
20942
|
+
},
|
|
20943
|
+
"includeArchived": {
|
|
20944
|
+
"type": "boolean",
|
|
20945
|
+
"description": "Whether to include archived records when the endpoint supports it."
|
|
20946
|
+
}
|
|
20947
|
+
},
|
|
20948
|
+
"additionalProperties": false
|
|
20949
|
+
},
|
|
20950
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.page) params.set('page', String(input.page))\n if (input.where) params.set('where', input.where)\n if (input.order) params.set('order', input.order)\n if (input.status) params.set('Statuses', input.status)\n if (input.modifiedAfter) params.set('If-Modified-Since', input.modifiedAfter)\n const res = await integration.get(`/api.xro/2.0/ManualJournals${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const manualJournals = Array.isArray(data?.ManualJournals) ? data.ManualJournals : []\n return {\n manualJournals: manualJournals.map(journal => ({\n manualJournalId: journal.ManualJournalID,\n narration: journal.Narration,\n status: journal.Status,\n date: journal.DateString || journal.Date,\n lineAmountTypes: journal.LineAmountTypes,\n journalLineCount: Array.isArray(journal.JournalLines) ? journal.JournalLines.length : undefined,\n updatedDateUtc: journal.UpdatedDateUTC,\n })),\n count: manualJournals.length,\n page: input.page || 1,\n }\n}",
|
|
20951
|
+
"scope": "read",
|
|
20952
|
+
"toolset": "accounting"
|
|
20953
|
+
},
|
|
20954
|
+
{
|
|
20955
|
+
"name": "create_manual_journal",
|
|
20956
|
+
"description": "Create a manual journal. Use this carefully; discover account codes with list_accounts and prefer DRAFT when supported by the organisation workflow.",
|
|
20957
|
+
"inputSchema": {
|
|
20958
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
20959
|
+
"type": "object",
|
|
20960
|
+
"definitions": {
|
|
20961
|
+
"journalLine": {
|
|
20962
|
+
"type": "object",
|
|
20963
|
+
"properties": {
|
|
20964
|
+
"lineAmount": {
|
|
20965
|
+
"type": "number",
|
|
20966
|
+
"description": "Debit lines are positive; credit lines are negative."
|
|
20967
|
+
},
|
|
20968
|
+
"accountCode": {
|
|
20969
|
+
"type": "string",
|
|
20970
|
+
"description": "Account code from list_accounts."
|
|
20971
|
+
},
|
|
20972
|
+
"description": {
|
|
20973
|
+
"type": "string"
|
|
20974
|
+
},
|
|
20975
|
+
"taxType": {
|
|
20976
|
+
"type": "string",
|
|
20977
|
+
"description": "Optional tax type from list_tax_rates."
|
|
20978
|
+
}
|
|
20979
|
+
},
|
|
20980
|
+
"required": [
|
|
20981
|
+
"lineAmount",
|
|
20982
|
+
"accountCode"
|
|
20983
|
+
],
|
|
20984
|
+
"additionalProperties": false
|
|
20985
|
+
}
|
|
20986
|
+
},
|
|
20987
|
+
"properties": {
|
|
20988
|
+
"tenantId": {
|
|
20989
|
+
"type": "string",
|
|
20990
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
20991
|
+
},
|
|
20992
|
+
"narration": {
|
|
20993
|
+
"type": "string",
|
|
20994
|
+
"description": "Description of the journal."
|
|
20995
|
+
},
|
|
20996
|
+
"journalLines": {
|
|
20997
|
+
"type": "array",
|
|
20998
|
+
"description": "At least two balanced journal lines. Debits must equal credits.",
|
|
20999
|
+
"items": {
|
|
21000
|
+
"$ref": "#/definitions/journalLine"
|
|
21001
|
+
},
|
|
21002
|
+
"minItems": 2
|
|
21003
|
+
},
|
|
21004
|
+
"date": {
|
|
21005
|
+
"type": "string",
|
|
21006
|
+
"description": "Journal date in YYYY-MM-DD format."
|
|
21007
|
+
},
|
|
21008
|
+
"lineAmountTypes": {
|
|
21009
|
+
"type": "string",
|
|
21010
|
+
"enum": [
|
|
21011
|
+
"EXCLUSIVE",
|
|
21012
|
+
"INCLUSIVE",
|
|
21013
|
+
"NO_TAX"
|
|
21014
|
+
],
|
|
21015
|
+
"description": "Defaults to NO_TAX."
|
|
21016
|
+
},
|
|
21017
|
+
"status": {
|
|
21018
|
+
"type": "string",
|
|
21019
|
+
"enum": [
|
|
21020
|
+
"DRAFT",
|
|
21021
|
+
"POSTED"
|
|
21022
|
+
],
|
|
21023
|
+
"description": "Prefer DRAFT unless the user explicitly asks to post."
|
|
21024
|
+
},
|
|
21025
|
+
"url": {
|
|
21026
|
+
"type": "string",
|
|
21027
|
+
"description": "Optional URL to a source document."
|
|
21028
|
+
},
|
|
21029
|
+
"showOnCashBasisReports": {
|
|
21030
|
+
"type": "boolean"
|
|
21031
|
+
},
|
|
21032
|
+
"extraFields": {
|
|
21033
|
+
"type": "object",
|
|
21034
|
+
"description": "Advanced Xero ManualJournal fields to merge into the generated object.",
|
|
21035
|
+
"additionalProperties": true
|
|
21036
|
+
}
|
|
21037
|
+
},
|
|
21038
|
+
"required": [
|
|
21039
|
+
"narration",
|
|
21040
|
+
"journalLines"
|
|
21041
|
+
],
|
|
21042
|
+
"additionalProperties": false
|
|
21043
|
+
},
|
|
21044
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const today = new Date().toISOString().slice(0, 10)\n const mapJournalLine = line => ({\n LineAmount: line.lineAmount,\n AccountCode: line.accountCode,\n ...(line.description ? { Description: line.description } : {}),\n ...(line.taxType ? { TaxType: line.taxType } : {}),\n })\n const summarizeManualJournal = journal => ({\n manualJournalId: journal?.ManualJournalID,\n narration: journal?.Narration,\n status: journal?.Status,\n date: journal?.DateString || journal?.Date,\n lineAmountTypes: journal?.LineAmountTypes,\n showOnCashBasisReports: journal?.ShowOnCashBasisReports,\n journalLineCount: Array.isArray(journal?.JournalLines) ? journal.JournalLines.length : undefined,\n xeroUrl: journal?.ManualJournalID ? `https://go.xero.com/Journal/View.aspx?invoiceID=${encodeURIComponent(journal.ManualJournalID)}` : null,\n })\n const lineAmountTypeMap = {\n EXCLUSIVE: 'Exclusive',\n INCLUSIVE: 'Inclusive',\n NO_TAX: 'NoTax',\n }\n const manualJournal = {\n Narration: input.narration,\n JournalLines: input.journalLines.map(mapJournalLine),\n Date: input.date || today,\n LineAmountTypes: lineAmountTypeMap[input.lineAmountTypes || 'NO_TAX'] || input.lineAmountTypes,\n Status: input.status || 'DRAFT',\n ...(input.url ? { Url: input.url } : {}),\n ...(input.showOnCashBasisReports !== undefined ? { ShowOnCashBasisReports: input.showOnCashBasisReports } : {}),\n ...(input.extraFields || {}),\n }\n const res = await integration.post('/api.xro/2.0/ManualJournals', { ManualJournals: [manualJournal] }, { headers })\n const data = await res.json()\n const created = Array.isArray(data?.ManualJournals) ? data.ManualJournals[0] : null\n return {\n manualJournal: created ? summarizeManualJournal(created) : null,\n }\n}",
|
|
21045
|
+
"scope": "write",
|
|
21046
|
+
"toolset": "accounting"
|
|
21047
|
+
},
|
|
21048
|
+
{
|
|
21049
|
+
"name": "list_attachments",
|
|
21050
|
+
"description": "List attachments for a supported Xero resource such as Invoices, Contacts, BankTransactions, CreditNotes, PurchaseOrders, or ManualJournals.",
|
|
21051
|
+
"inputSchema": {
|
|
21052
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21053
|
+
"type": "object",
|
|
21054
|
+
"properties": {
|
|
21055
|
+
"tenantId": {
|
|
21056
|
+
"type": "string",
|
|
21057
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
21058
|
+
},
|
|
21059
|
+
"resourceType": {
|
|
21060
|
+
"type": "string",
|
|
21061
|
+
"enum": [
|
|
21062
|
+
"Accounts",
|
|
21063
|
+
"BankTransactions",
|
|
21064
|
+
"BankTransfers",
|
|
21065
|
+
"Contacts",
|
|
21066
|
+
"CreditNotes",
|
|
21067
|
+
"Invoices",
|
|
21068
|
+
"ManualJournals",
|
|
21069
|
+
"PurchaseOrders",
|
|
21070
|
+
"Receipts",
|
|
21071
|
+
"RepeatingInvoices"
|
|
21072
|
+
],
|
|
21073
|
+
"description": "Xero attachment parent endpoint."
|
|
21074
|
+
},
|
|
21075
|
+
"resourceId": {
|
|
21076
|
+
"type": "string",
|
|
21077
|
+
"description": "ID of the parent Xero resource."
|
|
21078
|
+
}
|
|
21079
|
+
},
|
|
21080
|
+
"required": [
|
|
21081
|
+
"resourceType",
|
|
21082
|
+
"resourceId"
|
|
21083
|
+
],
|
|
21084
|
+
"additionalProperties": false
|
|
21085
|
+
},
|
|
21086
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const path = `/api.xro/2.0/${encodeURIComponent(input.resourceType)}/${encodeURIComponent(input.resourceId)}/Attachments`\n const res = await integration.get(path, { headers })\n const data = await res.json()\n const attachments = Array.isArray(data?.Attachments) ? data.Attachments : []\n return {\n attachments: attachments.map(attachment => ({\n attachmentId: attachment.AttachmentID,\n fileName: attachment.FileName,\n mimeType: attachment.MimeType,\n contentLength: attachment.ContentLength,\n includeOnline: attachment.IncludeOnline,\n url: attachment.Url,\n })),\n count: attachments.length,\n }\n}",
|
|
21087
|
+
"scope": "read",
|
|
21088
|
+
"toolset": "accounting"
|
|
21089
|
+
},
|
|
21090
|
+
{
|
|
21091
|
+
"name": "read_attachment_content",
|
|
21092
|
+
"description": "Extract readable text from an attachment on a supported Xero resource. Uses the shared file extractor for PDFs, Office files, CSV, text, HTML, and similar formats.",
|
|
21093
|
+
"inputSchema": {
|
|
21094
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21095
|
+
"type": "object",
|
|
21096
|
+
"properties": {
|
|
21097
|
+
"tenantId": {
|
|
21098
|
+
"type": "string",
|
|
21099
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
21100
|
+
},
|
|
21101
|
+
"resourceType": {
|
|
21102
|
+
"type": "string",
|
|
21103
|
+
"enum": [
|
|
21104
|
+
"Accounts",
|
|
21105
|
+
"BankTransactions",
|
|
21106
|
+
"BankTransfers",
|
|
21107
|
+
"Contacts",
|
|
21108
|
+
"CreditNotes",
|
|
21109
|
+
"Invoices",
|
|
21110
|
+
"ManualJournals",
|
|
21111
|
+
"PurchaseOrders",
|
|
21112
|
+
"Receipts",
|
|
21113
|
+
"RepeatingInvoices"
|
|
21114
|
+
],
|
|
21115
|
+
"description": "Xero attachment parent endpoint."
|
|
21116
|
+
},
|
|
21117
|
+
"resourceId": {
|
|
21118
|
+
"type": "string",
|
|
21119
|
+
"description": "ID of the parent Xero resource."
|
|
21120
|
+
},
|
|
21121
|
+
"fileName": {
|
|
21122
|
+
"type": "string",
|
|
21123
|
+
"description": "Attachment file name from list_attachments."
|
|
21124
|
+
}
|
|
21125
|
+
},
|
|
21126
|
+
"required": [
|
|
21127
|
+
"resourceType",
|
|
21128
|
+
"resourceId",
|
|
21129
|
+
"fileName"
|
|
21130
|
+
],
|
|
21131
|
+
"additionalProperties": false
|
|
21132
|
+
},
|
|
21133
|
+
"handlerCode": "async (input) => {\n const path = `/api.xro/2.0/${encodeURIComponent(input.resourceType)}/${encodeURIComponent(input.resourceId)}/Attachments/${encodeURIComponent(input.fileName)}`\n if (input.tenantId)\n throw new Error('read_attachment_content currently supports Custom Connections only because the shared file extractor cannot pass xero-tenant-id yet.')\n const extracted = await utils.extractFileContent({\n auth: true,\n source: path,\n })\n return {\n fileName: input.fileName,\n resourceType: input.resourceType,\n resourceId: input.resourceId,\n ...extracted,\n }\n}",
|
|
21134
|
+
"scope": "read",
|
|
21135
|
+
"toolset": "accounting"
|
|
21136
|
+
},
|
|
21137
|
+
{
|
|
21138
|
+
"name": "get_profit_and_loss",
|
|
21139
|
+
"description": "Get the Profit and Loss report for a date range or period. Returns Xero's report rows plus helper metadata for the query used.",
|
|
21140
|
+
"inputSchema": {
|
|
21141
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21142
|
+
"type": "object",
|
|
21143
|
+
"properties": {
|
|
21144
|
+
"tenantId": {
|
|
21145
|
+
"type": "string",
|
|
21146
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
21147
|
+
},
|
|
21148
|
+
"fromDate": {
|
|
21149
|
+
"type": "string",
|
|
21150
|
+
"description": "Start date in YYYY-MM-DD format."
|
|
21151
|
+
},
|
|
21152
|
+
"toDate": {
|
|
21153
|
+
"type": "string",
|
|
21154
|
+
"description": "End date in YYYY-MM-DD format."
|
|
21155
|
+
},
|
|
21156
|
+
"periods": {
|
|
21157
|
+
"type": "integer",
|
|
21158
|
+
"minimum": 1,
|
|
21159
|
+
"description": "Number of comparison periods."
|
|
21160
|
+
},
|
|
21161
|
+
"timeframe": {
|
|
21162
|
+
"type": "string",
|
|
21163
|
+
"enum": [
|
|
21164
|
+
"MONTH",
|
|
21165
|
+
"QUARTER",
|
|
21166
|
+
"YEAR"
|
|
21167
|
+
],
|
|
21168
|
+
"description": "Comparison period timeframe."
|
|
21169
|
+
},
|
|
21170
|
+
"trackingCategoryId": {
|
|
21171
|
+
"type": "string"
|
|
21172
|
+
},
|
|
21173
|
+
"trackingOptionId": {
|
|
21174
|
+
"type": "string"
|
|
21175
|
+
},
|
|
21176
|
+
"standardLayout": {
|
|
21177
|
+
"type": "boolean",
|
|
21178
|
+
"description": "Use Xero's standard Profit and Loss layout when true."
|
|
21179
|
+
},
|
|
21180
|
+
"paymentsOnly": {
|
|
21181
|
+
"type": "boolean",
|
|
21182
|
+
"description": "Limit the report to payments-only values when supported by the organisation."
|
|
21183
|
+
}
|
|
21184
|
+
},
|
|
21185
|
+
"additionalProperties": false
|
|
21186
|
+
},
|
|
21187
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.fromDate) params.set('fromDate', input.fromDate)\n if (input.toDate) params.set('toDate', input.toDate)\n if (input.periods) params.set('periods', String(input.periods))\n if (input.timeframe) params.set('timeframe', input.timeframe)\n if (input.trackingCategoryId) params.set('trackingCategoryID', input.trackingCategoryId)\n if (input.trackingOptionId) params.set('trackingOptionID', input.trackingOptionId)\n if (input.standardLayout !== undefined) params.set('standardLayout', String(input.standardLayout))\n if (input.paymentsOnly !== undefined) params.set('paymentsOnly', String(input.paymentsOnly))\n const res = await integration.get(`/api.xro/2.0/Reports/ProfitAndLoss${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const report = Array.isArray(data?.Reports) ? data.Reports[0] : null\n const rows = Array.isArray(report?.Rows)\n ? report.Rows.map(row => ({\n rowType: row.RowType,\n title: row.Title,\n cells: Array.isArray(row.Cells) ? row.Cells.map(cell => cell.Value) : [],\n rows: Array.isArray(row.Rows)\n ? row.Rows.map(child => ({\n rowType: child.RowType,\n title: child.Title,\n cells: Array.isArray(child.Cells) ? child.Cells.map(cell => cell.Value) : [],\n }))\n : [],\n }))\n : []\n const headings = rows.find(row => row.rowType === 'Header')?.cells || []\n const summaryText = rows\n .filter(row => row.title || row.cells.length)\n .slice(0, 12)\n .map(row => [row.title || row.rowType, ...row.cells].filter(Boolean).join(' | '))\n .join('\\n')\n return {\n report: report\n ? {\n title: report.ReportTitles?.join(' - ') || report.ReportName,\n dateRange: { fromDate: input.fromDate || null, toDate: input.toDate || null },\n updatedDateUtc: report.UpdatedDateUTC,\n headings,\n rows,\n summaryText,\n }\n : null,\n query: Object.fromEntries(params.entries()),\n }\n}",
|
|
21188
|
+
"scope": "read",
|
|
21189
|
+
"toolset": "reports"
|
|
21190
|
+
},
|
|
21191
|
+
{
|
|
21192
|
+
"name": "get_balance_sheet",
|
|
21193
|
+
"description": "Get the Balance Sheet report for a date or period. Use this for financial position summaries.",
|
|
21194
|
+
"inputSchema": {
|
|
21195
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21196
|
+
"type": "object",
|
|
21197
|
+
"properties": {
|
|
21198
|
+
"tenantId": {
|
|
21199
|
+
"type": "string",
|
|
21200
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
21201
|
+
},
|
|
21202
|
+
"date": {
|
|
21203
|
+
"type": "string",
|
|
21204
|
+
"description": "Report date in YYYY-MM-DD format."
|
|
21205
|
+
},
|
|
21206
|
+
"periods": {
|
|
21207
|
+
"type": "integer",
|
|
21208
|
+
"minimum": 1,
|
|
21209
|
+
"description": "Number of comparison periods."
|
|
21210
|
+
},
|
|
21211
|
+
"timeframe": {
|
|
21212
|
+
"type": "string",
|
|
21213
|
+
"enum": [
|
|
21214
|
+
"MONTH",
|
|
21215
|
+
"QUARTER",
|
|
21216
|
+
"YEAR"
|
|
21217
|
+
],
|
|
21218
|
+
"description": "Comparison period timeframe."
|
|
21219
|
+
},
|
|
21220
|
+
"trackingCategoryId": {
|
|
21221
|
+
"type": "string"
|
|
21222
|
+
},
|
|
21223
|
+
"trackingOptionId": {
|
|
21224
|
+
"type": "string"
|
|
21225
|
+
}
|
|
21226
|
+
},
|
|
21227
|
+
"additionalProperties": false
|
|
21228
|
+
},
|
|
21229
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.date) params.set('date', input.date)\n if (input.periods) params.set('periods', String(input.periods))\n if (input.timeframe) params.set('timeframe', input.timeframe)\n if (input.trackingCategoryId) params.set('trackingCategoryID', input.trackingCategoryId)\n if (input.trackingOptionId) params.set('trackingOptionID', input.trackingOptionId)\n const res = await integration.get(`/api.xro/2.0/Reports/BalanceSheet${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const report = Array.isArray(data?.Reports) ? data.Reports[0] : null\n const rows = Array.isArray(report?.Rows)\n ? report.Rows.map(row => ({\n rowType: row.RowType,\n title: row.Title,\n cells: Array.isArray(row.Cells) ? row.Cells.map(cell => cell.Value) : [],\n rows: Array.isArray(row.Rows)\n ? row.Rows.map(child => ({\n rowType: child.RowType,\n title: child.Title,\n cells: Array.isArray(child.Cells) ? child.Cells.map(cell => cell.Value) : [],\n }))\n : [],\n }))\n : []\n const headings = rows.find(row => row.rowType === 'Header')?.cells || []\n const summaryText = rows\n .filter(row => row.title || row.cells.length)\n .slice(0, 12)\n .map(row => [row.title || row.rowType, ...row.cells].filter(Boolean).join(' | '))\n .join('\\n')\n return {\n report: report\n ? {\n title: report.ReportTitles?.join(' - ') || report.ReportName,\n dateRange: { date: input.date || null },\n updatedDateUtc: report.UpdatedDateUTC,\n headings,\n rows,\n summaryText,\n }\n : null,\n query: Object.fromEntries(params.entries()),\n }\n}",
|
|
21230
|
+
"scope": "read",
|
|
21231
|
+
"toolset": "reports"
|
|
21232
|
+
},
|
|
21233
|
+
{
|
|
21234
|
+
"name": "get_trial_balance",
|
|
21235
|
+
"description": "Get the Trial Balance report at a point in time.",
|
|
21236
|
+
"inputSchema": {
|
|
21237
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21238
|
+
"type": "object",
|
|
21239
|
+
"properties": {
|
|
21240
|
+
"tenantId": {
|
|
21241
|
+
"type": "string",
|
|
21242
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
21243
|
+
},
|
|
21244
|
+
"date": {
|
|
21245
|
+
"type": "string",
|
|
21246
|
+
"description": "Report date in YYYY-MM-DD format."
|
|
21247
|
+
}
|
|
21248
|
+
},
|
|
21249
|
+
"additionalProperties": false
|
|
21250
|
+
},
|
|
21251
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.date) params.set('date', input.date)\n const res = await integration.get(`/api.xro/2.0/Reports/TrialBalance${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const report = Array.isArray(data?.Reports) ? data.Reports[0] : null\n const rows = Array.isArray(report?.Rows)\n ? report.Rows.map(row => ({\n rowType: row.RowType,\n title: row.Title,\n cells: Array.isArray(row.Cells) ? row.Cells.map(cell => cell.Value) : [],\n rows: Array.isArray(row.Rows)\n ? row.Rows.map(child => ({\n rowType: child.RowType,\n title: child.Title,\n cells: Array.isArray(child.Cells) ? child.Cells.map(cell => cell.Value) : [],\n }))\n : [],\n }))\n : []\n const headings = rows.find(row => row.rowType === 'Header')?.cells || []\n const summaryText = rows\n .filter(row => row.title || row.cells.length)\n .slice(0, 12)\n .map(row => [row.title || row.rowType, ...row.cells].filter(Boolean).join(' | '))\n .join('\\n')\n return {\n report: report\n ? {\n title: report.ReportTitles?.join(' - ') || report.ReportName,\n dateRange: { date: input.date || null },\n updatedDateUtc: report.UpdatedDateUTC,\n headings,\n rows,\n summaryText,\n }\n : null,\n query: Object.fromEntries(params.entries()),\n }\n}",
|
|
21252
|
+
"scope": "read",
|
|
21253
|
+
"toolset": "reports"
|
|
21254
|
+
},
|
|
21255
|
+
{
|
|
21256
|
+
"name": "get_bank_summary",
|
|
21257
|
+
"description": "Get the Bank Summary report for a date range.",
|
|
21258
|
+
"inputSchema": {
|
|
21259
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21260
|
+
"type": "object",
|
|
21261
|
+
"properties": {
|
|
21262
|
+
"tenantId": {
|
|
21263
|
+
"type": "string",
|
|
21264
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
21265
|
+
},
|
|
21266
|
+
"fromDate": {
|
|
21267
|
+
"type": "string",
|
|
21268
|
+
"description": "Start date in YYYY-MM-DD format."
|
|
21269
|
+
},
|
|
21270
|
+
"toDate": {
|
|
21271
|
+
"type": "string",
|
|
21272
|
+
"description": "End date in YYYY-MM-DD format."
|
|
21273
|
+
}
|
|
21274
|
+
},
|
|
21275
|
+
"additionalProperties": false
|
|
21276
|
+
},
|
|
21277
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.fromDate) params.set('fromDate', input.fromDate)\n if (input.toDate) params.set('toDate', input.toDate)\n const res = await integration.get(`/api.xro/2.0/Reports/BankSummary${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const report = Array.isArray(data?.Reports) ? data.Reports[0] : null\n const rows = Array.isArray(report?.Rows)\n ? report.Rows.map(row => ({\n rowType: row.RowType,\n title: row.Title,\n cells: Array.isArray(row.Cells) ? row.Cells.map(cell => cell.Value) : [],\n rows: Array.isArray(row.Rows)\n ? row.Rows.map(child => ({\n rowType: child.RowType,\n title: child.Title,\n cells: Array.isArray(child.Cells) ? child.Cells.map(cell => cell.Value) : [],\n }))\n : [],\n }))\n : []\n const headings = rows.find(row => row.rowType === 'Header')?.cells || []\n const summaryText = rows\n .filter(row => row.title || row.cells.length)\n .slice(0, 12)\n .map(row => [row.title || row.rowType, ...row.cells].filter(Boolean).join(' | '))\n .join('\\n')\n return {\n report: report\n ? {\n title: report.ReportTitles?.join(' - ') || report.ReportName,\n dateRange: { fromDate: input.fromDate || null, toDate: input.toDate || null },\n updatedDateUtc: report.UpdatedDateUTC,\n headings,\n rows,\n summaryText,\n }\n : null,\n query: Object.fromEntries(params.entries()),\n }\n}",
|
|
21278
|
+
"scope": "read",
|
|
21279
|
+
"toolset": "reports"
|
|
21280
|
+
},
|
|
21281
|
+
{
|
|
21282
|
+
"name": "get_aged_payables_by_contact",
|
|
21283
|
+
"description": "Get the Aged Payables by Contact report for a supplier contact. Provide contactId from list_contacts.",
|
|
21284
|
+
"inputSchema": {
|
|
21285
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21286
|
+
"type": "object",
|
|
21287
|
+
"properties": {
|
|
21288
|
+
"tenantId": {
|
|
21289
|
+
"type": "string",
|
|
21290
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
21291
|
+
},
|
|
21292
|
+
"contactId": {
|
|
21293
|
+
"type": "string",
|
|
21294
|
+
"description": "Xero contact ID."
|
|
21295
|
+
},
|
|
21296
|
+
"date": {
|
|
21297
|
+
"type": "string",
|
|
21298
|
+
"description": "Report date in YYYY-MM-DD format."
|
|
21299
|
+
}
|
|
21300
|
+
},
|
|
21301
|
+
"required": [
|
|
21302
|
+
"contactId"
|
|
21303
|
+
],
|
|
21304
|
+
"additionalProperties": false
|
|
21305
|
+
},
|
|
21306
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.contactId) params.set('contactId', input.contactId)\n if (input.date) params.set('date', input.date)\n const res = await integration.get(`/api.xro/2.0/Reports/AgedPayablesByContact${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const report = Array.isArray(data?.Reports) ? data.Reports[0] : null\n const rows = Array.isArray(report?.Rows)\n ? report.Rows.map(row => ({\n rowType: row.RowType,\n title: row.Title,\n cells: Array.isArray(row.Cells) ? row.Cells.map(cell => cell.Value) : [],\n rows: Array.isArray(row.Rows)\n ? row.Rows.map(child => ({\n rowType: child.RowType,\n title: child.Title,\n cells: Array.isArray(child.Cells) ? child.Cells.map(cell => cell.Value) : [],\n }))\n : [],\n }))\n : []\n const summaryText = rows\n .filter(row => row.title || row.cells.length)\n .slice(0, 12)\n .map(row => [row.title || row.rowType, ...row.cells].filter(Boolean).join(' | '))\n .join('\\n')\n return {\n report: report\n ? {\n title: report.ReportTitles?.join(' - ') || report.ReportName,\n dateRange: { date: input.date || null },\n updatedDateUtc: report.UpdatedDateUTC,\n rows,\n summaryText,\n }\n : null,\n query: Object.fromEntries(params.entries()),\n }\n}",
|
|
21307
|
+
"scope": "read",
|
|
21308
|
+
"toolset": "reports"
|
|
21309
|
+
},
|
|
21310
|
+
{
|
|
21311
|
+
"name": "get_aged_receivables_by_contact",
|
|
21312
|
+
"description": "Get the Aged Receivables by Contact report for a customer contact. Provide contactId from list_contacts.",
|
|
21313
|
+
"inputSchema": {
|
|
21314
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21315
|
+
"type": "object",
|
|
21316
|
+
"properties": {
|
|
21317
|
+
"tenantId": {
|
|
21318
|
+
"type": "string",
|
|
21319
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
21320
|
+
},
|
|
21321
|
+
"contactId": {
|
|
21322
|
+
"type": "string",
|
|
21323
|
+
"description": "Xero contact ID."
|
|
21324
|
+
},
|
|
21325
|
+
"date": {
|
|
21326
|
+
"type": "string",
|
|
21327
|
+
"description": "Report date in YYYY-MM-DD format."
|
|
21328
|
+
}
|
|
21329
|
+
},
|
|
21330
|
+
"required": [
|
|
21331
|
+
"contactId"
|
|
21332
|
+
],
|
|
21333
|
+
"additionalProperties": false
|
|
21334
|
+
},
|
|
21335
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.contactId) params.set('contactId', input.contactId)\n if (input.date) params.set('date', input.date)\n const res = await integration.get(`/api.xro/2.0/Reports/AgedReceivablesByContact${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const report = Array.isArray(data?.Reports) ? data.Reports[0] : null\n const rows = Array.isArray(report?.Rows)\n ? report.Rows.map(row => ({\n rowType: row.RowType,\n title: row.Title,\n cells: Array.isArray(row.Cells) ? row.Cells.map(cell => cell.Value) : [],\n rows: Array.isArray(row.Rows)\n ? row.Rows.map(child => ({\n rowType: child.RowType,\n title: child.Title,\n cells: Array.isArray(child.Cells) ? child.Cells.map(cell => cell.Value) : [],\n }))\n : [],\n }))\n : []\n const summaryText = rows\n .filter(row => row.title || row.cells.length)\n .slice(0, 12)\n .map(row => [row.title || row.rowType, ...row.cells].filter(Boolean).join(' | '))\n .join('\\n')\n return {\n report: report\n ? {\n title: report.ReportTitles?.join(' - ') || report.ReportName,\n dateRange: { date: input.date || null },\n updatedDateUtc: report.UpdatedDateUTC,\n rows,\n summaryText,\n }\n : null,\n query: Object.fromEntries(params.entries()),\n }\n}",
|
|
21336
|
+
"scope": "read",
|
|
21337
|
+
"toolset": "reports"
|
|
21338
|
+
},
|
|
21339
|
+
{
|
|
21340
|
+
"name": "get_budget_summary",
|
|
21341
|
+
"description": "Get the Budget Summary report for a date range and period count.",
|
|
21342
|
+
"inputSchema": {
|
|
21343
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21344
|
+
"type": "object",
|
|
21345
|
+
"properties": {
|
|
21346
|
+
"tenantId": {
|
|
21347
|
+
"type": "string",
|
|
21348
|
+
"description": "Xero tenant ID from list_connections. Omit for Custom Connections."
|
|
21349
|
+
},
|
|
21350
|
+
"date": {
|
|
21351
|
+
"type": "string",
|
|
21352
|
+
"description": "Report date in YYYY-MM-DD format."
|
|
21353
|
+
},
|
|
21354
|
+
"periods": {
|
|
21355
|
+
"type": "integer",
|
|
21356
|
+
"minimum": 1,
|
|
21357
|
+
"description": "Number of periods."
|
|
21358
|
+
},
|
|
21359
|
+
"timeframe": {
|
|
21360
|
+
"type": "string",
|
|
21361
|
+
"enum": [
|
|
21362
|
+
"MONTH",
|
|
21363
|
+
"QUARTER",
|
|
21364
|
+
"YEAR"
|
|
21365
|
+
],
|
|
21366
|
+
"description": "Period timeframe."
|
|
21367
|
+
}
|
|
21368
|
+
},
|
|
21369
|
+
"additionalProperties": false
|
|
21370
|
+
},
|
|
21371
|
+
"handlerCode": "async (input) => {\n const headers = input.tenantId ? { 'xero-tenant-id': input.tenantId } : {}\n const params = new URLSearchParams()\n if (input.date) params.set('date', input.date)\n if (input.periods) params.set('periods', String(input.periods))\n if (input.timeframe) params.set('timeframe', input.timeframe)\n const res = await integration.get(`/api.xro/2.0/Reports/BudgetSummary${params.toString() ? `?${params}` : ''}`, { headers })\n const data = await res.json()\n const report = Array.isArray(data?.Reports) ? data.Reports[0] : null\n const rows = Array.isArray(report?.Rows)\n ? report.Rows.map(row => ({\n rowType: row.RowType,\n title: row.Title,\n cells: Array.isArray(row.Cells) ? row.Cells.map(cell => cell.Value) : [],\n rows: Array.isArray(row.Rows)\n ? row.Rows.map(child => ({\n rowType: child.RowType,\n title: child.Title,\n cells: Array.isArray(child.Cells) ? child.Cells.map(cell => cell.Value) : [],\n }))\n : [],\n }))\n : []\n const headings = rows.find(row => row.rowType === 'Header')?.cells || []\n const summaryText = rows\n .filter(row => row.title || row.cells.length)\n .slice(0, 12)\n .map(row => [row.title || row.rowType, ...row.cells].filter(Boolean).join(' | '))\n .join('\\n')\n return {\n report: report\n ? {\n title: report.ReportTitles?.join(' - ') || report.ReportName,\n dateRange: { date: input.date || null },\n updatedDateUtc: report.UpdatedDateUTC,\n headings,\n rows,\n summaryText,\n }\n : null,\n query: Object.fromEntries(params.entries()),\n }\n}",
|
|
21372
|
+
"scope": "read",
|
|
21373
|
+
"toolset": "reports"
|
|
21374
|
+
}
|
|
21375
|
+
],
|
|
21376
|
+
"variantOwnerType": null
|
|
21377
|
+
}
|
|
21378
|
+
};
|
|
21379
|
+
|
|
21380
|
+
function humanizeName(name) {
|
|
21381
|
+
return name.replace(/_/g, " ").split(/\s+/).filter(Boolean).map((w) => w.length ? `${w[0].toUpperCase()}${w.slice(1).toLowerCase()}` : w).join(" ");
|
|
21382
|
+
}
|
|
21383
|
+
function getIntegration(type) {
|
|
21384
|
+
var _a;
|
|
21385
|
+
return (_a = GENERATED_INTEGRATIONS[type]) != null ? _a : null;
|
|
21386
|
+
}
|
|
21387
|
+
function cloneManifest(manifest) {
|
|
21388
|
+
return {
|
|
21389
|
+
...manifest,
|
|
21390
|
+
variantConfig: manifest.variantConfig ? JSON.parse(JSON.stringify(manifest.variantConfig)) : void 0,
|
|
21391
|
+
toolsets: manifest.toolsets ? { ...manifest.toolsets } : void 0,
|
|
21392
|
+
tools: manifest.tools.map((tool) => ({
|
|
21393
|
+
...tool,
|
|
21394
|
+
injectFromConfig: tool.injectFromConfig ? { ...tool.injectFromConfig } : void 0
|
|
21395
|
+
}))
|
|
21396
|
+
};
|
|
21397
|
+
}
|
|
21398
|
+
function cloneCredentialVariant(variant) {
|
|
21399
|
+
var _a, _b;
|
|
21400
|
+
return {
|
|
21401
|
+
...variant,
|
|
21402
|
+
injection: {
|
|
21403
|
+
headers: ((_a = variant.injection) == null ? void 0 : _a.headers) ? { ...variant.injection.headers } : void 0,
|
|
21404
|
+
query: ((_b = variant.injection) == null ? void 0 : _b.query) ? { ...variant.injection.query } : void 0
|
|
21405
|
+
},
|
|
21406
|
+
preprocess: typeof variant.preprocess === "object" && variant.preprocess !== null ? {
|
|
21407
|
+
...variant.preprocess,
|
|
21408
|
+
allowedOrigins: Array.isArray(variant.preprocess.allowedOrigins) ? [...variant.preprocess.allowedOrigins] : void 0
|
|
21409
|
+
} : variant.preprocess,
|
|
21410
|
+
healthCheck: "path" in variant.healthCheck ? { ...variant.healthCheck } : { notViable: true }
|
|
21411
|
+
};
|
|
21412
|
+
}
|
|
21413
|
+
function validateCredentialVariant(type, variantKey, variant) {
|
|
21414
|
+
const healthCheck = variant.healthCheck;
|
|
21415
|
+
const hasHealthCheckPath = "path" in healthCheck && typeof healthCheck.path === "string" && healthCheck.path.trim().length > 0;
|
|
21416
|
+
const healthCheckNotViable = "notViable" in healthCheck && healthCheck.notViable === true;
|
|
21417
|
+
if (hasHealthCheckPath === healthCheckNotViable) {
|
|
21418
|
+
throw new Error(`Invalid credentials config for '${type}/${variantKey}': declare exactly one of 'healthCheck.path' or 'healthCheck.notViable: true'.`);
|
|
21419
|
+
}
|
|
21420
|
+
if (hasHealthCheckPath) {
|
|
21421
|
+
if ("method" in healthCheck && healthCheck.method !== void 0 && typeof healthCheck.method !== "string") {
|
|
21422
|
+
throw new Error(`Invalid credentials config for '${type}/${variantKey}': healthCheck.method must be a string when provided.`);
|
|
21423
|
+
}
|
|
21424
|
+
if ("headers" in healthCheck && healthCheck.headers !== void 0) {
|
|
21425
|
+
const headers = healthCheck.headers;
|
|
21426
|
+
if (!headers || typeof headers !== "object" || Array.isArray(headers)) {
|
|
21427
|
+
throw new Error(`Invalid credentials config for '${type}/${variantKey}': healthCheck.headers must be an object when provided.`);
|
|
21428
|
+
}
|
|
21429
|
+
for (const [headerName, headerValue] of Object.entries(headers)) {
|
|
21430
|
+
if (!headerName.trim() || typeof headerValue !== "string") {
|
|
21431
|
+
throw new Error(`Invalid credentials config for '${type}/${variantKey}': healthCheck.headers must map non-empty names to string values.`);
|
|
21432
|
+
}
|
|
21433
|
+
}
|
|
21434
|
+
}
|
|
21435
|
+
if ("expectStatus" in healthCheck && healthCheck.expectStatus !== void 0) {
|
|
21436
|
+
const expectedStatuses = Array.isArray(healthCheck.expectStatus) ? healthCheck.expectStatus : [healthCheck.expectStatus];
|
|
21437
|
+
if (!expectedStatuses.length || expectedStatuses.some((status) => !Number.isInteger(status) || status < 100 || status > 599)) {
|
|
21438
|
+
throw new Error(`Invalid credentials config for '${type}/${variantKey}': healthCheck.expectStatus must be an HTTP status code or non-empty array of status codes.`);
|
|
21439
|
+
}
|
|
21440
|
+
}
|
|
21441
|
+
if ("description" in healthCheck && healthCheck.description !== void 0 && typeof healthCheck.description !== "string") {
|
|
21442
|
+
throw new Error(`Invalid credentials config for '${type}/${variantKey}': healthCheck.description must be a string when provided.`);
|
|
21443
|
+
}
|
|
21444
|
+
}
|
|
21445
|
+
if (healthCheckNotViable && "reason" in healthCheck && healthCheck.reason !== void 0 && typeof healthCheck.reason !== "string") {
|
|
21446
|
+
throw new Error(`Invalid credentials config for '${type}/${variantKey}': healthCheck.reason must be a string when provided.`);
|
|
21447
|
+
}
|
|
21448
|
+
}
|
|
21449
|
+
function validateCredentialVariantsFile(type, raw) {
|
|
21450
|
+
if (!(raw == null ? void 0 : raw.variants) || typeof raw.variants !== "object")
|
|
21451
|
+
throw new Error(`Invalid credentials config for '${type}': missing variants object.`);
|
|
21452
|
+
for (const [variantKey, variant] of Object.entries(raw.variants))
|
|
21453
|
+
validateCredentialVariant(type, variantKey, variant);
|
|
21454
|
+
return raw;
|
|
21455
|
+
}
|
|
21456
|
+
function cloneCredentialVariantsFile(type, variants) {
|
|
18696
21457
|
const validated = validateCredentialVariantsFile(type, variants);
|
|
18697
21458
|
return {
|
|
18698
21459
|
default: validated.default,
|
|
@@ -18919,14 +21680,13 @@ function sanitizeJsonSchema(schema) {
|
|
|
18919
21680
|
}
|
|
18920
21681
|
return out;
|
|
18921
21682
|
}
|
|
18922
|
-
function
|
|
18923
|
-
|
|
18924
|
-
|
|
18925
|
-
|
|
18926
|
-
const
|
|
18927
|
-
|
|
18928
|
-
|
|
18929
|
-
return `${base}${suffix}`;
|
|
21683
|
+
function sanitizeToolNamePart(value) {
|
|
21684
|
+
return (value || "").toLowerCase().replace(/[^a-z0-9_]/g, "_");
|
|
21685
|
+
}
|
|
21686
|
+
function makeIntegrationToolName(referenceId, name) {
|
|
21687
|
+
const integrationKey = sanitizeToolNamePart(referenceId);
|
|
21688
|
+
const toolKey = sanitizeToolNamePart(name);
|
|
21689
|
+
return `${integrationKey}__${toolKey}`;
|
|
18930
21690
|
}
|
|
18931
21691
|
|
|
18932
21692
|
const hoistedArtifactsByResult = /* @__PURE__ */ new WeakMap();
|
|
@@ -20315,6 +23075,7 @@ function ensureExtractorScript() {
|
|
|
20315
23075
|
}
|
|
20316
23076
|
const FILE_PROCESSING_DISABLED_TOOLS = {
|
|
20317
23077
|
"google-workspace": ["read_file_content"],
|
|
23078
|
+
"google-gmail": ["read_attachment_content"],
|
|
20318
23079
|
sharepoint: ["read_file_content"]
|
|
20319
23080
|
};
|
|
20320
23081
|
let capabilityPromise = null;
|
|
@@ -20417,6 +23178,9 @@ function isAbsoluteHttpUrl$1(value) {
|
|
|
20417
23178
|
return false;
|
|
20418
23179
|
}
|
|
20419
23180
|
}
|
|
23181
|
+
function isDataUrl(value) {
|
|
23182
|
+
return String(value || "").trimStart().toLowerCase().startsWith("data:");
|
|
23183
|
+
}
|
|
20420
23184
|
function parseContentDispositionFilename(value) {
|
|
20421
23185
|
var _a;
|
|
20422
23186
|
if (!value)
|
|
@@ -20485,6 +23249,35 @@ function inferFilename(response, source) {
|
|
|
20485
23249
|
const ext = extensionFromContentType(response.headers.get("content-type"));
|
|
20486
23250
|
return `downloaded-file${ext}`;
|
|
20487
23251
|
}
|
|
23252
|
+
function parseDataUrl(source) {
|
|
23253
|
+
const match = String(source || "").match(/^data:([^,]*),(.*)$/s);
|
|
23254
|
+
if (!match)
|
|
23255
|
+
throw new HttpError(400, "Invalid data URL passed to extractFileContent.");
|
|
23256
|
+
const metadata = match[1] || "";
|
|
23257
|
+
const rawPayload = match[2] || "";
|
|
23258
|
+
const metadataParts = metadata.split(";").map((part) => part.trim()).filter(Boolean);
|
|
23259
|
+
const mimeType = metadataParts.find((part) => part.toLowerCase() !== "base64" && !part.includes("=")) || "application/octet-stream";
|
|
23260
|
+
const isBase64 = metadataParts.some((part) => part.toLowerCase() === "base64");
|
|
23261
|
+
if (!isBase64)
|
|
23262
|
+
throw new HttpError(400, "extractFileContent data URLs must use base64 encoding.");
|
|
23263
|
+
let payload = rawPayload.replace(/\s/g, "");
|
|
23264
|
+
try {
|
|
23265
|
+
payload = decodeURIComponent(payload);
|
|
23266
|
+
} catch {
|
|
23267
|
+
}
|
|
23268
|
+
if (!payload || payload.length % 4 === 1 || !/^[A-Za-z0-9+/]*={0,2}$/.test(payload))
|
|
23269
|
+
throw new HttpError(400, "extractFileContent received an invalid base64 data URL payload.");
|
|
23270
|
+
return {
|
|
23271
|
+
bytes: Buffer.from(payload, "base64"),
|
|
23272
|
+
filename: `downloaded-file${extensionFromContentType(mimeType)}`
|
|
23273
|
+
};
|
|
23274
|
+
}
|
|
23275
|
+
async function readResponseFile(response, source) {
|
|
23276
|
+
return {
|
|
23277
|
+
bytes: Buffer.from(await response.arrayBuffer()),
|
|
23278
|
+
filename: inferFilename(response, source)
|
|
23279
|
+
};
|
|
23280
|
+
}
|
|
20488
23281
|
async function downloadWithAuth(args, getIntegration) {
|
|
20489
23282
|
if (!args.integration)
|
|
20490
23283
|
throw new HttpError(400, "extractFileContent requires an exact integration id/reference when `auth` is true.");
|
|
@@ -20493,7 +23286,7 @@ async function downloadWithAuth(args, getIntegration) {
|
|
|
20493
23286
|
}
|
|
20494
23287
|
async function downloadWithoutAuth(args) {
|
|
20495
23288
|
if (!isAbsoluteHttpUrl$1(args.source))
|
|
20496
|
-
throw new HttpError(400, "extractFileContent requires an absolute http(s) URL when `auth` is false.");
|
|
23289
|
+
throw new HttpError(400, "extractFileContent requires an absolute http(s) URL or data URL when `auth` is false.");
|
|
20497
23290
|
return fetch(args.source, { method: "GET" });
|
|
20498
23291
|
}
|
|
20499
23292
|
function createExtractFileContent(getIntegration, defaultIntegrationId) {
|
|
@@ -20508,18 +23301,22 @@ function createExtractFileContent(getIntegration, defaultIntegrationId) {
|
|
|
20508
23301
|
const capability = await getFileProcessingCapability();
|
|
20509
23302
|
if (!capability.enabled)
|
|
20510
23303
|
throw new HttpError(501, formatFileProcessingUnavailableMessage(capability));
|
|
20511
|
-
const
|
|
20512
|
-
|
|
20513
|
-
|
|
20514
|
-
|
|
20515
|
-
|
|
23304
|
+
const downloaded = isDataUrl(resolvedArgs.source) ? !resolvedArgs.auth ? parseDataUrl(resolvedArgs.source) : (() => {
|
|
23305
|
+
throw new HttpError(400, "extractFileContent data URLs must use `auth: false`.");
|
|
23306
|
+
})() : await (async () => {
|
|
23307
|
+
const response = resolvedArgs.auth ? await downloadWithAuth(resolvedArgs, getIntegration) : await downloadWithoutAuth(resolvedArgs);
|
|
23308
|
+
if (!response.ok) {
|
|
23309
|
+
const bodyText = await response.text().catch(() => "");
|
|
23310
|
+
throw new HttpError(response.status, `Failed to download file (${response.status})${bodyText ? `: ${bodyText.slice(0, 500)}` : ""}.`);
|
|
23311
|
+
}
|
|
23312
|
+
return await readResponseFile(response, resolvedArgs.source);
|
|
23313
|
+
})();
|
|
20516
23314
|
const tempDir = await mkdtemp(join(tmpdir(), "commandable-extract-"));
|
|
20517
23315
|
try {
|
|
20518
|
-
const filename =
|
|
23316
|
+
const filename = downloaded.filename;
|
|
20519
23317
|
const filePath = join(tempDir, filename);
|
|
20520
23318
|
const outputPath = join(tempDir, "result.json");
|
|
20521
|
-
|
|
20522
|
-
await writeFile$1(filePath, bytes);
|
|
23319
|
+
await writeFile$1(filePath, downloaded.bytes);
|
|
20523
23320
|
const pythonArgs = [extractorScriptPath(), "--input", filePath, "--output", outputPath];
|
|
20524
23321
|
const previewPages = typeof resolvedArgs.previewPages === "number" && resolvedArgs.previewPages > 0 ? Math.floor(resolvedArgs.previewPages) : 0;
|
|
20525
23322
|
if (previewPages > 0)
|
|
@@ -20610,7 +23407,7 @@ function buildToolsByIntegration(spaceId, integrations, proxy, opts = {}) {
|
|
|
20610
23407
|
const buildActions = (arr, scope) => arr.map((t) => {
|
|
20611
23408
|
const rawSchema = typeof t.inputSchema === "string" ? JSON.parse(t.inputSchema) : t.inputSchema;
|
|
20612
23409
|
const schemaObj = sanitizeJsonSchema(rawSchema);
|
|
20613
|
-
const toolName = makeIntegrationToolName(integ.
|
|
23410
|
+
const toolName = makeIntegrationToolName(integ.referenceId, t.name);
|
|
20614
23411
|
const description = `[${integ.label} | ${integ.type}] ${t.description}`;
|
|
20615
23412
|
const extractFileContent = createExtractFileContent(getIntegration, integ.id);
|
|
20616
23413
|
const wrapper = buildHandlerWrapper(integ.id, t.handlerCode, integ.config, t.injectFromConfig);
|
|
@@ -20628,7 +23425,7 @@ function buildToolsByIntegration(spaceId, integrations, proxy, opts = {}) {
|
|
|
20628
23425
|
});
|
|
20629
23426
|
const buildActionsFromToolDefinitions = (defs, scope) => defs.map((t) => {
|
|
20630
23427
|
const schemaObj = sanitizeJsonSchema(t.inputSchema);
|
|
20631
|
-
const toolName = makeIntegrationToolName(integ.
|
|
23428
|
+
const toolName = makeIntegrationToolName(integ.referenceId, t.name);
|
|
20632
23429
|
const description = `[${integ.label} | ${integ.type}] ${t.description}`;
|
|
20633
23430
|
const extractFileContent = createExtractFileContent(getIntegration, integ.id);
|
|
20634
23431
|
const wrapper = `async (input) => {
|
|
@@ -21456,20 +24253,24 @@ async function checkIntegrationHealth(params) {
|
|
|
21456
24253
|
const healthCheck = variant == null ? void 0 : variant.healthCheck;
|
|
21457
24254
|
const path = healthCheck && "path" in healthCheck ? healthCheck.path : null;
|
|
21458
24255
|
const method = healthCheck && "path" in healthCheck ? (_b = healthCheck.method) != null ? _b : "GET" : "GET";
|
|
24256
|
+
const headers = healthCheck && "path" in healthCheck ? healthCheck.headers : void 0;
|
|
24257
|
+
const expectedStatuses = healthCheck && "path" in healthCheck && healthCheck.expectStatus !== void 0 ? Array.isArray(healthCheck.expectStatus) ? healthCheck.expectStatus : [healthCheck.expectStatus] : [];
|
|
21459
24258
|
if (!path) {
|
|
21460
24259
|
return { status: "connected", skipped: true, checkedAt };
|
|
21461
24260
|
}
|
|
21462
24261
|
try {
|
|
21463
|
-
await proxy.call(integration, path, { method });
|
|
24262
|
+
await proxy.call(integration, path, { method, headers });
|
|
21464
24263
|
return { status: "connected", checkedAt };
|
|
21465
24264
|
} catch (err) {
|
|
21466
|
-
|
|
24265
|
+
const statusCode = (_c = err == null ? void 0 : err.statusCode) != null ? _c : null;
|
|
24266
|
+
if (typeof statusCode === "number" && expectedStatuses.includes(statusCode))
|
|
24267
|
+
return { status: "connected", checkedAt, message: err.message };
|
|
24268
|
+
if ((err == null ? void 0 : err.statusCode) === 400 && ((_d = err == null ? void 0 : err.message) == null ? void 0 : _d.includes("No credentials"))) {
|
|
21467
24269
|
return { status: "disconnected", checkedAt, message: err.message };
|
|
21468
24270
|
}
|
|
21469
|
-
if ((err == null ? void 0 : err.statusCode) === 400 && ((
|
|
24271
|
+
if ((err == null ? void 0 : err.statusCode) === 400 && ((_e = err == null ? void 0 : err.message) == null ? void 0 : _e.includes("credentialId"))) {
|
|
21470
24272
|
return { status: "disconnected", checkedAt, message: err.message };
|
|
21471
24273
|
}
|
|
21472
|
-
const statusCode = (_e = err == null ? void 0 : err.statusCode) != null ? _e : null;
|
|
21473
24274
|
if (statusCode === 401) {
|
|
21474
24275
|
return { status: "invalid_credentials", checkedAt, message: err.message };
|
|
21475
24276
|
}
|
|
@@ -21875,9 +24676,6 @@ var __defProp$2 = Object.defineProperty;
|
|
|
21875
24676
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
21876
24677
|
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
21877
24678
|
const SCOPE_RANK = { read: 0, write: 1, admin: 2 };
|
|
21878
|
-
function shortNodeId(nodeId) {
|
|
21879
|
-
return (nodeId || "").replace(/[^a-z0-9]/gi, "").slice(0, 8).toLowerCase();
|
|
21880
|
-
}
|
|
21881
24679
|
function humanize$1(s) {
|
|
21882
24680
|
return (s || "").replace(/_/g, " ").split(/\s+/g).filter(Boolean).map((w) => w.length ? `${w[0].toUpperCase()}${w.slice(1).toLowerCase()}` : w).join(" ");
|
|
21883
24681
|
}
|
|
@@ -21895,10 +24693,10 @@ const BUILDER_TOOL_NAMES = [
|
|
|
21895
24693
|
"commandable_test_custom_tool"
|
|
21896
24694
|
];
|
|
21897
24695
|
function makeAbilityId(integ, toolsetKey) {
|
|
21898
|
-
const
|
|
24696
|
+
const base = sanitizeAbilityKey(integ.referenceId);
|
|
21899
24697
|
if (!toolsetKey)
|
|
21900
|
-
return
|
|
21901
|
-
return `${
|
|
24698
|
+
return base;
|
|
24699
|
+
return `${base}__${sanitizeAbilityKey(toolsetKey)}`;
|
|
21902
24700
|
}
|
|
21903
24701
|
function scoreQuery(query, haystack) {
|
|
21904
24702
|
const q = (query || "").toLowerCase().trim();
|
|
@@ -22011,8 +24809,8 @@ class AbilityCatalog {
|
|
|
22011
24809
|
return existing.toolNames.length !== before;
|
|
22012
24810
|
}
|
|
22013
24811
|
removeIntegrationAbilities(integration) {
|
|
22014
|
-
const
|
|
22015
|
-
const removed = this.abilities.filter((a) => a.id.
|
|
24812
|
+
const prefix = sanitizeAbilityKey(integration.referenceId);
|
|
24813
|
+
const removed = this.abilities.filter((a) => a.id === prefix || a.id.startsWith(`${prefix}__`)).map((a) => a.id);
|
|
22016
24814
|
if (!removed.length)
|
|
22017
24815
|
return 0;
|
|
22018
24816
|
for (const id of removed)
|
|
@@ -22086,7 +24884,7 @@ class AbilityCatalog {
|
|
|
22086
24884
|
continue;
|
|
22087
24885
|
if (blocked == null ? void 0 : blocked.has(ref.name))
|
|
22088
24886
|
continue;
|
|
22089
|
-
const toolName = makeIntegrationToolName(integ.
|
|
24887
|
+
const toolName = makeIntegrationToolName(integ.referenceId, ref.name);
|
|
22090
24888
|
if (!this.toolIndex.has(toolName))
|
|
22091
24889
|
continue;
|
|
22092
24890
|
allTools.push(toolName);
|
|
@@ -22096,12 +24894,9 @@ class AbilityCatalog {
|
|
|
22096
24894
|
toolsByToolset.set(bucketKey, arr);
|
|
22097
24895
|
}
|
|
22098
24896
|
}
|
|
22099
|
-
const
|
|
22100
|
-
const typePrefix = `${sanitizeAbilityKey(integ.type)}__`;
|
|
24897
|
+
const referencePrefix = `${sanitizeAbilityKey(integ.referenceId)}__`;
|
|
22101
24898
|
const allForIntegration = [...this.toolIndex.keys()].filter((n) => {
|
|
22102
|
-
if (!n.
|
|
22103
|
-
return false;
|
|
22104
|
-
if (!n.startsWith(typePrefix))
|
|
24899
|
+
if (!n.startsWith(referencePrefix))
|
|
22105
24900
|
return false;
|
|
22106
24901
|
return true;
|
|
22107
24902
|
});
|
|
@@ -22181,7 +24976,7 @@ function buildExecutableToolFromDefinition(params) {
|
|
|
22181
24976
|
extractFileContent: createExtractFileContent(getIntegration, integration.id)
|
|
22182
24977
|
});
|
|
22183
24978
|
const scope = tool.scope || "write";
|
|
22184
|
-
const toolName = makeIntegrationToolName(integration.
|
|
24979
|
+
const toolName = makeIntegrationToolName(integration.referenceId, tool.name);
|
|
22185
24980
|
const description = `[${integration.label} | ${integration.type}] ${tool.description || tool.displayName || tool.name}`;
|
|
22186
24981
|
const inputSchema = sanitizeJsonSchema(tool.inputSchema || { type: "object", additionalProperties: true });
|
|
22187
24982
|
const wrapper = `async (input) => {
|
|
@@ -23047,7 +25842,7 @@ ${lines ? `${lines}
|
|
|
23047
25842
|
const integration = ctx.integrationsRef.current.find((i) => i.id === integrationId || i.referenceId === integrationId);
|
|
23048
25843
|
if (!integration)
|
|
23049
25844
|
throw new Error(`Unknown integration_id: ${integrationId}`);
|
|
23050
|
-
const materializedToolNames = [...((_h = ctx.toolIndexRef) == null ? void 0 : _h.byName.keys()) || []].filter((toolName) => toolName.
|
|
25845
|
+
const materializedToolNames = [...((_h = ctx.toolIndexRef) == null ? void 0 : _h.byName.keys()) || []].filter((toolName) => toolName.startsWith(`${integration.referenceId.replace(/[^a-z0-9_]/gi, "_").toLowerCase()}__`));
|
|
23051
25846
|
for (const toolName of materializedToolNames) {
|
|
23052
25847
|
(_i = ctx.toolIndexRef) == null ? void 0 : _i.byName.delete(toolName);
|
|
23053
25848
|
sessionState.removeToolFromAllSessions(toolName);
|
|
@@ -23569,7 +26364,7 @@ function hasAutoConfigFile() {
|
|
|
23569
26364
|
].map((f) => resolve$1(base, f));
|
|
23570
26365
|
return candidates.some((p) => existsSync(p) && statSync(p).isFile());
|
|
23571
26366
|
}
|
|
23572
|
-
const
|
|
26367
|
+
const _AquVwiIVM7a1K2p3HKZndtheEQgWg5MseXxRS5CsE6E = defineNitroPlugin(async () => {
|
|
23573
26368
|
const explicit = process.env.COMMANDABLE_CONFIG_FILE;
|
|
23574
26369
|
if (!explicit && !hasAutoConfigFile())
|
|
23575
26370
|
return;
|
|
@@ -23588,7 +26383,7 @@ const _M_TVKJFSaqgo9E7nGBulJC6Bj53qbW6Kmjg2BjXUCEw = defineNitroPlugin(async ()
|
|
|
23588
26383
|
}
|
|
23589
26384
|
});
|
|
23590
26385
|
|
|
23591
|
-
const
|
|
26386
|
+
const _lVWhYLiBO2LPJ2uGgGmGMgzdCSfVXfio7QJNE3KXLWg = defineNitroPlugin(async () => {
|
|
23592
26387
|
try {
|
|
23593
26388
|
const capability = await warmFileProcessingCapability();
|
|
23594
26389
|
if (!capability.enabled)
|
|
@@ -23600,157 +26395,157 @@ const _ZP9JqzcUWiqZ00FMxCGYad0cri1qDPlZLfZD4ElgrrI = defineNitroPlugin(async ()
|
|
|
23600
26395
|
}
|
|
23601
26396
|
});
|
|
23602
26397
|
|
|
23603
|
-
const
|
|
26398
|
+
const _1dydEfKs62cALEMU8o0N971FGk1682y6tf9StPR8As = defineNitroPlugin(() => {
|
|
23604
26399
|
getOrCreateEncryptionSecret();
|
|
23605
26400
|
});
|
|
23606
26401
|
|
|
23607
26402
|
const plugins = [
|
|
23608
|
-
|
|
23609
|
-
|
|
23610
|
-
|
|
23611
|
-
|
|
26403
|
+
_zUuxVGgAOQhH7E5atfn9Ptf95wF4esqexnSnzyTPmK8,
|
|
26404
|
+
_AquVwiIVM7a1K2p3HKZndtheEQgWg5MseXxRS5CsE6E,
|
|
26405
|
+
_lVWhYLiBO2LPJ2uGgGmGMgzdCSfVXfio7QJNE3KXLWg,
|
|
26406
|
+
_1dydEfKs62cALEMU8o0N971FGk1682y6tf9StPR8As
|
|
23612
26407
|
];
|
|
23613
26408
|
|
|
23614
26409
|
const assets = {
|
|
23615
26410
|
"/favicon.ico": {
|
|
23616
26411
|
"type": "image/vnd.microsoft.icon",
|
|
23617
26412
|
"etag": "\"10be-n8egyE9tcb7sKGr/pYCaQ4uWqxI\"",
|
|
23618
|
-
"mtime": "2026-04-
|
|
26413
|
+
"mtime": "2026-04-28T17:57:48.323Z",
|
|
23619
26414
|
"size": 4286,
|
|
23620
26415
|
"path": "../public/favicon.ico"
|
|
23621
26416
|
},
|
|
23622
26417
|
"/_fonts/57NSSoFy1VLVs2gqly8Ls9awBnZMFyXGrefpmqvdqmc-zJfbBtpgM4cDmcXBsqZNW79_kFnlpPd62b48glgdydA.woff2": {
|
|
23623
26418
|
"type": "font/woff2",
|
|
23624
26419
|
"etag": "\"4b5c-TAo9mx7r3xQs52+HbHcHJ52z8Qo\"",
|
|
23625
|
-
"mtime": "2026-04-
|
|
26420
|
+
"mtime": "2026-04-28T17:57:48.317Z",
|
|
23626
26421
|
"size": 19292,
|
|
23627
26422
|
"path": "../public/_fonts/57NSSoFy1VLVs2gqly8Ls9awBnZMFyXGrefpmqvdqmc-zJfbBtpgM4cDmcXBsqZNW79_kFnlpPd62b48glgdydA.woff2"
|
|
23628
26423
|
},
|
|
23629
26424
|
"/_fonts/8VR2wSMN-3U4NbWAVYXlkRV6hA0jFBXP-0RtL3X7fko-x2gYI4qfmkRdxyQQUPaBZdZdgl1TeVrquF_TxHeM4lM.woff2": {
|
|
23630
26425
|
"type": "font/woff2",
|
|
23631
26426
|
"etag": "\"212c-FshXJibFzNhd2HEIMP8C3JR5PYg\"",
|
|
23632
|
-
"mtime": "2026-04-
|
|
26427
|
+
"mtime": "2026-04-28T17:57:48.318Z",
|
|
23633
26428
|
"size": 8492,
|
|
23634
26429
|
"path": "../public/_fonts/8VR2wSMN-3U4NbWAVYXlkRV6hA0jFBXP-0RtL3X7fko-x2gYI4qfmkRdxyQQUPaBZdZdgl1TeVrquF_TxHeM4lM.woff2"
|
|
23635
26430
|
},
|
|
23636
26431
|
"/_fonts/GsKUclqeNLJ96g5AU593ug6yanivOiwjW_7zESNPChw-jHA4tBeM1bjF7LATGUpfBuSTyomIFrWBTzjF7txVYfg.woff2": {
|
|
23637
26432
|
"type": "font/woff2",
|
|
23638
26433
|
"etag": "\"680c-mJtsV33lkTAKSmfq5k3lKHSllcU\"",
|
|
23639
|
-
"mtime": "2026-04-
|
|
26434
|
+
"mtime": "2026-04-28T17:57:48.318Z",
|
|
23640
26435
|
"size": 26636,
|
|
23641
26436
|
"path": "../public/_fonts/GsKUclqeNLJ96g5AU593ug6yanivOiwjW_7zESNPChw-jHA4tBeM1bjF7LATGUpfBuSTyomIFrWBTzjF7txVYfg.woff2"
|
|
23642
26437
|
},
|
|
23643
26438
|
"/_fonts/Ld1FnTo3yTIwDyGfTQ5-Fws9AWsCbKfMvgxduXr7JcY-W25bL8NF1fjpLRSOgJb7RoZPHqGQNwMTM7S9tHVoxx8.woff2": {
|
|
23644
26439
|
"type": "font/woff2",
|
|
23645
26440
|
"etag": "\"6ec4-8OoFFPZKF1grqmfGVjh5JDE6DOU\"",
|
|
23646
|
-
"mtime": "2026-04-
|
|
26441
|
+
"mtime": "2026-04-28T17:57:48.318Z",
|
|
23647
26442
|
"size": 28356,
|
|
23648
26443
|
"path": "../public/_fonts/Ld1FnTo3yTIwDyGfTQ5-Fws9AWsCbKfMvgxduXr7JcY-W25bL8NF1fjpLRSOgJb7RoZPHqGQNwMTM7S9tHVoxx8.woff2"
|
|
23649
26444
|
},
|
|
23650
26445
|
"/_fonts/NdzqRASp2bovDUhQT1IRE_EMqKJ2KYQdTCfFcBvL8yw-KhwZiS86o3fErOe5GGMExHUemmI_dBfaEFxjISZrBd0.woff2": {
|
|
23651
26446
|
"type": "font/woff2",
|
|
23652
26447
|
"etag": "\"1d98-cDZfMibtk4T04FTTAmlfhWDpkN0\"",
|
|
23653
|
-
"mtime": "2026-04-
|
|
26448
|
+
"mtime": "2026-04-28T17:57:48.318Z",
|
|
23654
26449
|
"size": 7576,
|
|
23655
26450
|
"path": "../public/_fonts/NdzqRASp2bovDUhQT1IRE_EMqKJ2KYQdTCfFcBvL8yw-KhwZiS86o3fErOe5GGMExHUemmI_dBfaEFxjISZrBd0.woff2"
|
|
23656
26451
|
},
|
|
23657
26452
|
"/_fonts/iTkrULNFJJkTvihIg1Vqi5IODRH_9btXCioVF5l98I8-AndUyau2HR2felA_ra8V2mutQgschhasE5FD1dXGJX8.woff2": {
|
|
23658
26453
|
"type": "font/woff2",
|
|
23659
26454
|
"etag": "\"47c4-5xyngHnzzhetUee74tMx9OTgqNQ\"",
|
|
23660
|
-
"mtime": "2026-04-
|
|
26455
|
+
"mtime": "2026-04-28T17:57:48.318Z",
|
|
23661
26456
|
"size": 18372,
|
|
23662
26457
|
"path": "../public/_fonts/iTkrULNFJJkTvihIg1Vqi5IODRH_9btXCioVF5l98I8-AndUyau2HR2felA_ra8V2mutQgschhasE5FD1dXGJX8.woff2"
|
|
23663
26458
|
},
|
|
23664
|
-
"/_nuxt/
|
|
26459
|
+
"/_nuxt/BZ8athzM.js": {
|
|
23665
26460
|
"type": "text/javascript; charset=utf-8",
|
|
23666
|
-
"etag": "\"
|
|
23667
|
-
"mtime": "2026-04-
|
|
23668
|
-
"size":
|
|
23669
|
-
"path": "../public/_nuxt/
|
|
26461
|
+
"etag": "\"d7b-bo5LDZYg8h0KJrRJjoz1tlPmdRo\"",
|
|
26462
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
26463
|
+
"size": 3451,
|
|
26464
|
+
"path": "../public/_nuxt/BZ8athzM.js"
|
|
23670
26465
|
},
|
|
23671
|
-
"/_nuxt/
|
|
26466
|
+
"/_nuxt/CiSdBjBt.js": {
|
|
23672
26467
|
"type": "text/javascript; charset=utf-8",
|
|
23673
|
-
"etag": "\"e99-
|
|
23674
|
-
"mtime": "2026-04-
|
|
26468
|
+
"etag": "\"e99-9LMfGEEWjCGZ3Oa0GdbKNntD/tc\"",
|
|
26469
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
23675
26470
|
"size": 3737,
|
|
23676
|
-
"path": "../public/_nuxt/
|
|
26471
|
+
"path": "../public/_nuxt/CiSdBjBt.js"
|
|
23677
26472
|
},
|
|
23678
|
-
"/_nuxt/
|
|
26473
|
+
"/_nuxt/Vt66r6sN.js": {
|
|
23679
26474
|
"type": "text/javascript; charset=utf-8",
|
|
23680
|
-
"etag": "\"1df7-
|
|
23681
|
-
"mtime": "2026-04-
|
|
26475
|
+
"etag": "\"1df7-3bELG1uFN8suLzh1cLFlZbYl6zg\"",
|
|
26476
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
23682
26477
|
"size": 7671,
|
|
23683
|
-
"path": "../public/_nuxt/
|
|
23684
|
-
},
|
|
23685
|
-
"/_nuxt/DSWYWRXT.js": {
|
|
23686
|
-
"type": "text/javascript; charset=utf-8",
|
|
23687
|
-
"etag": "\"10875-8b+YwIvP6QkcBFnHXqxd+WeZ05o\"",
|
|
23688
|
-
"mtime": "2026-04-12T18:58:38.510Z",
|
|
23689
|
-
"size": 67701,
|
|
23690
|
-
"path": "../public/_nuxt/DSWYWRXT.js"
|
|
26478
|
+
"path": "../public/_nuxt/Vt66r6sN.js"
|
|
23691
26479
|
},
|
|
23692
|
-
"/_nuxt/
|
|
26480
|
+
"/_nuxt/B6ti3873.js": {
|
|
23693
26481
|
"type": "text/javascript; charset=utf-8",
|
|
23694
|
-
"etag": "\"194dc-
|
|
23695
|
-
"mtime": "2026-04-
|
|
26482
|
+
"etag": "\"194dc-0jLXXucZxinj1WIeQALJhFSiqBM\"",
|
|
26483
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
23696
26484
|
"size": 103644,
|
|
23697
|
-
"path": "../public/_nuxt/
|
|
26485
|
+
"path": "../public/_nuxt/B6ti3873.js"
|
|
23698
26486
|
},
|
|
23699
|
-
"/_nuxt/
|
|
26487
|
+
"/_nuxt/BuJvZwTh.js": {
|
|
23700
26488
|
"type": "text/javascript; charset=utf-8",
|
|
23701
|
-
"etag": "\"
|
|
23702
|
-
"mtime": "2026-04-
|
|
23703
|
-
"size":
|
|
23704
|
-
"path": "../public/_nuxt/
|
|
26489
|
+
"etag": "\"10875-jI7p7PC8XYTrsiB6P1KTm9OW02I\"",
|
|
26490
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
26491
|
+
"size": 67701,
|
|
26492
|
+
"path": "../public/_nuxt/BuJvZwTh.js"
|
|
23705
26493
|
},
|
|
23706
26494
|
"/_nuxt/_id_.DhlLK-mY.css": {
|
|
23707
26495
|
"type": "text/css; charset=utf-8",
|
|
23708
26496
|
"etag": "\"2f4-xtV37kE566jU74wpZnFHA29RoAY\"",
|
|
23709
|
-
"mtime": "2026-04-
|
|
26497
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
23710
26498
|
"size": 756,
|
|
23711
26499
|
"path": "../public/_nuxt/_id_.DhlLK-mY.css"
|
|
23712
26500
|
},
|
|
26501
|
+
"/_nuxt/D_Ecm3JY.js": {
|
|
26502
|
+
"type": "text/javascript; charset=utf-8",
|
|
26503
|
+
"etag": "\"ab-OTrt3/Pw7AlxGhPlIrQjGFjRSR4\"",
|
|
26504
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
26505
|
+
"size": 171,
|
|
26506
|
+
"path": "../public/_nuxt/D_Ecm3JY.js"
|
|
26507
|
+
},
|
|
23713
26508
|
"/_nuxt/error-404.C7fg894-.css": {
|
|
23714
26509
|
"type": "text/css; charset=utf-8",
|
|
23715
26510
|
"etag": "\"97e-fiQ3o7A11L9BuXRBr0GJldkx0AU\"",
|
|
23716
|
-
"mtime": "2026-04-
|
|
26511
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
23717
26512
|
"size": 2430,
|
|
23718
26513
|
"path": "../public/_nuxt/error-404.C7fg894-.css"
|
|
23719
26514
|
},
|
|
23720
26515
|
"/_nuxt/error-500.DjUK_N2Y.css": {
|
|
23721
26516
|
"type": "text/css; charset=utf-8",
|
|
23722
26517
|
"etag": "\"773-Qf61bSDos4KtmZDaA06FmZyUYNo\"",
|
|
23723
|
-
"mtime": "2026-04-
|
|
26518
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
23724
26519
|
"size": 1907,
|
|
23725
26520
|
"path": "../public/_nuxt/error-500.DjUK_N2Y.css"
|
|
23726
26521
|
},
|
|
23727
26522
|
"/_nuxt/builds/latest.json": {
|
|
23728
26523
|
"type": "application/json",
|
|
23729
|
-
"etag": "\"47-
|
|
23730
|
-
"mtime": "2026-04-
|
|
26524
|
+
"etag": "\"47-TQX72Swoa7t4jw5HcBGsQR8FzY0\"",
|
|
26525
|
+
"mtime": "2026-04-28T17:57:48.316Z",
|
|
23731
26526
|
"size": 71,
|
|
23732
26527
|
"path": "../public/_nuxt/builds/latest.json"
|
|
23733
26528
|
},
|
|
23734
|
-
"/_nuxt/builds/meta/
|
|
26529
|
+
"/_nuxt/builds/meta/6152dcdc-6d3b-4e0a-8c56-4584c72c8765.json": {
|
|
23735
26530
|
"type": "application/json",
|
|
23736
|
-
"etag": "\"58-
|
|
23737
|
-
"mtime": "2026-04-
|
|
26531
|
+
"etag": "\"58-d/z3J0a3FmSy2TB7Una/XGJcn94\"",
|
|
26532
|
+
"mtime": "2026-04-28T17:57:48.314Z",
|
|
23738
26533
|
"size": 88,
|
|
23739
|
-
"path": "../public/_nuxt/builds/meta/
|
|
23740
|
-
},
|
|
23741
|
-
"/_nuxt/BUmYUDQu.js": {
|
|
23742
|
-
"type": "text/javascript; charset=utf-8",
|
|
23743
|
-
"etag": "\"66cba-d/pdEXVc78H3VlgFN3kVzKpvD1Q\"",
|
|
23744
|
-
"mtime": "2026-04-12T18:58:38.510Z",
|
|
23745
|
-
"size": 421050,
|
|
23746
|
-
"path": "../public/_nuxt/BUmYUDQu.js"
|
|
26534
|
+
"path": "../public/_nuxt/builds/meta/6152dcdc-6d3b-4e0a-8c56-4584c72c8765.json"
|
|
23747
26535
|
},
|
|
23748
26536
|
"/_nuxt/entry.Y3mA4bzA.css": {
|
|
23749
26537
|
"type": "text/css; charset=utf-8",
|
|
23750
26538
|
"etag": "\"2d46b-zfrD3Ny9WW6qm4fCXAfX5eIAxPA\"",
|
|
23751
|
-
"mtime": "2026-04-
|
|
26539
|
+
"mtime": "2026-04-28T17:57:48.321Z",
|
|
23752
26540
|
"size": 185451,
|
|
23753
26541
|
"path": "../public/_nuxt/entry.Y3mA4bzA.css"
|
|
26542
|
+
},
|
|
26543
|
+
"/_nuxt/bOjQRRUc.js": {
|
|
26544
|
+
"type": "text/javascript; charset=utf-8",
|
|
26545
|
+
"etag": "\"66cba-ROXbp6pQG1qRn50SMispE0HMqw0\"",
|
|
26546
|
+
"mtime": "2026-04-28T17:57:48.322Z",
|
|
26547
|
+
"size": 421050,
|
|
26548
|
+
"path": "../public/_nuxt/bOjQRRUc.js"
|
|
23754
26549
|
}
|
|
23755
26550
|
};
|
|
23756
26551
|
|
|
@@ -23892,7 +26687,7 @@ function getAsset (id) {
|
|
|
23892
26687
|
|
|
23893
26688
|
const METHODS = /* @__PURE__ */ new Set(["HEAD", "GET"]);
|
|
23894
26689
|
const EncodingMap = { gzip: ".gz", br: ".br" };
|
|
23895
|
-
const
|
|
26690
|
+
const _nP7_Js = eventHandler((event) => {
|
|
23896
26691
|
if (event.method && !METHODS.has(event.method)) {
|
|
23897
26692
|
return;
|
|
23898
26693
|
}
|
|
@@ -23960,7 +26755,7 @@ const BEARER_PREFIX_RE = /^Bearer[ \t]+/i;
|
|
|
23960
26755
|
function isMcpPath(pathname) {
|
|
23961
26756
|
return pathname === "/mcp" || pathname.startsWith("/mcp/");
|
|
23962
26757
|
}
|
|
23963
|
-
const
|
|
26758
|
+
const _VsXl2a = defineEventHandler(async (event) => {
|
|
23964
26759
|
var _a, _b;
|
|
23965
26760
|
if (!isMcpPath(event.path))
|
|
23966
26761
|
return;
|
|
@@ -24297,7 +27092,7 @@ const collections = {
|
|
|
24297
27092
|
};
|
|
24298
27093
|
|
|
24299
27094
|
const DEFAULT_ENDPOINT = "https://api.iconify.design";
|
|
24300
|
-
const
|
|
27095
|
+
const _07evdj = defineCachedEventHandler(async (event) => {
|
|
24301
27096
|
const url = getRequestURL(event);
|
|
24302
27097
|
if (!url)
|
|
24303
27098
|
return createError$1({ status: 400, message: "Invalid icon request" });
|
|
@@ -24347,57 +27142,57 @@ const _qZilHW = defineCachedEventHandler(async (event) => {
|
|
|
24347
27142
|
// 1 week
|
|
24348
27143
|
});
|
|
24349
27144
|
|
|
24350
|
-
const
|
|
24351
|
-
const
|
|
24352
|
-
const
|
|
24353
|
-
const
|
|
24354
|
-
const
|
|
24355
|
-
const
|
|
24356
|
-
const
|
|
24357
|
-
const
|
|
24358
|
-
const
|
|
24359
|
-
const
|
|
24360
|
-
const
|
|
24361
|
-
const
|
|
24362
|
-
const
|
|
24363
|
-
const
|
|
24364
|
-
const
|
|
24365
|
-
const
|
|
24366
|
-
const
|
|
24367
|
-
const
|
|
24368
|
-
const
|
|
24369
|
-
const
|
|
24370
|
-
const
|
|
24371
|
-
const
|
|
27145
|
+
const _lazy_rQMQx5 = () => import('../routes/api/_commandable/status.get.mjs');
|
|
27146
|
+
const _lazy__doBUX = () => import('../routes/api/catalog.get.mjs');
|
|
27147
|
+
const _lazy_u4B20q = () => import('../routes/api/catalog/_type/tools.get.mjs');
|
|
27148
|
+
const _lazy_029V4o = () => import('../routes/api/catalog/_type/toolsets.get.mjs');
|
|
27149
|
+
const _lazy_azzc35 = () => import('../routes/api/integrations/_id_.delete.mjs');
|
|
27150
|
+
const _lazy_gWcuQ4 = () => import('../routes/api/integrations/_id/credentials-config.get.mjs');
|
|
27151
|
+
const _lazy_n3SXvL = () => import('../routes/api/integrations/_id/credentials-status.get.mjs');
|
|
27152
|
+
const _lazy_1ybFiB = () => import('../routes/api/integrations/_id/credentials.delete.mjs');
|
|
27153
|
+
const _lazy_Aos7tC = () => import('../routes/api/integrations/_id/credentials.post.mjs');
|
|
27154
|
+
const _lazy_Gup8dS = () => import('../routes/api/integrations/_id/permissions.post.mjs');
|
|
27155
|
+
const _lazy_4NNYku = () => import('../routes/api/integrations/_id/tools.delete.mjs');
|
|
27156
|
+
const _lazy_26WqJh = () => import('../routes/api/integrations/_id/tools.get.mjs');
|
|
27157
|
+
const _lazy_vPm_0i = () => import('../routes/api/integrations/_id/toolsets.get.mjs');
|
|
27158
|
+
const _lazy_5oSjkc = () => import('../routes/api/integrations/_id/toolsets.post.mjs');
|
|
27159
|
+
const _lazy_HaRaH2 = () => import('../routes/api/integrations/_id/variant-options.post.mjs');
|
|
27160
|
+
const _lazy_xaif49 = () => import('../routes/api/index.get.mjs');
|
|
27161
|
+
const _lazy_JZIC7v = () => import('../routes/api/index.post.mjs');
|
|
27162
|
+
const _lazy_jGrRMD = () => import('../routes/health.get.mjs');
|
|
27163
|
+
const _lazy_o0bRnv = () => import('../routes/mcp.mjs');
|
|
27164
|
+
const _lazy_nXZgsW = () => import('../routes/mcp/create.mjs');
|
|
27165
|
+
const _lazy_ArDuzZ = () => import('../routes/mcp/static.mjs');
|
|
27166
|
+
const _lazy_FEvF4o = () => import('../routes/renderer.mjs').then(function (n) { return n.r; });
|
|
24372
27167
|
|
|
24373
27168
|
const handlers = [
|
|
24374
|
-
{ route: '', handler:
|
|
24375
|
-
{ route: '', handler:
|
|
24376
|
-
{ route: '/api/_commandable/status', handler:
|
|
24377
|
-
{ route: '/api/catalog', handler:
|
|
24378
|
-
{ route: '/api/catalog/:type/tools', handler:
|
|
24379
|
-
{ route: '/api/catalog/:type/toolsets', handler:
|
|
24380
|
-
{ route: '/api/integrations/:id', handler:
|
|
24381
|
-
{ route: '/api/integrations/:id/credentials-config', handler:
|
|
24382
|
-
{ route: '/api/integrations/:id/credentials-status', handler:
|
|
24383
|
-
{ route: '/api/integrations/:id/credentials', handler:
|
|
24384
|
-
{ route: '/api/integrations/:id/credentials', handler:
|
|
24385
|
-
{ route: '/api/integrations/:id/permissions', handler:
|
|
24386
|
-
{ route: '/api/integrations/:id/tools', handler:
|
|
24387
|
-
{ route: '/api/integrations/:id/tools', handler:
|
|
24388
|
-
{ route: '/api/integrations/:id/toolsets', handler:
|
|
24389
|
-
{ route: '/api/integrations/:id/toolsets', handler:
|
|
24390
|
-
{ route: '/api/integrations/:id/variant-options', handler:
|
|
24391
|
-
{ route: '/api/integrations', handler:
|
|
24392
|
-
{ route: '/api/integrations', handler:
|
|
24393
|
-
{ route: '/health', handler:
|
|
24394
|
-
{ route: '/mcp', handler:
|
|
24395
|
-
{ route: '/mcp/create', handler:
|
|
24396
|
-
{ route: '/mcp/static', handler:
|
|
24397
|
-
{ route: '/__nuxt_error', handler:
|
|
27169
|
+
{ route: '', handler: _nP7_Js, lazy: false, middleware: true, method: undefined },
|
|
27170
|
+
{ route: '', handler: _VsXl2a, lazy: false, middleware: true, method: undefined },
|
|
27171
|
+
{ route: '/api/_commandable/status', handler: _lazy_rQMQx5, lazy: true, middleware: false, method: "get" },
|
|
27172
|
+
{ route: '/api/catalog', handler: _lazy__doBUX, lazy: true, middleware: false, method: "get" },
|
|
27173
|
+
{ route: '/api/catalog/:type/tools', handler: _lazy_u4B20q, lazy: true, middleware: false, method: "get" },
|
|
27174
|
+
{ route: '/api/catalog/:type/toolsets', handler: _lazy_029V4o, lazy: true, middleware: false, method: "get" },
|
|
27175
|
+
{ route: '/api/integrations/:id', handler: _lazy_azzc35, lazy: true, middleware: false, method: "delete" },
|
|
27176
|
+
{ route: '/api/integrations/:id/credentials-config', handler: _lazy_gWcuQ4, lazy: true, middleware: false, method: "get" },
|
|
27177
|
+
{ route: '/api/integrations/:id/credentials-status', handler: _lazy_n3SXvL, lazy: true, middleware: false, method: "get" },
|
|
27178
|
+
{ route: '/api/integrations/:id/credentials', handler: _lazy_1ybFiB, lazy: true, middleware: false, method: "delete" },
|
|
27179
|
+
{ route: '/api/integrations/:id/credentials', handler: _lazy_Aos7tC, lazy: true, middleware: false, method: "post" },
|
|
27180
|
+
{ route: '/api/integrations/:id/permissions', handler: _lazy_Gup8dS, lazy: true, middleware: false, method: "post" },
|
|
27181
|
+
{ route: '/api/integrations/:id/tools', handler: _lazy_4NNYku, lazy: true, middleware: false, method: "delete" },
|
|
27182
|
+
{ route: '/api/integrations/:id/tools', handler: _lazy_26WqJh, lazy: true, middleware: false, method: "get" },
|
|
27183
|
+
{ route: '/api/integrations/:id/toolsets', handler: _lazy_vPm_0i, lazy: true, middleware: false, method: "get" },
|
|
27184
|
+
{ route: '/api/integrations/:id/toolsets', handler: _lazy_5oSjkc, lazy: true, middleware: false, method: "post" },
|
|
27185
|
+
{ route: '/api/integrations/:id/variant-options', handler: _lazy_HaRaH2, lazy: true, middleware: false, method: "post" },
|
|
27186
|
+
{ route: '/api/integrations', handler: _lazy_xaif49, lazy: true, middleware: false, method: "get" },
|
|
27187
|
+
{ route: '/api/integrations', handler: _lazy_JZIC7v, lazy: true, middleware: false, method: "post" },
|
|
27188
|
+
{ route: '/health', handler: _lazy_jGrRMD, lazy: true, middleware: false, method: "get" },
|
|
27189
|
+
{ route: '/mcp', handler: _lazy_o0bRnv, lazy: true, middleware: false, method: undefined },
|
|
27190
|
+
{ route: '/mcp/create', handler: _lazy_nXZgsW, lazy: true, middleware: false, method: undefined },
|
|
27191
|
+
{ route: '/mcp/static', handler: _lazy_ArDuzZ, lazy: true, middleware: false, method: undefined },
|
|
27192
|
+
{ route: '/__nuxt_error', handler: _lazy_FEvF4o, lazy: true, middleware: false, method: undefined },
|
|
24398
27193
|
{ route: '/__nuxt_island/**', handler: _SxA8c9, lazy: false, middleware: false, method: undefined },
|
|
24399
|
-
{ route: '/api/_nuxt_icon/:collection', handler:
|
|
24400
|
-
{ route: '/**', handler:
|
|
27194
|
+
{ route: '/api/_nuxt_icon/:collection', handler: _07evdj, lazy: false, middleware: false, method: undefined },
|
|
27195
|
+
{ route: '/**', handler: _lazy_FEvF4o, lazy: true, middleware: false, method: undefined }
|
|
24401
27196
|
];
|
|
24402
27197
|
|
|
24403
27198
|
function createNitroApp() {
|