@codemill-solutions/yuki-mcp 1.4.0 → 1.5.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.
- package/README.md +16 -1
- package/dist/index.js +17 -25
- package/dist/index.js.map +1 -1
- package/dist/tools/administrations.d.ts +20 -0
- package/dist/tools/administrations.d.ts.map +1 -1
- package/dist/tools/administrations.js +80 -3
- package/dist/tools/administrations.js.map +1 -1
- package/dist/yuki-client.d.ts +40 -2
- package/dist/yuki-client.d.ts.map +1 -1
- package/dist/yuki-client.js +71 -2
- package/dist/yuki-client.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -120,9 +120,23 @@ When a keys file is present, `YUKI_API_KEY` becomes optional — the file keys a
|
|
|
120
120
|
|
|
121
121
|
If neither `YUKI_API_KEY` nor a keys file is found at startup, the server logs a warning but continues running — tools will return an error when called.
|
|
122
122
|
|
|
123
|
+
### Reloading keys at runtime
|
|
124
|
+
|
|
125
|
+
When a new key is generated externally — for example by a sibling MCP server that drives the Yuki Integraties UI to create a fresh API key for a new administration — the new entry only lands in `~/.yuki/api-keys.json`. By default the MCP server reads that file once at startup, so a freshly added key would require a server restart before it can be used for SOAP calls.
|
|
126
|
+
|
|
127
|
+
The **`reload_keys`** tool (see [Available tools](#available-tools-31) below) avoids this: it re-reads the keys file from disk and replaces the in-memory map in place. Sessions for keys that **changed** or were **removed** are evicted from the session cache automatically; sessions for unchanged keys stay warm so subsequent calls do not pay the re-authentication cost.
|
|
128
|
+
|
|
129
|
+
Typical flow for a sibling tool that has just minted a new key:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
1. (external) write the new key to ~/.yuki/api-keys.json
|
|
133
|
+
2. yuki-mcp.reload_keys() → { added: [<adminId>], updated: [], removed: [], total: N }
|
|
134
|
+
3. yuki-mcp.get_administrations → now works for the new admin without restart
|
|
135
|
+
```
|
|
136
|
+
|
|
123
137
|
---
|
|
124
138
|
|
|
125
|
-
## Available tools (
|
|
139
|
+
## Available tools (31)
|
|
126
140
|
|
|
127
141
|
### Administrations
|
|
128
142
|
|
|
@@ -130,6 +144,7 @@ If neither `YUKI_API_KEY` nor a keys file is found at startup, the server logs a
|
|
|
130
144
|
|------|-------------|
|
|
131
145
|
| `get_administrations` | List all administrations (companies) for this API key. **Run this first** to find the correct `administrationId`. |
|
|
132
146
|
| `get_administration_id` | Look up an administration's GUID by its exact name. Useful when you know the name but not the GUID. |
|
|
147
|
+
| `reload_keys` | Re-read the `administrationId → apiKey` JSON file from disk without restarting the server. Returns a diff of added/updated/removed IDs and invalidates affected sessions. Use after an external `create_api_key` flow. |
|
|
133
148
|
|
|
134
149
|
### Relations
|
|
135
150
|
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import 'dotenv/config';
|
|
2
|
-
import { readFileSync, existsSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
import { homedir } from 'os';
|
|
5
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
7
|
-
import { YukiClient } from './yuki-client.js';
|
|
4
|
+
import { YukiClient, loadApiKeysFile } from './yuki-client.js';
|
|
8
5
|
// Read tools
|
|
9
|
-
import { registerAdministrationTools, registerAdministrationLookupTools } from './tools/administrations.js';
|
|
6
|
+
import { registerAdministrationTools, registerAdministrationLookupTools, registerReloadKeysTools, } from './tools/administrations.js';
|
|
10
7
|
import { registerRelationTools } from './tools/relations.js';
|
|
11
8
|
import { registerInvoiceTools } from './tools/invoices.js';
|
|
12
9
|
import { registerTransactionTools } from './tools/transactions.js';
|
|
@@ -28,26 +25,20 @@ import { registerBackofficeTools } from './tools/backoffice.js';
|
|
|
28
25
|
// The file format is a plain JSON object:
|
|
29
26
|
// { "<administrationId>": "<apiKey>", ... }
|
|
30
27
|
//
|
|
31
|
-
// Path resolution
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
try {
|
|
41
|
-
const raw = JSON.parse(readFileSync(keysFilePath, 'utf-8'));
|
|
42
|
-
for (const [adminId, key] of Object.entries(raw)) {
|
|
43
|
-
if (adminId && key)
|
|
44
|
-
apiKeyMap.set(adminId, key);
|
|
45
|
-
}
|
|
28
|
+
// Path resolution + parsing lives in `yuki-client.ts` (`loadApiKeysFile`) so
|
|
29
|
+
// the runtime `reload_keys` tool can share the exact same behaviour.
|
|
30
|
+
let apiKeyMap = new Map();
|
|
31
|
+
let keysFilePath = '(none)';
|
|
32
|
+
try {
|
|
33
|
+
const loaded = loadApiKeysFile();
|
|
34
|
+
keysFilePath = loaded.path;
|
|
35
|
+
apiKeyMap = loaded.map;
|
|
36
|
+
if (loaded.found) {
|
|
46
37
|
process.stderr.write(`[yuki-mcp] Loaded ${apiKeyMap.size} API keys from ${keysFilePath}\n`);
|
|
47
38
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
process.stderr.write(`[yuki-mcp] Warning: could not read API keys file at ${keysFilePath}: ${err}\n`);
|
|
51
42
|
}
|
|
52
43
|
// ── Environment validation ────────────────────────────────────────────────────
|
|
53
44
|
const apiKey = process.env['YUKI_API_KEY'] ?? '';
|
|
@@ -65,11 +56,12 @@ const yukiClient = new YukiClient(apiKey, domainId, apiKeyMap);
|
|
|
65
56
|
// ── MCP server ────────────────────────────────────────────────────────────────
|
|
66
57
|
const server = new McpServer({
|
|
67
58
|
name: 'yuki-mcp',
|
|
68
|
-
version: '1.
|
|
59
|
+
version: '1.5.0',
|
|
69
60
|
});
|
|
70
61
|
// ── Read tools ────────────────────────────────────────────────────────────────
|
|
71
62
|
registerAdministrationTools(server, yukiClient);
|
|
72
63
|
registerAdministrationLookupTools(server, yukiClient);
|
|
64
|
+
registerReloadKeysTools(server, yukiClient);
|
|
73
65
|
registerRelationTools(server, yukiClient);
|
|
74
66
|
registerInvoiceTools(server, yukiClient);
|
|
75
67
|
registerTransactionTools(server, yukiClient);
|
|
@@ -92,6 +84,6 @@ const keyInfo = apiKeyMap.size > 0
|
|
|
92
84
|
: apiKey
|
|
93
85
|
? 'single YUKI_API_KEY'
|
|
94
86
|
: 'no API keys configured';
|
|
95
|
-
process.stderr.write(`[yuki-mcp] Server started —
|
|
87
|
+
process.stderr.write(`[yuki-mcp] Server started — 31 tools registered. ` +
|
|
96
88
|
`Domain ID: ${domainId || '(none)'} — ${keyInfo}\n`);
|
|
97
89
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,4 +21,24 @@ export declare function registerAdministrationTools(server: McpServer, client: Y
|
|
|
21
21
|
* Rate cost: 1 request.
|
|
22
22
|
*/
|
|
23
23
|
export declare function registerAdministrationLookupTools(server: McpServer, client: YukiClient): void;
|
|
24
|
+
/**
|
|
25
|
+
* reload_keys
|
|
26
|
+
*
|
|
27
|
+
* Re-read the api-keys JSON file from disk and replace the in-memory
|
|
28
|
+
* administrationId → apiKey map without restarting the MCP server. Sessions
|
|
29
|
+
* for keys that changed or were removed are invalidated automatically;
|
|
30
|
+
* sessions for unchanged keys stay warm.
|
|
31
|
+
*
|
|
32
|
+
* Path resolution matches startup:
|
|
33
|
+
* 1. `path` argument (explicit override)
|
|
34
|
+
* 2. YUKI_API_KEYS_FILE env var
|
|
35
|
+
* 3. ~/.yuki/api-keys.json
|
|
36
|
+
* 4. ./api-keys.json
|
|
37
|
+
*
|
|
38
|
+
* Intended use: after a fresh key has been generated by a sibling tool/server,
|
|
39
|
+
* call this to make the new key immediately available to all SOAP tools.
|
|
40
|
+
*
|
|
41
|
+
* Rate cost: 0 SOAP requests. Pure file read + in-memory map swap.
|
|
42
|
+
*/
|
|
43
|
+
export declare function registerReloadKeysTools(server: McpServer, client: YukiClient): void;
|
|
24
44
|
//# sourceMappingURL=administrations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"administrations.d.ts","sourceRoot":"","sources":["../../src/tools/administrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"administrations.d.ts","sourceRoot":"","sources":["../../src/tools/administrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAmB,MAAM,mBAAmB,CAAC;AAEhE;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAqDvF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAuC7F;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CA0EnF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { loadApiKeysFile } from '../yuki-client.js';
|
|
2
3
|
/**
|
|
3
4
|
* Register tools related to Yuki administrations.
|
|
4
5
|
*
|
|
@@ -71,9 +72,7 @@ export function registerAdministrationLookupTools(server, client) {
|
|
|
71
72
|
'Use this to resolve an administration name to the ID required by other tools. ' +
|
|
72
73
|
'For a full list of administrations and IDs use get_administrations.',
|
|
73
74
|
inputSchema: {
|
|
74
|
-
administrationName: z
|
|
75
|
-
.string()
|
|
76
|
-
.describe('Exact name of the administration as shown in Yuki (case-sensitive).'),
|
|
75
|
+
administrationName: z.string().describe('Exact name of the administration as shown in Yuki (case-sensitive).'),
|
|
77
76
|
},
|
|
78
77
|
}, async ({ administrationName }) => {
|
|
79
78
|
try {
|
|
@@ -101,6 +100,84 @@ export function registerAdministrationLookupTools(server, client) {
|
|
|
101
100
|
}
|
|
102
101
|
});
|
|
103
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* reload_keys
|
|
105
|
+
*
|
|
106
|
+
* Re-read the api-keys JSON file from disk and replace the in-memory
|
|
107
|
+
* administrationId → apiKey map without restarting the MCP server. Sessions
|
|
108
|
+
* for keys that changed or were removed are invalidated automatically;
|
|
109
|
+
* sessions for unchanged keys stay warm.
|
|
110
|
+
*
|
|
111
|
+
* Path resolution matches startup:
|
|
112
|
+
* 1. `path` argument (explicit override)
|
|
113
|
+
* 2. YUKI_API_KEYS_FILE env var
|
|
114
|
+
* 3. ~/.yuki/api-keys.json
|
|
115
|
+
* 4. ./api-keys.json
|
|
116
|
+
*
|
|
117
|
+
* Intended use: after a fresh key has been generated by a sibling tool/server,
|
|
118
|
+
* call this to make the new key immediately available to all SOAP tools.
|
|
119
|
+
*
|
|
120
|
+
* Rate cost: 0 SOAP requests. Pure file read + in-memory map swap.
|
|
121
|
+
*/
|
|
122
|
+
export function registerReloadKeysTools(server, client) {
|
|
123
|
+
server.registerTool('reload_keys', {
|
|
124
|
+
description: 'Reload the administrationId → apiKey map from the JSON keys file without ' +
|
|
125
|
+
'restarting the MCP server. Use after a new key has been generated externally ' +
|
|
126
|
+
'(for example via a `create_api_key` flow) to make it usable for SOAP calls ' +
|
|
127
|
+
'immediately. Sessions for changed/removed keys are invalidated; unchanged ' +
|
|
128
|
+
'keys keep their cached session. Returns a diff of added/updated/removed IDs.',
|
|
129
|
+
inputSchema: {
|
|
130
|
+
path: z
|
|
131
|
+
.string()
|
|
132
|
+
.optional()
|
|
133
|
+
.describe('Optional explicit path to the api-keys JSON file. ' +
|
|
134
|
+
'Defaults to YUKI_API_KEYS_FILE → ~/.yuki/api-keys.json → ./api-keys.json.'),
|
|
135
|
+
},
|
|
136
|
+
}, async ({ path }) => {
|
|
137
|
+
try {
|
|
138
|
+
const loaded = loadApiKeysFile(path);
|
|
139
|
+
if (!loaded.found) {
|
|
140
|
+
return {
|
|
141
|
+
content: [
|
|
142
|
+
{
|
|
143
|
+
type: 'text',
|
|
144
|
+
text: JSON.stringify({
|
|
145
|
+
success: false,
|
|
146
|
+
error: `API keys file not found at ${loaded.path}`,
|
|
147
|
+
source: loaded.path,
|
|
148
|
+
}, null, 2),
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
isError: true,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const diff = client.reloadApiKeys(loaded.map);
|
|
155
|
+
return {
|
|
156
|
+
content: [
|
|
157
|
+
{
|
|
158
|
+
type: 'text',
|
|
159
|
+
text: JSON.stringify({
|
|
160
|
+
success: true,
|
|
161
|
+
source: loaded.path,
|
|
162
|
+
added: diff.added,
|
|
163
|
+
updated: diff.updated,
|
|
164
|
+
removed: diff.removed,
|
|
165
|
+
total: diff.total,
|
|
166
|
+
unchanged: diff.total - diff.added.length - diff.updated.length,
|
|
167
|
+
}, null, 2),
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
174
|
+
return {
|
|
175
|
+
content: [{ type: 'text', text: JSON.stringify({ success: false, error: message }, null, 2) }],
|
|
176
|
+
isError: true,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
104
181
|
/** Normalise the parsed SOAP result into a flat array of administration objects. */
|
|
105
182
|
function normalizeAdministrations(result) {
|
|
106
183
|
if (!result)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"administrations.js","sourceRoot":"","sources":["../../src/tools/administrations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"administrations.js","sourceRoot":"","sources":["../../src/tools/administrations.ts"],"names":[],"mappings":"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"}
|
package/dist/yuki-client.d.ts
CHANGED
|
@@ -21,13 +21,38 @@ export interface SoapCallOptions {
|
|
|
21
21
|
/** Key-value pairs serialised as child XML elements inside the method element */
|
|
22
22
|
params: Record<string, SoapParamValue>;
|
|
23
23
|
}
|
|
24
|
+
export interface LoadedApiKeys {
|
|
25
|
+
/** Absolute path that was read from. */
|
|
26
|
+
path: string;
|
|
27
|
+
/** Map of administrationId → apiKey. Empty if the file did not exist. */
|
|
28
|
+
map: Map<string, string>;
|
|
29
|
+
/** True when the resolved file existed and was parsed. */
|
|
30
|
+
found: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare function resolveApiKeysFilePath(explicitPath?: string): string;
|
|
33
|
+
export declare function loadApiKeysFile(explicitPath?: string): LoadedApiKeys;
|
|
34
|
+
/**
|
|
35
|
+
* Diff returned by `YukiClient.reloadApiKeys` so callers can report what changed
|
|
36
|
+
* — useful for the `reload_keys` MCP tool and for log-stderr lines.
|
|
37
|
+
*/
|
|
38
|
+
export interface ApiKeyReloadDiff {
|
|
39
|
+
/** Keys that did not exist before this reload. */
|
|
40
|
+
added: string[];
|
|
41
|
+
/** Keys that existed before but had a different value (session invalidated). */
|
|
42
|
+
updated: string[];
|
|
43
|
+
/** Keys that existed before but are no longer in the file (session invalidated). */
|
|
44
|
+
removed: string[];
|
|
45
|
+
/** Final size of the map after reload. */
|
|
46
|
+
total: number;
|
|
47
|
+
}
|
|
24
48
|
export declare class YukiClient {
|
|
25
49
|
private readonly apiKey;
|
|
26
50
|
private readonly domainId;
|
|
27
51
|
private readonly parser;
|
|
28
52
|
/**
|
|
29
|
-
* Map from administrationId → apiKey
|
|
30
|
-
*
|
|
53
|
+
* Map from administrationId → apiKey. Populated from the JSON keys file at
|
|
54
|
+
* startup and mutated in place by `reloadApiKeys()` so that all tools
|
|
55
|
+
* automatically see the latest set without rebuilding the client.
|
|
31
56
|
*/
|
|
32
57
|
private readonly apiKeyMap;
|
|
33
58
|
/**
|
|
@@ -59,6 +84,19 @@ export declare class YukiClient {
|
|
|
59
84
|
get defaultDomainId(): string;
|
|
60
85
|
/** Number of administration-specific API keys loaded from the keys file. */
|
|
61
86
|
get apiKeyCount(): number;
|
|
87
|
+
/**
|
|
88
|
+
* Replace the in-memory `apiKeyMap` with `next`, in place. Sessions for keys
|
|
89
|
+
* that **changed** or were **removed** are evicted from the session cache so
|
|
90
|
+
* the next call re-authenticates against Yuki with the correct credentials.
|
|
91
|
+
* Sessions for keys that did not change are kept warm.
|
|
92
|
+
*
|
|
93
|
+
* Designed to be called from the `reload_keys` MCP tool after a fresh
|
|
94
|
+
* `api-keys.json` has been written (e.g. by a `create_api_key` flow in a
|
|
95
|
+
* sibling MCP server). Avoids the need to restart the MCP server.
|
|
96
|
+
*
|
|
97
|
+
* Returns a diff so callers can report what changed.
|
|
98
|
+
*/
|
|
99
|
+
reloadApiKeys(next: Map<string, string>): ApiKeyReloadDiff;
|
|
62
100
|
/** Build a SOAP 1.1 envelope around the given method body. */
|
|
63
101
|
private buildSoapEnvelope;
|
|
64
102
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yuki-client.d.ts","sourceRoot":"","sources":["../src/yuki-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"yuki-client.d.ts","sourceRoot":"","sources":["../src/yuki-client.ts"],"names":[],"mappings":"AAgDA;;;;;;;;;GASG;AACH,qBAAa,QAAQ;IACP,QAAQ,CAAC,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CACjC;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9E,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;AAaD,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzB,0DAA0D;IAC1D,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,sBAAsB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAMpE;AAED,wBAAgB,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CAWpE;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gFAAgF;IAChF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oFAAoF;IACpF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;CACf;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;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAEhD;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;gBAE9C,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAgB7E;;;;;;;;;;OAUG;IACG,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCrD;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IASzC,mEAAmE;IACnE,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,4EAA4E;IAC5E,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,gBAAgB;IAmC1D,8DAA8D;IAC9D,OAAO,CAAC,iBAAiB;IAczB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAYvB;;;;;;;OAOG;IACG,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAsD1D,4EAA4E;IAC5E,OAAO,CAAC,gBAAgB;CAoBzB;AAID;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7C"}
|
package/dist/yuki-client.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import { XMLParser } from 'fast-xml-parser';
|
|
3
|
+
import { readFileSync, existsSync } from 'fs';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { homedir } from 'os';
|
|
3
6
|
// Confirmed via WSDL inspection of api.yukiworks.nl
|
|
4
7
|
const YUKI_BASE_URL = 'https://api.yukiworks.nl/ws/';
|
|
5
8
|
const YUKI_NAMESPACE = 'http://www.theyukicompany.com/';
|
|
@@ -56,13 +59,37 @@ export class XmlValue {
|
|
|
56
59
|
this.xml = xml;
|
|
57
60
|
}
|
|
58
61
|
}
|
|
62
|
+
export function resolveApiKeysFilePath(explicitPath) {
|
|
63
|
+
if (explicitPath)
|
|
64
|
+
return explicitPath;
|
|
65
|
+
if (process.env['YUKI_API_KEYS_FILE'])
|
|
66
|
+
return process.env['YUKI_API_KEYS_FILE'];
|
|
67
|
+
const userPath = join(homedir(), '.yuki', 'api-keys.json');
|
|
68
|
+
if (existsSync(userPath))
|
|
69
|
+
return userPath;
|
|
70
|
+
return 'api-keys.json';
|
|
71
|
+
}
|
|
72
|
+
export function loadApiKeysFile(explicitPath) {
|
|
73
|
+
const path = resolveApiKeysFilePath(explicitPath);
|
|
74
|
+
const map = new Map();
|
|
75
|
+
if (!existsSync(path)) {
|
|
76
|
+
return { path, map, found: false };
|
|
77
|
+
}
|
|
78
|
+
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
79
|
+
for (const [adminId, key] of Object.entries(raw)) {
|
|
80
|
+
if (adminId && key)
|
|
81
|
+
map.set(adminId, key);
|
|
82
|
+
}
|
|
83
|
+
return { path, map, found: true };
|
|
84
|
+
}
|
|
59
85
|
export class YukiClient {
|
|
60
86
|
apiKey;
|
|
61
87
|
domainId;
|
|
62
88
|
parser;
|
|
63
89
|
/**
|
|
64
|
-
* Map from administrationId → apiKey
|
|
65
|
-
*
|
|
90
|
+
* Map from administrationId → apiKey. Populated from the JSON keys file at
|
|
91
|
+
* startup and mutated in place by `reloadApiKeys()` so that all tools
|
|
92
|
+
* automatically see the latest set without rebuilding the client.
|
|
66
93
|
*/
|
|
67
94
|
apiKeyMap;
|
|
68
95
|
/**
|
|
@@ -145,6 +172,48 @@ export class YukiClient {
|
|
|
145
172
|
get apiKeyCount() {
|
|
146
173
|
return this.apiKeyMap.size;
|
|
147
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Replace the in-memory `apiKeyMap` with `next`, in place. Sessions for keys
|
|
177
|
+
* that **changed** or were **removed** are evicted from the session cache so
|
|
178
|
+
* the next call re-authenticates against Yuki with the correct credentials.
|
|
179
|
+
* Sessions for keys that did not change are kept warm.
|
|
180
|
+
*
|
|
181
|
+
* Designed to be called from the `reload_keys` MCP tool after a fresh
|
|
182
|
+
* `api-keys.json` has been written (e.g. by a `create_api_key` flow in a
|
|
183
|
+
* sibling MCP server). Avoids the need to restart the MCP server.
|
|
184
|
+
*
|
|
185
|
+
* Returns a diff so callers can report what changed.
|
|
186
|
+
*/
|
|
187
|
+
reloadApiKeys(next) {
|
|
188
|
+
const added = [];
|
|
189
|
+
const updated = [];
|
|
190
|
+
const removed = [];
|
|
191
|
+
// Detect updates + removals against the previous state
|
|
192
|
+
for (const [adminId, previousKey] of this.apiKeyMap) {
|
|
193
|
+
const nextKey = next.get(adminId);
|
|
194
|
+
if (nextKey === undefined) {
|
|
195
|
+
removed.push(adminId);
|
|
196
|
+
// Evict the cached session for the removed key
|
|
197
|
+
this.sessionCache.delete(previousKey);
|
|
198
|
+
}
|
|
199
|
+
else if (nextKey !== previousKey) {
|
|
200
|
+
updated.push(adminId);
|
|
201
|
+
// Evict the session bound to the old key value
|
|
202
|
+
this.sessionCache.delete(previousKey);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Detect additions
|
|
206
|
+
for (const adminId of next.keys()) {
|
|
207
|
+
if (!this.apiKeyMap.has(adminId))
|
|
208
|
+
added.push(adminId);
|
|
209
|
+
}
|
|
210
|
+
// Apply the new state in place (preserves the Map reference)
|
|
211
|
+
this.apiKeyMap.clear();
|
|
212
|
+
for (const [adminId, key] of next) {
|
|
213
|
+
this.apiKeyMap.set(adminId, key);
|
|
214
|
+
}
|
|
215
|
+
return { added, updated, removed, total: this.apiKeyMap.size };
|
|
216
|
+
}
|
|
148
217
|
// ── Core SOAP plumbing ──────────────────────────────────────────────────────
|
|
149
218
|
/** Build a SOAP 1.1 envelope around the given method body. */
|
|
150
219
|
buildSoapEnvelope(method, paramsXml) {
|
package/dist/yuki-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yuki-client.js","sourceRoot":"","sources":["../src/yuki-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"yuki-client.js","sourceRoot":"","sources":["../src/yuki-client.ts"],"names":[],"mappings":"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"}
|