@openziti/ziti-mcp-server 0.1.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/LICENSE +201 -0
- package/README.md +868 -0
- package/dist/auth/client-credentials-flow.d.ts +21 -0
- package/dist/auth/client-credentials-flow.js +63 -0
- package/dist/auth/client-credentials-flow.js.map +1 -0
- package/dist/auth/device-auth-flow.d.ts +47 -0
- package/dist/auth/device-auth-flow.js +291 -0
- package/dist/auth/device-auth-flow.js.map +1 -0
- package/dist/clients/base.d.ts +74 -0
- package/dist/clients/base.js +109 -0
- package/dist/clients/base.js.map +1 -0
- package/dist/clients/claude.d.ts +22 -0
- package/dist/clients/claude.js +40 -0
- package/dist/clients/claude.js.map +1 -0
- package/dist/clients/cursor.d.ts +22 -0
- package/dist/clients/cursor.js +39 -0
- package/dist/clients/cursor.js.map +1 -0
- package/dist/clients/index.d.ts +33 -0
- package/dist/clients/index.js +39 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/types.d.ts +70 -0
- package/dist/clients/types.js +2 -0
- package/dist/clients/types.js.map +1 -0
- package/dist/clients/utils.d.ts +22 -0
- package/dist/clients/utils.js +46 -0
- package/dist/clients/utils.js.map +1 -0
- package/dist/clients/vscode.d.ts +76 -0
- package/dist/clients/vscode.js +159 -0
- package/dist/clients/vscode.js.map +1 -0
- package/dist/clients/windsurf.d.ts +22 -0
- package/dist/clients/windsurf.js +39 -0
- package/dist/clients/windsurf.js.map +1 -0
- package/dist/commands/init.d.ts +45 -0
- package/dist/commands/init.js +133 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logout.d.ts +12 -0
- package/dist/commands/logout.js +90 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/run.d.ts +15 -0
- package/dist/commands/run.js +94 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/session.d.ts +12 -0
- package/dist/commands/session.js +99 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +105 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +67 -0
- package/dist/server.js +171 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/api-sessions.d.ts +3 -0
- package/dist/tools/api-sessions.js +86 -0
- package/dist/tools/api-sessions.js.map +1 -0
- package/dist/tools/auth-policies.d.ts +3 -0
- package/dist/tools/auth-policies.js +347 -0
- package/dist/tools/auth-policies.js.map +1 -0
- package/dist/tools/authenticators.d.ts +3 -0
- package/dist/tools/authenticators.js +183 -0
- package/dist/tools/authenticators.js.map +1 -0
- package/dist/tools/certificate-authorities.d.ts +3 -0
- package/dist/tools/certificate-authorities.js +288 -0
- package/dist/tools/certificate-authorities.js.map +1 -0
- package/dist/tools/config-types.d.ts +3 -0
- package/dist/tools/config-types.js +194 -0
- package/dist/tools/config-types.js.map +1 -0
- package/dist/tools/configs.d.ts +3 -0
- package/dist/tools/configs.js +203 -0
- package/dist/tools/configs.js.map +1 -0
- package/dist/tools/controller-settings.d.ts +3 -0
- package/dist/tools/controller-settings.js +219 -0
- package/dist/tools/controller-settings.js.map +1 -0
- package/dist/tools/controllers.d.ts +3 -0
- package/dist/tools/controllers.js +89 -0
- package/dist/tools/controllers.js.map +1 -0
- package/dist/tools/edge-router-policies.d.ts +3 -0
- package/dist/tools/edge-router-policies.js +262 -0
- package/dist/tools/edge-router-policies.js.map +1 -0
- package/dist/tools/edge-routers.d.ts +3 -0
- package/dist/tools/edge-routers.js +381 -0
- package/dist/tools/edge-routers.js.map +1 -0
- package/dist/tools/enrollments.d.ts +3 -0
- package/dist/tools/enrollments.js +187 -0
- package/dist/tools/enrollments.js.map +1 -0
- package/dist/tools/external-jwt-signers.d.ts +3 -0
- package/dist/tools/external-jwt-signers.js +242 -0
- package/dist/tools/external-jwt-signers.js.map +1 -0
- package/dist/tools/identities.d.ts +3 -0
- package/dist/tools/identities.js +741 -0
- package/dist/tools/identities.js.map +1 -0
- package/dist/tools/identity-types.d.ts +3 -0
- package/dist/tools/identity-types.js +58 -0
- package/dist/tools/identity-types.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +101 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/posture-checks.d.ts +3 -0
- package/dist/tools/posture-checks.js +254 -0
- package/dist/tools/posture-checks.js.map +1 -0
- package/dist/tools/routers.d.ts +3 -0
- package/dist/tools/routers.js +169 -0
- package/dist/tools/routers.js.map +1 -0
- package/dist/tools/service-edge-router-policies.d.ts +3 -0
- package/dist/tools/service-edge-router-policies.js +282 -0
- package/dist/tools/service-edge-router-policies.js.map +1 -0
- package/dist/tools/service-policies.d.ts +3 -0
- package/dist/tools/service-policies.js +311 -0
- package/dist/tools/service-policies.js.map +1 -0
- package/dist/tools/services.d.ts +3 -0
- package/dist/tools/services.js +403 -0
- package/dist/tools/services.js.map +1 -0
- package/dist/tools/sessions.d.ts +3 -0
- package/dist/tools/sessions.js +86 -0
- package/dist/tools/sessions.js.map +1 -0
- package/dist/tools/terminators.d.ts +3 -0
- package/dist/tools/terminators.js +187 -0
- package/dist/tools/terminators.js.map +1 -0
- package/dist/tools/transit-routers.d.ts +3 -0
- package/dist/tools/transit-routers.js +169 -0
- package/dist/tools/transit-routers.js.map +1 -0
- package/dist/utils/analytics.d.ts +75 -0
- package/dist/utils/analytics.js +191 -0
- package/dist/utils/analytics.js.map +1 -0
- package/dist/utils/auth0-client.d.ts +27 -0
- package/dist/utils/auth0-client.js +67 -0
- package/dist/utils/auth0-client.js.map +1 -0
- package/dist/utils/authenticated-client.d.ts +6 -0
- package/dist/utils/authenticated-client.js +55 -0
- package/dist/utils/authenticated-client.js.map +1 -0
- package/dist/utils/config.d.ts +65 -0
- package/dist/utils/config.js +80 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/constants.d.ts +15 -0
- package/dist/utils/constants.js +17 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/controller-client/client/client.gen.d.ts +2 -0
- package/dist/utils/controller-client/client/client.gen.js +229 -0
- package/dist/utils/controller-client/client/client.gen.js.map +1 -0
- package/dist/utils/controller-client/client/index.d.ts +8 -0
- package/dist/utils/controller-client/client/index.js +7 -0
- package/dist/utils/controller-client/client/index.js.map +1 -0
- package/dist/utils/controller-client/client/types.gen.d.ts +117 -0
- package/dist/utils/controller-client/client/types.gen.js +3 -0
- package/dist/utils/controller-client/client/types.gen.js.map +1 -0
- package/dist/utils/controller-client/client/utils.gen.d.ts +33 -0
- package/dist/utils/controller-client/client/utils.gen.js +232 -0
- package/dist/utils/controller-client/client/utils.gen.js.map +1 -0
- package/dist/utils/controller-client/client.gen.d.ts +12 -0
- package/dist/utils/controller-client/client.gen.js +6 -0
- package/dist/utils/controller-client/client.gen.js.map +1 -0
- package/dist/utils/controller-client/core/auth.gen.d.ts +18 -0
- package/dist/utils/controller-client/core/auth.gen.js +15 -0
- package/dist/utils/controller-client/core/auth.gen.js.map +1 -0
- package/dist/utils/controller-client/core/bodySerializer.gen.d.ts +25 -0
- package/dist/utils/controller-client/core/bodySerializer.gen.js +58 -0
- package/dist/utils/controller-client/core/bodySerializer.gen.js.map +1 -0
- package/dist/utils/controller-client/core/params.gen.d.ts +43 -0
- package/dist/utils/controller-client/core/params.gen.js +101 -0
- package/dist/utils/controller-client/core/params.gen.js.map +1 -0
- package/dist/utils/controller-client/core/pathSerializer.gen.d.ts +33 -0
- package/dist/utils/controller-client/core/pathSerializer.gen.js +115 -0
- package/dist/utils/controller-client/core/pathSerializer.gen.js.map +1 -0
- package/dist/utils/controller-client/core/queryKeySerializer.gen.d.ts +18 -0
- package/dist/utils/controller-client/core/queryKeySerializer.gen.js +100 -0
- package/dist/utils/controller-client/core/queryKeySerializer.gen.js.map +1 -0
- package/dist/utils/controller-client/core/serverSentEvents.gen.d.ts +71 -0
- package/dist/utils/controller-client/core/serverSentEvents.gen.js +136 -0
- package/dist/utils/controller-client/core/serverSentEvents.gen.js.map +1 -0
- package/dist/utils/controller-client/core/types.gen.d.ts +78 -0
- package/dist/utils/controller-client/core/types.gen.js +3 -0
- package/dist/utils/controller-client/core/types.gen.js.map +1 -0
- package/dist/utils/controller-client/core/utils.gen.d.ts +19 -0
- package/dist/utils/controller-client/core/utils.gen.js +88 -0
- package/dist/utils/controller-client/core/utils.gen.js.map +1 -0
- package/dist/utils/controller-client/index.d.ts +2 -0
- package/dist/utils/controller-client/index.js +3 -0
- package/dist/utils/controller-client/index.js.map +1 -0
- package/dist/utils/controller-client/sdk.gen.d.ts +1302 -0
- package/dist/utils/controller-client/sdk.gen.js +4436 -0
- package/dist/utils/controller-client/sdk.gen.js.map +1 -0
- package/dist/utils/controller-client/types.gen.d.ts +9170 -0
- package/dist/utils/controller-client/types.gen.js +3 -0
- package/dist/utils/controller-client/types.gen.js.map +1 -0
- package/dist/utils/glob.d.ts +75 -0
- package/dist/utils/glob.js +110 -0
- package/dist/utils/glob.js.map +1 -0
- package/dist/utils/http-utility.d.ts +5 -0
- package/dist/utils/http-utility.js +68 -0
- package/dist/utils/http-utility.js.map +1 -0
- package/dist/utils/keychain.d.ts +129 -0
- package/dist/utils/keychain.js +193 -0
- package/dist/utils/keychain.js.map +1 -0
- package/dist/utils/logger.d.ts +4 -0
- package/dist/utils/logger.js +28 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/package.d.ts +3 -0
- package/dist/utils/package.js +9 -0
- package/dist/utils/package.js.map +1 -0
- package/dist/utils/scopes.d.ts +12 -0
- package/dist/utils/scopes.js +19 -0
- package/dist/utils/scopes.js.map +1 -0
- package/dist/utils/terminal.d.ts +35 -0
- package/dist/utils/terminal.js +409 -0
- package/dist/utils/terminal.js.map +1 -0
- package/dist/utils/tools.d.ts +63 -0
- package/dist/utils/tools.js +149 -0
- package/dist/utils/tools.js.map +1 -0
- package/dist/utils/types.d.ts +55 -0
- package/dist/utils/types.js +3 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for client credentials configuration
|
|
3
|
+
*/
|
|
4
|
+
export interface ClientCredentialsConfig {
|
|
5
|
+
zitiControllerHost: string;
|
|
6
|
+
idpDomain: string;
|
|
7
|
+
idpClientId: string;
|
|
8
|
+
idpClientSecret: string;
|
|
9
|
+
audience?: string;
|
|
10
|
+
scopes?: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Request authorization using client credentials flow
|
|
14
|
+
*
|
|
15
|
+
* This method is primarily designed for Private Cloud users who cannot use the
|
|
16
|
+
* device authorization flow. It uses client credentials flow to obtain an access token.
|
|
17
|
+
*
|
|
18
|
+
* @param {ClientCredentialsConfig} config - Configuration for client credentials flow
|
|
19
|
+
* @returns {Promise<void>}
|
|
20
|
+
*/
|
|
21
|
+
export declare function requestClientCredentialsAuthorization(config: ClientCredentialsConfig): Promise<void>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { cliOutput } from '../utils/terminal.js';
|
|
3
|
+
import { log, logError } from '../utils/logger.js';
|
|
4
|
+
import { keychain } from '../utils/keychain.js';
|
|
5
|
+
import { getAuthenticationClient } from '../utils/auth0-client.js';
|
|
6
|
+
/**
|
|
7
|
+
* Request authorization using client credentials flow
|
|
8
|
+
*
|
|
9
|
+
* This method is primarily designed for Private Cloud users who cannot use the
|
|
10
|
+
* device authorization flow. It uses client credentials flow to obtain an access token.
|
|
11
|
+
*
|
|
12
|
+
* @param {ClientCredentialsConfig} config - Configuration for client credentials flow
|
|
13
|
+
* @returns {Promise<void>}
|
|
14
|
+
*/
|
|
15
|
+
export async function requestClientCredentialsAuthorization(config) {
|
|
16
|
+
log('Initiating client credentials flow authentication...');
|
|
17
|
+
try {
|
|
18
|
+
// Auth client
|
|
19
|
+
const authClient = await getAuthenticationClient(config.idpDomain, config.idpClientId, config.idpClientSecret);
|
|
20
|
+
// Set audience if provided, otherwise use a default based on the domain
|
|
21
|
+
const audience = config.audience || `https://${config.idpDomain}/api/v2/`;
|
|
22
|
+
// Make the token request
|
|
23
|
+
const { data: { access_token, expires_in }, } = await authClient.oauth.clientCredentialsGrant({
|
|
24
|
+
audience,
|
|
25
|
+
});
|
|
26
|
+
const tokenSet = { access_token, expires_in };
|
|
27
|
+
// Store the token information
|
|
28
|
+
await storeTokenInfo(tokenSet, config.zitiControllerHost, config.idpDomain);
|
|
29
|
+
cliOutput(`\n${chalk.green('✓')} Successfully authenticated to ${chalk.blue(config.idpDomain)} using client credentials.\n`);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
logError('Client credentials authentication error:', error);
|
|
33
|
+
cliOutput(`\n${chalk.red('✗')} Failed to authenticate with client credentials.\n`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Store token information from client credentials flow
|
|
39
|
+
*
|
|
40
|
+
* @param {any} tokenSet - Token response from the server
|
|
41
|
+
* @param {string} domain - The domain used for authentication
|
|
42
|
+
*/
|
|
43
|
+
async function storeTokenInfo(tokenSet, zitiControllerHost, domain) {
|
|
44
|
+
// For client credentials flow, we use the provided domain directly,
|
|
45
|
+
// as the token may not contain tenant information in the same format as device flow
|
|
46
|
+
// Store access token
|
|
47
|
+
await keychain.setToken(tokenSet.access_token);
|
|
48
|
+
await keychain.setZitiControllerHost(zitiControllerHost);
|
|
49
|
+
await keychain.setDomain(domain);
|
|
50
|
+
// Client credentials flow typically doesn't return refresh tokens
|
|
51
|
+
// but we'll handle it just in case
|
|
52
|
+
if (tokenSet.refresh_token) {
|
|
53
|
+
await keychain.setRefreshToken(tokenSet.refresh_token);
|
|
54
|
+
log('Refresh token stored in keychain');
|
|
55
|
+
}
|
|
56
|
+
// Set token expiration
|
|
57
|
+
if (tokenSet.expires_in) {
|
|
58
|
+
const expiresAt = Date.now() + tokenSet.expires_in * 1000;
|
|
59
|
+
await keychain.setTokenExpiresAt(expiresAt);
|
|
60
|
+
log(`Token expires at: ${new Date(expiresAt).toISOString()}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=client-credentials-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-credentials-flow.js","sourceRoot":"","sources":["../../src/auth/client-credentials-flow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAcnE;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,qCAAqC,CACzD,MAA+B;IAE/B,GAAG,CAAC,sDAAsD,CAAC,CAAC;IAE5D,IAAI,CAAC;QACH,cAAc;QACd,MAAM,UAAU,GAAG,MAAM,uBAAuB,CAC9C,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,eAAe,CACvB,CAAC;QAEF,wEAAwE;QACxE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,WAAW,MAAM,CAAC,SAAS,UAAU,CAAC;QAE1E,yBAAyB;QACzB,MAAM,EACJ,IAAI,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,GACnC,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,sBAAsB,CAAC;YAChD,QAAQ;SACT,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;QAE9C,8BAA8B;QAC9B,MAAM,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAE5E,SAAS,CACP,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kCAAkC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,8BAA8B,CAClH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,QAAQ,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;QAC5D,SAAS,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,cAAc,CAC3B,QAAa,EACb,kBAA0B,EAC1B,MAAc;IAEd,oEAAoE;IACpE,oFAAoF;IAEpF,qBAAqB;IACrB,MAAM,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,QAAQ,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;IACzD,MAAM,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAEjC,kEAAkE;IAClE,mCAAmC;IACnC,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;QAC3B,MAAM,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QACvD,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAC1C,CAAC;IAED,uBAAuB;IACvB,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC;QAC1D,MAAM,QAAQ,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAC5C,GAAG,CAAC,qBAAqB,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
declare function requestAuthorization(selectedScopes?: string[]): Promise<void>;
|
|
2
|
+
export declare function refreshAccessToken(selectedScopes?: string[]): Promise<string | null>;
|
|
3
|
+
/**
|
|
4
|
+
* Revokes the refresh token that is previously set within keychain when offline_access is requested.
|
|
5
|
+
* Returns true if the call is successful or if the refresh token does not exist.
|
|
6
|
+
* @returns {Promise<boolean>}
|
|
7
|
+
*/
|
|
8
|
+
export declare function revokeRefreshToken(): Promise<boolean>;
|
|
9
|
+
/**
|
|
10
|
+
* Determines if the current access token is expired or will expire soon.
|
|
11
|
+
*
|
|
12
|
+
* This security check is crucial for maintaining continuous authenticated access
|
|
13
|
+
* to Auth0 APIs. It includes a configurable buffer time to proactively detect
|
|
14
|
+
* tokens that will expire soon, preventing potential disruptions during operations
|
|
15
|
+
* that might span multiple API calls. This proactive approach allows the system to
|
|
16
|
+
* initiate refresh flows before actual expiration occurs.
|
|
17
|
+
*
|
|
18
|
+
* The function considers a token expired in the following cases:
|
|
19
|
+
* - No expiration time is found in the keychain via `keychain.getTokenExpiresAt()`
|
|
20
|
+
* - Current time + buffer exceeds the token's expiration time
|
|
21
|
+
* - Error occurs during expiration check (fails secure)
|
|
22
|
+
*
|
|
23
|
+
* This function is used both by `validateAuthorization()` in `run.ts` for user-friendly
|
|
24
|
+
* startup validation and by `validateConfig()` for continuous runtime validation.
|
|
25
|
+
*
|
|
26
|
+
* @param {number} bufferSeconds - Seconds before actual expiration to consider token expired (default: 300s/5min)
|
|
27
|
+
* @returns {Promise<boolean>} True if token is expired or will expire within the buffer period
|
|
28
|
+
*/
|
|
29
|
+
export declare function isTokenExpired(bufferSeconds?: number): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Retrieves a valid access token for OpenZiti Controller Management API operations.
|
|
32
|
+
*
|
|
33
|
+
* This function serves as the main entry point for credential retrieval,
|
|
34
|
+
* ensuring that only valid, non-expired tokens are provided to API operations.
|
|
35
|
+
* It implements a critical security checkpoint that prevents operations from
|
|
36
|
+
* proceeding with invalid authentication, which could lead to API failures
|
|
37
|
+
* or unpredictable behavior.
|
|
38
|
+
*
|
|
39
|
+
* The function performs these key security checks:
|
|
40
|
+
* 1. Verifies token expiration status using isTokenExpired
|
|
41
|
+
* 2. Provides clear guidance to users when re-authentication is needed
|
|
42
|
+
* 3. Handles errors gracefully with a fail-secure approach
|
|
43
|
+
*
|
|
44
|
+
* @returns {Promise<string|null>} A valid access token, or null if no valid token is available
|
|
45
|
+
*/
|
|
46
|
+
export declare function getValidAccessToken(): Promise<string | null>;
|
|
47
|
+
export { requestAuthorization };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import open from 'open';
|
|
3
|
+
import { startSpinner, stopSpinner, getTenantFromToken, cliOutput, promptForBrowserPermission, } from '../utils/terminal.js';
|
|
4
|
+
import { log, logError } from '../utils/logger.js';
|
|
5
|
+
import { keychain } from '../utils/keychain.js';
|
|
6
|
+
import { DEFAULT_SCOPES } from '../utils/scopes.js';
|
|
7
|
+
function getConfig(selectedScopes) {
|
|
8
|
+
// If selectedScopes is provided, use those scopes
|
|
9
|
+
// If not provided or empty, use DEFAULT_SCOPES (which is now empty by default)
|
|
10
|
+
const scopes = selectedScopes && selectedScopes.length > 0
|
|
11
|
+
? selectedScopes.join(' ')
|
|
12
|
+
: DEFAULT_SCOPES.join(' ');
|
|
13
|
+
return {
|
|
14
|
+
tenant: 'auth0.auth0.com',
|
|
15
|
+
clientId: '2lhnuYMRQ8IpR5hNsOhDFQqrGQUQMRm5',
|
|
16
|
+
audience: 'https://*.auth0.com/api/v2/',
|
|
17
|
+
scopes,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async function requestAuthorization(selectedScopes) {
|
|
21
|
+
const config = getConfig(selectedScopes);
|
|
22
|
+
const body = {
|
|
23
|
+
client_id: config.clientId,
|
|
24
|
+
};
|
|
25
|
+
if (config.audience) {
|
|
26
|
+
body.audience = config.audience;
|
|
27
|
+
}
|
|
28
|
+
if (config.scopes.length) {
|
|
29
|
+
body.scope = config.scopes;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const response = await fetch(`https://${config.tenant}/oauth/device/code`, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
body: new URLSearchParams(body),
|
|
35
|
+
headers: {
|
|
36
|
+
Accept: 'application/json',
|
|
37
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
const jsonRes = await response.json();
|
|
41
|
+
if (!jsonRes.error) {
|
|
42
|
+
cliOutput(`\nVerify this code on screen: ${chalk.bold.green(jsonRes.user_code)}\n`);
|
|
43
|
+
// Wait for user to press Enter to open browser
|
|
44
|
+
await promptForBrowserPermission();
|
|
45
|
+
openBrowser(jsonRes.verification_uri_complete);
|
|
46
|
+
await exchangeDeviceCodeForToken(jsonRes, selectedScopes);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
logError('Error', jsonRes);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
logError('Error', err);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function wait(ms) {
|
|
59
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
60
|
+
}
|
|
61
|
+
function isValidUrl(url) {
|
|
62
|
+
try {
|
|
63
|
+
const parsedUrl = new URL(url);
|
|
64
|
+
// Check for safe protocols
|
|
65
|
+
return ['http:', 'https:'].includes(parsedUrl.protocol);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
logError('Error', error);
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function openBrowser(url) {
|
|
73
|
+
if (!url || !isValidUrl(url)) {
|
|
74
|
+
logError('Invalid URL provided:', url);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
open(url)
|
|
78
|
+
.then(() => {
|
|
79
|
+
log('Browser opened successfully');
|
|
80
|
+
})
|
|
81
|
+
.catch((err) => {
|
|
82
|
+
logError('Failed to open browser:', err);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async function exchangeDeviceCodeForToken(deviceCode, selectedScopes) {
|
|
86
|
+
const config = getConfig(selectedScopes);
|
|
87
|
+
startSpinner('Waiting for authorization...');
|
|
88
|
+
while (true) {
|
|
89
|
+
try {
|
|
90
|
+
const response = await fetch(`https://${config.tenant}/oauth/token`, {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
body: new URLSearchParams({
|
|
93
|
+
client_id: config.clientId,
|
|
94
|
+
device_code: deviceCode.device_code,
|
|
95
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
96
|
+
}),
|
|
97
|
+
headers: {
|
|
98
|
+
Accept: 'application/json',
|
|
99
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
const jsonRes = await response.json();
|
|
103
|
+
if (!jsonRes.error) {
|
|
104
|
+
fetchUserInfo(jsonRes); // Success case
|
|
105
|
+
break; // Exit loop once successful
|
|
106
|
+
}
|
|
107
|
+
else if (['authorization_pending', 'slow_down'].includes(jsonRes.error)) {
|
|
108
|
+
await wait(5000); // Wait before polling again
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
stopSpinner();
|
|
112
|
+
logError('Unexpected error:', jsonRes.error);
|
|
113
|
+
break; // Exit loop on unknown error
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
stopSpinner();
|
|
118
|
+
logError('Error in token exchange:', err);
|
|
119
|
+
break; // Exit loop on fetch failure
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
stopSpinner();
|
|
123
|
+
}
|
|
124
|
+
async function fetchUserInfo(tokenSet) {
|
|
125
|
+
const tenantName = getTenantFromToken(tokenSet.access_token);
|
|
126
|
+
// Store tokens in keychain
|
|
127
|
+
await keychain.setToken(tokenSet.access_token);
|
|
128
|
+
await keychain.setDomain(tenantName);
|
|
129
|
+
if (tokenSet.refresh_token) {
|
|
130
|
+
await keychain.setRefreshToken(tokenSet.refresh_token);
|
|
131
|
+
log('Refresh token stored in keychain');
|
|
132
|
+
}
|
|
133
|
+
if (tokenSet.expires_in) {
|
|
134
|
+
const expiresAt = Date.now() + tokenSet.expires_in * 1000;
|
|
135
|
+
await keychain.setTokenExpiresAt(expiresAt);
|
|
136
|
+
log(`Token expires at: ${new Date(expiresAt).toISOString()}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export async function refreshAccessToken(selectedScopes) {
|
|
140
|
+
try {
|
|
141
|
+
log('Attempting to refresh access token');
|
|
142
|
+
const refreshToken = await keychain.getRefreshToken();
|
|
143
|
+
if (!refreshToken) {
|
|
144
|
+
log('No refresh token found in keychain');
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
const config = getConfig(selectedScopes);
|
|
148
|
+
const response = await fetch(`https://${config.tenant}/oauth/token`, {
|
|
149
|
+
method: 'POST',
|
|
150
|
+
body: new URLSearchParams({
|
|
151
|
+
grant_type: 'refresh_token',
|
|
152
|
+
client_id: config.clientId,
|
|
153
|
+
refresh_token: refreshToken,
|
|
154
|
+
}),
|
|
155
|
+
headers: {
|
|
156
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
const tokenSet = await response.json();
|
|
160
|
+
if (tokenSet.error) {
|
|
161
|
+
log(`Error refreshing token: ${tokenSet.error}`);
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
// Store new tokens
|
|
165
|
+
const tenantName = getTenantFromToken(tokenSet.access_token);
|
|
166
|
+
await keychain.setToken(tokenSet.access_token);
|
|
167
|
+
await keychain.setDomain(tenantName);
|
|
168
|
+
if (tokenSet.refresh_token) {
|
|
169
|
+
await keychain.setRefreshToken(tokenSet.refresh_token);
|
|
170
|
+
}
|
|
171
|
+
if (tokenSet.expires_in) {
|
|
172
|
+
const expiresAt = Date.now() + tokenSet.expires_in * 1000;
|
|
173
|
+
await keychain.setTokenExpiresAt(expiresAt);
|
|
174
|
+
}
|
|
175
|
+
log('Successfully refreshed access token');
|
|
176
|
+
return tokenSet.access_token;
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
log('Error refreshing access token:', error);
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Revokes the refresh token that is previously set within keychain when offline_access is requested.
|
|
185
|
+
* Returns true if the call is successful or if the refresh token does not exist.
|
|
186
|
+
* @returns {Promise<boolean>}
|
|
187
|
+
*/
|
|
188
|
+
export async function revokeRefreshToken() {
|
|
189
|
+
try {
|
|
190
|
+
log('Attempting to revoke refresh token');
|
|
191
|
+
const refreshToken = await keychain.getRefreshToken();
|
|
192
|
+
if (!refreshToken) {
|
|
193
|
+
log('No refresh token found in keychain');
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
const config = getConfig();
|
|
197
|
+
const response = await fetch(`https://${config.tenant}/oauth/revoke`, {
|
|
198
|
+
method: 'POST',
|
|
199
|
+
body: new URLSearchParams({
|
|
200
|
+
client_id: config.clientId,
|
|
201
|
+
token: refreshToken,
|
|
202
|
+
}),
|
|
203
|
+
headers: {
|
|
204
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
if (response.status === 200) {
|
|
208
|
+
log('Refresh token successfully revoked');
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
log('Error calling revoke API: ', response.statusText);
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
log('Error revoking refresh token:', error);
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Determines if the current access token is expired or will expire soon.
|
|
223
|
+
*
|
|
224
|
+
* This security check is crucial for maintaining continuous authenticated access
|
|
225
|
+
* to Auth0 APIs. It includes a configurable buffer time to proactively detect
|
|
226
|
+
* tokens that will expire soon, preventing potential disruptions during operations
|
|
227
|
+
* that might span multiple API calls. This proactive approach allows the system to
|
|
228
|
+
* initiate refresh flows before actual expiration occurs.
|
|
229
|
+
*
|
|
230
|
+
* The function considers a token expired in the following cases:
|
|
231
|
+
* - No expiration time is found in the keychain via `keychain.getTokenExpiresAt()`
|
|
232
|
+
* - Current time + buffer exceeds the token's expiration time
|
|
233
|
+
* - Error occurs during expiration check (fails secure)
|
|
234
|
+
*
|
|
235
|
+
* This function is used both by `validateAuthorization()` in `run.ts` for user-friendly
|
|
236
|
+
* startup validation and by `validateConfig()` for continuous runtime validation.
|
|
237
|
+
*
|
|
238
|
+
* @param {number} bufferSeconds - Seconds before actual expiration to consider token expired (default: 300s/5min)
|
|
239
|
+
* @returns {Promise<boolean>} True if token is expired or will expire within the buffer period
|
|
240
|
+
*/
|
|
241
|
+
export async function isTokenExpired(bufferSeconds = 300) {
|
|
242
|
+
try {
|
|
243
|
+
const expiresAt = await keychain.getTokenExpiresAt();
|
|
244
|
+
if (!expiresAt) {
|
|
245
|
+
log('No token expiration time found');
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
const now = Date.now();
|
|
249
|
+
const isExpired = now + bufferSeconds * 1000 >= expiresAt;
|
|
250
|
+
if (isExpired) {
|
|
251
|
+
log(`Token is expired or will expire soon. Expires at: ${new Date(expiresAt).toISOString()}`);
|
|
252
|
+
}
|
|
253
|
+
return isExpired;
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
log('Error checking token expiration:', error);
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Retrieves a valid access token for OpenZiti Controller Management API operations.
|
|
262
|
+
*
|
|
263
|
+
* This function serves as the main entry point for credential retrieval,
|
|
264
|
+
* ensuring that only valid, non-expired tokens are provided to API operations.
|
|
265
|
+
* It implements a critical security checkpoint that prevents operations from
|
|
266
|
+
* proceeding with invalid authentication, which could lead to API failures
|
|
267
|
+
* or unpredictable behavior.
|
|
268
|
+
*
|
|
269
|
+
* The function performs these key security checks:
|
|
270
|
+
* 1. Verifies token expiration status using isTokenExpired
|
|
271
|
+
* 2. Provides clear guidance to users when re-authentication is needed
|
|
272
|
+
* 3. Handles errors gracefully with a fail-secure approach
|
|
273
|
+
*
|
|
274
|
+
* @returns {Promise<string|null>} A valid access token, or null if no valid token is available
|
|
275
|
+
*/
|
|
276
|
+
export async function getValidAccessToken() {
|
|
277
|
+
try {
|
|
278
|
+
const expired = await isTokenExpired();
|
|
279
|
+
if (expired) {
|
|
280
|
+
log('Token is expired. Please authenticate again using `npx @openziti/openziti-mcp-server init`');
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
return await keychain.getToken();
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
log('Error getting valid access token:', error);
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
export { requestAuthorization };
|
|
291
|
+
//# sourceMappingURL=device-auth-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-auth-flow.js","sourceRoot":"","sources":["../../src/auth/device-auth-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ClientOptions } from '../utils/types.js';
|
|
2
|
+
import type { ServerConfig, ClientConfig, ClientManager, ClientType } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class providing common functionality for all supported MCP client managers.
|
|
5
|
+
*
|
|
6
|
+
* Subclasses should extend this class to handle client-specific configuration paths and custom behaviors.
|
|
7
|
+
*/
|
|
8
|
+
export declare abstract class BaseClientManager implements ClientManager {
|
|
9
|
+
protected readonly clientType: ClientType;
|
|
10
|
+
readonly displayName: string;
|
|
11
|
+
protected readonly capabilities?: string[];
|
|
12
|
+
/**
|
|
13
|
+
* Initializes a new BaseClientManager instance.
|
|
14
|
+
*
|
|
15
|
+
* @param options - Configuration options including client type, display name, and optional capabilities.
|
|
16
|
+
*/
|
|
17
|
+
constructor(options: {
|
|
18
|
+
clientType: ClientType;
|
|
19
|
+
displayName: string;
|
|
20
|
+
capabilities?: string[];
|
|
21
|
+
});
|
|
22
|
+
/**
|
|
23
|
+
* Returns the absolute path to the client's configuration file.
|
|
24
|
+
*
|
|
25
|
+
* Subclasses must implement this method to provide client-specific path resolution.
|
|
26
|
+
* Implementations are responsible for ensuring any necessary directories exist.
|
|
27
|
+
*
|
|
28
|
+
* @returns The resolved configuration file path.
|
|
29
|
+
*/
|
|
30
|
+
abstract getConfigPath(): string;
|
|
31
|
+
/**
|
|
32
|
+
* Updates the client’s configuration with OpenZiti MCP server settings.
|
|
33
|
+
*
|
|
34
|
+
* Loads the existing configuration, applies updates for the MCP server,
|
|
35
|
+
* and writes the updated configuration back to disk.
|
|
36
|
+
*
|
|
37
|
+
* @param options - Client configuration options such as enabled tools and read-only mode.
|
|
38
|
+
*/
|
|
39
|
+
configure(options: ClientOptions): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Creates an MCP server configuration entry based on the provided client options.
|
|
42
|
+
*
|
|
43
|
+
* This method transforms the user’s options into a command, arguments,
|
|
44
|
+
* environment variables, and optional capabilities that the client will use to start the MCP server.
|
|
45
|
+
*
|
|
46
|
+
* Subclasses may override this method if additional customization of the server config is needed.
|
|
47
|
+
*
|
|
48
|
+
* @param options - Options controlling server configuration, such as selected tools and read-only mode.
|
|
49
|
+
* @returns A fully-formed ServerConfig object.
|
|
50
|
+
* @protected
|
|
51
|
+
*/
|
|
52
|
+
protected createServerConfig(options: ClientOptions): ServerConfig;
|
|
53
|
+
/**
|
|
54
|
+
* Loads the client’s configuration from disk.
|
|
55
|
+
*
|
|
56
|
+
* Attempts to read and parse the configuration file at the given path.
|
|
57
|
+
* Returns a default configuration object if the file is missing or cannot be read.
|
|
58
|
+
*
|
|
59
|
+
* @param configPath - Path to the client’s configuration file.
|
|
60
|
+
* @returns A parsed ClientConfig object.
|
|
61
|
+
* @protected
|
|
62
|
+
*/
|
|
63
|
+
protected readConfig(configPath: string): ClientConfig;
|
|
64
|
+
/**
|
|
65
|
+
* Writes the provided configuration object to disk.
|
|
66
|
+
*
|
|
67
|
+
* Serializes the configuration to formatted JSON and saves it at the specified path.
|
|
68
|
+
*
|
|
69
|
+
* @param configPath - Path where the configuration should be saved.
|
|
70
|
+
* @param config - Configuration object to serialize and write.
|
|
71
|
+
* @protected
|
|
72
|
+
*/
|
|
73
|
+
protected writeConfig(configPath: string, config: ClientConfig): void;
|
|
74
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { log } from '../utils/logger.js';
|
|
4
|
+
import { cliOutput } from '../utils/terminal.js';
|
|
5
|
+
import { packageName } from '../utils/package.js';
|
|
6
|
+
import { MCP_SERVER_NAME } from '../utils/constants.js';
|
|
7
|
+
/**
|
|
8
|
+
* Abstract base class providing common functionality for all supported MCP client managers.
|
|
9
|
+
*
|
|
10
|
+
* Subclasses should extend this class to handle client-specific configuration paths and custom behaviors.
|
|
11
|
+
*/
|
|
12
|
+
export class BaseClientManager {
|
|
13
|
+
clientType;
|
|
14
|
+
displayName;
|
|
15
|
+
capabilities;
|
|
16
|
+
/**
|
|
17
|
+
* Initializes a new BaseClientManager instance.
|
|
18
|
+
*
|
|
19
|
+
* @param options - Configuration options including client type, display name, and optional capabilities.
|
|
20
|
+
*/
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.clientType = options.clientType;
|
|
23
|
+
this.displayName = options.displayName;
|
|
24
|
+
this.capabilities = options.capabilities;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Updates the client’s configuration with OpenZiti MCP server settings.
|
|
28
|
+
*
|
|
29
|
+
* Loads the existing configuration, applies updates for the MCP server,
|
|
30
|
+
* and writes the updated configuration back to disk.
|
|
31
|
+
*
|
|
32
|
+
* @param options - Client configuration options such as enabled tools and read-only mode.
|
|
33
|
+
*/
|
|
34
|
+
async configure(options) {
|
|
35
|
+
const configPath = this.getConfigPath();
|
|
36
|
+
const config = this.readConfig(configPath);
|
|
37
|
+
const mcpServers = config.mcpServers || {};
|
|
38
|
+
const serverConfig = this.createServerConfig(options);
|
|
39
|
+
mcpServers[MCP_SERVER_NAME] = serverConfig;
|
|
40
|
+
config.mcpServers = mcpServers;
|
|
41
|
+
this.writeConfig(configPath, config);
|
|
42
|
+
log(`Updated ${this.displayName} config file at: ${configPath}`);
|
|
43
|
+
cliOutput(`\n${chalk.green('✓')} OpenZiti MCP server configured. ${chalk.yellow(`Restart ${this.displayName}`)} to apply changes.\n`);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Creates an MCP server configuration entry based on the provided client options.
|
|
47
|
+
*
|
|
48
|
+
* This method transforms the user’s options into a command, arguments,
|
|
49
|
+
* environment variables, and optional capabilities that the client will use to start the MCP server.
|
|
50
|
+
*
|
|
51
|
+
* Subclasses may override this method if additional customization of the server config is needed.
|
|
52
|
+
*
|
|
53
|
+
* @param options - Options controlling server configuration, such as selected tools and read-only mode.
|
|
54
|
+
* @returns A fully-formed ServerConfig object.
|
|
55
|
+
* @protected
|
|
56
|
+
*/
|
|
57
|
+
createServerConfig(options) {
|
|
58
|
+
const args = ['-y', packageName, 'run', '--tools', `${options.tools.join(',')}`];
|
|
59
|
+
if (options.readOnly) {
|
|
60
|
+
args.push('--read-only');
|
|
61
|
+
}
|
|
62
|
+
const config = {
|
|
63
|
+
command: 'npx',
|
|
64
|
+
args,
|
|
65
|
+
env: {
|
|
66
|
+
DEBUG: 'ziti-mcp',
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
if (this.capabilities?.length) {
|
|
70
|
+
config.capabilities = this.capabilities;
|
|
71
|
+
}
|
|
72
|
+
return config;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Loads the client’s configuration from disk.
|
|
76
|
+
*
|
|
77
|
+
* Attempts to read and parse the configuration file at the given path.
|
|
78
|
+
* Returns a default configuration object if the file is missing or cannot be read.
|
|
79
|
+
*
|
|
80
|
+
* @param configPath - Path to the client’s configuration file.
|
|
81
|
+
* @returns A parsed ClientConfig object.
|
|
82
|
+
* @protected
|
|
83
|
+
*/
|
|
84
|
+
readConfig(configPath) {
|
|
85
|
+
if (fs.existsSync(configPath)) {
|
|
86
|
+
try {
|
|
87
|
+
const data = fs.readFileSync(configPath, 'utf-8');
|
|
88
|
+
return JSON.parse(data);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
log(`Warning: Could not read config at ${configPath}: ${err}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { mcpServers: {} };
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Writes the provided configuration object to disk.
|
|
98
|
+
*
|
|
99
|
+
* Serializes the configuration to formatted JSON and saves it at the specified path.
|
|
100
|
+
*
|
|
101
|
+
* @param configPath - Path where the configuration should be saved.
|
|
102
|
+
* @param config - Configuration object to serialize and write.
|
|
103
|
+
* @protected
|
|
104
|
+
*/
|
|
105
|
+
writeConfig(configPath, config) {
|
|
106
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/clients/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseClientManager } from './base.js';
|
|
2
|
+
/**
|
|
3
|
+
* Client manager implementation for Claude Desktop.
|
|
4
|
+
*
|
|
5
|
+
* Responsible for configuring and managing the MCP server integration
|
|
6
|
+
* for the Claude Desktop application.
|
|
7
|
+
*
|
|
8
|
+
* @see {@link https://claude.ai/download | Claude Desktop Download}
|
|
9
|
+
*/
|
|
10
|
+
export declare class ClaudeClientManager extends BaseClientManager {
|
|
11
|
+
constructor();
|
|
12
|
+
/**
|
|
13
|
+
* Returns the path to the Claude Desktop configuration file.
|
|
14
|
+
*
|
|
15
|
+
* Resolves the platform-specific configuration directory,
|
|
16
|
+
* ensures the directory exists on disk, and constructs the full path
|
|
17
|
+
* to the Claude Desktop configuration file.
|
|
18
|
+
*
|
|
19
|
+
* @returns The absolute path to the configuration file.
|
|
20
|
+
*/
|
|
21
|
+
getConfigPath(): string;
|
|
22
|
+
}
|