@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,72 @@
1
+ /**
2
+ * Wraps a raw XML string so it is embedded directly into the SOAP body
3
+ * without being HTML-entity-encoded.
4
+ *
5
+ * Use this for the `xmlDoc` parameter of ProcessSalesInvoices,
6
+ * ProcessPurchaseInvoices, ProcessJournal, UpdateContact, etc.
7
+ *
8
+ * @example
9
+ * params: { sessionId: sid, xmlDoc: new XmlValue('<Root>...</Root>') }
10
+ */
11
+ export declare class XmlValue {
12
+ readonly xml: string;
13
+ constructor(xml: string);
14
+ }
15
+ export type SoapParamValue = string | number | boolean | XmlValue | undefined;
16
+ export interface SoapCallOptions {
17
+ /** Filename of the ASMX service, e.g. "Accounting.asmx" */
18
+ service: string;
19
+ /** SOAP method name, e.g. "GLAccountTransactions" */
20
+ method: string;
21
+ /** Key-value pairs serialised as child XML elements inside the method element */
22
+ params: Record<string, SoapParamValue>;
23
+ }
24
+ export declare class YukiClient {
25
+ private readonly apiKey;
26
+ private readonly domainId;
27
+ private readonly parser;
28
+ /** Cached session ID obtained from Authenticate — reused across calls. */
29
+ private cachedSessionID;
30
+ constructor(apiKey: string, domainId: string);
31
+ /**
32
+ * Return a valid Yuki session ID, authenticating if needed.
33
+ *
34
+ * Yuki uses a two-step auth flow:
35
+ * 1. POST Authenticate(accessKey) → returns a temporary sessionID string
36
+ * 2. Pass that sessionID in all subsequent SOAP calls
37
+ *
38
+ * The session ID is cached for the lifetime of this process.
39
+ * On session expiry (SOAP fault) callers should catch the error, reset
40
+ * the cache via invalidateSession(), and retry.
41
+ */
42
+ getSessionID(): Promise<string>;
43
+ /** Clear the cached session so the next call re-authenticates. */
44
+ invalidateSession(): void;
45
+ /** The default domain / administration ID from the environment. */
46
+ get defaultDomainId(): string;
47
+ /** Build a SOAP 1.1 envelope around the given method body. */
48
+ private buildSoapEnvelope;
49
+ /**
50
+ * Serialise a params object to sibling XML elements, skipping undefined/empty values.
51
+ * - XmlValue instances are embedded as raw XML (no escaping).
52
+ * - All other values are XML-escaped to prevent injection.
53
+ */
54
+ private serializeParams;
55
+ /**
56
+ * Execute a SOAP call against a Yuki web service.
57
+ *
58
+ * Returns the parsed inner content of `<{method}Result>`, or the full
59
+ * `<{method}Response>` when no Result wrapper is present.
60
+ *
61
+ * Throws a descriptive Error on SOAP faults or HTTP errors.
62
+ */
63
+ callSoap(options: SoapCallOptions): Promise<unknown>;
64
+ /** Parse a SOAP fault string from raw XML, returning null if none found. */
65
+ private extractSoapFault;
66
+ }
67
+ /**
68
+ * Escape special XML characters in a plain-text value.
69
+ * Always call this before embedding user-supplied strings inside XML.
70
+ */
71
+ export declare function escapeXml(str: string): string;
72
+ //# sourceMappingURL=yuki-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yuki-client.d.ts","sourceRoot":"","sources":["../src/yuki-client.ts"],"names":[],"mappings":"AAwBA;;;;;;;;;GASG;AACH,qBAAa,QAAQ;IACP,QAAQ,CAAC,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CACjC;AAED,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,OAAO,GACP,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,WAAW,eAAe;IAC9B,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACxC;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IAEnC,0EAA0E;IAC1E,OAAO,CAAC,eAAe,CAAuB;gBAElC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAe5C;;;;;;;;;;OAUG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAoBrC,kEAAkE;IAClE,iBAAiB,IAAI,IAAI;IAIzB,mEAAmE;IACnE,IAAI,eAAe,IAAI,MAAM,CAE5B;IAID,8DAA8D;IAC9D,OAAO,CAAC,iBAAiB;IAczB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAYvB;;;;;;;OAOG;IACG,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IA0D1D,4EAA4E;IAC5E,OAAO,CAAC,gBAAgB;CAoBzB;AAID;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7C"}
@@ -0,0 +1,227 @@
1
+ import axios from "axios";
2
+ import { XMLParser } from "fast-xml-parser";
3
+ // Confirmed via WSDL inspection of api.yukiworks.nl
4
+ const YUKI_BASE_URL = "https://api.yukiworks.nl/ws/";
5
+ const YUKI_NAMESPACE = "http://www.theyukicompany.com/";
6
+ // Tags that should always be treated as arrays even when there is only one element
7
+ const ALWAYS_ARRAY_TAGS = new Set([
8
+ "Administration",
9
+ "SalesInvoice",
10
+ "PurchaseInvoice",
11
+ "Contact",
12
+ "Relation",
13
+ "Transaction",
14
+ "BankTransaction",
15
+ "GLAccount",
16
+ "DebtorItem",
17
+ "CreditorItem",
18
+ "InvoiceLine",
19
+ "Line",
20
+ "Row",
21
+ ]);
22
+ /**
23
+ * Wraps a raw XML string so it is embedded directly into the SOAP body
24
+ * without being HTML-entity-encoded.
25
+ *
26
+ * Use this for the `xmlDoc` parameter of ProcessSalesInvoices,
27
+ * ProcessPurchaseInvoices, ProcessJournal, UpdateContact, etc.
28
+ *
29
+ * @example
30
+ * params: { sessionId: sid, xmlDoc: new XmlValue('<Root>...</Root>') }
31
+ */
32
+ export class XmlValue {
33
+ xml;
34
+ constructor(xml) {
35
+ this.xml = xml;
36
+ }
37
+ }
38
+ export class YukiClient {
39
+ apiKey;
40
+ domainId;
41
+ parser;
42
+ /** Cached session ID obtained from Authenticate — reused across calls. */
43
+ cachedSessionID = null;
44
+ constructor(apiKey, domainId) {
45
+ this.apiKey = apiKey;
46
+ this.domainId = domainId;
47
+ this.parser = new XMLParser({
48
+ ignoreAttributes: false,
49
+ attributeNamePrefix: "@_",
50
+ // Strip namespace prefixes so we can address tags by their local name
51
+ removeNSPrefix: true,
52
+ parseAttributeValue: true,
53
+ parseTagValue: true,
54
+ // Force known collection tags to always be arrays
55
+ isArray: (tagName) => ALWAYS_ARRAY_TAGS.has(tagName),
56
+ });
57
+ }
58
+ /**
59
+ * Return a valid Yuki session ID, authenticating if needed.
60
+ *
61
+ * Yuki uses a two-step auth flow:
62
+ * 1. POST Authenticate(accessKey) → returns a temporary sessionID string
63
+ * 2. Pass that sessionID in all subsequent SOAP calls
64
+ *
65
+ * The session ID is cached for the lifetime of this process.
66
+ * On session expiry (SOAP fault) callers should catch the error, reset
67
+ * the cache via invalidateSession(), and retry.
68
+ */
69
+ async getSessionID() {
70
+ if (this.cachedSessionID)
71
+ return this.cachedSessionID;
72
+ const result = await this.callSoap({
73
+ service: "Accounting.asmx",
74
+ method: "Authenticate",
75
+ params: { accessKey: this.apiKey },
76
+ });
77
+ const sessionID = extractString(result);
78
+ if (!sessionID) {
79
+ throw new Error("Authenticate returned an empty session ID. Check your YUKI_API_KEY.");
80
+ }
81
+ this.cachedSessionID = sessionID;
82
+ return sessionID;
83
+ }
84
+ /** Clear the cached session so the next call re-authenticates. */
85
+ invalidateSession() {
86
+ this.cachedSessionID = null;
87
+ }
88
+ /** The default domain / administration ID from the environment. */
89
+ get defaultDomainId() {
90
+ return this.domainId;
91
+ }
92
+ // ── Core SOAP plumbing ──────────────────────────────────────────────────────
93
+ /** Build a SOAP 1.1 envelope around the given method body. */
94
+ buildSoapEnvelope(method, paramsXml) {
95
+ return `<?xml version="1.0" encoding="utf-8"?>
96
+ <soap:Envelope
97
+ xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
98
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
99
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema">
100
+ <soap:Body>
101
+ <${method} xmlns="${YUKI_NAMESPACE}">
102
+ ${paramsXml}
103
+ </${method}>
104
+ </soap:Body>
105
+ </soap:Envelope>`;
106
+ }
107
+ /**
108
+ * Serialise a params object to sibling XML elements, skipping undefined/empty values.
109
+ * - XmlValue instances are embedded as raw XML (no escaping).
110
+ * - All other values are XML-escaped to prevent injection.
111
+ */
112
+ serializeParams(params) {
113
+ return Object.entries(params)
114
+ .filter(([, v]) => v !== undefined && v !== "")
115
+ .map(([key, v]) => {
116
+ if (v instanceof XmlValue) {
117
+ return `<${key}>${v.xml}</${key}>`;
118
+ }
119
+ return `<${key}>${escapeXml(String(v))}</${key}>`;
120
+ })
121
+ .join("\n ");
122
+ }
123
+ /**
124
+ * Execute a SOAP call against a Yuki web service.
125
+ *
126
+ * Returns the parsed inner content of `<{method}Result>`, or the full
127
+ * `<{method}Response>` when no Result wrapper is present.
128
+ *
129
+ * Throws a descriptive Error on SOAP faults or HTTP errors.
130
+ */
131
+ async callSoap(options) {
132
+ const { service, method, params } = options;
133
+ const url = `${YUKI_BASE_URL}${service}`;
134
+ const soapBody = this.buildSoapEnvelope(method, this.serializeParams(params));
135
+ const soapAction = `${YUKI_NAMESPACE}${method}`;
136
+ let responseData;
137
+ try {
138
+ const response = await axios.post(url, soapBody, {
139
+ headers: {
140
+ "Content-Type": "text/xml; charset=utf-8",
141
+ SOAPAction: `"${soapAction}"`,
142
+ },
143
+ timeout: 30_000,
144
+ responseType: "text",
145
+ });
146
+ responseData = response.data;
147
+ }
148
+ catch (err) {
149
+ if (axios.isAxiosError(err)) {
150
+ if (err.response?.data) {
151
+ const fault = this.extractSoapFault(err.response.data);
152
+ if (fault)
153
+ throw new Error(`SOAP Fault: ${fault}`);
154
+ throw new Error(`HTTP ${err.response.status} ${err.response.statusText} from ${url}`);
155
+ }
156
+ throw new Error(`Network error calling Yuki API: ${err.message}`);
157
+ }
158
+ throw err;
159
+ }
160
+ const parsed = this.parser.parse(responseData);
161
+ const body = parsed?.Envelope?.Body;
162
+ if (!body) {
163
+ throw new Error("Invalid SOAP response: missing <soap:Body>");
164
+ }
165
+ if (body["Fault"]) {
166
+ const fault = this.extractSoapFault(responseData);
167
+ throw new Error(`SOAP Fault: ${fault ?? "Unknown SOAP fault"}`);
168
+ }
169
+ // Unwrap <{method}Response><{method}Result> automatically
170
+ const responseKey = `${method}Response`;
171
+ const resultKey = `${method}Result`;
172
+ const methodResponse = body[responseKey];
173
+ if (methodResponse) {
174
+ return resultKey in methodResponse ? methodResponse[resultKey] : methodResponse;
175
+ }
176
+ return body;
177
+ }
178
+ /** Parse a SOAP fault string from raw XML, returning null if none found. */
179
+ extractSoapFault(xml) {
180
+ try {
181
+ const parsed = this.parser.parse(xml);
182
+ const body = parsed?.Envelope?.Body;
183
+ const fault = body?.Fault;
184
+ if (!fault)
185
+ return null;
186
+ // SOAP 1.1 faultstring
187
+ if (typeof fault["faultstring"] === "string")
188
+ return fault["faultstring"];
189
+ // SOAP 1.2 Reason/Text
190
+ const text = fault["Reason"]?.Text;
191
+ if (typeof text === "string")
192
+ return text;
193
+ return JSON.stringify(fault);
194
+ }
195
+ catch {
196
+ return null;
197
+ }
198
+ }
199
+ }
200
+ // ── Helpers ───────────────────────────────────────────────────────────────────
201
+ /**
202
+ * Escape special XML characters in a plain-text value.
203
+ * Always call this before embedding user-supplied strings inside XML.
204
+ */
205
+ export function escapeXml(str) {
206
+ return str
207
+ .replace(/&/g, "&amp;")
208
+ .replace(/</g, "&lt;")
209
+ .replace(/>/g, "&gt;")
210
+ .replace(/"/g, "&quot;")
211
+ .replace(/'/g, "&apos;");
212
+ }
213
+ /** Extract a plain string value from a parsed SOAP result (handles wrapping objects). */
214
+ function extractString(value) {
215
+ if (typeof value === "string")
216
+ return value.trim() || null;
217
+ if (typeof value === "number")
218
+ return String(value);
219
+ // fast-xml-parser sometimes wraps a text node in { "#text": "..." }
220
+ if (value && typeof value === "object") {
221
+ const text = value["#text"];
222
+ if (typeof text === "string")
223
+ return text.trim() || null;
224
+ }
225
+ return null;
226
+ }
227
+ //# sourceMappingURL=yuki-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yuki-client.js","sourceRoot":"","sources":["../src/yuki-client.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@codemill-solutions/yuki-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for the Yuki accounting SOAP API",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "start": "node dist/index.js",
14
+ "dev": "tsx src/index.ts",
15
+ "inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
16
+ "agent": "npx tsx scripts/test-agent.ts",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "publishConfig": {
20
+ "registry": "https://registry.npmjs.org",
21
+ "access": "public"
22
+ },
23
+ "dependencies": {
24
+ "@anthropic-ai/sdk": "^0.78.0",
25
+ "@modelcontextprotocol/sdk": "^1.10.1",
26
+ "axios": "^1.7.9",
27
+ "dotenv": "^16.4.7",
28
+ "fast-xml-parser": "^5.5.3",
29
+ "zod": "^3.24.1"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.10.10",
33
+ "prettier": "^3.8.1",
34
+ "tsx": "^4.19.2",
35
+ "typescript": "^5.7.3"
36
+ }
37
+ }