@mcp-ts/sdk 2.4.2 → 2.4.3
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/adapters/agui-adapter.d.mts +1 -1
- package/dist/adapters/agui-adapter.d.ts +1 -1
- package/dist/adapters/agui-middleware.d.mts +1 -1
- package/dist/adapters/agui-middleware.d.ts +1 -1
- package/dist/adapters/ai-adapter.d.mts +1 -1
- package/dist/adapters/ai-adapter.d.ts +1 -1
- package/dist/adapters/langchain-adapter.d.mts +1 -1
- package/dist/adapters/langchain-adapter.d.ts +1 -1
- package/dist/adapters/mastra-adapter.d.mts +1 -1
- package/dist/adapters/mastra-adapter.d.ts +1 -1
- package/dist/bin/mcp-ts.js +5 -5
- package/dist/bin/mcp-ts.js.map +1 -1
- package/dist/bin/mcp-ts.mjs +5 -5
- package/dist/bin/mcp-ts.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +71 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +71 -15
- package/dist/index.mjs.map +1 -1
- package/dist/{multi-session-client-CWs-AE78.d.mts → multi-session-client-B6hsYO8V.d.mts} +17 -0
- package/dist/{multi-session-client-BluyCPo9.d.ts → multi-session-client-DOBvtaQV.d.ts} +17 -0
- package/dist/server/index.d.mts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +71 -15
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +71 -15
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/bin/mcp-ts.ts +5 -5
- package/src/server/mcp/multi-session-client.ts +13 -0
- package/src/server/mcp/oauth-client.ts +49 -7
- package/src/server/storage/index.ts +8 -8
package/dist/server/index.mjs
CHANGED
|
@@ -1666,12 +1666,12 @@ async function createStorage() {
|
|
|
1666
1666
|
}
|
|
1667
1667
|
if (type === "supabase") {
|
|
1668
1668
|
const url = process.env.SUPABASE_URL;
|
|
1669
|
-
const key = process.env.
|
|
1669
|
+
const key = process.env.SUPABASE_SECRET_KEY || process.env.SUPABASE_ANON_KEY;
|
|
1670
1670
|
if (!url || !key) {
|
|
1671
|
-
console.warn('[mcp-ts][Storage] Explicit selection "supabase" requires SUPABASE_URL and
|
|
1671
|
+
console.warn('[mcp-ts][Storage] Explicit selection "supabase" requires SUPABASE_URL and SUPABASE_SECRET_KEY.');
|
|
1672
1672
|
} else {
|
|
1673
|
-
if (!process.env.
|
|
1674
|
-
console.warn('[mcp-ts][Storage] \u26A0\uFE0F Warning: Using "SUPABASE_ANON_KEY" for server-side storage. You may encounter RLS policy violations. "
|
|
1673
|
+
if (!process.env.SUPABASE_SECRET_KEY) {
|
|
1674
|
+
console.warn('[mcp-ts][Storage] \u26A0\uFE0F Warning: Using "SUPABASE_ANON_KEY" for server-side storage. You may encounter RLS policy violations. "SUPABASE_SECRET_KEY" is recommended.');
|
|
1675
1675
|
}
|
|
1676
1676
|
try {
|
|
1677
1677
|
const { createClient } = await import('@supabase/supabase-js');
|
|
@@ -1726,13 +1726,13 @@ async function createStorage() {
|
|
|
1726
1726
|
console.log(`[mcp-ts][Storage] Auto-detection: "sqlite" (${process.env.MCP_TS_STORAGE_SQLITE_PATH})`);
|
|
1727
1727
|
return await initializeStorage(new SqliteStorage({ path: process.env.MCP_TS_STORAGE_SQLITE_PATH }));
|
|
1728
1728
|
}
|
|
1729
|
-
if (process.env.SUPABASE_URL && (process.env.
|
|
1729
|
+
if (process.env.SUPABASE_URL && (process.env.SUPABASE_SECRET_KEY || process.env.SUPABASE_ANON_KEY)) {
|
|
1730
1730
|
try {
|
|
1731
1731
|
const { createClient } = await import('@supabase/supabase-js');
|
|
1732
1732
|
const url = process.env.SUPABASE_URL;
|
|
1733
|
-
const key = process.env.
|
|
1734
|
-
if (!process.env.
|
|
1735
|
-
console.warn('[mcp-ts][Storage] \u26A0\uFE0F Warning: Using "SUPABASE_ANON_KEY" for server-side storage. You may encounter RLS policy violations. "
|
|
1733
|
+
const key = process.env.SUPABASE_SECRET_KEY || process.env.SUPABASE_ANON_KEY;
|
|
1734
|
+
if (!process.env.SUPABASE_SECRET_KEY) {
|
|
1735
|
+
console.warn('[mcp-ts][Storage] \u26A0\uFE0F Warning: Using "SUPABASE_ANON_KEY" for server-side storage. You may encounter RLS policy violations. "SUPABASE_SECRET_KEY" is recommended.');
|
|
1736
1736
|
}
|
|
1737
1737
|
const client = createClient(url, key);
|
|
1738
1738
|
console.log('[mcp-ts][Storage] Auto-detection: "supabase" (via SUPABASE_URL)');
|
|
@@ -2230,7 +2230,6 @@ var MCPClient = class {
|
|
|
2230
2230
|
const response = await fetch(url, { ...init, signal });
|
|
2231
2231
|
const hasSessionHeader = init?.headers && new Headers(init.headers).has("mcp-session-id");
|
|
2232
2232
|
if (response.status === 404 && hasSessionHeader) {
|
|
2233
|
-
this.client = null;
|
|
2234
2233
|
throw new Error("MCP_SESSION_EXPIRED: Downstream session was not found on the server.");
|
|
2235
2234
|
}
|
|
2236
2235
|
return response;
|
|
@@ -2611,7 +2610,9 @@ var MCPClient = class {
|
|
|
2611
2610
|
method: "tools/list",
|
|
2612
2611
|
params: {}
|
|
2613
2612
|
};
|
|
2614
|
-
const result = await this.
|
|
2613
|
+
const result = await this.withRetry(
|
|
2614
|
+
() => this.client.request(request, ListToolsResultSchema)
|
|
2615
|
+
);
|
|
2615
2616
|
if (this.serverId) {
|
|
2616
2617
|
this._onConnectionEvent.fire({
|
|
2617
2618
|
type: "tools_discovered",
|
|
@@ -2651,7 +2652,9 @@ var MCPClient = class {
|
|
|
2651
2652
|
}
|
|
2652
2653
|
};
|
|
2653
2654
|
try {
|
|
2654
|
-
const result = await this.
|
|
2655
|
+
const result = await this.withRetry(
|
|
2656
|
+
() => this.client.request(request, CallToolResultSchema)
|
|
2657
|
+
);
|
|
2655
2658
|
this._onObservabilityEvent.fire({
|
|
2656
2659
|
type: "mcp:client:tool_call",
|
|
2657
2660
|
level: "info",
|
|
@@ -2703,7 +2706,9 @@ var MCPClient = class {
|
|
|
2703
2706
|
method: "prompts/list",
|
|
2704
2707
|
params: {}
|
|
2705
2708
|
};
|
|
2706
|
-
const result = await this.
|
|
2709
|
+
const result = await this.withRetry(
|
|
2710
|
+
() => this.client.request(request, ListPromptsResultSchema)
|
|
2711
|
+
);
|
|
2707
2712
|
this.emitStateChange("READY");
|
|
2708
2713
|
this.emitProgress(`Discovered ${result.prompts.length} prompts`);
|
|
2709
2714
|
return result;
|
|
@@ -2732,7 +2737,9 @@ var MCPClient = class {
|
|
|
2732
2737
|
arguments: args
|
|
2733
2738
|
}
|
|
2734
2739
|
};
|
|
2735
|
-
return await this.
|
|
2740
|
+
return await this.withRetry(
|
|
2741
|
+
() => this.client.request(request, GetPromptResultSchema)
|
|
2742
|
+
);
|
|
2736
2743
|
}
|
|
2737
2744
|
/**
|
|
2738
2745
|
* Lists all available resources from the connected MCP server
|
|
@@ -2749,7 +2756,9 @@ var MCPClient = class {
|
|
|
2749
2756
|
method: "resources/list",
|
|
2750
2757
|
params: {}
|
|
2751
2758
|
};
|
|
2752
|
-
const result = await this.
|
|
2759
|
+
const result = await this.withRetry(
|
|
2760
|
+
() => this.client.request(request, ListResourcesResultSchema)
|
|
2761
|
+
);
|
|
2753
2762
|
this.emitStateChange("READY");
|
|
2754
2763
|
this.emitProgress(`Discovered ${result.resources.length} resources`);
|
|
2755
2764
|
return result;
|
|
@@ -2776,7 +2785,36 @@ var MCPClient = class {
|
|
|
2776
2785
|
uri
|
|
2777
2786
|
}
|
|
2778
2787
|
};
|
|
2779
|
-
return await this.
|
|
2788
|
+
return await this.withRetry(
|
|
2789
|
+
() => this.client.request(request, ReadResourceResultSchema)
|
|
2790
|
+
);
|
|
2791
|
+
}
|
|
2792
|
+
/**
|
|
2793
|
+
* Wraps an MCP request with automatic transport-session recovery.
|
|
2794
|
+
*
|
|
2795
|
+
* When the downstream MCP server rejects the request with a 404 indicating
|
|
2796
|
+
* the transport session has expired, this method tears down the stale SDK
|
|
2797
|
+
* client and transport, calls {@link reconnect} to negotiate a fresh session,
|
|
2798
|
+
* and retries the request once.
|
|
2799
|
+
*
|
|
2800
|
+
* Non-transient errors (network failures, auth errors, etc.) propagate as-is.
|
|
2801
|
+
*/
|
|
2802
|
+
async withRetry(fn) {
|
|
2803
|
+
try {
|
|
2804
|
+
return await fn();
|
|
2805
|
+
} catch (error) {
|
|
2806
|
+
if (!(error instanceof Error && error.message.includes("MCP_SESSION_EXPIRED"))) throw error;
|
|
2807
|
+
if (this.client) {
|
|
2808
|
+
try {
|
|
2809
|
+
await this.client.close();
|
|
2810
|
+
} catch {
|
|
2811
|
+
}
|
|
2812
|
+
this.transport = null;
|
|
2813
|
+
this.client = null;
|
|
2814
|
+
}
|
|
2815
|
+
await this.reconnect();
|
|
2816
|
+
return await fn();
|
|
2817
|
+
}
|
|
2780
2818
|
}
|
|
2781
2819
|
/**
|
|
2782
2820
|
* Reconnects to MCP server using existing OAuth provider from Redis
|
|
@@ -2789,6 +2827,12 @@ var MCPClient = class {
|
|
|
2789
2827
|
if (!this.oauthProvider) {
|
|
2790
2828
|
throw new Error("OAuth provider not initialized");
|
|
2791
2829
|
}
|
|
2830
|
+
if (this.client) {
|
|
2831
|
+
try {
|
|
2832
|
+
await this.client.close();
|
|
2833
|
+
} catch {
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2792
2836
|
this.client = new Client(
|
|
2793
2837
|
{
|
|
2794
2838
|
name: MCP_CLIENT_NAME,
|
|
@@ -2984,6 +3028,18 @@ var MultiSessionClient = class {
|
|
|
2984
3028
|
getClients() {
|
|
2985
3029
|
return this.clients;
|
|
2986
3030
|
}
|
|
3031
|
+
/**
|
|
3032
|
+
* Removes and disconnects a single session by ID.
|
|
3033
|
+
*
|
|
3034
|
+
* @returns `true` if the session was found and removed, `false` if not found.
|
|
3035
|
+
*/
|
|
3036
|
+
async removeSession(sessionId) {
|
|
3037
|
+
const idx = this.clients.findIndex((c) => c.getSessionId() === sessionId);
|
|
3038
|
+
if (idx === -1) return false;
|
|
3039
|
+
const [client] = this.clients.splice(idx, 1);
|
|
3040
|
+
await client.disconnect();
|
|
3041
|
+
return true;
|
|
3042
|
+
}
|
|
2987
3043
|
/**
|
|
2988
3044
|
* Gracefully disconnects all active MCP clients and clears the internal list.
|
|
2989
3045
|
*
|