@mcp-ts/sdk 1.3.9 → 1.3.10
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 +0 -1
- package/dist/client/react.d.mts +9 -27
- package/dist/client/react.d.ts +9 -27
- package/dist/client/react.js +99 -73
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +100 -74
- package/dist/client/react.mjs.map +1 -1
- package/dist/index.js +78 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +73 -6
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.js +78 -6
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +73 -6
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client/react/index.ts +5 -1
- package/src/client/react/use-app-host.ts +5 -4
- package/src/client/react/use-mcp-apps.tsx +89 -112
- package/src/client/react/use-mcp.ts +52 -24
- package/src/server/storage/crypto.ts +92 -0
- package/src/server/storage/supabase-backend.ts +7 -6
package/dist/server/index.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { ListToolsResultSchema, CallToolResultSchema, ListPromptsResultSchema, G
|
|
|
7
7
|
import * as fs2 from 'fs';
|
|
8
8
|
import { promises } from 'fs';
|
|
9
9
|
import * as path from 'path';
|
|
10
|
+
import { createDecipheriv, randomBytes, createCipheriv } from 'crypto';
|
|
10
11
|
|
|
11
12
|
var __defProp = Object.defineProperty;
|
|
12
13
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -707,6 +708,72 @@ var SqliteStorage = class {
|
|
|
707
708
|
}
|
|
708
709
|
}
|
|
709
710
|
};
|
|
711
|
+
var ALGORITHM = "aes-256-gcm";
|
|
712
|
+
var IV_LENGTH = 12;
|
|
713
|
+
var ENCRYPTION_PREFIX = "enc:1:";
|
|
714
|
+
var warningLogged = false;
|
|
715
|
+
function getKey() {
|
|
716
|
+
const keyString = process.env.STORAGE_ENCRYPTION_KEY;
|
|
717
|
+
if (!keyString) return null;
|
|
718
|
+
if (keyString.length === 64) {
|
|
719
|
+
return Buffer.from(keyString, "hex");
|
|
720
|
+
} else {
|
|
721
|
+
const keyBuffer = Buffer.alloc(32);
|
|
722
|
+
keyBuffer.write(keyString, 0, 32, "utf-8");
|
|
723
|
+
return keyBuffer;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
function encryptObject(data) {
|
|
727
|
+
if (data === void 0 || data === null) return data;
|
|
728
|
+
const key = getKey();
|
|
729
|
+
if (!key) {
|
|
730
|
+
if (!warningLogged) {
|
|
731
|
+
console.warn("[mcp-ts][Storage] WARNING: STORAGE_ENCRYPTION_KEY is not set. Saving sensitive data in plain-text.");
|
|
732
|
+
warningLogged = true;
|
|
733
|
+
}
|
|
734
|
+
return data;
|
|
735
|
+
}
|
|
736
|
+
try {
|
|
737
|
+
const text = JSON.stringify(data);
|
|
738
|
+
const iv = randomBytes(IV_LENGTH);
|
|
739
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
740
|
+
let encrypted = cipher.update(text, "utf-8", "hex");
|
|
741
|
+
encrypted += cipher.final("hex");
|
|
742
|
+
const authTag = cipher.getAuthTag().toString("hex");
|
|
743
|
+
return `${ENCRYPTION_PREFIX}${iv.toString("hex")}:${authTag}:${encrypted}`;
|
|
744
|
+
} catch (e) {
|
|
745
|
+
console.error("[mcp-ts][Storage] Encryption failed, falling back to plain-text.", e);
|
|
746
|
+
return data;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
function decryptObject(data) {
|
|
750
|
+
if (data === void 0 || data === null) return data;
|
|
751
|
+
if (typeof data !== "string" || !data.startsWith(ENCRYPTION_PREFIX)) {
|
|
752
|
+
return data;
|
|
753
|
+
}
|
|
754
|
+
const key = getKey();
|
|
755
|
+
if (!key) {
|
|
756
|
+
console.warn("[mcp-ts][Storage] WARNING: Found encrypted data but STORAGE_ENCRYPTION_KEY is missing. Returning raw encrypted string.");
|
|
757
|
+
return data;
|
|
758
|
+
}
|
|
759
|
+
try {
|
|
760
|
+
const parts = data.split(":");
|
|
761
|
+
if (parts.length !== 5) {
|
|
762
|
+
return data;
|
|
763
|
+
}
|
|
764
|
+
const iv = Buffer.from(parts[2], "hex");
|
|
765
|
+
const authTag = Buffer.from(parts[3], "hex");
|
|
766
|
+
const encryptedText = parts[4];
|
|
767
|
+
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
768
|
+
decipher.setAuthTag(authTag);
|
|
769
|
+
let decrypted = decipher.update(encryptedText, "hex", "utf-8");
|
|
770
|
+
decrypted += decipher.final("utf-8");
|
|
771
|
+
return JSON.parse(decrypted);
|
|
772
|
+
} catch (e) {
|
|
773
|
+
console.error("[mcp-ts][Storage] Decryption failed.", e);
|
|
774
|
+
return data;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
710
777
|
|
|
711
778
|
// src/server/storage/supabase-backend.ts
|
|
712
779
|
var SupabaseStorageBackend = class {
|
|
@@ -739,10 +806,10 @@ var SupabaseStorageBackend = class {
|
|
|
739
806
|
callbackUrl: row.callback_url,
|
|
740
807
|
createdAt: new Date(row.created_at).getTime(),
|
|
741
808
|
identity: row.identity,
|
|
742
|
-
headers: row.headers,
|
|
809
|
+
headers: decryptObject(row.headers),
|
|
743
810
|
active: row.active,
|
|
744
811
|
clientInformation: row.client_information,
|
|
745
|
-
tokens: row.tokens,
|
|
812
|
+
tokens: decryptObject(row.tokens),
|
|
746
813
|
codeVerifier: row.code_verifier,
|
|
747
814
|
clientId: row.client_id
|
|
748
815
|
};
|
|
@@ -763,10 +830,10 @@ var SupabaseStorageBackend = class {
|
|
|
763
830
|
callback_url: session.callbackUrl,
|
|
764
831
|
created_at: new Date(session.createdAt || Date.now()).toISOString(),
|
|
765
832
|
identity,
|
|
766
|
-
headers: session.headers,
|
|
833
|
+
headers: encryptObject(session.headers),
|
|
767
834
|
active: session.active ?? false,
|
|
768
835
|
client_information: session.clientInformation,
|
|
769
|
-
tokens: session.tokens,
|
|
836
|
+
tokens: encryptObject(session.tokens),
|
|
770
837
|
code_verifier: session.codeVerifier,
|
|
771
838
|
client_id: session.clientId,
|
|
772
839
|
expires_at: expiresAt
|
|
@@ -791,9 +858,9 @@ var SupabaseStorageBackend = class {
|
|
|
791
858
|
if ("transportType" in data) updateData.transport_type = data.transportType;
|
|
792
859
|
if ("callbackUrl" in data) updateData.callback_url = data.callbackUrl;
|
|
793
860
|
if ("active" in data) updateData.active = data.active;
|
|
794
|
-
if ("headers" in data) updateData.headers = data.headers;
|
|
861
|
+
if ("headers" in data) updateData.headers = encryptObject(data.headers);
|
|
795
862
|
if ("clientInformation" in data) updateData.client_information = data.clientInformation;
|
|
796
|
-
if ("tokens" in data) updateData.tokens = data.tokens;
|
|
863
|
+
if ("tokens" in data) updateData.tokens = encryptObject(data.tokens);
|
|
797
864
|
if ("codeVerifier" in data) updateData.code_verifier = data.codeVerifier;
|
|
798
865
|
if ("clientId" in data) updateData.client_id = data.clientId;
|
|
799
866
|
const { data: updatedRows, error } = await this.supabase.from("mcp_sessions").update(updateData).eq("identity", identity).eq("session_id", sessionId).select("id");
|