@atlassian/mcp-compressor 0.32.1 → 0.33.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/dist/cli.js +1 -1
- package/dist/native_client.d.ts +18 -0
- package/dist/native_client.js +113 -14
- package/native/index.darwin-arm64.node +0 -0
- package/native/index.darwin-x64.node +0 -0
- package/native/index.linux-arm64-gnu.node +0 -0
- package/native/index.linux-x64-gnu.node +0 -0
- package/native/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -61,7 +61,7 @@ function buildProgram(options = {}) {
|
|
|
61
61
|
"invoke_tool, list_tools). The name will be sanitized to conform to MCP\n" +
|
|
62
62
|
"tool name specifications (only A-Z, a-z, 0-9, _, -, .).")
|
|
63
63
|
.option("-l, --log-level <level>", "The logging level.", "error")
|
|
64
|
-
.option("--toonify", "Convert JSON tool responses to TOON format automatically.")
|
|
64
|
+
.option("--toonify", "Convert JSON, CSV and YAML tool responses to TOON format automatically.")
|
|
65
65
|
.option("--cli-mode", "Start in CLI mode: expose a single help MCP tool, start a local HTTP\n" +
|
|
66
66
|
"bridge, and generate a shell script for interacting with the wrapped\n" +
|
|
67
67
|
"server via CLI. --toonify is automatically enabled in this mode.")
|
package/dist/native_client.d.ts
CHANGED
|
@@ -54,6 +54,19 @@ export interface GeneratedCodeClient {
|
|
|
54
54
|
environment: Record<string, string>;
|
|
55
55
|
}
|
|
56
56
|
export declare function normalizeServers(servers: NativeServersInput): Promise<NormalizedBackendConfig[] | string>;
|
|
57
|
+
/**
|
|
58
|
+
* Hand a freshly started native session to `build`, closing the session if
|
|
59
|
+
* `build` throws.
|
|
60
|
+
*
|
|
61
|
+
* A started session owns backend processes and sockets that are only reachable
|
|
62
|
+
* through the object `build` returns. Without this the session would leak for
|
|
63
|
+
* the lifetime of the host process whenever adoption failed.
|
|
64
|
+
*
|
|
65
|
+
* Internal; not part of the public package surface.
|
|
66
|
+
*/
|
|
67
|
+
export declare function adoptNativeSession<T>(session: {
|
|
68
|
+
close(): void;
|
|
69
|
+
}, build: () => T): T;
|
|
57
70
|
export declare class CompressorProxy {
|
|
58
71
|
private readonly session;
|
|
59
72
|
private readonly defaultServer;
|
|
@@ -87,10 +100,15 @@ export declare class CompressorProxy {
|
|
|
87
100
|
export declare class CompressorClient {
|
|
88
101
|
private readonly options;
|
|
89
102
|
private session;
|
|
103
|
+
private proxy;
|
|
104
|
+
private connectPromise;
|
|
105
|
+
private closingPromise;
|
|
90
106
|
private readonly mode;
|
|
91
107
|
private authProviders;
|
|
92
108
|
constructor(options: CompressorClientOptions);
|
|
93
109
|
connect(): Promise<CompressorProxy>;
|
|
110
|
+
private startConnection;
|
|
94
111
|
close(): Promise<void>;
|
|
112
|
+
private closeCurrentConnection;
|
|
95
113
|
private defaultServer;
|
|
96
114
|
}
|
package/dist/native_client.js
CHANGED
|
@@ -152,6 +152,31 @@ function transformMode(mode) {
|
|
|
152
152
|
return "cli";
|
|
153
153
|
return mode;
|
|
154
154
|
}
|
|
155
|
+
const proxyCloseCallbacks = new WeakMap();
|
|
156
|
+
/**
|
|
157
|
+
* Hand a freshly started native session to `build`, closing the session if
|
|
158
|
+
* `build` throws.
|
|
159
|
+
*
|
|
160
|
+
* A started session owns backend processes and sockets that are only reachable
|
|
161
|
+
* through the object `build` returns. Without this the session would leak for
|
|
162
|
+
* the lifetime of the host process whenever adoption failed.
|
|
163
|
+
*
|
|
164
|
+
* Internal; not part of the public package surface.
|
|
165
|
+
*/
|
|
166
|
+
export function adoptNativeSession(session, build) {
|
|
167
|
+
try {
|
|
168
|
+
return build();
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
try {
|
|
172
|
+
session.close();
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Closing a session that never became reachable is best effort.
|
|
176
|
+
}
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
155
180
|
export class CompressorProxy {
|
|
156
181
|
session;
|
|
157
182
|
defaultServer;
|
|
@@ -242,8 +267,18 @@ export class CompressorProxy {
|
|
|
242
267
|
return (await this.invokeWrapper(wrapper, { tool_name: tool, tool_input: toolInput })).text;
|
|
243
268
|
}
|
|
244
269
|
close() {
|
|
270
|
+
if (this.closed) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
245
273
|
this.closed = true;
|
|
246
|
-
|
|
274
|
+
try {
|
|
275
|
+
this.session.close();
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
const onClose = proxyCloseCallbacks.get(this);
|
|
279
|
+
proxyCloseCallbacks.delete(this);
|
|
280
|
+
onClose?.();
|
|
281
|
+
}
|
|
247
282
|
}
|
|
248
283
|
toExecutableTools() {
|
|
249
284
|
const result = {};
|
|
@@ -285,6 +320,9 @@ export class CompressorProxy {
|
|
|
285
320
|
export class CompressorClient {
|
|
286
321
|
options;
|
|
287
322
|
session = null;
|
|
323
|
+
proxy = null;
|
|
324
|
+
connectPromise = null;
|
|
325
|
+
closingPromise = null;
|
|
288
326
|
mode;
|
|
289
327
|
authProviders = [];
|
|
290
328
|
constructor(options) {
|
|
@@ -292,9 +330,32 @@ export class CompressorClient {
|
|
|
292
330
|
this.mode = options.mode ?? "compressed";
|
|
293
331
|
}
|
|
294
332
|
async connect() {
|
|
295
|
-
if (this.
|
|
296
|
-
|
|
333
|
+
if (this.closingPromise) {
|
|
334
|
+
try {
|
|
335
|
+
await this.closingPromise;
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
// The close caller receives the error; cleared state can reconnect independently.
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
if (this.proxy) {
|
|
342
|
+
return this.proxy;
|
|
297
343
|
}
|
|
344
|
+
if (this.connectPromise) {
|
|
345
|
+
return this.connectPromise;
|
|
346
|
+
}
|
|
347
|
+
const connection = this.startConnection();
|
|
348
|
+
this.connectPromise = connection;
|
|
349
|
+
try {
|
|
350
|
+
return await connection;
|
|
351
|
+
}
|
|
352
|
+
finally {
|
|
353
|
+
if (this.connectPromise === connection) {
|
|
354
|
+
this.connectPromise = null;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
async startConnection() {
|
|
298
359
|
const normalized = await normalizeServersWithProviders(this.options.servers);
|
|
299
360
|
const config = {
|
|
300
361
|
compressionLevel: this.options.compressionLevel ?? "medium",
|
|
@@ -305,17 +366,55 @@ export class CompressorClient {
|
|
|
305
366
|
transformMode: transformMode(this.mode),
|
|
306
367
|
};
|
|
307
368
|
this.authProviders = typeof normalized === "string" ? [] : normalized.providers;
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
369
|
+
const session = typeof normalized === "string"
|
|
370
|
+
? await startCompressedSessionFromMcpConfig(config, normalized)
|
|
371
|
+
: normalized.providers.length > 0
|
|
372
|
+
? await startCompressedSessionWithAuthProviders(config, normalized.backends, normalized.providers)
|
|
373
|
+
: await startCompressedSession(config, normalized.backends);
|
|
374
|
+
const proxy = adoptNativeSession(session, () => {
|
|
375
|
+
const adopted = new CompressorProxy(session, this.defaultServer(), this.authProviders);
|
|
376
|
+
proxyCloseCallbacks.set(adopted, () => {
|
|
377
|
+
if (this.proxy === adopted) {
|
|
378
|
+
this.proxy = null;
|
|
379
|
+
this.session = null;
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
return adopted;
|
|
383
|
+
});
|
|
384
|
+
this.session = session;
|
|
385
|
+
this.proxy = proxy;
|
|
386
|
+
return proxy;
|
|
387
|
+
}
|
|
388
|
+
close() {
|
|
389
|
+
if (!this.closingPromise) {
|
|
390
|
+
const closing = this.closeCurrentConnection();
|
|
391
|
+
let trackedClosing;
|
|
392
|
+
trackedClosing = closing.finally(() => {
|
|
393
|
+
if (this.closingPromise === trackedClosing) {
|
|
394
|
+
this.closingPromise = null;
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
this.closingPromise = trackedClosing;
|
|
398
|
+
}
|
|
399
|
+
return this.closingPromise;
|
|
400
|
+
}
|
|
401
|
+
async closeCurrentConnection() {
|
|
402
|
+
try {
|
|
403
|
+
await this.connectPromise;
|
|
404
|
+
}
|
|
405
|
+
catch {
|
|
406
|
+
// A failed connection has no native session to release.
|
|
407
|
+
}
|
|
408
|
+
const proxy = this.proxy;
|
|
409
|
+
try {
|
|
410
|
+
proxy?.close();
|
|
411
|
+
}
|
|
412
|
+
finally {
|
|
413
|
+
if (this.proxy === proxy) {
|
|
414
|
+
this.proxy = null;
|
|
415
|
+
this.session = null;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
319
418
|
}
|
|
320
419
|
defaultServer() {
|
|
321
420
|
const servers = this.options.servers;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlassian/mcp-compressor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "TypeScript MCP server wrapper for reducing tokens consumed by MCP tools.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/atlassian-labs/mcp-compressor",
|