@mcp-ts/sdk 1.3.6 → 1.3.9

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 (103) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +398 -404
  3. package/dist/adapters/agui-adapter.d.mts +1 -1
  4. package/dist/adapters/agui-adapter.d.ts +1 -1
  5. package/dist/adapters/agui-adapter.js +2 -2
  6. package/dist/adapters/agui-adapter.js.map +1 -1
  7. package/dist/adapters/agui-adapter.mjs +2 -2
  8. package/dist/adapters/agui-adapter.mjs.map +1 -1
  9. package/dist/adapters/agui-middleware.d.mts +1 -1
  10. package/dist/adapters/agui-middleware.d.ts +1 -1
  11. package/dist/adapters/agui-middleware.js.map +1 -1
  12. package/dist/adapters/agui-middleware.mjs.map +1 -1
  13. package/dist/adapters/ai-adapter.d.mts +1 -1
  14. package/dist/adapters/ai-adapter.d.ts +1 -1
  15. package/dist/adapters/ai-adapter.js +1 -1
  16. package/dist/adapters/ai-adapter.js.map +1 -1
  17. package/dist/adapters/ai-adapter.mjs +1 -1
  18. package/dist/adapters/ai-adapter.mjs.map +1 -1
  19. package/dist/adapters/langchain-adapter.d.mts +1 -1
  20. package/dist/adapters/langchain-adapter.d.ts +1 -1
  21. package/dist/adapters/langchain-adapter.js +1 -1
  22. package/dist/adapters/langchain-adapter.js.map +1 -1
  23. package/dist/adapters/langchain-adapter.mjs +1 -1
  24. package/dist/adapters/langchain-adapter.mjs.map +1 -1
  25. package/dist/adapters/mastra-adapter.d.mts +1 -1
  26. package/dist/adapters/mastra-adapter.d.ts +1 -1
  27. package/dist/adapters/mastra-adapter.js +1 -1
  28. package/dist/adapters/mastra-adapter.js.map +1 -1
  29. package/dist/adapters/mastra-adapter.mjs +1 -1
  30. package/dist/adapters/mastra-adapter.mjs.map +1 -1
  31. package/dist/bin/mcp-ts.js +0 -0
  32. package/dist/bin/mcp-ts.js.map +1 -1
  33. package/dist/bin/mcp-ts.mjs +0 -0
  34. package/dist/bin/mcp-ts.mjs.map +1 -1
  35. package/dist/client/index.js.map +1 -1
  36. package/dist/client/index.mjs.map +1 -1
  37. package/dist/client/react.d.mts +2 -2
  38. package/dist/client/react.d.ts +2 -2
  39. package/dist/client/react.js +25 -2
  40. package/dist/client/react.js.map +1 -1
  41. package/dist/client/react.mjs +26 -3
  42. package/dist/client/react.mjs.map +1 -1
  43. package/dist/client/vue.js.map +1 -1
  44. package/dist/client/vue.mjs.map +1 -1
  45. package/dist/index.d.mts +1 -1
  46. package/dist/index.d.ts +1 -1
  47. package/dist/index.js +134 -71
  48. package/dist/index.js.map +1 -1
  49. package/dist/index.mjs +134 -71
  50. package/dist/index.mjs.map +1 -1
  51. package/dist/{multi-session-client-BYLarghq.d.ts → multi-session-client-CHE8QpVE.d.ts} +75 -5
  52. package/dist/{multi-session-client-CzhMkE0k.d.mts → multi-session-client-CQsRbxYI.d.mts} +75 -5
  53. package/dist/server/index.d.mts +1 -1
  54. package/dist/server/index.d.ts +1 -1
  55. package/dist/server/index.js +134 -71
  56. package/dist/server/index.js.map +1 -1
  57. package/dist/server/index.mjs +134 -71
  58. package/dist/server/index.mjs.map +1 -1
  59. package/dist/shared/index.js +10 -2
  60. package/dist/shared/index.js.map +1 -1
  61. package/dist/shared/index.mjs +10 -2
  62. package/dist/shared/index.mjs.map +1 -1
  63. package/package.json +185 -185
  64. package/src/adapters/agui-adapter.ts +222 -222
  65. package/src/adapters/agui-middleware.ts +382 -382
  66. package/src/adapters/ai-adapter.ts +115 -115
  67. package/src/adapters/langchain-adapter.ts +127 -127
  68. package/src/adapters/mastra-adapter.ts +126 -126
  69. package/src/bin/mcp-ts.ts +102 -102
  70. package/src/client/core/app-host.ts +417 -417
  71. package/src/client/core/sse-client.ts +371 -371
  72. package/src/client/core/types.ts +31 -31
  73. package/src/client/index.ts +27 -27
  74. package/src/client/react/index.ts +16 -16
  75. package/src/client/react/use-app-host.ts +73 -73
  76. package/src/client/react/use-mcp-apps.tsx +247 -214
  77. package/src/client/react/use-mcp.ts +641 -641
  78. package/src/client/vue/index.ts +10 -10
  79. package/src/client/vue/use-mcp.ts +617 -617
  80. package/src/index.ts +11 -11
  81. package/src/server/handlers/nextjs-handler.ts +204 -204
  82. package/src/server/handlers/sse-handler.ts +631 -631
  83. package/src/server/index.ts +57 -57
  84. package/src/server/mcp/multi-session-client.ts +228 -132
  85. package/src/server/mcp/oauth-client.ts +1188 -1188
  86. package/src/server/mcp/storage-oauth-provider.ts +272 -272
  87. package/src/server/storage/file-backend.ts +157 -170
  88. package/src/server/storage/index.ts +176 -175
  89. package/src/server/storage/memory-backend.ts +123 -136
  90. package/src/server/storage/redis-backend.ts +276 -289
  91. package/src/server/storage/redis.ts +160 -160
  92. package/src/server/storage/sqlite-backend.ts +182 -186
  93. package/src/server/storage/supabase-backend.ts +228 -227
  94. package/src/server/storage/types.ts +116 -116
  95. package/src/shared/constants.ts +29 -29
  96. package/src/shared/errors.ts +133 -133
  97. package/src/shared/event-routing.ts +28 -28
  98. package/src/shared/events.ts +180 -180
  99. package/src/shared/index.ts +75 -75
  100. package/src/shared/tool-utils.ts +61 -61
  101. package/src/shared/types.ts +282 -282
  102. package/src/shared/utils.ts +38 -16
  103. package/supabase/migrations/20260330195700_install_mcp_sessions.sql +84 -84
@@ -1,272 +1,272 @@
1
- import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
2
- import type {
3
- OAuthClientInformationFull,
4
- OAuthClientInformationMixed,
5
- OAuthClientMetadata,
6
- OAuthTokens
7
- } from "@modelcontextprotocol/sdk/shared/auth.js";
8
- import { storage, SessionData } from "../storage/index.js";
9
- import {
10
- DEFAULT_CLIENT_NAME,
11
- DEFAULT_CLIENT_URI,
12
- DEFAULT_LOGO_URI,
13
- DEFAULT_POLICY_URI,
14
- SOFTWARE_ID,
15
- SOFTWARE_VERSION,
16
- TOKEN_EXPIRY_BUFFER_MS,
17
- } from '../../shared/constants.js';
18
-
19
- /**
20
- * Extension of OAuthClientProvider interface with additional methods
21
- * Enables server-specific tracking and state management
22
- */
23
- export interface AgentsOAuthProvider extends OAuthClientProvider {
24
- authUrl: string | undefined;
25
- clientId: string | undefined;
26
- serverId: string | undefined;
27
- checkState(
28
- state: string
29
- ): Promise<{ valid: boolean; serverId?: string; error?: string }>;
30
- consumeState(state: string): Promise<void>;
31
- deleteCodeVerifier(): Promise<void>;
32
- isTokenExpired(): boolean;
33
- setTokenExpiresAt(expiresAt: number): void;
34
- }
35
-
36
- export interface StorageOAuthClientProviderOptions {
37
- identity: string;
38
- serverId: string;
39
- sessionId: string;
40
- redirectUrl: string;
41
- clientName?: string;
42
- clientUri?: string;
43
- logoUri?: string;
44
- policyUri?: string;
45
- clientId?: string;
46
- clientSecret?: string;
47
- onRedirect?: (url: string) => void;
48
- }
49
-
50
- /**
51
- * Storage-backed OAuth provider implementation for MCP
52
- * Stores OAuth tokens, client information, and PKCE verifiers using the configured StorageBackend
53
- */
54
- export class StorageOAuthClientProvider implements AgentsOAuthProvider {
55
- public readonly identity: string;
56
- public readonly serverId: string;
57
- public readonly sessionId: string;
58
- public readonly redirectUrl: string;
59
-
60
- private readonly clientName?: string;
61
- private readonly clientUri?: string;
62
- private readonly logoUri?: string;
63
- private readonly policyUri?: string;
64
- private readonly clientSecret?: string;
65
-
66
- private _authUrl: string | undefined;
67
- private _clientId: string | undefined;
68
- private onRedirectCallback?: (url: string) => void;
69
- private tokenExpiresAt?: number;
70
-
71
- /**
72
- * Creates a new storage-backed OAuth provider
73
- * @param options - Provider configuration
74
- */
75
- constructor(options: StorageOAuthClientProviderOptions) {
76
- this.identity = options.identity;
77
- this.serverId = options.serverId;
78
- this.sessionId = options.sessionId;
79
- this.redirectUrl = options.redirectUrl;
80
- this.clientName = options.clientName;
81
- this.clientUri = options.clientUri;
82
- this.logoUri = options.logoUri;
83
- this.policyUri = options.policyUri;
84
- this._clientId = options.clientId;
85
- this.clientSecret = options.clientSecret;
86
- this.onRedirectCallback = options.onRedirect;
87
- }
88
-
89
- get clientMetadata(): OAuthClientMetadata {
90
- return {
91
- client_name: this.clientName || DEFAULT_CLIENT_NAME,
92
- client_uri: this.clientUri || DEFAULT_CLIENT_URI,
93
- logo_uri: this.logoUri || DEFAULT_LOGO_URI,
94
- policy_uri: this.policyUri || DEFAULT_POLICY_URI,
95
- grant_types: ["authorization_code", "refresh_token"],
96
- redirect_uris: [this.redirectUrl],
97
- response_types: ["code"],
98
- token_endpoint_auth_method: this.clientSecret ? "client_secret_basic" : "none",
99
- software_id: SOFTWARE_ID,
100
- software_version: SOFTWARE_VERSION,
101
- };
102
- }
103
-
104
- get clientId() {
105
- return this._clientId;
106
- }
107
-
108
- set clientId(clientId_: string | undefined) {
109
- this._clientId = clientId_;
110
- }
111
-
112
- /**
113
- * Loads OAuth data from storage session
114
- * @private
115
- */
116
- private async getSessionData(): Promise<SessionData> {
117
- const data = await storage.getSession(this.identity, this.sessionId);
118
- if (!data) {
119
- return {} as SessionData;
120
- }
121
- return data;
122
- }
123
-
124
- /**
125
- * Saves OAuth data to storage
126
- * @param data - Partial OAuth data to save
127
- * @private
128
- * @throws Error if session doesn't exist (session must be created by controller layer)
129
- */
130
- private async saveSessionData(data: Partial<SessionData>): Promise<void> {
131
- await storage.updateSession(this.identity, this.sessionId, data);
132
- }
133
-
134
- /**
135
- * Retrieves stored OAuth client information
136
- */
137
- async clientInformation(): Promise<OAuthClientInformationMixed | undefined> {
138
- const data = await this.getSessionData();
139
-
140
- if (data.clientId && !this._clientId) {
141
- this._clientId = data.clientId;
142
- }
143
-
144
- if (data.clientInformation) {
145
- return data.clientInformation;
146
- }
147
-
148
- if (!this._clientId) {
149
- return undefined;
150
- }
151
-
152
- return {
153
- client_id: this._clientId,
154
- ...(this.clientSecret ? { client_secret: this.clientSecret } : {}),
155
- };
156
- }
157
-
158
- /**
159
- * Stores OAuth client information
160
- */
161
- async saveClientInformation(clientInformation: OAuthClientInformationFull): Promise<void> {
162
- await this.saveSessionData({
163
- clientInformation,
164
- clientId: clientInformation.client_id
165
- });
166
- this.clientId = clientInformation.client_id;
167
- }
168
-
169
- /**
170
- * Stores OAuth tokens
171
- */
172
- async saveTokens(tokens: OAuthTokens): Promise<void> {
173
- const data: Partial<SessionData> = { tokens };
174
-
175
- if (tokens.expires_in) {
176
- this.tokenExpiresAt = Date.now() + (tokens.expires_in * 1000) - TOKEN_EXPIRY_BUFFER_MS;
177
- }
178
-
179
- await this.saveSessionData(data);
180
- }
181
-
182
- get authUrl() {
183
- return this._authUrl;
184
- }
185
-
186
- async state(): Promise<string> {
187
- return this.sessionId;
188
- }
189
-
190
- async checkState(_state: string): Promise<{ valid: boolean; serverId?: string; error?: string }> {
191
- const data = await storage.getSession(this.identity, this.sessionId);
192
-
193
- if (!data) {
194
- return { valid: false, error: "Session not found" };
195
- }
196
-
197
- return { valid: true, serverId: this.serverId };
198
- }
199
-
200
- async consumeState(_state: string): Promise<void> {
201
- // No-op
202
- }
203
-
204
- async redirectToAuthorization(authUrl: URL): Promise<void> {
205
- this._authUrl = authUrl.toString();
206
- if (this.onRedirectCallback) {
207
- this.onRedirectCallback(authUrl.toString());
208
- }
209
- }
210
-
211
- async invalidateCredentials(
212
- scope: "all" | "client" | "tokens" | "verifier"
213
- ): Promise<void> {
214
- if (scope === "all") {
215
- await storage.removeSession(this.identity, this.sessionId);
216
- } else {
217
- const updates: Partial<SessionData> = {};
218
-
219
- if (scope === "client") {
220
- updates.clientInformation = undefined;
221
- updates.clientId = undefined;
222
- } else if (scope === "tokens") {
223
- updates.tokens = undefined;
224
- } else if (scope === "verifier") {
225
- updates.codeVerifier = undefined;
226
- }
227
- await this.saveSessionData(updates);
228
- }
229
- }
230
-
231
- async saveCodeVerifier(verifier: string): Promise<void> {
232
- await this.saveSessionData({ codeVerifier: verifier });
233
- }
234
-
235
- async codeVerifier(): Promise<string> {
236
- const data = await this.getSessionData();
237
-
238
- if (data.clientId && !this._clientId) {
239
- this._clientId = data.clientId;
240
- }
241
-
242
- if (!data.codeVerifier) {
243
- throw new Error("No code verifier found");
244
- }
245
- return data.codeVerifier;
246
- }
247
-
248
- async deleteCodeVerifier(): Promise<void> {
249
- await this.saveSessionData({ codeVerifier: undefined });
250
- }
251
-
252
- async tokens(): Promise<OAuthTokens | undefined> {
253
- const data = await this.getSessionData();
254
-
255
- if (data.clientId && !this._clientId) {
256
- this._clientId = data.clientId;
257
- }
258
-
259
- return data.tokens;
260
- }
261
-
262
- isTokenExpired(): boolean {
263
- if (!this.tokenExpiresAt) {
264
- return false;
265
- }
266
- return Date.now() >= this.tokenExpiresAt;
267
- }
268
-
269
- setTokenExpiresAt(expiresAt: number): void {
270
- this.tokenExpiresAt = expiresAt;
271
- }
272
- }
1
+ import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
2
+ import type {
3
+ OAuthClientInformationFull,
4
+ OAuthClientInformationMixed,
5
+ OAuthClientMetadata,
6
+ OAuthTokens
7
+ } from "@modelcontextprotocol/sdk/shared/auth.js";
8
+ import { storage, SessionData } from "../storage/index.js";
9
+ import {
10
+ DEFAULT_CLIENT_NAME,
11
+ DEFAULT_CLIENT_URI,
12
+ DEFAULT_LOGO_URI,
13
+ DEFAULT_POLICY_URI,
14
+ SOFTWARE_ID,
15
+ SOFTWARE_VERSION,
16
+ TOKEN_EXPIRY_BUFFER_MS,
17
+ } from '../../shared/constants.js';
18
+
19
+ /**
20
+ * Extension of OAuthClientProvider interface with additional methods
21
+ * Enables server-specific tracking and state management
22
+ */
23
+ export interface AgentsOAuthProvider extends OAuthClientProvider {
24
+ authUrl: string | undefined;
25
+ clientId: string | undefined;
26
+ serverId: string | undefined;
27
+ checkState(
28
+ state: string
29
+ ): Promise<{ valid: boolean; serverId?: string; error?: string }>;
30
+ consumeState(state: string): Promise<void>;
31
+ deleteCodeVerifier(): Promise<void>;
32
+ isTokenExpired(): boolean;
33
+ setTokenExpiresAt(expiresAt: number): void;
34
+ }
35
+
36
+ export interface StorageOAuthClientProviderOptions {
37
+ identity: string;
38
+ serverId: string;
39
+ sessionId: string;
40
+ redirectUrl: string;
41
+ clientName?: string;
42
+ clientUri?: string;
43
+ logoUri?: string;
44
+ policyUri?: string;
45
+ clientId?: string;
46
+ clientSecret?: string;
47
+ onRedirect?: (url: string) => void;
48
+ }
49
+
50
+ /**
51
+ * Storage-backed OAuth provider implementation for MCP
52
+ * Stores OAuth tokens, client information, and PKCE verifiers using the configured StorageBackend
53
+ */
54
+ export class StorageOAuthClientProvider implements AgentsOAuthProvider {
55
+ public readonly identity: string;
56
+ public readonly serverId: string;
57
+ public readonly sessionId: string;
58
+ public readonly redirectUrl: string;
59
+
60
+ private readonly clientName?: string;
61
+ private readonly clientUri?: string;
62
+ private readonly logoUri?: string;
63
+ private readonly policyUri?: string;
64
+ private readonly clientSecret?: string;
65
+
66
+ private _authUrl: string | undefined;
67
+ private _clientId: string | undefined;
68
+ private onRedirectCallback?: (url: string) => void;
69
+ private tokenExpiresAt?: number;
70
+
71
+ /**
72
+ * Creates a new storage-backed OAuth provider
73
+ * @param options - Provider configuration
74
+ */
75
+ constructor(options: StorageOAuthClientProviderOptions) {
76
+ this.identity = options.identity;
77
+ this.serverId = options.serverId;
78
+ this.sessionId = options.sessionId;
79
+ this.redirectUrl = options.redirectUrl;
80
+ this.clientName = options.clientName;
81
+ this.clientUri = options.clientUri;
82
+ this.logoUri = options.logoUri;
83
+ this.policyUri = options.policyUri;
84
+ this._clientId = options.clientId;
85
+ this.clientSecret = options.clientSecret;
86
+ this.onRedirectCallback = options.onRedirect;
87
+ }
88
+
89
+ get clientMetadata(): OAuthClientMetadata {
90
+ return {
91
+ client_name: this.clientName || DEFAULT_CLIENT_NAME,
92
+ client_uri: this.clientUri || DEFAULT_CLIENT_URI,
93
+ logo_uri: this.logoUri || DEFAULT_LOGO_URI,
94
+ policy_uri: this.policyUri || DEFAULT_POLICY_URI,
95
+ grant_types: ["authorization_code", "refresh_token"],
96
+ redirect_uris: [this.redirectUrl],
97
+ response_types: ["code"],
98
+ token_endpoint_auth_method: this.clientSecret ? "client_secret_basic" : "none",
99
+ software_id: SOFTWARE_ID,
100
+ software_version: SOFTWARE_VERSION,
101
+ };
102
+ }
103
+
104
+ get clientId() {
105
+ return this._clientId;
106
+ }
107
+
108
+ set clientId(clientId_: string | undefined) {
109
+ this._clientId = clientId_;
110
+ }
111
+
112
+ /**
113
+ * Loads OAuth data from storage session
114
+ * @private
115
+ */
116
+ private async getSessionData(): Promise<SessionData> {
117
+ const data = await storage.getSession(this.identity, this.sessionId);
118
+ if (!data) {
119
+ return {} as SessionData;
120
+ }
121
+ return data;
122
+ }
123
+
124
+ /**
125
+ * Saves OAuth data to storage
126
+ * @param data - Partial OAuth data to save
127
+ * @private
128
+ * @throws Error if session doesn't exist (session must be created by controller layer)
129
+ */
130
+ private async saveSessionData(data: Partial<SessionData>): Promise<void> {
131
+ await storage.updateSession(this.identity, this.sessionId, data);
132
+ }
133
+
134
+ /**
135
+ * Retrieves stored OAuth client information
136
+ */
137
+ async clientInformation(): Promise<OAuthClientInformationMixed | undefined> {
138
+ const data = await this.getSessionData();
139
+
140
+ if (data.clientId && !this._clientId) {
141
+ this._clientId = data.clientId;
142
+ }
143
+
144
+ if (data.clientInformation) {
145
+ return data.clientInformation;
146
+ }
147
+
148
+ if (!this._clientId) {
149
+ return undefined;
150
+ }
151
+
152
+ return {
153
+ client_id: this._clientId,
154
+ ...(this.clientSecret ? { client_secret: this.clientSecret } : {}),
155
+ };
156
+ }
157
+
158
+ /**
159
+ * Stores OAuth client information
160
+ */
161
+ async saveClientInformation(clientInformation: OAuthClientInformationFull): Promise<void> {
162
+ await this.saveSessionData({
163
+ clientInformation,
164
+ clientId: clientInformation.client_id
165
+ });
166
+ this.clientId = clientInformation.client_id;
167
+ }
168
+
169
+ /**
170
+ * Stores OAuth tokens
171
+ */
172
+ async saveTokens(tokens: OAuthTokens): Promise<void> {
173
+ const data: Partial<SessionData> = { tokens };
174
+
175
+ if (tokens.expires_in) {
176
+ this.tokenExpiresAt = Date.now() + (tokens.expires_in * 1000) - TOKEN_EXPIRY_BUFFER_MS;
177
+ }
178
+
179
+ await this.saveSessionData(data);
180
+ }
181
+
182
+ get authUrl() {
183
+ return this._authUrl;
184
+ }
185
+
186
+ async state(): Promise<string> {
187
+ return this.sessionId;
188
+ }
189
+
190
+ async checkState(_state: string): Promise<{ valid: boolean; serverId?: string; error?: string }> {
191
+ const data = await storage.getSession(this.identity, this.sessionId);
192
+
193
+ if (!data) {
194
+ return { valid: false, error: "Session not found" };
195
+ }
196
+
197
+ return { valid: true, serverId: this.serverId };
198
+ }
199
+
200
+ async consumeState(_state: string): Promise<void> {
201
+ // No-op
202
+ }
203
+
204
+ async redirectToAuthorization(authUrl: URL): Promise<void> {
205
+ this._authUrl = authUrl.toString();
206
+ if (this.onRedirectCallback) {
207
+ this.onRedirectCallback(authUrl.toString());
208
+ }
209
+ }
210
+
211
+ async invalidateCredentials(
212
+ scope: "all" | "client" | "tokens" | "verifier"
213
+ ): Promise<void> {
214
+ if (scope === "all") {
215
+ await storage.removeSession(this.identity, this.sessionId);
216
+ } else {
217
+ const updates: Partial<SessionData> = {};
218
+
219
+ if (scope === "client") {
220
+ updates.clientInformation = undefined;
221
+ updates.clientId = undefined;
222
+ } else if (scope === "tokens") {
223
+ updates.tokens = undefined;
224
+ } else if (scope === "verifier") {
225
+ updates.codeVerifier = undefined;
226
+ }
227
+ await this.saveSessionData(updates);
228
+ }
229
+ }
230
+
231
+ async saveCodeVerifier(verifier: string): Promise<void> {
232
+ await this.saveSessionData({ codeVerifier: verifier });
233
+ }
234
+
235
+ async codeVerifier(): Promise<string> {
236
+ const data = await this.getSessionData();
237
+
238
+ if (data.clientId && !this._clientId) {
239
+ this._clientId = data.clientId;
240
+ }
241
+
242
+ if (!data.codeVerifier) {
243
+ throw new Error("No code verifier found");
244
+ }
245
+ return data.codeVerifier;
246
+ }
247
+
248
+ async deleteCodeVerifier(): Promise<void> {
249
+ await this.saveSessionData({ codeVerifier: undefined });
250
+ }
251
+
252
+ async tokens(): Promise<OAuthTokens | undefined> {
253
+ const data = await this.getSessionData();
254
+
255
+ if (data.clientId && !this._clientId) {
256
+ this._clientId = data.clientId;
257
+ }
258
+
259
+ return data.tokens;
260
+ }
261
+
262
+ isTokenExpired(): boolean {
263
+ if (!this.tokenExpiresAt) {
264
+ return false;
265
+ }
266
+ return Date.now() >= this.tokenExpiresAt;
267
+ }
268
+
269
+ setTokenExpiresAt(expiresAt: number): void {
270
+ this.tokenExpiresAt = expiresAt;
271
+ }
272
+ }