@mcp-ts/sdk 1.3.9 → 1.4.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/README.md +0 -1
- package/dist/adapters/langchain-adapter.js.map +1 -1
- package/dist/adapters/langchain-adapter.mjs.map +1 -1
- package/dist/client/index.d.mts +3 -189
- package/dist/client/index.d.ts +3 -189
- package/dist/client/index.js +218 -54
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +215 -55
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/react.d.mts +29 -40
- package/dist/client/react.d.ts +29 -40
- package/dist/client/react.js +492 -147
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +490 -149
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.d.mts +3 -2
- package/dist/client/vue.d.ts +3 -2
- package/dist/client/vue.js +239 -63
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs +236 -64
- package/dist/client/vue.mjs.map +1 -1
- package/dist/index-CQr9q0bF.d.mts +295 -0
- package/dist/index-nE_7Io0I.d.ts +295 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +315 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +303 -65
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.js +93 -10
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +88 -10
- package/dist/server/index.mjs.map +1 -1
- package/package.json +13 -11
- package/src/adapters/langchain-adapter.ts +1 -1
- package/src/client/core/app-host.ts +252 -65
- package/src/client/core/constants.ts +30 -0
- package/src/client/index.ts +6 -1
- package/src/client/react/index.ts +6 -1
- package/src/client/react/use-app-host.ts +13 -19
- package/src/client/react/use-mcp-apps.tsx +297 -125
- package/src/client/react/use-mcp.ts +75 -36
- package/src/client/utils/app-host-utils.ts +62 -0
- package/src/client/vue/use-mcp.ts +23 -12
- package/src/server/mcp/oauth-client.ts +31 -8
- 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");
|
|
@@ -1587,13 +1654,24 @@ var MCPClient = class _MCPClient {
|
|
|
1587
1654
|
}
|
|
1588
1655
|
} catch (error) {
|
|
1589
1656
|
if (error instanceof UnauthorizedError$1 || error instanceof Error && error.message.toLowerCase().includes("unauthorized")) {
|
|
1590
|
-
this.emitStateChange("AUTHENTICATING");
|
|
1591
|
-
console.log(`[MCPClient] Saving session ${this.sessionId} with 10min TTL (OAuth pending)`);
|
|
1592
|
-
await this.saveSession(Math.floor(STATE_EXPIRATION_MS / 1e3), false);
|
|
1593
1657
|
let authUrl = "";
|
|
1594
1658
|
if (this.oauthProvider) {
|
|
1595
|
-
authUrl = this.oauthProvider.authUrl || "";
|
|
1659
|
+
authUrl = (this.oauthProvider.authUrl || "").trim();
|
|
1596
1660
|
}
|
|
1661
|
+
if (!authUrl) {
|
|
1662
|
+
const detail = error instanceof Error && error.message.trim().length > 0 ? error.message.trim() : "Unauthorized";
|
|
1663
|
+
const message = detail.toLowerCase() === "unauthorized" ? "OAuth authorization URL not available" : `OAuth authorization URL not available: ${detail}`;
|
|
1664
|
+
this.emitError(message, "auth");
|
|
1665
|
+
this.emitStateChange("FAILED");
|
|
1666
|
+
try {
|
|
1667
|
+
await storage.removeSession(this.identity, this.sessionId);
|
|
1668
|
+
} catch {
|
|
1669
|
+
}
|
|
1670
|
+
throw new Error(message);
|
|
1671
|
+
}
|
|
1672
|
+
this.emitStateChange("AUTHENTICATING");
|
|
1673
|
+
console.log(`[MCPClient] Saving session ${this.sessionId} with 10min TTL (OAuth pending)`);
|
|
1674
|
+
await this.saveSession(Math.floor(STATE_EXPIRATION_MS / 1e3), false);
|
|
1597
1675
|
if (this.serverId) {
|
|
1598
1676
|
this._onConnectionEvent.fire({
|
|
1599
1677
|
type: "auth_required",
|