@mcp-ts/sdk 1.3.5 → 1.3.6
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/bin/mcp-ts.d.mts +1 -0
- package/dist/bin/mcp-ts.d.ts +1 -0
- package/dist/bin/mcp-ts.js +105 -0
- package/dist/bin/mcp-ts.js.map +1 -0
- package/dist/bin/mcp-ts.mjs +82 -0
- package/dist/bin/mcp-ts.mjs.map +1 -0
- package/dist/index.js +279 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +217 -21
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.js +262 -21
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +217 -21
- package/dist/server/index.mjs.map +1 -1
- package/package.json +19 -6
- package/src/bin/mcp-ts.ts +102 -0
- package/src/server/handlers/nextjs-handler.ts +12 -12
- package/src/server/handlers/sse-handler.ts +61 -61
- package/src/server/storage/file-backend.ts +1 -0
- package/src/server/storage/index.ts +67 -25
- package/src/server/storage/memory-backend.ts +4 -0
- package/src/server/storage/redis-backend.ts +9 -0
- package/src/server/storage/sqlite-backend.ts +1 -0
- package/src/server/storage/supabase-backend.ts +227 -0
- package/src/shared/event-routing.ts +28 -28
- package/supabase/migrations/20260330195700_install_mcp_sessions.sql +84 -0
package/dist/index.js
CHANGED
|
@@ -43,6 +43,12 @@ var __export = (target, all) => {
|
|
|
43
43
|
};
|
|
44
44
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
45
45
|
|
|
46
|
+
// node_modules/tsup/assets/cjs_shims.js
|
|
47
|
+
var init_cjs_shims = __esm({
|
|
48
|
+
"node_modules/tsup/assets/cjs_shims.js"() {
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
46
52
|
// src/server/storage/redis.ts
|
|
47
53
|
var redis_exports = {};
|
|
48
54
|
__export(redis_exports, {
|
|
@@ -118,6 +124,7 @@ async function closeRedis() {
|
|
|
118
124
|
var redisInstance, redis;
|
|
119
125
|
var init_redis = __esm({
|
|
120
126
|
"src/server/storage/redis.ts"() {
|
|
127
|
+
init_cjs_shims();
|
|
121
128
|
redisInstance = null;
|
|
122
129
|
redis = new Proxy({}, {
|
|
123
130
|
get(_target, prop) {
|
|
@@ -134,7 +141,26 @@ var init_redis = __esm({
|
|
|
134
141
|
}
|
|
135
142
|
});
|
|
136
143
|
|
|
144
|
+
// src/index.ts
|
|
145
|
+
init_cjs_shims();
|
|
146
|
+
|
|
147
|
+
// src/server/index.ts
|
|
148
|
+
init_cjs_shims();
|
|
149
|
+
|
|
150
|
+
// src/server/mcp/oauth-client.ts
|
|
151
|
+
init_cjs_shims();
|
|
152
|
+
|
|
153
|
+
// src/server/mcp/storage-oauth-provider.ts
|
|
154
|
+
init_cjs_shims();
|
|
155
|
+
|
|
156
|
+
// src/server/storage/index.ts
|
|
157
|
+
init_cjs_shims();
|
|
158
|
+
|
|
159
|
+
// src/server/storage/redis-backend.ts
|
|
160
|
+
init_cjs_shims();
|
|
161
|
+
|
|
137
162
|
// src/shared/constants.ts
|
|
163
|
+
init_cjs_shims();
|
|
138
164
|
var SESSION_TTL_SECONDS = 43200;
|
|
139
165
|
var STATE_EXPIRATION_MS = 10 * 60 * 1e3;
|
|
140
166
|
var DEFAULT_HEARTBEAT_INTERVAL_MS = 3e4;
|
|
@@ -166,6 +192,14 @@ var RedisStorageBackend = class {
|
|
|
166
192
|
__publicField(this, "IDENTITY_KEY_PREFIX", "mcp:identity:");
|
|
167
193
|
__publicField(this, "IDENTITY_KEY_SUFFIX", ":sessions");
|
|
168
194
|
}
|
|
195
|
+
async init() {
|
|
196
|
+
try {
|
|
197
|
+
await this.redis.ping();
|
|
198
|
+
console.log("[mcp-ts][Storage] Redis: \u2713 Connected to server.");
|
|
199
|
+
} catch (error) {
|
|
200
|
+
throw new Error(`[RedisStorage] Failed to connect to Redis: ${error.message}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
169
203
|
/**
|
|
170
204
|
* Generates Redis key for a specific session
|
|
171
205
|
* @private
|
|
@@ -376,6 +410,9 @@ var RedisStorageBackend = class {
|
|
|
376
410
|
}
|
|
377
411
|
}
|
|
378
412
|
};
|
|
413
|
+
|
|
414
|
+
// src/server/storage/memory-backend.ts
|
|
415
|
+
init_cjs_shims();
|
|
379
416
|
var firstChar2 = nanoid.customAlphabet(
|
|
380
417
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
|
381
418
|
1
|
|
@@ -391,6 +428,9 @@ var MemoryStorageBackend = class {
|
|
|
391
428
|
// Map<identity, Set<sessionId>>
|
|
392
429
|
__publicField(this, "identitySessions", /* @__PURE__ */ new Map());
|
|
393
430
|
}
|
|
431
|
+
async init() {
|
|
432
|
+
console.log("[mcp-ts][Storage] Memory: \u2713 internal memory store active.");
|
|
433
|
+
}
|
|
394
434
|
getSessionKey(identity, sessionId) {
|
|
395
435
|
return `${identity}:${sessionId}`;
|
|
396
436
|
}
|
|
@@ -466,6 +506,9 @@ var MemoryStorageBackend = class {
|
|
|
466
506
|
async disconnect() {
|
|
467
507
|
}
|
|
468
508
|
};
|
|
509
|
+
|
|
510
|
+
// src/server/storage/file-backend.ts
|
|
511
|
+
init_cjs_shims();
|
|
469
512
|
var firstChar3 = nanoid.customAlphabet(
|
|
470
513
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
|
471
514
|
1
|
|
@@ -510,6 +553,7 @@ var FileStorageBackend = class {
|
|
|
510
553
|
}
|
|
511
554
|
}
|
|
512
555
|
this.initialized = true;
|
|
556
|
+
console.log(`[mcp-ts][Storage] File: \u2713 storage directory at ${path__namespace.dirname(this.filePath)} verified.`);
|
|
513
557
|
}
|
|
514
558
|
async ensureInitialized() {
|
|
515
559
|
if (!this.initialized) await this.init();
|
|
@@ -586,6 +630,9 @@ var FileStorageBackend = class {
|
|
|
586
630
|
async disconnect() {
|
|
587
631
|
}
|
|
588
632
|
};
|
|
633
|
+
|
|
634
|
+
// src/server/storage/sqlite-backend.ts
|
|
635
|
+
init_cjs_shims();
|
|
589
636
|
var SqliteStorage = class {
|
|
590
637
|
constructor(options = {}) {
|
|
591
638
|
__publicField(this, "db", null);
|
|
@@ -614,6 +661,7 @@ var SqliteStorage = class {
|
|
|
614
661
|
CREATE INDEX IF NOT EXISTS idx_${this.table}_identity ON ${this.table}(identity);
|
|
615
662
|
`);
|
|
616
663
|
this.initialized = true;
|
|
664
|
+
console.log(`[mcp-ts][Storage] SQLite: \u2713 database at ${this.dbPath} verified.`);
|
|
617
665
|
} catch (error) {
|
|
618
666
|
if (error.code === "MODULE_NOT_FOUND" || error.message?.includes("better-sqlite3")) {
|
|
619
667
|
throw new Error(
|
|
@@ -729,6 +777,161 @@ var SqliteStorage = class {
|
|
|
729
777
|
}
|
|
730
778
|
};
|
|
731
779
|
|
|
780
|
+
// src/server/storage/supabase-backend.ts
|
|
781
|
+
init_cjs_shims();
|
|
782
|
+
var SupabaseStorageBackend = class {
|
|
783
|
+
constructor(supabase) {
|
|
784
|
+
this.supabase = supabase;
|
|
785
|
+
__publicField(this, "DEFAULT_TTL", SESSION_TTL_SECONDS);
|
|
786
|
+
}
|
|
787
|
+
async init() {
|
|
788
|
+
const { error } = await this.supabase.from("mcp_sessions").select("session_id").limit(0);
|
|
789
|
+
if (error) {
|
|
790
|
+
if (error.code === "42P01") {
|
|
791
|
+
throw new Error(
|
|
792
|
+
'[SupabaseStorage] Table "mcp_sessions" not found in your database. Please run "npx mcp-ts supabase-init" in your project to set up the required table and RLS policies.'
|
|
793
|
+
);
|
|
794
|
+
}
|
|
795
|
+
throw new Error(`[SupabaseStorage] Initialization check failed: ${error.message}`);
|
|
796
|
+
}
|
|
797
|
+
console.log('[mcp-ts][Storage] Supabase: \u2713 "mcp_sessions" table verified.');
|
|
798
|
+
}
|
|
799
|
+
generateSessionId() {
|
|
800
|
+
return crypto.randomUUID();
|
|
801
|
+
}
|
|
802
|
+
mapRowToSessionData(row) {
|
|
803
|
+
return {
|
|
804
|
+
sessionId: row.session_id,
|
|
805
|
+
serverId: row.server_id,
|
|
806
|
+
serverName: row.server_name,
|
|
807
|
+
serverUrl: row.server_url,
|
|
808
|
+
transportType: row.transport_type,
|
|
809
|
+
callbackUrl: row.callback_url,
|
|
810
|
+
createdAt: new Date(row.created_at).getTime(),
|
|
811
|
+
identity: row.identity,
|
|
812
|
+
headers: row.headers,
|
|
813
|
+
active: row.active,
|
|
814
|
+
clientInformation: row.client_information,
|
|
815
|
+
tokens: row.tokens,
|
|
816
|
+
codeVerifier: row.code_verifier,
|
|
817
|
+
clientId: row.client_id
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
async createSession(session, ttl) {
|
|
821
|
+
const { sessionId, identity } = session;
|
|
822
|
+
if (!sessionId || !identity) throw new Error("identity and sessionId required");
|
|
823
|
+
const effectiveTtl = ttl ?? this.DEFAULT_TTL;
|
|
824
|
+
const expiresAt = new Date(Date.now() + effectiveTtl * 1e3).toISOString();
|
|
825
|
+
const { error } = await this.supabase.from("mcp_sessions").insert({
|
|
826
|
+
session_id: sessionId,
|
|
827
|
+
user_id: identity,
|
|
828
|
+
// Maps user_id to identity to support RLS using auth.uid()
|
|
829
|
+
server_id: session.serverId,
|
|
830
|
+
server_name: session.serverName,
|
|
831
|
+
server_url: session.serverUrl,
|
|
832
|
+
transport_type: session.transportType,
|
|
833
|
+
callback_url: session.callbackUrl,
|
|
834
|
+
created_at: new Date(session.createdAt || Date.now()).toISOString(),
|
|
835
|
+
identity,
|
|
836
|
+
headers: session.headers,
|
|
837
|
+
active: session.active ?? false,
|
|
838
|
+
client_information: session.clientInformation,
|
|
839
|
+
tokens: session.tokens,
|
|
840
|
+
code_verifier: session.codeVerifier,
|
|
841
|
+
client_id: session.clientId,
|
|
842
|
+
expires_at: expiresAt
|
|
843
|
+
});
|
|
844
|
+
if (error) {
|
|
845
|
+
if (error.code === "23505") {
|
|
846
|
+
throw new Error(`Session ${sessionId} already exists`);
|
|
847
|
+
}
|
|
848
|
+
throw new Error(`Failed to create session in Supabase: ${error.message}`);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
async updateSession(identity, sessionId, data, ttl) {
|
|
852
|
+
const effectiveTtl = ttl ?? this.DEFAULT_TTL;
|
|
853
|
+
const expiresAt = new Date(Date.now() + effectiveTtl * 1e3).toISOString();
|
|
854
|
+
const updateData = {
|
|
855
|
+
expires_at: expiresAt,
|
|
856
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
857
|
+
};
|
|
858
|
+
if ("serverId" in data) updateData.server_id = data.serverId;
|
|
859
|
+
if ("serverName" in data) updateData.server_name = data.serverName;
|
|
860
|
+
if ("serverUrl" in data) updateData.server_url = data.serverUrl;
|
|
861
|
+
if ("transportType" in data) updateData.transport_type = data.transportType;
|
|
862
|
+
if ("callbackUrl" in data) updateData.callback_url = data.callbackUrl;
|
|
863
|
+
if ("active" in data) updateData.active = data.active;
|
|
864
|
+
if ("headers" in data) updateData.headers = data.headers;
|
|
865
|
+
if ("clientInformation" in data) updateData.client_information = data.clientInformation;
|
|
866
|
+
if ("tokens" in data) updateData.tokens = data.tokens;
|
|
867
|
+
if ("codeVerifier" in data) updateData.code_verifier = data.codeVerifier;
|
|
868
|
+
if ("clientId" in data) updateData.client_id = data.clientId;
|
|
869
|
+
const { data: updatedRows, error } = await this.supabase.from("mcp_sessions").update(updateData).eq("identity", identity).eq("session_id", sessionId).select("id");
|
|
870
|
+
if (error) {
|
|
871
|
+
throw new Error(`Failed to update session: ${error.message}`);
|
|
872
|
+
}
|
|
873
|
+
if (!updatedRows || updatedRows.length === 0) {
|
|
874
|
+
throw new Error(`Session ${sessionId} not found for identity ${identity}`);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
async getSession(identity, sessionId) {
|
|
878
|
+
const { data, error } = await this.supabase.from("mcp_sessions").select("*").eq("identity", identity).eq("session_id", sessionId).maybeSingle();
|
|
879
|
+
if (error) {
|
|
880
|
+
console.error("[SupabaseStorage] Failed to get session:", error);
|
|
881
|
+
return null;
|
|
882
|
+
}
|
|
883
|
+
if (!data) return null;
|
|
884
|
+
return this.mapRowToSessionData(data);
|
|
885
|
+
}
|
|
886
|
+
async getIdentitySessionsData(identity) {
|
|
887
|
+
const { data, error } = await this.supabase.from("mcp_sessions").select("*").eq("identity", identity);
|
|
888
|
+
if (error) {
|
|
889
|
+
console.error(`[SupabaseStorage] Failed to get session data for ${identity}:`, error);
|
|
890
|
+
return [];
|
|
891
|
+
}
|
|
892
|
+
return data.map((row) => this.mapRowToSessionData(row));
|
|
893
|
+
}
|
|
894
|
+
async removeSession(identity, sessionId) {
|
|
895
|
+
const { error } = await this.supabase.from("mcp_sessions").delete().eq("identity", identity).eq("session_id", sessionId);
|
|
896
|
+
if (error) {
|
|
897
|
+
console.error("[SupabaseStorage] Failed to remove session:", error);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
async getIdentityMcpSessions(identity) {
|
|
901
|
+
const { data, error } = await this.supabase.from("mcp_sessions").select("session_id").eq("identity", identity);
|
|
902
|
+
if (error) {
|
|
903
|
+
console.error(`[SupabaseStorage] Failed to get sessions for ${identity}:`, error);
|
|
904
|
+
return [];
|
|
905
|
+
}
|
|
906
|
+
return data.map((row) => row.session_id);
|
|
907
|
+
}
|
|
908
|
+
async getAllSessionIds() {
|
|
909
|
+
const { data, error } = await this.supabase.from("mcp_sessions").select("session_id");
|
|
910
|
+
if (error) {
|
|
911
|
+
console.error("[SupabaseStorage] Failed to get all sessions:", error);
|
|
912
|
+
return [];
|
|
913
|
+
}
|
|
914
|
+
return data.map((row) => row.session_id);
|
|
915
|
+
}
|
|
916
|
+
async clearAll() {
|
|
917
|
+
const { error } = await this.supabase.from("mcp_sessions").delete().neq("session_id", "");
|
|
918
|
+
if (error) {
|
|
919
|
+
console.error("[SupabaseStorage] Failed to clear sessions:", error);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
async cleanupExpiredSessions() {
|
|
923
|
+
const { error } = await this.supabase.from("mcp_sessions").delete().lt("expires_at", (/* @__PURE__ */ new Date()).toISOString());
|
|
924
|
+
if (error) {
|
|
925
|
+
console.error("[SupabaseStorage] Failed to cleanup expired sessions:", error);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
async disconnect() {
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
// src/server/storage/types.ts
|
|
933
|
+
init_cjs_shims();
|
|
934
|
+
|
|
732
935
|
// src/server/storage/index.ts
|
|
733
936
|
var storageInstance = null;
|
|
734
937
|
var storagePromise = null;
|
|
@@ -747,53 +950,85 @@ async function createStorage() {
|
|
|
747
950
|
try {
|
|
748
951
|
const { getRedis: getRedis2 } = await Promise.resolve().then(() => (init_redis(), redis_exports));
|
|
749
952
|
const redis2 = await getRedis2();
|
|
750
|
-
console.log(
|
|
751
|
-
return new RedisStorageBackend(redis2);
|
|
953
|
+
console.log('[mcp-ts][Storage] Explicit selection: "redis"');
|
|
954
|
+
return await initializeStorage(new RedisStorageBackend(redis2));
|
|
752
955
|
} catch (error) {
|
|
753
|
-
console.error("[Storage] Failed to initialize Redis:", error.message);
|
|
754
|
-
console.log("[Storage] Falling back to In-Memory storage");
|
|
755
|
-
return new MemoryStorageBackend();
|
|
956
|
+
console.error("[mcp-ts][Storage] Failed to initialize Redis:", error.message);
|
|
957
|
+
console.log("[mcp-ts][Storage] Falling back to In-Memory storage");
|
|
958
|
+
return await initializeStorage(new MemoryStorageBackend());
|
|
756
959
|
}
|
|
757
960
|
}
|
|
758
961
|
if (type === "file") {
|
|
759
962
|
const filePath = process.env.MCP_TS_STORAGE_FILE;
|
|
760
|
-
|
|
761
|
-
console.warn('[Storage] MCP_TS_STORAGE_TYPE is "file" but MCP_TS_STORAGE_FILE is missing');
|
|
762
|
-
}
|
|
763
|
-
console.log(`[Storage] Using File storage (${filePath}) (Explicit)`);
|
|
963
|
+
console.log(`[mcp-ts][Storage] Explicit selection: "file" (${filePath || "default"})`);
|
|
764
964
|
return await initializeStorage(new FileStorageBackend({ path: filePath }));
|
|
765
965
|
}
|
|
766
966
|
if (type === "sqlite") {
|
|
767
967
|
const dbPath = process.env.MCP_TS_STORAGE_SQLITE_PATH;
|
|
768
|
-
console.log(`[Storage]
|
|
968
|
+
console.log(`[mcp-ts][Storage] Explicit selection: "sqlite" (${dbPath || "default"})`);
|
|
769
969
|
return await initializeStorage(new SqliteStorage({ path: dbPath }));
|
|
770
970
|
}
|
|
971
|
+
if (type === "supabase") {
|
|
972
|
+
const url = process.env.SUPABASE_URL;
|
|
973
|
+
const key = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_ANON_KEY;
|
|
974
|
+
if (!url || !key) {
|
|
975
|
+
console.warn('[mcp-ts][Storage] Explicit selection "supabase" requires SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY.');
|
|
976
|
+
} else {
|
|
977
|
+
if (!process.env.SUPABASE_SERVICE_ROLE_KEY) {
|
|
978
|
+
console.warn('[mcp-ts][Storage] \u26A0\uFE0F Warning: Using "SUPABASE_ANON_KEY" for server-side storage. You may encounter RLS policy violations. "SUPABASE_SERVICE_ROLE_KEY" is recommended.');
|
|
979
|
+
}
|
|
980
|
+
try {
|
|
981
|
+
const { createClient } = await import('@supabase/supabase-js');
|
|
982
|
+
const client = createClient(url, key);
|
|
983
|
+
console.log('[mcp-ts][Storage] Explicit selection: "supabase"');
|
|
984
|
+
return await initializeStorage(new SupabaseStorageBackend(client));
|
|
985
|
+
} catch (error) {
|
|
986
|
+
console.error("[mcp-ts][Storage] Failed to initialize Supabase:", error.message);
|
|
987
|
+
console.log("[mcp-ts][Storage] Falling back to In-Memory storage");
|
|
988
|
+
return await initializeStorage(new MemoryStorageBackend());
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
}
|
|
771
992
|
if (type === "memory") {
|
|
772
|
-
console.log(
|
|
773
|
-
return new MemoryStorageBackend();
|
|
993
|
+
console.log('[mcp-ts][Storage] Explicit selection: "memory"');
|
|
994
|
+
return await initializeStorage(new MemoryStorageBackend());
|
|
774
995
|
}
|
|
775
996
|
if (process.env.REDIS_URL) {
|
|
776
997
|
try {
|
|
777
998
|
const { getRedis: getRedis2 } = await Promise.resolve().then(() => (init_redis(), redis_exports));
|
|
778
999
|
const redis2 = await getRedis2();
|
|
779
|
-
console.log(
|
|
780
|
-
return new RedisStorageBackend(redis2);
|
|
1000
|
+
console.log('[mcp-ts][Storage] Auto-detection: "redis" (via REDIS_URL)');
|
|
1001
|
+
return await initializeStorage(new RedisStorageBackend(redis2));
|
|
781
1002
|
} catch (error) {
|
|
782
|
-
console.error("[Storage] Redis auto-detection failed:", error.message);
|
|
783
|
-
console.log("[Storage] Falling back to
|
|
784
|
-
return new MemoryStorageBackend();
|
|
1003
|
+
console.error("[mcp-ts][Storage] Redis auto-detection failed:", error.message);
|
|
1004
|
+
console.log("[mcp-ts][Storage] Falling back to next available backend");
|
|
785
1005
|
}
|
|
786
1006
|
}
|
|
787
1007
|
if (process.env.MCP_TS_STORAGE_FILE) {
|
|
788
|
-
console.log(`[Storage] Auto-
|
|
1008
|
+
console.log(`[mcp-ts][Storage] Auto-detection: "file" (${process.env.MCP_TS_STORAGE_FILE})`);
|
|
789
1009
|
return await initializeStorage(new FileStorageBackend({ path: process.env.MCP_TS_STORAGE_FILE }));
|
|
790
1010
|
}
|
|
791
1011
|
if (process.env.MCP_TS_STORAGE_SQLITE_PATH) {
|
|
792
|
-
console.log(`[Storage] Auto-
|
|
1012
|
+
console.log(`[mcp-ts][Storage] Auto-detection: "sqlite" (${process.env.MCP_TS_STORAGE_SQLITE_PATH})`);
|
|
793
1013
|
return await initializeStorage(new SqliteStorage({ path: process.env.MCP_TS_STORAGE_SQLITE_PATH }));
|
|
794
1014
|
}
|
|
795
|
-
|
|
796
|
-
|
|
1015
|
+
if (process.env.SUPABASE_URL && (process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_ANON_KEY)) {
|
|
1016
|
+
try {
|
|
1017
|
+
const { createClient } = await import('@supabase/supabase-js');
|
|
1018
|
+
const url = process.env.SUPABASE_URL;
|
|
1019
|
+
const key = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_ANON_KEY;
|
|
1020
|
+
if (!process.env.SUPABASE_SERVICE_ROLE_KEY) {
|
|
1021
|
+
console.warn('[mcp-ts][Storage] \u26A0\uFE0F Warning: Using "SUPABASE_ANON_KEY" for server-side storage. You may encounter RLS policy violations. "SUPABASE_SERVICE_ROLE_KEY" is recommended.');
|
|
1022
|
+
}
|
|
1023
|
+
const client = createClient(url, key);
|
|
1024
|
+
console.log('[mcp-ts][Storage] Auto-detection: "supabase" (via SUPABASE_URL)');
|
|
1025
|
+
return await initializeStorage(new SupabaseStorageBackend(client));
|
|
1026
|
+
} catch (error) {
|
|
1027
|
+
console.error("[mcp-ts][Storage] Supabase auto-detection failed:", error.message);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
console.log('[mcp-ts][Storage] Defaulting to: "memory"');
|
|
1031
|
+
return await initializeStorage(new MemoryStorageBackend());
|
|
797
1032
|
}
|
|
798
1033
|
async function getStorage() {
|
|
799
1034
|
if (storageInstance) {
|
|
@@ -1004,6 +1239,7 @@ var StorageOAuthClientProvider = class {
|
|
|
1004
1239
|
};
|
|
1005
1240
|
|
|
1006
1241
|
// src/shared/utils.ts
|
|
1242
|
+
init_cjs_shims();
|
|
1007
1243
|
function sanitizeServerLabel(name) {
|
|
1008
1244
|
let sanitized = name.replace(/[^a-zA-Z0-9-_]/g, "_").replace(/_{2,}/g, "_").toLowerCase();
|
|
1009
1245
|
if (!/^[a-zA-Z]/.test(sanitized)) {
|
|
@@ -1013,6 +1249,7 @@ function sanitizeServerLabel(name) {
|
|
|
1013
1249
|
}
|
|
1014
1250
|
|
|
1015
1251
|
// src/shared/events.ts
|
|
1252
|
+
init_cjs_shims();
|
|
1016
1253
|
var Emitter = class {
|
|
1017
1254
|
constructor() {
|
|
1018
1255
|
__publicField(this, "listeners", /* @__PURE__ */ new Set());
|
|
@@ -1074,6 +1311,7 @@ var DisposableStore = class {
|
|
|
1074
1311
|
};
|
|
1075
1312
|
|
|
1076
1313
|
// src/shared/errors.ts
|
|
1314
|
+
init_cjs_shims();
|
|
1077
1315
|
var McpError = class extends Error {
|
|
1078
1316
|
constructor(code, message, cause) {
|
|
1079
1317
|
super(message);
|
|
@@ -2042,6 +2280,7 @@ var MCPClient = class _MCPClient {
|
|
|
2042
2280
|
};
|
|
2043
2281
|
|
|
2044
2282
|
// src/server/mcp/multi-session-client.ts
|
|
2283
|
+
init_cjs_shims();
|
|
2045
2284
|
var MultiSessionClient = class {
|
|
2046
2285
|
constructor(identity, options = {}) {
|
|
2047
2286
|
__publicField(this, "clients", []);
|
|
@@ -2131,7 +2370,11 @@ var MultiSessionClient = class {
|
|
|
2131
2370
|
}
|
|
2132
2371
|
};
|
|
2133
2372
|
|
|
2373
|
+
// src/server/handlers/sse-handler.ts
|
|
2374
|
+
init_cjs_shims();
|
|
2375
|
+
|
|
2134
2376
|
// src/shared/event-routing.ts
|
|
2377
|
+
init_cjs_shims();
|
|
2135
2378
|
function isRpcResponseEvent(event) {
|
|
2136
2379
|
return "id" in event && ("result" in event || "error" in event);
|
|
2137
2380
|
}
|
|
@@ -2570,6 +2813,7 @@ function writeSSEEvent(res, event, data) {
|
|
|
2570
2813
|
}
|
|
2571
2814
|
|
|
2572
2815
|
// src/server/handlers/nextjs-handler.ts
|
|
2816
|
+
init_cjs_shims();
|
|
2573
2817
|
function createNextMcpHandler(options = {}) {
|
|
2574
2818
|
const {
|
|
2575
2819
|
getIdentity = (request) => new URL(request.url).searchParams.get("identity"),
|
|
@@ -2717,6 +2961,12 @@ data: ${JSON.stringify(data)}
|
|
|
2717
2961
|
}
|
|
2718
2962
|
return { GET, POST };
|
|
2719
2963
|
}
|
|
2964
|
+
|
|
2965
|
+
// src/client/index.ts
|
|
2966
|
+
init_cjs_shims();
|
|
2967
|
+
|
|
2968
|
+
// src/client/core/sse-client.ts
|
|
2969
|
+
init_cjs_shims();
|
|
2720
2970
|
var CONNECTION_EVENT_INTERVAL_MS = 300;
|
|
2721
2971
|
var SSEClient = class {
|
|
2722
2972
|
constructor(options) {
|
|
@@ -2965,6 +3215,9 @@ var SSEClient = class {
|
|
|
2965
3215
|
}
|
|
2966
3216
|
}
|
|
2967
3217
|
};
|
|
3218
|
+
|
|
3219
|
+
// src/client/core/app-host.ts
|
|
3220
|
+
init_cjs_shims();
|
|
2968
3221
|
var HOST_INFO = { name: "mcp-ts-host", version: "1.0.0" };
|
|
2969
3222
|
var SANDBOX_PERMISSIONS = [
|
|
2970
3223
|
"allow-scripts",
|
|
@@ -3262,7 +3515,11 @@ var AppHost = class {
|
|
|
3262
3515
|
}
|
|
3263
3516
|
};
|
|
3264
3517
|
|
|
3518
|
+
// src/shared/index.ts
|
|
3519
|
+
init_cjs_shims();
|
|
3520
|
+
|
|
3265
3521
|
// src/shared/types.ts
|
|
3522
|
+
init_cjs_shims();
|
|
3266
3523
|
function isConnectSuccess(response) {
|
|
3267
3524
|
return "success" in response && response.success === true;
|
|
3268
3525
|
}
|
|
@@ -3280,6 +3537,7 @@ function isCallToolSuccess(response) {
|
|
|
3280
3537
|
}
|
|
3281
3538
|
|
|
3282
3539
|
// src/shared/tool-utils.ts
|
|
3540
|
+
init_cjs_shims();
|
|
3283
3541
|
function getToolUiResourceUri(tool) {
|
|
3284
3542
|
const meta = tool._meta;
|
|
3285
3543
|
if (!meta?.ui) return void 0;
|