@wrongstack/mcp 0.298.3 → 0.300.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/index.js +46 -21
- package/dist/registry-slots.d.ts +1 -1
- package/dist/registry.d.ts +1 -0
- package/dist/transport-base.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3769,7 +3769,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
3769
3769
|
if (lazy) {
|
|
3770
3770
|
await this.startLazy(slot);
|
|
3771
3771
|
} else {
|
|
3772
|
-
await this.
|
|
3772
|
+
await this.singleFlightConnect(slot);
|
|
3773
3773
|
}
|
|
3774
3774
|
}
|
|
3775
3775
|
/** Record an intentionally disabled configuration without opening a transport. */
|
|
@@ -3805,7 +3805,21 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
3805
3805
|
);
|
|
3806
3806
|
return;
|
|
3807
3807
|
}
|
|
3808
|
-
await this.
|
|
3808
|
+
await this.singleFlightConnect(slot);
|
|
3809
|
+
}
|
|
3810
|
+
singleFlightConnect(slot) {
|
|
3811
|
+
if (slot.client && slot.state === "connected") return Promise.resolve(slot.client);
|
|
3812
|
+
if (slot.connecting) return slot.connecting;
|
|
3813
|
+
const promise = (async () => {
|
|
3814
|
+
try {
|
|
3815
|
+
await this.attemptConnect(slot);
|
|
3816
|
+
return slot.client;
|
|
3817
|
+
} finally {
|
|
3818
|
+
slot.connecting = void 0;
|
|
3819
|
+
}
|
|
3820
|
+
})();
|
|
3821
|
+
slot.connecting = promise;
|
|
3822
|
+
return promise;
|
|
3809
3823
|
}
|
|
3810
3824
|
/**
|
|
3811
3825
|
* Ensure a lazy server is connected, spawning it on demand. Single-flight:
|
|
@@ -3816,28 +3830,20 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
3816
3830
|
if (!slot) throw new Error(`MCP server "${name}" not registered`);
|
|
3817
3831
|
slot.lastUsed = Date.now();
|
|
3818
3832
|
if (slot.client && slot.state === "connected") return slot.client;
|
|
3819
|
-
if (slot.connecting) return slot.connecting;
|
|
3820
3833
|
const waking = slot.state === "dormant";
|
|
3821
3834
|
if (waking) {
|
|
3822
3835
|
slot.operations.wakeCount++;
|
|
3823
3836
|
this.recordOperation(slot, "wake", "lazy-demand");
|
|
3837
|
+
slot.attempts = 0;
|
|
3838
|
+
slot.reconnectCycles = 0;
|
|
3824
3839
|
}
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
}
|
|
3833
|
-
slot.lastUsed = Date.now();
|
|
3834
|
-
this.ensureIdleSweep();
|
|
3835
|
-
return slot.client;
|
|
3836
|
-
} finally {
|
|
3837
|
-
slot.connecting = void 0;
|
|
3838
|
-
}
|
|
3839
|
-
})();
|
|
3840
|
-
return slot.connecting;
|
|
3840
|
+
const client = await this.singleFlightConnect(slot);
|
|
3841
|
+
if (!client) {
|
|
3842
|
+
throw new Error(`MCP server "${name}" failed to connect on demand`);
|
|
3843
|
+
}
|
|
3844
|
+
slot.lastUsed = Date.now();
|
|
3845
|
+
this.ensureIdleSweep();
|
|
3846
|
+
return client;
|
|
3841
3847
|
}
|
|
3842
3848
|
/**
|
|
3843
3849
|
* Register all cached tools for a given server into the tool registry.
|
|
@@ -3898,6 +3904,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
3898
3904
|
clearTimeout(slot.reconnectTimer);
|
|
3899
3905
|
slot.reconnectTimer = void 0;
|
|
3900
3906
|
}
|
|
3907
|
+
slot.state = "disconnected";
|
|
3901
3908
|
if (slot.client) {
|
|
3902
3909
|
slot.client.removeExitListener(this.onChildExit);
|
|
3903
3910
|
if (slot.onDisconnect) slot.client.removeDisconnectListener(slot.onDisconnect);
|
|
@@ -3916,7 +3923,6 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
3916
3923
|
slot.resourceTemplates = void 0;
|
|
3917
3924
|
slot.prompts = void 0;
|
|
3918
3925
|
slot.registeredLazy = false;
|
|
3919
|
-
slot.state = "disconnected";
|
|
3920
3926
|
this.recordOperation(slot, "stop", "manual");
|
|
3921
3927
|
this.events.emit("mcp.server.disconnected", { name, reason: "stop" });
|
|
3922
3928
|
}
|
|
@@ -3928,7 +3934,11 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
3928
3934
|
await this.stop(name);
|
|
3929
3935
|
slot.attempts = 0;
|
|
3930
3936
|
slot.reconnectCycles = 0;
|
|
3931
|
-
|
|
3937
|
+
if (slot.lazy) {
|
|
3938
|
+
await this.startLazy(slot);
|
|
3939
|
+
} else {
|
|
3940
|
+
await this.singleFlightConnect(slot);
|
|
3941
|
+
}
|
|
3932
3942
|
}
|
|
3933
3943
|
list() {
|
|
3934
3944
|
return Array.from(this.servers.values()).map((s) => {
|
|
@@ -4356,6 +4366,9 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
4356
4366
|
const MAX_ATTEMPTS = MCP_CONSTANTS.RECONNECT.MAX_ATTEMPTS;
|
|
4357
4367
|
let attempt = 0;
|
|
4358
4368
|
while (attempt < MAX_ATTEMPTS) {
|
|
4369
|
+
if (this.servers.has(slot.cfg.name) && this.servers.get(slot.cfg.name) !== slot) {
|
|
4370
|
+
return;
|
|
4371
|
+
}
|
|
4359
4372
|
attempt++;
|
|
4360
4373
|
const startedAt = Date.now();
|
|
4361
4374
|
slot.state = attempt === 1 ? "connecting" : "reconnecting";
|
|
@@ -4385,6 +4398,15 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
4385
4398
|
client.addToolsChangedListener(this.onToolsChanged);
|
|
4386
4399
|
this.addCatalogListeners(client);
|
|
4387
4400
|
await client.connect();
|
|
4401
|
+
if (slot.state === "disconnected" || this.servers.has(slot.cfg.name) && this.servers.get(slot.cfg.name) !== slot) {
|
|
4402
|
+
client.removeExitListener(this.onChildExit);
|
|
4403
|
+
if (boundDisconnect) client.removeDisconnectListener(boundDisconnect);
|
|
4404
|
+
client.removeToolsChangedListener(this.onToolsChanged);
|
|
4405
|
+
this.removeCatalogListeners(client);
|
|
4406
|
+
await client.close().catch(() => {
|
|
4407
|
+
});
|
|
4408
|
+
return;
|
|
4409
|
+
}
|
|
4388
4410
|
if (slot.client && slot.client !== client) {
|
|
4389
4411
|
const prior = slot.client;
|
|
4390
4412
|
const priorDisconnect = slot.onDisconnect;
|
|
@@ -4457,6 +4479,9 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
4457
4479
|
}
|
|
4458
4480
|
const delay = 500 * 2 ** attempt;
|
|
4459
4481
|
await new Promise((r) => setTimeout(r, delay));
|
|
4482
|
+
if (slot.state === "disconnected" || this.servers.has(slot.cfg.name) && this.servers.get(slot.cfg.name) !== slot) {
|
|
4483
|
+
return;
|
|
4484
|
+
}
|
|
4460
4485
|
}
|
|
4461
4486
|
}
|
|
4462
4487
|
}
|
package/dist/registry-slots.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export interface ServerSlot {
|
|
|
26
26
|
/** Epoch ms of the last tool call — drives idle auto-sleep. */
|
|
27
27
|
lastUsed: number;
|
|
28
28
|
/** Single-flight guard so concurrent first-calls trigger only one connect. */
|
|
29
|
-
connecting?: Promise<MCPClient> | undefined;
|
|
29
|
+
connecting?: Promise<MCPClient | undefined> | undefined;
|
|
30
30
|
/** Whether this lazy server's resolver wrappers are registered (register once). */
|
|
31
31
|
registeredLazy: boolean;
|
|
32
32
|
/** Bounded, payload-free operational telemetry for this server. */
|
package/dist/registry.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export declare class MCPRegistry {
|
|
|
46
46
|
* cache yet, do a one-time cold discovery connect to learn + cache the tools.
|
|
47
47
|
*/
|
|
48
48
|
private startLazy;
|
|
49
|
+
private singleFlightConnect;
|
|
49
50
|
/**
|
|
50
51
|
* Ensure a lazy server is connected, spawning it on demand. Single-flight:
|
|
51
52
|
* concurrent first-calls share one connect. Resolver wrappers call this.
|
package/dist/transport-base.d.ts
CHANGED
|
@@ -62,7 +62,7 @@ export declare abstract class BaseHTTPTransport {
|
|
|
62
62
|
protected protocolVersion?: string | undefined;
|
|
63
63
|
constructor(opts: HttpTransportOptions, transportName: string);
|
|
64
64
|
getState(): ConnectionState;
|
|
65
|
-
protected fetchWithAuthorization(input: string, init: RequestInit, signal?: AbortSignal | undefined): Promise<Response>;
|
|
65
|
+
protected fetchWithAuthorization(input: string | URL, init: RequestInit, signal?: AbortSignal | undefined): Promise<Response>;
|
|
66
66
|
listTools(): MCPTool[];
|
|
67
67
|
getServerMetadata(): MCPServerMetadata | undefined;
|
|
68
68
|
onDisconnect(cb: () => void): () => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.300.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack Model Context Protocol client and registry: stdio, SSE, and streamable HTTP transports.",
|
|
6
6
|
"repository": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"!dist/**/*.map"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@wrongstack/core": "0.
|
|
29
|
+
"@wrongstack/core": "0.300.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^26.1.2",
|