@doxhub/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.
Files changed (106) hide show
  1. package/README.md +231 -0
  2. package/dist/api-client.d.ts +27 -0
  3. package/dist/api-client.d.ts.map +1 -0
  4. package/dist/api-client.js +75 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/auth/check-permissions.d.ts +16 -0
  7. package/dist/auth/check-permissions.d.ts.map +1 -0
  8. package/dist/auth/check-permissions.js +43 -0
  9. package/dist/auth/check-permissions.js.map +1 -0
  10. package/dist/auth/get-user-workspaces.d.ts +3 -0
  11. package/dist/auth/get-user-workspaces.d.ts.map +1 -0
  12. package/dist/auth/get-user-workspaces.js +16 -0
  13. package/dist/auth/get-user-workspaces.js.map +1 -0
  14. package/dist/auth/mcp-token-verify.d.ts +10 -0
  15. package/dist/auth/mcp-token-verify.d.ts.map +1 -0
  16. package/dist/auth/mcp-token-verify.js +43 -0
  17. package/dist/auth/mcp-token-verify.js.map +1 -0
  18. package/dist/auth/verify-token.d.ts +4 -0
  19. package/dist/auth/verify-token.d.ts.map +1 -0
  20. package/dist/auth/verify-token.js +61 -0
  21. package/dist/auth/verify-token.js.map +1 -0
  22. package/dist/cli/config-manager.d.ts +29 -0
  23. package/dist/cli/config-manager.d.ts.map +1 -0
  24. package/dist/cli/config-manager.js +111 -0
  25. package/dist/cli/config-manager.js.map +1 -0
  26. package/dist/cli/credentials.d.ts +64 -0
  27. package/dist/cli/credentials.d.ts.map +1 -0
  28. package/dist/cli/credentials.js +117 -0
  29. package/dist/cli/credentials.js.map +1 -0
  30. package/dist/cli/profiles.d.ts +3 -0
  31. package/dist/cli/profiles.d.ts.map +1 -0
  32. package/dist/cli/profiles.js +35 -0
  33. package/dist/cli/profiles.js.map +1 -0
  34. package/dist/cli/revoke.d.ts +3 -0
  35. package/dist/cli/revoke.d.ts.map +1 -0
  36. package/dist/cli/revoke.js +60 -0
  37. package/dist/cli/revoke.js.map +1 -0
  38. package/dist/cli/setup.d.ts +11 -0
  39. package/dist/cli/setup.d.ts.map +1 -0
  40. package/dist/cli/setup.js +296 -0
  41. package/dist/cli/setup.js.map +1 -0
  42. package/dist/cli/status.d.ts +2 -0
  43. package/dist/cli/status.d.ts.map +1 -0
  44. package/dist/cli/status.js +45 -0
  45. package/dist/cli/status.js.map +1 -0
  46. package/dist/index.d.ts +3 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +124 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/queries/file-queries.d.ts +15 -0
  51. package/dist/queries/file-queries.d.ts.map +1 -0
  52. package/dist/queries/file-queries.js +75 -0
  53. package/dist/queries/file-queries.js.map +1 -0
  54. package/dist/queries/search-queries.d.ts +7 -0
  55. package/dist/queries/search-queries.d.ts.map +1 -0
  56. package/dist/queries/search-queries.js +93 -0
  57. package/dist/queries/search-queries.js.map +1 -0
  58. package/dist/queries/version-queries.d.ts +26 -0
  59. package/dist/queries/version-queries.d.ts.map +1 -0
  60. package/dist/queries/version-queries.js +46 -0
  61. package/dist/queries/version-queries.js.map +1 -0
  62. package/dist/queries/workspace-queries.d.ts +10 -0
  63. package/dist/queries/workspace-queries.d.ts.map +1 -0
  64. package/dist/queries/workspace-queries.js +108 -0
  65. package/dist/queries/workspace-queries.js.map +1 -0
  66. package/dist/server.d.ts +21 -0
  67. package/dist/server.d.ts.map +1 -0
  68. package/dist/server.js +81 -0
  69. package/dist/server.js.map +1 -0
  70. package/dist/tools/get-file-versions.d.ts +30 -0
  71. package/dist/tools/get-file-versions.d.ts.map +1 -0
  72. package/dist/tools/get-file-versions.js +42 -0
  73. package/dist/tools/get-file-versions.js.map +1 -0
  74. package/dist/tools/get-file.d.ts +26 -0
  75. package/dist/tools/get-file.d.ts.map +1 -0
  76. package/dist/tools/get-file.js +51 -0
  77. package/dist/tools/get-file.js.map +1 -0
  78. package/dist/tools/get-project-structure.d.ts +26 -0
  79. package/dist/tools/get-project-structure.d.ts.map +1 -0
  80. package/dist/tools/get-project-structure.js +37 -0
  81. package/dist/tools/get-project-structure.js.map +1 -0
  82. package/dist/tools/index.d.ts +8 -0
  83. package/dist/tools/index.d.ts.map +1 -0
  84. package/dist/tools/index.js +8 -0
  85. package/dist/tools/index.js.map +1 -0
  86. package/dist/tools/list-files.d.ts +35 -0
  87. package/dist/tools/list-files.d.ts.map +1 -0
  88. package/dist/tools/list-files.js +74 -0
  89. package/dist/tools/list-files.js.map +1 -0
  90. package/dist/tools/list-projects.d.ts +19 -0
  91. package/dist/tools/list-projects.d.ts.map +1 -0
  92. package/dist/tools/list-projects.js +74 -0
  93. package/dist/tools/list-projects.js.map +1 -0
  94. package/dist/tools/list-workspaces.d.ts +17 -0
  95. package/dist/tools/list-workspaces.d.ts.map +1 -0
  96. package/dist/tools/list-workspaces.js +45 -0
  97. package/dist/tools/list-workspaces.js.map +1 -0
  98. package/dist/tools/search-documentation.d.ts +38 -0
  99. package/dist/tools/search-documentation.d.ts.map +1 -0
  100. package/dist/tools/search-documentation.js +53 -0
  101. package/dist/tools/search-documentation.js.map +1 -0
  102. package/dist/types.d.ts +126 -0
  103. package/dist/types.d.ts.map +1 -0
  104. package/dist/types.js +2 -0
  105. package/dist/types.js.map +1 -0
  106. package/package.json +57 -0
@@ -0,0 +1,111 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ /**
5
+ * Get Claude Desktop config file path based on OS
6
+ */
7
+ export function getClaudeConfigPath() {
8
+ const platform = os.platform();
9
+ const homeDir = os.homedir();
10
+ switch (platform) {
11
+ case 'darwin': // macOS
12
+ return path.join(homeDir, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
13
+ case 'win32': // Windows
14
+ return path.join(process.env.APPDATA || '', 'Claude', 'claude_desktop_config.json');
15
+ case 'linux':
16
+ return path.join(homeDir, '.config', 'Claude', 'claude_desktop_config.json');
17
+ default:
18
+ return null;
19
+ }
20
+ }
21
+ /**
22
+ * Check if Claude Desktop config exists
23
+ */
24
+ export function claudeConfigExists() {
25
+ const configPath = getClaudeConfigPath();
26
+ return configPath ? fs.existsSync(configPath) : false;
27
+ }
28
+ /**
29
+ * Read Claude Desktop config
30
+ */
31
+ export function readClaudeConfig() {
32
+ const configPath = getClaudeConfigPath();
33
+ if (!configPath) {
34
+ throw new Error('Unsupported operating system');
35
+ }
36
+ if (!fs.existsSync(configPath)) {
37
+ // Return default empty config
38
+ return {
39
+ mcpServers: {},
40
+ };
41
+ }
42
+ const content = fs.readFileSync(configPath, 'utf-8');
43
+ return JSON.parse(content);
44
+ }
45
+ /**
46
+ * Write Claude Desktop config
47
+ */
48
+ export function writeClaudeConfig(config) {
49
+ const configPath = getClaudeConfigPath();
50
+ if (!configPath) {
51
+ throw new Error('Unsupported operating system');
52
+ }
53
+ // Ensure directory exists
54
+ const configDir = path.dirname(configPath);
55
+ if (!fs.existsSync(configDir)) {
56
+ fs.mkdirSync(configDir, { recursive: true });
57
+ }
58
+ // Write with pretty formatting
59
+ const content = JSON.stringify(config, null, 2);
60
+ fs.writeFileSync(configPath, content, 'utf-8');
61
+ }
62
+ /**
63
+ * Add or update DoxHub MCP server in Claude config
64
+ */
65
+ export function updateClaudeConfigForDoxHub(profileName = 'default') {
66
+ const config = readClaudeConfig();
67
+ // Initialize mcpServers if not exists
68
+ if (!config.mcpServers) {
69
+ config.mcpServers = {};
70
+ }
71
+ // Determine the key name for the server
72
+ const serverKey = profileName === 'default' ? 'doxhub' : `doxhub-${profileName}`;
73
+ // Add/update DoxHub MCP server entry
74
+ config.mcpServers[serverKey] = {
75
+ command: 'npx',
76
+ args: [
77
+ '@doxhub/mcp-server',
78
+ ...(profileName !== 'default' ? ['--profile', profileName] : []),
79
+ ],
80
+ env: {
81
+ DOXHUB_PROFILE: profileName,
82
+ },
83
+ };
84
+ writeClaudeConfig(config);
85
+ }
86
+ /**
87
+ * Remove DoxHub MCP server from Claude config
88
+ */
89
+ export function removeFromClaudeConfig(profileName = 'default') {
90
+ const config = readClaudeConfig();
91
+ if (!config.mcpServers) {
92
+ return;
93
+ }
94
+ const serverKey = profileName === 'default' ? 'doxhub' : `doxhub-${profileName}`;
95
+ delete config.mcpServers[serverKey];
96
+ writeClaudeConfig(config);
97
+ }
98
+ /**
99
+ * Check if DoxHub is configured in Claude Desktop
100
+ */
101
+ export function isDoxHubConfigured(profileName = 'default') {
102
+ try {
103
+ const config = readClaudeConfig();
104
+ const serverKey = profileName === 'default' ? 'doxhub' : `doxhub-${profileName}`;
105
+ return config.mcpServers && serverKey in config.mcpServers;
106
+ }
107
+ catch {
108
+ return false;
109
+ }
110
+ }
111
+ //# sourceMappingURL=config-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/cli/config-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ export interface CredentialProfile {
2
+ apiUrl: string;
3
+ accessToken: string;
4
+ workspaceId: string | null;
5
+ createdAt: string;
6
+ expiresAt: string;
7
+ }
8
+ export interface CredentialsFile {
9
+ profiles: Record<string, CredentialProfile>;
10
+ currentProfile: string;
11
+ }
12
+ /**
13
+ * Ensure credentials directory exists with proper permissions
14
+ */
15
+ export declare function ensureCredentialsDir(): void;
16
+ /**
17
+ * Read credentials file
18
+ */
19
+ export declare function readCredentials(): CredentialsFile;
20
+ /**
21
+ * Write credentials file with secure permissions
22
+ */
23
+ export declare function writeCredentials(credentials: CredentialsFile): void;
24
+ /**
25
+ * Save a profile to credentials
26
+ */
27
+ export declare function saveProfile(profileName: string, profile: CredentialProfile, setAsCurrent?: boolean): void;
28
+ /**
29
+ * Get a profile by name
30
+ */
31
+ export declare function getProfile(profileName?: string): CredentialProfile | null;
32
+ /**
33
+ * Get current profile
34
+ */
35
+ export declare function getCurrentProfile(): CredentialProfile | null;
36
+ /**
37
+ * List all profiles
38
+ */
39
+ export declare function listProfiles(): {
40
+ name: string;
41
+ profile: CredentialProfile;
42
+ isCurrent: boolean;
43
+ }[];
44
+ /**
45
+ * Switch current profile
46
+ */
47
+ export declare function switchProfile(profileName: string): void;
48
+ /**
49
+ * Delete a profile
50
+ */
51
+ export declare function deleteProfile(profileName: string): void;
52
+ /**
53
+ * Check if credentials file exists
54
+ */
55
+ export declare function credentialsExist(): boolean;
56
+ /**
57
+ * Get credentials directory path
58
+ */
59
+ export declare function getCredentialsDir(): string;
60
+ /**
61
+ * Get credentials file path
62
+ */
63
+ export declare function getCredentialsPath(): string;
64
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/cli/credentials.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC5C,cAAc,EAAE,MAAM,CAAC;CACxB;AAKD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAI3C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,eAAe,CAYjD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,eAAe,GAAG,IAAI,CAKnE;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,iBAAiB,EAC1B,YAAY,GAAE,OAAc,GAC3B,IAAI,CAUN;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAKzE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,iBAAiB,GAAG,IAAI,CAE5D;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,EAAE,CAQjG;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CASvD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAgBvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
@@ -0,0 +1,117 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ const CREDENTIALS_DIR = path.join(os.homedir(), '.doxhub');
5
+ const CREDENTIALS_PATH = path.join(CREDENTIALS_DIR, 'credentials.json');
6
+ /**
7
+ * Ensure credentials directory exists with proper permissions
8
+ */
9
+ export function ensureCredentialsDir() {
10
+ if (!fs.existsSync(CREDENTIALS_DIR)) {
11
+ fs.mkdirSync(CREDENTIALS_DIR, { recursive: true, mode: 0o700 });
12
+ }
13
+ }
14
+ /**
15
+ * Read credentials file
16
+ */
17
+ export function readCredentials() {
18
+ ensureCredentialsDir();
19
+ if (!fs.existsSync(CREDENTIALS_PATH)) {
20
+ return {
21
+ profiles: {},
22
+ currentProfile: 'default',
23
+ };
24
+ }
25
+ const content = fs.readFileSync(CREDENTIALS_PATH, 'utf-8');
26
+ return JSON.parse(content);
27
+ }
28
+ /**
29
+ * Write credentials file with secure permissions
30
+ */
31
+ export function writeCredentials(credentials) {
32
+ ensureCredentialsDir();
33
+ const content = JSON.stringify(credentials, null, 2);
34
+ fs.writeFileSync(CREDENTIALS_PATH, content, { mode: 0o600 });
35
+ }
36
+ /**
37
+ * Save a profile to credentials
38
+ */
39
+ export function saveProfile(profileName, profile, setAsCurrent = true) {
40
+ const credentials = readCredentials();
41
+ credentials.profiles[profileName] = profile;
42
+ if (setAsCurrent) {
43
+ credentials.currentProfile = profileName;
44
+ }
45
+ writeCredentials(credentials);
46
+ }
47
+ /**
48
+ * Get a profile by name
49
+ */
50
+ export function getProfile(profileName) {
51
+ const credentials = readCredentials();
52
+ const name = profileName || credentials.currentProfile;
53
+ return credentials.profiles[name] || null;
54
+ }
55
+ /**
56
+ * Get current profile
57
+ */
58
+ export function getCurrentProfile() {
59
+ return getProfile();
60
+ }
61
+ /**
62
+ * List all profiles
63
+ */
64
+ export function listProfiles() {
65
+ const credentials = readCredentials();
66
+ return Object.entries(credentials.profiles).map(([name, profile]) => ({
67
+ name,
68
+ profile,
69
+ isCurrent: name === credentials.currentProfile,
70
+ }));
71
+ }
72
+ /**
73
+ * Switch current profile
74
+ */
75
+ export function switchProfile(profileName) {
76
+ const credentials = readCredentials();
77
+ if (!credentials.profiles[profileName]) {
78
+ throw new Error(`Profile "${profileName}" not found`);
79
+ }
80
+ credentials.currentProfile = profileName;
81
+ writeCredentials(credentials);
82
+ }
83
+ /**
84
+ * Delete a profile
85
+ */
86
+ export function deleteProfile(profileName) {
87
+ const credentials = readCredentials();
88
+ if (!credentials.profiles[profileName]) {
89
+ throw new Error(`Profile "${profileName}" not found`);
90
+ }
91
+ delete credentials.profiles[profileName];
92
+ // If deleting current profile, switch to another one or default
93
+ if (credentials.currentProfile === profileName) {
94
+ const remainingProfiles = Object.keys(credentials.profiles);
95
+ credentials.currentProfile = remainingProfiles.length > 0 ? remainingProfiles[0] : 'default';
96
+ }
97
+ writeCredentials(credentials);
98
+ }
99
+ /**
100
+ * Check if credentials file exists
101
+ */
102
+ export function credentialsExist() {
103
+ return fs.existsSync(CREDENTIALS_PATH);
104
+ }
105
+ /**
106
+ * Get credentials directory path
107
+ */
108
+ export function getCredentialsDir() {
109
+ return CREDENTIALS_DIR;
110
+ }
111
+ /**
112
+ * Get credentials file path
113
+ */
114
+ export function getCredentialsPath() {
115
+ return CREDENTIALS_PATH;
116
+ }
117
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/cli/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function profilesCommand(): void;
2
+ export declare function switchProfile(profileName: string): void;
3
+ //# sourceMappingURL=profiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/cli/profiles.ts"],"names":[],"mappings":"AAEA,wBAAgB,eAAe,IAAI,IAAI,CAwBtC;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAUvD"}
@@ -0,0 +1,35 @@
1
+ import { listProfiles, switchProfile as doSwitchProfile, credentialsExist } from './credentials.js';
2
+ export function profilesCommand() {
3
+ console.log('\nšŸ“ DoxHub MCP Profiles\n');
4
+ if (!credentialsExist()) {
5
+ console.log('āŒ No profiles found');
6
+ console.log('\nRun "npx @doxhub/mcp-server setup" to create a profile.\n');
7
+ return;
8
+ }
9
+ const profiles = listProfiles();
10
+ if (profiles.length === 0) {
11
+ console.log('āŒ No profiles found\n');
12
+ return;
13
+ }
14
+ profiles.forEach(({ name, profile, isCurrent }) => {
15
+ const marker = isCurrent ? '→' : ' ';
16
+ console.log(`${marker} ${name}`);
17
+ console.log(` API: ${profile.apiUrl}`);
18
+ console.log(` Workspace: ${profile.workspaceId || 'All'}`);
19
+ console.log(` Expires: ${new Date(profile.expiresAt).toLocaleDateString()}`);
20
+ console.log('');
21
+ });
22
+ }
23
+ export function switchProfile(profileName) {
24
+ try {
25
+ doSwitchProfile(profileName);
26
+ console.log(`\nāœ“ Switched to profile: ${profileName}\n`);
27
+ console.log('šŸ’” Note: Restart Claude Desktop or wait for the next MCP request');
28
+ console.log(' to start using the new workspace.\n');
29
+ }
30
+ catch (error) {
31
+ console.error(`\nāŒ Error: ${error instanceof Error ? error.message : error}\n`);
32
+ process.exit(1);
33
+ }
34
+ }
35
+ //# sourceMappingURL=profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/cli/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,IAAI,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpG,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAE1C,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;QAC3E,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAEhC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE;QAChD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,WAAW,IAAI,KAAK,EAAE,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,IAAI,CAAC;QACH,eAAe,CAAC,WAAW,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,4BAA4B,WAAW,IAAI,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;QAChF,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,cAAc,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function revokeCommand(profileName?: string): Promise<void>;
2
+ export declare function logoutCommand(): Promise<void>;
3
+ //# sourceMappingURL=revoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revoke.d.ts","sourceRoot":"","sources":["../../src/cli/revoke.ts"],"names":[],"mappings":"AAkBA,wBAAsB,aAAa,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDvE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnD"}
@@ -0,0 +1,60 @@
1
+ import readline from 'readline';
2
+ import { getCurrentProfile, deleteProfile } from './credentials.js';
3
+ import { removeFromClaudeConfig } from './config-manager.js';
4
+ async function askConfirmation(question) {
5
+ const rl = readline.createInterface({
6
+ input: process.stdin,
7
+ output: process.stdout,
8
+ });
9
+ return new Promise((resolve) => {
10
+ rl.question(`${question} (y/n): `, (answer) => {
11
+ rl.close();
12
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
13
+ });
14
+ });
15
+ }
16
+ export async function revokeCommand(profileName) {
17
+ console.log('\nšŸ—‘ļø Revoke MCP Token\n');
18
+ const profile = getCurrentProfile();
19
+ if (!profile) {
20
+ console.log('āŒ No active profile found\n');
21
+ return;
22
+ }
23
+ const name = profileName || 'default';
24
+ console.log(`Profile: ${name}`);
25
+ console.log('This will:');
26
+ console.log('• Revoke the token on the server (if possible)');
27
+ console.log('• Remove credentials from ~/.doxhub/credentials.json');
28
+ console.log('• Remove from Claude Desktop config (if present)\n');
29
+ const confirmed = await askConfirmation('Are you sure?');
30
+ if (!confirmed) {
31
+ console.log('\nCancelled\n');
32
+ return;
33
+ }
34
+ try {
35
+ // Try to revoke on server (requires API call)
36
+ // For now, just remove locally
37
+ console.log('āš ļø Note: Token is removed locally but remains active on server.');
38
+ console.log(' Revoke from Settings > MCP Tokens in the web app.\n');
39
+ // Remove from credentials
40
+ deleteProfile(name);
41
+ console.log('āœ“ Credentials removed');
42
+ // Remove from Claude config
43
+ try {
44
+ removeFromClaudeConfig(name);
45
+ console.log('āœ“ Removed from Claude Desktop config');
46
+ }
47
+ catch (error) {
48
+ console.log('āš ļø Could not remove from Claude Desktop config');
49
+ }
50
+ console.log('\nāœ… Token revoked locally\n');
51
+ }
52
+ catch (error) {
53
+ console.error(`\nāŒ Error: ${error instanceof Error ? error.message : error}\n`);
54
+ process.exit(1);
55
+ }
56
+ }
57
+ export async function logoutCommand() {
58
+ await revokeCommand();
59
+ }
60
+ //# sourceMappingURL=revoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revoke.js","sourceRoot":"","sources":["../../src/cli/revoke.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,KAAK,UAAU,eAAe,CAAC,QAAgB;IAC7C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE;YAC5C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAoB;IACtD,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAEzC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,IAAI,SAAS,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAElE,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,eAAe,CAAC,CAAC;IAEzD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,8CAA8C;QAC9C,+BAA+B;QAC/B,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;QAChF,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QAEtE,0BAA0B;QAC1B,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAErC,4BAA4B;QAC5B,IAAI,CAAC;YACH,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,cAAc,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,11 @@
1
+ interface SetupOptions {
2
+ profile?: string;
3
+ apiUrl?: string;
4
+ skipBrowser?: boolean;
5
+ }
6
+ /**
7
+ * Main setup command
8
+ */
9
+ export declare function setupCommand(options?: SetupOptions): Promise<void>;
10
+ export {};
11
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAMA,UAAU,YAAY;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAmDD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2F5E"}