@loop_ouroboros/mcp-hub-lite 1.2.6 → 1.2.7
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/CHANGELOG.md +659 -640
- package/dist/client/assets/HomeView-CgEri1kD.js +1 -0
- package/dist/client/assets/{ResourceDetailView-BGBtmsyc.js → ResourceDetailView-B8Qo1_jK.js} +1 -1
- package/dist/client/assets/ResourcesView-B12FzUdo.js +1 -0
- package/dist/client/assets/ServerDashboard-B3O-crvv.js +1 -0
- package/dist/client/assets/ServerDetail-Bz5_9yOY.js +2 -0
- package/dist/client/assets/{ServerDetail-CtnNKJGx.css → ServerDetail-CXg8rI3q.css} +1 -1
- package/dist/client/assets/{ServerListView-C7kcd4GC.js → ServerListView-SlZN8ppC.js} +2 -2
- package/dist/client/assets/{ServerStatusTags.vue_vue_type_script_setup_true_lang-BHhwEuGe.js → ServerStatusTags.vue_vue_type_script_setup_true_lang-DmGg4uuV.js} +1 -1
- package/dist/client/assets/SettingsView-D8fiOG0O.js +1 -0
- package/dist/client/assets/ToolCallDialog-DYEdhnCk.js +1 -0
- package/dist/client/assets/ToolsView-BreAl-yn.js +1 -0
- package/dist/client/assets/{_baseClone-kbJbcBJT.js → _baseClone-BYxCbA_9.js} +1 -1
- package/dist/client/assets/{el-form-item-iQ0G8e97.js → el-form-item-ySymCPMr.js} +2 -2
- package/dist/client/assets/el-input-C85p6Nqj.js +1 -0
- package/dist/client/assets/el-loading-DIjKEx81.js +1 -0
- package/dist/client/assets/{el-overlay-Cy5xg31y.js → el-overlay-B_CxiSem.js} +1 -1
- package/dist/client/assets/el-radio-group-BjkTCPRf.js +1 -0
- package/dist/client/assets/el-skeleton-item-CupTKK6n.js +1 -0
- package/dist/client/assets/{el-switch-KpjV93lm.js → el-switch-BosIJ9jf.js} +1 -1
- package/dist/client/assets/el-tab-pane-BydxdJoc.js +1 -0
- package/dist/client/assets/{el-table-column-fofd_2n-.js → el-table-column-DV5TZOUW.js} +1 -1
- package/dist/client/assets/index-kC4mf0Vo.js +2 -0
- package/dist/client/assets/{index-DpH6ZSbs.css → index-xJkq2euk.css} +1 -1
- package/dist/client/assets/omit-DxDGRttI.js +1 -0
- package/dist/client/assets/{raf-MWAHt9ca.js → raf-Y9AoxecD.js} +1 -1
- package/dist/client/assets/{vue-vendor-CbgVSHIh.js → vue-vendor-Dwcr0jep.js} +1 -1
- package/dist/client/index.html +3 -3
- package/dist/server/shared/types/websocket.types.d.ts +28 -19
- package/dist/server/shared/types/websocket.types.d.ts.map +1 -1
- package/dist/server/shared/types/websocket.types.js +3 -2
- package/dist/server/src/api/ws/ws-handler.d.ts.map +1 -1
- package/dist/server/src/api/ws/ws-handler.js +4 -3
- package/dist/server/src/app.d.ts.map +1 -1
- package/dist/server/src/app.js +46 -0
- package/dist/server/src/models/event.model.d.ts +0 -13
- package/dist/server/src/models/event.model.d.ts.map +1 -1
- package/dist/server/src/models/server.model.d.ts +0 -29
- package/dist/server/src/models/server.model.d.ts.map +1 -1
- package/dist/server/src/models/types.d.ts +1 -70
- package/dist/server/src/models/types.d.ts.map +1 -1
- package/dist/server/src/models/types.js +1 -67
- package/dist/server/src/server/dev-server.js +24 -6
- package/dist/server/src/services/connection/connection-manager.d.ts +13 -0
- package/dist/server/src/services/connection/connection-manager.d.ts.map +1 -1
- package/dist/server/src/services/connection/connection-manager.js +122 -5
- package/dist/server/src/services/event-bus.service.d.ts +0 -4
- package/dist/server/src/services/event-bus.service.d.ts.map +1 -1
- package/dist/server/src/services/event-bus.service.js +1 -6
- package/dist/server/src/services/gateway/request-handlers/initialize-handler.d.ts.map +1 -1
- package/dist/server/src/services/gateway/request-handlers/initialize-handler.js +1 -0
- package/dist/server/src/services/mcp-oauth/index.d.ts +5 -0
- package/dist/server/src/services/mcp-oauth/index.d.ts.map +1 -0
- package/dist/server/src/services/mcp-oauth/index.js +3 -0
- package/dist/server/src/services/mcp-oauth/oauth-callback-server.d.ts +19 -0
- package/dist/server/src/services/mcp-oauth/oauth-callback-server.d.ts.map +1 -0
- package/dist/server/src/services/mcp-oauth/oauth-callback-server.js +100 -0
- package/dist/server/src/services/mcp-oauth/oauth-provider.d.ts +42 -0
- package/dist/server/src/services/mcp-oauth/oauth-provider.d.ts.map +1 -0
- package/dist/server/src/services/mcp-oauth/oauth-provider.js +121 -0
- package/dist/server/src/services/mcp-oauth/oauth-token-storage.d.ts +23 -0
- package/dist/server/src/services/mcp-oauth/oauth-token-storage.d.ts.map +1 -0
- package/dist/server/src/services/mcp-oauth/oauth-token-storage.js +92 -0
- package/dist/server/src/services/mcp-oauth/oauth-types.d.ts +21 -0
- package/dist/server/src/services/mcp-oauth/oauth-types.d.ts.map +1 -0
- package/dist/server/src/services/mcp-oauth/oauth-types.js +4 -0
- package/dist/server/src/utils/network-security.d.ts +33 -0
- package/dist/server/src/utils/network-security.d.ts.map +1 -0
- package/dist/server/src/utils/network-security.js +83 -0
- package/dist/server/src/utils/transports/streamable-http-transport.d.ts +12 -1
- package/dist/server/src/utils/transports/streamable-http-transport.d.ts.map +1 -1
- package/dist/server/src/utils/transports/streamable-http-transport.js +20 -1
- package/dist/server/src/utils/transports/transport-factory.d.ts +2 -0
- package/dist/server/src/utils/transports/transport-factory.d.ts.map +1 -1
- package/dist/server/src/utils/transports/transport-factory.js +17 -2
- package/dist/server/src/utils/transports/transport.interface.d.ts +2 -0
- package/dist/server/src/utils/transports/transport.interface.d.ts.map +1 -1
- package/dist/server/tests/unit/utils/network-security.test.d.ts +2 -0
- package/dist/server/tests/unit/utils/network-security.test.d.ts.map +1 -0
- package/dist/server/tests/unit/utils/network-security.test.js +123 -0
- package/dist/server/vite.config.js +1 -1
- package/package.json +111 -111
- package/dist/client/assets/HomeView-BnO4yIT9.js +0 -1
- package/dist/client/assets/ResourcesView-B5Xg0ynh.js +0 -1
- package/dist/client/assets/ServerDashboard-DYAVrrUk.js +0 -1
- package/dist/client/assets/ServerDetail-q94ZFfjL.js +0 -2
- package/dist/client/assets/SettingsView-BM6P5yrT.js +0 -1
- package/dist/client/assets/ToolCallDialog-BoAGxlB5.js +0 -1
- package/dist/client/assets/ToolsView-lqFhr7Bk.js +0 -1
- package/dist/client/assets/el-input-DkJq57wP.js +0 -1
- package/dist/client/assets/el-loading-C3v6a9xV.js +0 -1
- package/dist/client/assets/el-radio-group-C9QUL5mm.js +0 -1
- package/dist/client/assets/el-skeleton-item-Bbmpc0Xz.js +0 -1
- package/dist/client/assets/el-tab-pane-YsYuBcem.js +0 -1
- package/dist/client/assets/index-5tzIwwtS.js +0 -1
- package/dist/client/assets/index-MqHvQjDP.js +0 -2
- package/dist/client/assets/omit-CB4hTeTH.js +0 -1
- package/dist/client/assets/typescript-Bp3YSIOJ.js +0 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
2
|
import { TransportFactory } from '../../utils/transports/transport-factory.js';
|
|
3
|
+
import { UnauthorizedError, auth } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
4
|
+
import { StreamableHttpTransport } from '../../utils/transports/streamable-http-transport.js';
|
|
3
5
|
import { logger, LOG_MODULES, formatMcpMessageForLogging, logNotificationMessage } from '../../utils/logger.js';
|
|
4
6
|
import { getAppVersion } from '../../utils/version.js';
|
|
5
7
|
import { getMcpCommDebugSetting } from '../../utils/json-utils.js';
|
|
@@ -98,6 +100,10 @@ export class McpConnectionManager {
|
|
|
98
100
|
const serverId = server.id || 'unknown';
|
|
99
101
|
const compositeKey = getCompositeKey(serverName, serverIndex);
|
|
100
102
|
const { maxRetries, baseRetryDelay } = this.getRetryConfig();
|
|
103
|
+
// Create OAuth provider once per-connect (shared across retries)
|
|
104
|
+
const isStreamableHttp = server.type === 'streamable-http' || server.type === 'http';
|
|
105
|
+
let oauthProvider = null;
|
|
106
|
+
let oauthStarted = false;
|
|
101
107
|
// Retry loop for connection attempts
|
|
102
108
|
let lastError;
|
|
103
109
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
@@ -111,7 +117,21 @@ export class McpConnectionManager {
|
|
|
111
117
|
// 4. Get server info
|
|
112
118
|
const serverInfo = this.getServerInfo(serverId);
|
|
113
119
|
// 5. Create transport and set up callbacks
|
|
114
|
-
const { transport, pid } = this.initializeTransport(server, serverInfo, compositeKey, serverName, serverIndex);
|
|
120
|
+
const { transport, pid } = this.initializeTransport(server, serverInfo, compositeKey, serverName, serverIndex, oauthProvider ?? undefined);
|
|
121
|
+
// Capture OAuth provider from the transport (reuse across retries)
|
|
122
|
+
if (!oauthProvider && transport instanceof StreamableHttpTransport) {
|
|
123
|
+
const provider = transport.getOAuthProvider();
|
|
124
|
+
if (provider) {
|
|
125
|
+
oauthProvider =
|
|
126
|
+
provider;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Start OAuth callback server once before connecting
|
|
130
|
+
if (oauthProvider && !oauthStarted) {
|
|
131
|
+
await oauthProvider.startCallbackServer();
|
|
132
|
+
oauthStarted = true;
|
|
133
|
+
logger.info(`OAuth callback server started for [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
|
|
134
|
+
}
|
|
115
135
|
// 6. Establish client connection
|
|
116
136
|
const client = await this.establishClientConnection(transport);
|
|
117
137
|
// 7. Register connection
|
|
@@ -122,12 +142,30 @@ export class McpConnectionManager {
|
|
|
122
142
|
this.publishConnectionEvents(serverName, serverIndex);
|
|
123
143
|
// 10. Refresh resources
|
|
124
144
|
await this.refreshServerResources(serverName, serverIndex, server.type);
|
|
145
|
+
// 11. Request log notifications from downstream server
|
|
146
|
+
await this.requestLoggingFromServer(compositeKey, client, server.type);
|
|
125
147
|
return true;
|
|
126
148
|
}
|
|
127
149
|
catch (error) {
|
|
150
|
+
// Handle OAuth flow for Streamable HTTP servers (only on first attempt)
|
|
151
|
+
if (isStreamableHttp &&
|
|
152
|
+
oauthProvider &&
|
|
153
|
+
error instanceof UnauthorizedError &&
|
|
154
|
+
attempt === 1) {
|
|
155
|
+
logger.info(`OAuth required for server [${compositeKey}], waiting for browser auth...`, LOG_MODULES.CONNECTION_MANAGER);
|
|
156
|
+
const oauthHandled = await this.handleOAuthFlow(oauthProvider, server.url || '', compositeKey);
|
|
157
|
+
if (oauthHandled) {
|
|
158
|
+
logger.info(`OAuth flow completed for [${compositeKey}], retrying connection...`, LOG_MODULES.CONNECTION_MANAGER);
|
|
159
|
+
continue; // Retry connection — authProvider now has tokens
|
|
160
|
+
}
|
|
161
|
+
}
|
|
128
162
|
lastError = await this.handleConnectionError(error, compositeKey, attempt, maxRetries, baseRetryDelay);
|
|
129
163
|
}
|
|
130
164
|
}
|
|
165
|
+
// Clean up callback server
|
|
166
|
+
if (oauthProvider) {
|
|
167
|
+
await oauthProvider.stopCallbackServer();
|
|
168
|
+
}
|
|
131
169
|
// All retries failed
|
|
132
170
|
this.handleFinalFailure(compositeKey, serverName, serverIndex, lastError);
|
|
133
171
|
return false;
|
|
@@ -186,7 +224,7 @@ export class McpConnectionManager {
|
|
|
186
224
|
/**
|
|
187
225
|
* Creates transport and sets up all callbacks.
|
|
188
226
|
*/
|
|
189
|
-
initializeTransport(server, serverInfo, compositeKey, serverName, serverIndex) {
|
|
227
|
+
initializeTransport(server, serverInfo, compositeKey, serverName, serverIndex, authProvider) {
|
|
190
228
|
const readyPatterns = server.type === 'stdio' ? (serverInfo.config.template.readyPatterns ?? []) : undefined;
|
|
191
229
|
const readyTimeout = configManager.getConfig().system.startup?.readyTimeout ?? 120000;
|
|
192
230
|
const transport = TransportFactory.createTransport({
|
|
@@ -194,7 +232,8 @@ export class McpConnectionManager {
|
|
|
194
232
|
name: serverName
|
|
195
233
|
}, compositeKey, {
|
|
196
234
|
readyPatterns,
|
|
197
|
-
readyTimeout
|
|
235
|
+
readyTimeout,
|
|
236
|
+
authProvider
|
|
198
237
|
});
|
|
199
238
|
// Set up message handler for notifications/message
|
|
200
239
|
transport.onmessage = (message) => {
|
|
@@ -357,6 +396,76 @@ export class McpConnectionManager {
|
|
|
357
396
|
resources
|
|
358
397
|
});
|
|
359
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* Sends logging/setLevel request to downstream server to start receiving log notifications.
|
|
401
|
+
* This is a best-effort request — servers that don't support logging will silently ignore it.
|
|
402
|
+
*/
|
|
403
|
+
async requestLoggingFromServer(compositeKey, client, serverType) {
|
|
404
|
+
// SSE is unidirectional — cannot send requests to the server
|
|
405
|
+
if (serverType === 'sse')
|
|
406
|
+
return;
|
|
407
|
+
try {
|
|
408
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
409
|
+
await client.request({ method: 'logging/setLevel', params: { level: 'info' } }, { timeout: 5000 });
|
|
410
|
+
logger.info(`Sent logging/setLevel to server [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
|
|
411
|
+
}
|
|
412
|
+
catch {
|
|
413
|
+
// Server may not support logging — not an error condition
|
|
414
|
+
logger.debug(`Server [${compositeKey}] does not support logging/setLevel`, LOG_MODULES.CONNECTION_MANAGER);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Handles the OAuth authorization flow for Streamable HTTP servers.
|
|
419
|
+
* Starts a local callback server, waits for the user to complete auth in the browser,
|
|
420
|
+
* then finishes the auth on the transport.
|
|
421
|
+
*
|
|
422
|
+
* @returns true if OAuth was handled successfully, false otherwise
|
|
423
|
+
*/
|
|
424
|
+
async handleOAuthFlow(provider, serverUrl, compositeKey) {
|
|
425
|
+
try {
|
|
426
|
+
const callbackServer = provider.getCallbackServer();
|
|
427
|
+
if (!callbackServer) {
|
|
428
|
+
logger.warn(`No callback server for [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
// SDK has already called redirectToAuthorization via authProvider
|
|
432
|
+
// Wait for the auth code from the callback server
|
|
433
|
+
const authCode = await new Promise((resolve, reject) => {
|
|
434
|
+
const timeout = setTimeout(() => {
|
|
435
|
+
callbackServer.removeAllListeners('auth-code-received');
|
|
436
|
+
resolve(null);
|
|
437
|
+
}, 5 * 60 * 1000);
|
|
438
|
+
callbackServer.once('auth-code-received', (code) => {
|
|
439
|
+
clearTimeout(timeout);
|
|
440
|
+
resolve(code);
|
|
441
|
+
});
|
|
442
|
+
callbackServer.once('error', (err) => {
|
|
443
|
+
clearTimeout(timeout);
|
|
444
|
+
reject(err);
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
if (!authCode) {
|
|
448
|
+
logger.warn(`OAuth flow timed out for server [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
// Exchange the authorization code for tokens via SDK
|
|
452
|
+
logger.info(`Exchanging OAuth code for tokens for [${compositeKey}]...`, LOG_MODULES.CONNECTION_MANAGER);
|
|
453
|
+
const result = await auth(provider, {
|
|
454
|
+
serverUrl,
|
|
455
|
+
authorizationCode: authCode
|
|
456
|
+
});
|
|
457
|
+
if (result === 'AUTHORIZED') {
|
|
458
|
+
logger.info(`OAuth token exchange succeeded for [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
|
|
459
|
+
return true;
|
|
460
|
+
}
|
|
461
|
+
logger.warn(`OAuth token exchange returned ${result} for [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
catch (error) {
|
|
465
|
+
logger.error(`OAuth flow error for server [${compositeKey}]: ${error instanceof Error ? error.message : String(error)}`, LOG_MODULES.CONNECTION_MANAGER);
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
360
469
|
/**
|
|
361
470
|
* Handles connection error with logging and retry delay.
|
|
362
471
|
*/
|
|
@@ -375,10 +484,18 @@ export class McpConnectionManager {
|
|
|
375
484
|
*/
|
|
376
485
|
handleFinalFailure(compositeKey, serverName, serverIndex, lastError) {
|
|
377
486
|
const errorMessage = lastError?.message || 'Connection failed after all retries';
|
|
487
|
+
// Fetch recent error logs (stderr) to help diagnose startup failures
|
|
488
|
+
const recentErrorLogs = logStorage.getLogs(compositeKey, { level: 'error', limit: 10 });
|
|
489
|
+
const logDetail = recentErrorLogs.length > 0
|
|
490
|
+
? '\n\n--- Recent stderr output ---\n' + recentErrorLogs.map((l) => l.message).join('\n')
|
|
491
|
+
: '';
|
|
492
|
+
// Write connection error to logStorage so it appears in the log viewer
|
|
493
|
+
// This ensures errors from all transport types (stdio, streamable-http, sse) are visible
|
|
494
|
+
logStorage.append(compositeKey, 'error', `[CONNECTION] ${errorMessage}`);
|
|
378
495
|
logger.error(`Failed to connect to server ${compositeKey} after retries:`, lastError, LOG_MODULES.CONNECTION_MANAGER);
|
|
379
496
|
this.serverStatus.set(compositeKey, {
|
|
380
497
|
connected: false,
|
|
381
|
-
error: errorMessage,
|
|
498
|
+
error: errorMessage + logDetail,
|
|
382
499
|
lastCheck: Date.now(),
|
|
383
500
|
toolsCount: 0,
|
|
384
501
|
resourcesCount: 0
|
|
@@ -387,7 +504,7 @@ export class McpConnectionManager {
|
|
|
387
504
|
serverName,
|
|
388
505
|
serverIndex,
|
|
389
506
|
status: 'error',
|
|
390
|
-
error: errorMessage,
|
|
507
|
+
error: errorMessage + logDetail,
|
|
391
508
|
timestamp: Date.now()
|
|
392
509
|
});
|
|
393
510
|
}
|
|
@@ -159,11 +159,7 @@ export declare const EventTypes: {
|
|
|
159
159
|
readonly TOOL_CALL_ERROR: "tool-call-error";
|
|
160
160
|
readonly RESOURCES_UPDATED: "resources";
|
|
161
161
|
readonly LOG_ENTRY: "log";
|
|
162
|
-
readonly LOGS_CLEARED: "logs-cleared";
|
|
163
|
-
readonly SYSTEM_HEALTH: "system-health";
|
|
164
162
|
readonly CONFIGURATION_UPDATED: "configuration-updated";
|
|
165
|
-
readonly CLIENT_CONNECTED: "client-connected";
|
|
166
|
-
readonly CLIENT_DISCONNECTED: "client-disconnected";
|
|
167
163
|
};
|
|
168
164
|
export declare const eventBus: EventBusService;
|
|
169
165
|
//# sourceMappingURL=event-bus.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.service.d.ts","sourceRoot":"","sources":["../../../../src/services/event-bus.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAqD;IAEtE;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAajD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI;IAU7E;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,WAAW;IAWnB;;;;;;;;;;;;;;OAcG;IACH,cAAc,IAAI,IAAI;IAItB;;;;;;;;;;;;;;OAcG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB;;;;;;;;;;;;;;;OAeG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAI5C;AAGD,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"event-bus.service.d.ts","sourceRoot":"","sources":["../../../../src/services/event-bus.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAqD;IAEtE;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAajD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI;IAU7E;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,WAAW;IAWnB;;;;;;;;;;;;;;OAcG;IACH,cAAc,IAAI,IAAI;IAItB;;;;;;;;;;;;;;OAcG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB;;;;;;;;;;;;;;;OAeG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAI5C;AAGD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;CA4Bb,CAAC;AAGX,eAAO,MAAM,QAAQ,iBAAwB,CAAC"}
|
|
@@ -188,13 +188,8 @@ export const EventTypes = {
|
|
|
188
188
|
RESOURCES_UPDATED: 'resources',
|
|
189
189
|
// Log related events
|
|
190
190
|
LOG_ENTRY: 'log',
|
|
191
|
-
LOGS_CLEARED: 'logs-cleared',
|
|
192
191
|
// System related events
|
|
193
|
-
|
|
194
|
-
CONFIGURATION_UPDATED: 'configuration-updated',
|
|
195
|
-
// Client related events
|
|
196
|
-
CLIENT_CONNECTED: 'client-connected',
|
|
197
|
-
CLIENT_DISCONNECTED: 'client-disconnected'
|
|
192
|
+
CONFIGURATION_UPDATED: 'configuration-updated'
|
|
198
193
|
};
|
|
199
194
|
// Create global event bus instance
|
|
200
195
|
export const eventBus = new EventBusService();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialize-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/initialize-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"initialize-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/initialize-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsElE"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { McpOAuthClientProvider } from './oauth-provider.js';
|
|
2
|
+
export { OAuthCallbackServer } from './oauth-callback-server.js';
|
|
3
|
+
export { OAuthTokenStorage } from './oauth-token-storage.js';
|
|
4
|
+
export type { McpOAuthConfig, McpOAuthProviderOptions } from './oauth-types.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/services/mcp-oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local HTTP server for OAuth callback handling.
|
|
3
|
+
*
|
|
4
|
+
* Listens on 127.0.0.1 with a dynamic port, captures the authorization code
|
|
5
|
+
* from the OAuth redirect, displays a success page to the user, and emits
|
|
6
|
+
* the code via EventEmitter. Auto-closes after 5 minutes of inactivity.
|
|
7
|
+
*/
|
|
8
|
+
import { EventEmitter } from 'node:events';
|
|
9
|
+
export declare class OAuthCallbackServer extends EventEmitter {
|
|
10
|
+
private server;
|
|
11
|
+
private port;
|
|
12
|
+
private timeout;
|
|
13
|
+
constructor(port?: number);
|
|
14
|
+
get callbackUrl(): string;
|
|
15
|
+
get redirectUrl(): string;
|
|
16
|
+
start(): Promise<void>;
|
|
17
|
+
stop(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=oauth-callback-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-callback-server.d.ts","sourceRoot":"","sources":["../../../../../src/services/mcp-oauth/oauth-callback-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA2B3C,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,OAAO,CAA+B;gBAElC,IAAI,GAAE,MAAU;IAK5B,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA6CtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAkB5B"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local HTTP server for OAuth callback handling.
|
|
3
|
+
*
|
|
4
|
+
* Listens on 127.0.0.1 with a dynamic port, captures the authorization code
|
|
5
|
+
* from the OAuth redirect, displays a success page to the user, and emits
|
|
6
|
+
* the code via EventEmitter. Auto-closes after 5 minutes of inactivity.
|
|
7
|
+
*/
|
|
8
|
+
import http from 'node:http';
|
|
9
|
+
import { EventEmitter } from 'node:events';
|
|
10
|
+
import { logger, LOG_MODULES } from '../../utils/logger/index.js';
|
|
11
|
+
const CALLBACK_PATH = '/oauth/callback';
|
|
12
|
+
const CALLBACK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
|
|
13
|
+
const SUCCESS_HTML = `<!DOCTYPE html>
|
|
14
|
+
<html lang="en">
|
|
15
|
+
<head>
|
|
16
|
+
<meta charset="UTF-8">
|
|
17
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
18
|
+
<title>Authentication Successful</title>
|
|
19
|
+
<style>
|
|
20
|
+
body { font-family: system-ui, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #f5f5f5; }
|
|
21
|
+
.card { background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); text-align: center; max-width: 400px; }
|
|
22
|
+
h1 { color: #22c55e; margin: 0 0 0.5rem; }
|
|
23
|
+
p { color: #666; margin: 0; }
|
|
24
|
+
</style>
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
<div class="card">
|
|
28
|
+
<h1>Authentication Successful</h1>
|
|
29
|
+
<p>You can close this page and return to MCP Hub Lite.</p>
|
|
30
|
+
</div>
|
|
31
|
+
</body>
|
|
32
|
+
</html>`;
|
|
33
|
+
export class OAuthCallbackServer extends EventEmitter {
|
|
34
|
+
server = null;
|
|
35
|
+
port;
|
|
36
|
+
timeout = null;
|
|
37
|
+
constructor(port = 0) {
|
|
38
|
+
super();
|
|
39
|
+
this.port = port;
|
|
40
|
+
}
|
|
41
|
+
get callbackUrl() {
|
|
42
|
+
return `http://127.0.0.1:${this.port}${CALLBACK_PATH}`;
|
|
43
|
+
}
|
|
44
|
+
get redirectUrl() {
|
|
45
|
+
return this.callbackUrl;
|
|
46
|
+
}
|
|
47
|
+
async start() {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
this.server = http.createServer((req, res) => {
|
|
50
|
+
if (!req.url)
|
|
51
|
+
return;
|
|
52
|
+
const url = new URL(req.url, `http://127.0.0.1:${this.port}`);
|
|
53
|
+
if (url.pathname === CALLBACK_PATH) {
|
|
54
|
+
const code = url.searchParams.get('code');
|
|
55
|
+
if (code) {
|
|
56
|
+
logger.info('OAuth callback received authorization code', LOG_MODULES.dynamic('oauth'));
|
|
57
|
+
this.emit('auth-code-received', code);
|
|
58
|
+
}
|
|
59
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
60
|
+
res.end(SUCCESS_HTML);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
res.writeHead(404);
|
|
64
|
+
res.end('Not found');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
this.server.on('error', (err) => {
|
|
68
|
+
logger.error(`OAuth callback server error: ${err.message}`, LOG_MODULES.dynamic('oauth'));
|
|
69
|
+
reject(err);
|
|
70
|
+
});
|
|
71
|
+
this.server.listen(this.port, '127.0.0.1', () => {
|
|
72
|
+
const addr = this.server.address();
|
|
73
|
+
if (addr && typeof addr === 'object') {
|
|
74
|
+
this.port = addr.port;
|
|
75
|
+
}
|
|
76
|
+
logger.info(`OAuth callback server started on ${this.callbackUrl}`, LOG_MODULES.dynamic('oauth'));
|
|
77
|
+
this.timeout = setTimeout(() => this.stop(), CALLBACK_TIMEOUT);
|
|
78
|
+
resolve();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async stop() {
|
|
83
|
+
if (this.timeout) {
|
|
84
|
+
clearTimeout(this.timeout);
|
|
85
|
+
this.timeout = null;
|
|
86
|
+
}
|
|
87
|
+
return new Promise((resolve) => {
|
|
88
|
+
if (this.server) {
|
|
89
|
+
this.server.close(() => {
|
|
90
|
+
logger.info('OAuth callback server stopped', LOG_MODULES.dynamic('oauth'));
|
|
91
|
+
this.server = null;
|
|
92
|
+
resolve();
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
resolve();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP OAuth Client Provider implementing the SDK's OAuthClientProvider interface.
|
|
3
|
+
*
|
|
4
|
+
* Handles the full OAuth 2.0 authorization code flow with PKCE for MCP servers:
|
|
5
|
+
* - Persists tokens and client info to JSON files
|
|
6
|
+
* - Opens system browser for user authorization
|
|
7
|
+
* - Manages a local HTTP callback server for auth code capture
|
|
8
|
+
* - Supports token refresh and credential invalidation
|
|
9
|
+
*/
|
|
10
|
+
import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
11
|
+
import type { OAuthClientInformationMixed, OAuthTokens, OAuthClientMetadata } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
12
|
+
import { OAuthCallbackServer } from './oauth-callback-server.js';
|
|
13
|
+
import type { McpOAuthProviderOptions } from './oauth-types.js';
|
|
14
|
+
export declare class McpOAuthClientProvider implements OAuthClientProvider {
|
|
15
|
+
private _callbackServer;
|
|
16
|
+
private storage;
|
|
17
|
+
private _configDir;
|
|
18
|
+
private _callbackPort;
|
|
19
|
+
private _serverUrlHash;
|
|
20
|
+
constructor(options: McpOAuthProviderOptions);
|
|
21
|
+
get redirectUrl(): string;
|
|
22
|
+
get clientMetadata(): OAuthClientMetadata;
|
|
23
|
+
clientInformation(): OAuthClientInformationMixed | undefined;
|
|
24
|
+
saveClientInformation(info: OAuthClientInformationMixed): void;
|
|
25
|
+
tokens(): OAuthTokens | undefined;
|
|
26
|
+
saveTokens(tokens: OAuthTokens): void;
|
|
27
|
+
redirectToAuthorization(authorizationUrl: URL): Promise<void>;
|
|
28
|
+
saveCodeVerifier(codeVerifier: string): void;
|
|
29
|
+
codeVerifier(): string;
|
|
30
|
+
invalidateCredentials(scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery'): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Starts the local callback server for auth code capture.
|
|
33
|
+
* Idempotent — returns existing server if already running.
|
|
34
|
+
*/
|
|
35
|
+
startCallbackServer(): Promise<OAuthCallbackServer>;
|
|
36
|
+
/**
|
|
37
|
+
* Stops the callback server after auth flow completes.
|
|
38
|
+
*/
|
|
39
|
+
stopCallbackServer(): Promise<void>;
|
|
40
|
+
getCallbackServer(): OAuthCallbackServer | null;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=oauth-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-provider.d.ts","sourceRoot":"","sources":["../../../../../src/services/mcp-oauth/oauth-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,KAAK,EACV,2BAA2B,EAC3B,WAAW,EACX,mBAAmB,EACpB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAMhE,qBAAa,sBAAuB,YAAW,mBAAmB;IAChE,OAAO,CAAC,eAAe,CAAoC;IAC3D,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,EAAE,uBAAuB;IAO5C,IAAI,WAAW,IAAI,MAAM,CAGxB;IAED,IAAI,cAAc,IAAI,mBAAmB,CAQxC;IAED,iBAAiB,IAAI,2BAA2B,GAAG,SAAS;IAI5D,qBAAqB,CAAC,IAAI,EAAE,2BAA2B,GAAG,IAAI;IAI9D,MAAM,IAAI,WAAW,GAAG,SAAS;IAIjC,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAI/B,uBAAuB,CAAC,gBAAgB,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BnE,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAI5C,YAAY,IAAI,MAAM;IAIhB,qBAAqB,CACzB,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,GAC5D,OAAO,CAAC,IAAI,CAAC;IAKhB;;;OAGG;IACG,mBAAmB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IASzD;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzC,iBAAiB,IAAI,mBAAmB,GAAG,IAAI;CAGhD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP OAuth Client Provider implementing the SDK's OAuthClientProvider interface.
|
|
3
|
+
*
|
|
4
|
+
* Handles the full OAuth 2.0 authorization code flow with PKCE for MCP servers:
|
|
5
|
+
* - Persists tokens and client info to JSON files
|
|
6
|
+
* - Opens system browser for user authorization
|
|
7
|
+
* - Manages a local HTTP callback server for auth code capture
|
|
8
|
+
* - Supports token refresh and credential invalidation
|
|
9
|
+
*/
|
|
10
|
+
import { exec } from 'node:child_process';
|
|
11
|
+
import { promisify } from 'node:util';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import os from 'node:os';
|
|
14
|
+
import { OAuthTokenStorage } from './oauth-token-storage.js';
|
|
15
|
+
import { OAuthCallbackServer } from './oauth-callback-server.js';
|
|
16
|
+
const execAsync = promisify(exec);
|
|
17
|
+
const DEFAULT_CONFIG_DIR = path.join(os.homedir(), '.mcp-hub-lite', 'oauth');
|
|
18
|
+
export class McpOAuthClientProvider {
|
|
19
|
+
_callbackServer = null;
|
|
20
|
+
storage;
|
|
21
|
+
_configDir;
|
|
22
|
+
_callbackPort;
|
|
23
|
+
_serverUrlHash;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this._serverUrlHash = options.serverUrlHash;
|
|
26
|
+
this._configDir = options.configDir || DEFAULT_CONFIG_DIR;
|
|
27
|
+
this._callbackPort = options.callbackPort || 0;
|
|
28
|
+
this.storage = new OAuthTokenStorage(this._configDir, this._serverUrlHash);
|
|
29
|
+
}
|
|
30
|
+
get redirectUrl() {
|
|
31
|
+
if (!this._callbackServer)
|
|
32
|
+
return '';
|
|
33
|
+
return this._callbackServer.redirectUrl;
|
|
34
|
+
}
|
|
35
|
+
get clientMetadata() {
|
|
36
|
+
return {
|
|
37
|
+
redirect_uris: [this.redirectUrl],
|
|
38
|
+
token_endpoint_auth_method: 'none',
|
|
39
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
40
|
+
response_types: ['code'],
|
|
41
|
+
client_name: 'MCP Hub Lite'
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
clientInformation() {
|
|
45
|
+
return this.storage.getClientInfo();
|
|
46
|
+
}
|
|
47
|
+
saveClientInformation(info) {
|
|
48
|
+
this.storage.saveClientInfo(info);
|
|
49
|
+
}
|
|
50
|
+
tokens() {
|
|
51
|
+
return this.storage.getTokens();
|
|
52
|
+
}
|
|
53
|
+
saveTokens(tokens) {
|
|
54
|
+
this.storage.saveTokens(tokens);
|
|
55
|
+
}
|
|
56
|
+
async redirectToAuthorization(authorizationUrl) {
|
|
57
|
+
const urlStr = authorizationUrl.toString();
|
|
58
|
+
const platform = process.platform;
|
|
59
|
+
let command;
|
|
60
|
+
if (platform === 'win32') {
|
|
61
|
+
command = `start "" "${urlStr}"`;
|
|
62
|
+
}
|
|
63
|
+
else if (platform === 'darwin') {
|
|
64
|
+
command = `open "${urlStr}"`;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
command = `xdg-open "${urlStr}"`;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
await execAsync(command);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Fallback: spawn detached
|
|
74
|
+
const { spawn } = await import('node:child_process');
|
|
75
|
+
if (platform === 'win32') {
|
|
76
|
+
spawn('cmd', ['/c', 'start', '', urlStr], { detached: true, stdio: 'ignore' }).unref();
|
|
77
|
+
}
|
|
78
|
+
else if (platform === 'darwin') {
|
|
79
|
+
spawn('open', [urlStr], { detached: true, stdio: 'ignore' }).unref();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
spawn('xdg-open', [urlStr], { detached: true, stdio: 'ignore' }).unref();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
saveCodeVerifier(codeVerifier) {
|
|
87
|
+
this.storage.saveCodeVerifier(codeVerifier);
|
|
88
|
+
}
|
|
89
|
+
codeVerifier() {
|
|
90
|
+
return this.storage.getCodeVerifier() || '';
|
|
91
|
+
}
|
|
92
|
+
async invalidateCredentials(scope) {
|
|
93
|
+
if (scope === 'discovery')
|
|
94
|
+
return; // Not persisted
|
|
95
|
+
this.storage.clear(scope);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Starts the local callback server for auth code capture.
|
|
99
|
+
* Idempotent — returns existing server if already running.
|
|
100
|
+
*/
|
|
101
|
+
async startCallbackServer() {
|
|
102
|
+
if (this._callbackServer) {
|
|
103
|
+
return this._callbackServer;
|
|
104
|
+
}
|
|
105
|
+
this._callbackServer = new OAuthCallbackServer(this._callbackPort);
|
|
106
|
+
await this._callbackServer.start();
|
|
107
|
+
return this._callbackServer;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Stops the callback server after auth flow completes.
|
|
111
|
+
*/
|
|
112
|
+
async stopCallbackServer() {
|
|
113
|
+
if (this._callbackServer) {
|
|
114
|
+
await this._callbackServer.stop();
|
|
115
|
+
this._callbackServer = null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
getCallbackServer() {
|
|
119
|
+
return this._callbackServer;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON file-based OAuth token persistence.
|
|
3
|
+
*
|
|
4
|
+
* Stores OAuth credentials (client info, tokens, code verifier) as JSON files
|
|
5
|
+
* in the config directory. Uses atomic writes (tmp + rename) to prevent corruption.
|
|
6
|
+
*/
|
|
7
|
+
import type { OAuthClientInformationMixed, OAuthTokens } from './oauth-types.js';
|
|
8
|
+
export declare class OAuthTokenStorage {
|
|
9
|
+
private cache;
|
|
10
|
+
private filePath;
|
|
11
|
+
constructor(configDir: string, serverUrlHash: string);
|
|
12
|
+
private ensureDir;
|
|
13
|
+
private loadFromFile;
|
|
14
|
+
private saveToFile;
|
|
15
|
+
getClientInfo(): OAuthClientInformationMixed | undefined;
|
|
16
|
+
saveClientInfo(info: OAuthClientInformationMixed): void;
|
|
17
|
+
getTokens(): OAuthTokens | undefined;
|
|
18
|
+
saveTokens(tokens: OAuthTokens): void;
|
|
19
|
+
getCodeVerifier(): string | undefined;
|
|
20
|
+
saveCodeVerifier(verifier: string): void;
|
|
21
|
+
clear(scope: 'all' | 'client' | 'tokens' | 'verifier'): void;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=oauth-token-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-token-storage.d.ts","sourceRoot":"","sources":["../../../../../src/services/mcp-oauth/oauth-token-storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EACV,2BAA2B,EAC3B,WAAW,EAEZ,MAAM,kBAAkB,CAAC;AAE1B,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,QAAQ,CAAS;gBAEb,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;IAIpD,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,UAAU;IAclB,aAAa,IAAI,2BAA2B,GAAG,SAAS;IAOxD,cAAc,CAAC,IAAI,EAAE,2BAA2B,GAAG,IAAI;IAKvD,SAAS,IAAI,WAAW,GAAG,SAAS;IAOpC,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAKrC,eAAe,IAAI,MAAM,GAAG,SAAS;IAOrC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKxC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,IAAI;CAiB7D"}
|