@codemill-solutions/yuki-mcp 1.0.0

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.
@@ -0,0 +1,269 @@
1
+ import { z } from "zod";
2
+ import { readFileSync, existsSync } from "fs";
3
+ import { basename } from "path";
4
+ /**
5
+ * Register tools for uploading documents to the Yuki archive.
6
+ *
7
+ * The Yuki Archive service stores source documents (PDFs) alongside
8
+ * their financial data. Attaching a PDF to a purchase invoice is
9
+ * strongly recommended for audit compliance.
10
+ *
11
+ * Yuki service: Archive.asmx
12
+ * Method: UploadDocumentWithData(sessionID, fileName, data, folder,
13
+ * administrationID, currency, amount,
14
+ * costCategory, paymentMethod, project, remarks)
15
+ *
16
+ * Note: Archive.asmx uses sessionID / administrationID (uppercase D).
17
+ */
18
+ export function registerDocumentTools(server, client) {
19
+ /**
20
+ * upload_document
21
+ *
22
+ * Upload a PDF (or other document) to the Yuki archive with optional
23
+ * financial metadata. This is the recommended way to attach source
24
+ * documents to purchase invoices in Yuki.
25
+ *
26
+ * Use this when:
27
+ * - A purchase invoice PDF needs to be stored in Yuki's archive
28
+ * - You want Yuki to process the document automatically (OCR)
29
+ * - Attaching supporting documents (receipts, bank statements) to bookings
30
+ *
31
+ * Folder IDs (use get_document_folders to retrieve the full list):
32
+ * - Common folders: purchase invoices, bank statements, general
33
+ *
34
+ * Rate cost: 1 request.
35
+ */
36
+ server.registerTool("upload_document", {
37
+ description: "Upload a document (PDF) to the Yuki archive with financial metadata. " +
38
+ "Use this to attach source documents to purchase invoices or store receipts. " +
39
+ "The document must be provided as a base64-encoded string. " +
40
+ "Call get_document_folders first to find the correct folder ID.",
41
+ inputSchema: {
42
+ fileName: z.string()
43
+ .describe("File name including extension (e.g. 'invoice-2024-0042.pdf')"),
44
+ dataBase64: z.string()
45
+ .describe("File content encoded as a base64 string"),
46
+ folder: z.number().int().optional()
47
+ .describe("Archive folder ID. Use get_document_folders to list available folders."),
48
+ currency: z.string().optional().default("EUR")
49
+ .describe("ISO 4217 currency code for the document amount"),
50
+ amount: z.number().optional()
51
+ .describe("Total amount on the document (e.g. invoice total including VAT)"),
52
+ costCategory: z.string().optional()
53
+ .describe("GL account code for automatic cost categorisation (e.g. '4000')"),
54
+ paymentMethod: z.number().int().optional()
55
+ .describe("Payment method code. 0 = unknown, 1 = transfer, 2 = direct collection"),
56
+ project: z.string().optional()
57
+ .describe("Project code to link this document to a Yuki project"),
58
+ remarks: z.string().optional()
59
+ .describe("Internal remarks shown in the archive"),
60
+ administrationId: z.string().optional()
61
+ .describe("Administration ID (GUID). Defaults to YUKI_DOMAIN_ID env var."),
62
+ },
63
+ }, async ({ fileName, dataBase64, folder, currency, amount, costCategory, paymentMethod, project, remarks, administrationId }) => {
64
+ try {
65
+ const adminId = administrationId ?? client.defaultDomainId;
66
+ if (!adminId) {
67
+ throw new Error("administrationId is required (or set YUKI_DOMAIN_ID env var)");
68
+ }
69
+ const sessionID = await client.getSessionID();
70
+ // Archive.asmx uses sessionID / administrationID (uppercase D)
71
+ const result = await client.callSoap({
72
+ service: "Archive.asmx",
73
+ method: "UploadDocumentWithData",
74
+ params: {
75
+ sessionID,
76
+ fileName,
77
+ data: dataBase64,
78
+ ...(folder !== undefined && { folder }),
79
+ administrationID: adminId,
80
+ currency: currency ?? "EUR",
81
+ ...(amount !== undefined && { amount }),
82
+ ...(costCategory !== undefined && { costCategory }),
83
+ ...(paymentMethod !== undefined && { paymentMethod }),
84
+ ...(project !== undefined && { project }),
85
+ ...(remarks !== undefined && { remarks }),
86
+ },
87
+ });
88
+ return {
89
+ content: [
90
+ {
91
+ type: "text",
92
+ text: JSON.stringify({ success: true, fileName, result }, null, 2),
93
+ },
94
+ ],
95
+ };
96
+ }
97
+ catch (err) {
98
+ const message = err instanceof Error ? err.message : String(err);
99
+ return {
100
+ content: [
101
+ {
102
+ type: "text",
103
+ text: JSON.stringify({ success: false, error: message }, null, 2),
104
+ },
105
+ ],
106
+ isError: true,
107
+ };
108
+ }
109
+ });
110
+ /**
111
+ * upload_document_from_path
112
+ *
113
+ * Upload a PDF from the local filesystem to the Yuki archive.
114
+ * Reads the file at filePath, converts it to base64 internally, and
115
+ * calls UploadDocumentWithData — avoiding the need to pass large base64
116
+ * strings through the MCP context.
117
+ *
118
+ * Rate cost: 1 request.
119
+ */
120
+ server.registerTool("upload_document_from_path", {
121
+ description: "Upload a PDF from a local file path to the Yuki archive. " +
122
+ "Reads and encodes the file internally — no need to pass base64 strings. " +
123
+ "Use this instead of upload_document when the file is available on disk. " +
124
+ "Call get_document_folders first to find the correct folder ID.",
125
+ inputSchema: {
126
+ filePath: z.string()
127
+ .describe("Absolute path to the file on the local filesystem (e.g. '/tmp/invoice-2024-0042.pdf')"),
128
+ fileName: z.string().optional()
129
+ .describe("Override the file name sent to Yuki. Defaults to the basename of filePath."),
130
+ folder: z.number().int().optional()
131
+ .describe("Archive folder ID. Use get_document_folders to list available folders."),
132
+ currency: z.string().optional().default("EUR")
133
+ .describe("ISO 4217 currency code for the document amount"),
134
+ amount: z.number().optional()
135
+ .describe("Total amount on the document (e.g. invoice total including VAT)"),
136
+ costCategory: z.string().optional()
137
+ .describe("GL account code for automatic cost categorisation (e.g. '4000')"),
138
+ paymentMethod: z.number().int().optional()
139
+ .describe("Payment method code. 0 = unknown, 1 = transfer, 2 = direct collection"),
140
+ project: z.string().optional()
141
+ .describe("Project code to link this document to a Yuki project"),
142
+ remarks: z.string().optional()
143
+ .describe("Internal remarks shown in the archive"),
144
+ administrationId: z.string().optional()
145
+ .describe("Administration ID (GUID). Defaults to YUKI_DOMAIN_ID env var."),
146
+ },
147
+ }, async ({ filePath, fileName, folder, currency, amount, costCategory, paymentMethod, project, remarks, administrationId }) => {
148
+ try {
149
+ const adminId = administrationId ?? client.defaultDomainId;
150
+ if (!adminId) {
151
+ throw new Error("administrationId is required (or set YUKI_DOMAIN_ID env var)");
152
+ }
153
+ // Validate file existence before making any API calls
154
+ if (!existsSync(filePath)) {
155
+ throw new Error(`File not found: ${filePath}`);
156
+ }
157
+ let fileBuffer;
158
+ try {
159
+ fileBuffer = readFileSync(filePath);
160
+ }
161
+ catch (readErr) {
162
+ throw new Error(`Cannot read file at ${filePath}: ${readErr instanceof Error ? readErr.message : String(readErr)}`);
163
+ }
164
+ // Check for PDF magic bytes (%PDF)
165
+ if (fileBuffer.length < 4 ||
166
+ fileBuffer[0] !== 0x25 || // %
167
+ fileBuffer[1] !== 0x50 || // P
168
+ fileBuffer[2] !== 0x44 || // D
169
+ fileBuffer[3] !== 0x46 // F
170
+ ) {
171
+ throw new Error(`File does not appear to be a PDF (missing %PDF header): ${filePath}`);
172
+ }
173
+ const resolvedFileName = fileName ?? basename(filePath);
174
+ const dataBase64 = fileBuffer.toString("base64");
175
+ const sessionID = await client.getSessionID();
176
+ const result = await client.callSoap({
177
+ service: "Archive.asmx",
178
+ method: "UploadDocumentWithData",
179
+ params: {
180
+ sessionID,
181
+ fileName: resolvedFileName,
182
+ data: dataBase64,
183
+ ...(folder !== undefined && { folder }),
184
+ administrationID: adminId,
185
+ currency: currency ?? "EUR",
186
+ ...(amount !== undefined && { amount }),
187
+ ...(costCategory !== undefined && { costCategory }),
188
+ ...(paymentMethod !== undefined && { paymentMethod }),
189
+ ...(project !== undefined && { project }),
190
+ ...(remarks !== undefined && { remarks }),
191
+ },
192
+ });
193
+ return {
194
+ content: [
195
+ {
196
+ type: "text",
197
+ text: JSON.stringify({ success: true, filePath, fileName: resolvedFileName,
198
+ fileSizeBytes: fileBuffer.length, result }, null, 2),
199
+ },
200
+ ],
201
+ };
202
+ }
203
+ catch (err) {
204
+ const message = err instanceof Error ? err.message : String(err);
205
+ return {
206
+ content: [
207
+ {
208
+ type: "text",
209
+ text: JSON.stringify({ success: false, error: message }, null, 2),
210
+ },
211
+ ],
212
+ isError: true,
213
+ };
214
+ }
215
+ });
216
+ /**
217
+ * get_document_folders
218
+ *
219
+ * List all archive folders available in this Yuki administration.
220
+ * Use this to find the correct folder ID before calling upload_document.
221
+ *
222
+ * Rate cost: 1 request.
223
+ */
224
+ server.registerTool("get_document_folders", {
225
+ description: "List all archive folders in the Yuki administration. " +
226
+ "Use this to find the correct folder ID to pass to upload_document.",
227
+ inputSchema: {
228
+ administrationId: z.string().optional()
229
+ .describe("Administration ID (GUID). Defaults to YUKI_DOMAIN_ID env var."),
230
+ },
231
+ }, async ({ administrationId }) => {
232
+ try {
233
+ const adminId = administrationId ?? client.defaultDomainId;
234
+ if (!adminId) {
235
+ throw new Error("administrationId is required (or set YUKI_DOMAIN_ID env var)");
236
+ }
237
+ const sessionID = await client.getSessionID();
238
+ const result = await client.callSoap({
239
+ service: "Archive.asmx",
240
+ method: "DocumentFolders",
241
+ params: {
242
+ sessionID,
243
+ administrationID: adminId,
244
+ },
245
+ });
246
+ return {
247
+ content: [
248
+ {
249
+ type: "text",
250
+ text: JSON.stringify({ success: true, result }, null, 2),
251
+ },
252
+ ],
253
+ };
254
+ }
255
+ catch (err) {
256
+ const message = err instanceof Error ? err.message : String(err);
257
+ return {
258
+ content: [
259
+ {
260
+ type: "text",
261
+ text: JSON.stringify({ success: false, error: message }, null, 2),
262
+ },
263
+ ],
264
+ isError: true,
265
+ };
266
+ }
267
+ });
268
+ }
269
+ //# sourceMappingURL=documents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.js","sourceRoot":"","sources":["../../src/tools/documents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { YukiClient } from "../yuki-client.js";
3
+ /**
4
+ * Register tools for retrieving outstanding invoices from Yuki.
5
+ *
6
+ * Note: The Yuki SOAP API exposes outstanding (open) invoice items via
7
+ * the Accounting service. Full invoice history with date-range filtering
8
+ * is not available via SOAP — use the Yuki web interface or the
9
+ * ProcessSalesInvoices/ProcessPurchaseInvoices methods for write operations.
10
+ *
11
+ * Sales receivables: OutstandingDebtorItems
12
+ * Purchase payables: OutstandingCreditorItems
13
+ *
14
+ * Yuki service: Accounting.asmx
15
+ */
16
+ export declare function registerInvoiceTools(server: McpServer, client: YukiClient): void;
17
+ /**
18
+ * Register the write tools for sales and purchase invoices.
19
+ * Called from registerInvoiceTools — same server/client instance.
20
+ */
21
+ export declare function registerInvoiceWriteTools(server: McpServer, client: YukiClient): void;
22
+ //# sourceMappingURL=invoices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoices.d.ts","sourceRoot":"","sources":["../../src/tools/invoices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAuB,MAAM,mBAAmB,CAAC;AAEpE;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,UAAU,GACjB,IAAI,CAsPN;AA0BD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,UAAU,GACjB,IAAI,CA8KN"}