@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.
Files changed (47) hide show
  1. package/README.md +0 -1
  2. package/dist/adapters/langchain-adapter.js.map +1 -1
  3. package/dist/adapters/langchain-adapter.mjs.map +1 -1
  4. package/dist/client/index.d.mts +3 -189
  5. package/dist/client/index.d.ts +3 -189
  6. package/dist/client/index.js +218 -54
  7. package/dist/client/index.js.map +1 -1
  8. package/dist/client/index.mjs +215 -55
  9. package/dist/client/index.mjs.map +1 -1
  10. package/dist/client/react.d.mts +29 -40
  11. package/dist/client/react.d.ts +29 -40
  12. package/dist/client/react.js +492 -147
  13. package/dist/client/react.js.map +1 -1
  14. package/dist/client/react.mjs +490 -149
  15. package/dist/client/react.mjs.map +1 -1
  16. package/dist/client/vue.d.mts +3 -2
  17. package/dist/client/vue.d.ts +3 -2
  18. package/dist/client/vue.js +239 -63
  19. package/dist/client/vue.js.map +1 -1
  20. package/dist/client/vue.mjs +236 -64
  21. package/dist/client/vue.mjs.map +1 -1
  22. package/dist/index-CQr9q0bF.d.mts +295 -0
  23. package/dist/index-nE_7Io0I.d.ts +295 -0
  24. package/dist/index.d.mts +2 -1
  25. package/dist/index.d.ts +2 -1
  26. package/dist/index.js +315 -64
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +303 -65
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/server/index.js +93 -10
  31. package/dist/server/index.js.map +1 -1
  32. package/dist/server/index.mjs +88 -10
  33. package/dist/server/index.mjs.map +1 -1
  34. package/package.json +13 -11
  35. package/src/adapters/langchain-adapter.ts +1 -1
  36. package/src/client/core/app-host.ts +252 -65
  37. package/src/client/core/constants.ts +30 -0
  38. package/src/client/index.ts +6 -1
  39. package/src/client/react/index.ts +6 -1
  40. package/src/client/react/use-app-host.ts +13 -19
  41. package/src/client/react/use-mcp-apps.tsx +297 -125
  42. package/src/client/react/use-mcp.ts +75 -36
  43. package/src/client/utils/app-host-utils.ts +62 -0
  44. package/src/client/vue/use-mcp.ts +23 -12
  45. package/src/server/mcp/oauth-client.ts +31 -8
  46. package/src/server/storage/crypto.ts +92 -0
  47. package/src/server/storage/supabase-backend.ts +7 -6
@@ -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",