@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/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
|
import { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge';
|
|
11
12
|
|
|
12
13
|
var __defProp = Object.defineProperty;
|
|
@@ -710,6 +711,72 @@ var SqliteStorage = class {
|
|
|
710
711
|
}
|
|
711
712
|
}
|
|
712
713
|
};
|
|
714
|
+
var ALGORITHM = "aes-256-gcm";
|
|
715
|
+
var IV_LENGTH = 12;
|
|
716
|
+
var ENCRYPTION_PREFIX = "enc:1:";
|
|
717
|
+
var warningLogged = false;
|
|
718
|
+
function getKey() {
|
|
719
|
+
const keyString = process.env.STORAGE_ENCRYPTION_KEY;
|
|
720
|
+
if (!keyString) return null;
|
|
721
|
+
if (keyString.length === 64) {
|
|
722
|
+
return Buffer.from(keyString, "hex");
|
|
723
|
+
} else {
|
|
724
|
+
const keyBuffer = Buffer.alloc(32);
|
|
725
|
+
keyBuffer.write(keyString, 0, 32, "utf-8");
|
|
726
|
+
return keyBuffer;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
function encryptObject(data) {
|
|
730
|
+
if (data === void 0 || data === null) return data;
|
|
731
|
+
const key = getKey();
|
|
732
|
+
if (!key) {
|
|
733
|
+
if (!warningLogged) {
|
|
734
|
+
console.warn("[mcp-ts][Storage] WARNING: STORAGE_ENCRYPTION_KEY is not set. Saving sensitive data in plain-text.");
|
|
735
|
+
warningLogged = true;
|
|
736
|
+
}
|
|
737
|
+
return data;
|
|
738
|
+
}
|
|
739
|
+
try {
|
|
740
|
+
const text = JSON.stringify(data);
|
|
741
|
+
const iv = randomBytes(IV_LENGTH);
|
|
742
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
743
|
+
let encrypted = cipher.update(text, "utf-8", "hex");
|
|
744
|
+
encrypted += cipher.final("hex");
|
|
745
|
+
const authTag = cipher.getAuthTag().toString("hex");
|
|
746
|
+
return `${ENCRYPTION_PREFIX}${iv.toString("hex")}:${authTag}:${encrypted}`;
|
|
747
|
+
} catch (e) {
|
|
748
|
+
console.error("[mcp-ts][Storage] Encryption failed, falling back to plain-text.", e);
|
|
749
|
+
return data;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
function decryptObject(data) {
|
|
753
|
+
if (data === void 0 || data === null) return data;
|
|
754
|
+
if (typeof data !== "string" || !data.startsWith(ENCRYPTION_PREFIX)) {
|
|
755
|
+
return data;
|
|
756
|
+
}
|
|
757
|
+
const key = getKey();
|
|
758
|
+
if (!key) {
|
|
759
|
+
console.warn("[mcp-ts][Storage] WARNING: Found encrypted data but STORAGE_ENCRYPTION_KEY is missing. Returning raw encrypted string.");
|
|
760
|
+
return data;
|
|
761
|
+
}
|
|
762
|
+
try {
|
|
763
|
+
const parts = data.split(":");
|
|
764
|
+
if (parts.length !== 5) {
|
|
765
|
+
return data;
|
|
766
|
+
}
|
|
767
|
+
const iv = Buffer.from(parts[2], "hex");
|
|
768
|
+
const authTag = Buffer.from(parts[3], "hex");
|
|
769
|
+
const encryptedText = parts[4];
|
|
770
|
+
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
771
|
+
decipher.setAuthTag(authTag);
|
|
772
|
+
let decrypted = decipher.update(encryptedText, "hex", "utf-8");
|
|
773
|
+
decrypted += decipher.final("utf-8");
|
|
774
|
+
return JSON.parse(decrypted);
|
|
775
|
+
} catch (e) {
|
|
776
|
+
console.error("[mcp-ts][Storage] Decryption failed.", e);
|
|
777
|
+
return data;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
713
780
|
|
|
714
781
|
// src/server/storage/supabase-backend.ts
|
|
715
782
|
var SupabaseStorageBackend = class {
|
|
@@ -742,10 +809,10 @@ var SupabaseStorageBackend = class {
|
|
|
742
809
|
callbackUrl: row.callback_url,
|
|
743
810
|
createdAt: new Date(row.created_at).getTime(),
|
|
744
811
|
identity: row.identity,
|
|
745
|
-
headers: row.headers,
|
|
812
|
+
headers: decryptObject(row.headers),
|
|
746
813
|
active: row.active,
|
|
747
814
|
clientInformation: row.client_information,
|
|
748
|
-
tokens: row.tokens,
|
|
815
|
+
tokens: decryptObject(row.tokens),
|
|
749
816
|
codeVerifier: row.code_verifier,
|
|
750
817
|
clientId: row.client_id
|
|
751
818
|
};
|
|
@@ -766,10 +833,10 @@ var SupabaseStorageBackend = class {
|
|
|
766
833
|
callback_url: session.callbackUrl,
|
|
767
834
|
created_at: new Date(session.createdAt || Date.now()).toISOString(),
|
|
768
835
|
identity,
|
|
769
|
-
headers: session.headers,
|
|
836
|
+
headers: encryptObject(session.headers),
|
|
770
837
|
active: session.active ?? false,
|
|
771
838
|
client_information: session.clientInformation,
|
|
772
|
-
tokens: session.tokens,
|
|
839
|
+
tokens: encryptObject(session.tokens),
|
|
773
840
|
code_verifier: session.codeVerifier,
|
|
774
841
|
client_id: session.clientId,
|
|
775
842
|
expires_at: expiresAt
|
|
@@ -794,9 +861,9 @@ var SupabaseStorageBackend = class {
|
|
|
794
861
|
if ("transportType" in data) updateData.transport_type = data.transportType;
|
|
795
862
|
if ("callbackUrl" in data) updateData.callback_url = data.callbackUrl;
|
|
796
863
|
if ("active" in data) updateData.active = data.active;
|
|
797
|
-
if ("headers" in data) updateData.headers = data.headers;
|
|
864
|
+
if ("headers" in data) updateData.headers = encryptObject(data.headers);
|
|
798
865
|
if ("clientInformation" in data) updateData.client_information = data.clientInformation;
|
|
799
|
-
if ("tokens" in data) updateData.tokens = data.tokens;
|
|
866
|
+
if ("tokens" in data) updateData.tokens = encryptObject(data.tokens);
|
|
800
867
|
if ("codeVerifier" in data) updateData.code_verifier = data.codeVerifier;
|
|
801
868
|
if ("clientId" in data) updateData.client_id = data.clientId;
|
|
802
869
|
const { data: updatedRows, error } = await this.supabase.from("mcp_sessions").update(updateData).eq("identity", identity).eq("session_id", sessionId).select("id");
|