imcp 0.1.5 → 0.1.6

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 (186) hide show
  1. package/.github/ISSUE_TEMPLATE/JitAccess.yml +28 -0
  2. package/.github/acl/access.yml +20 -0
  3. package/.github/compliance/inventory.yml +5 -0
  4. package/.github/policies/jit.yml +19 -0
  5. package/.github/workflows/build.yml +28 -0
  6. package/.roo/rules-code/rules.md +88 -0
  7. package/docs/ONBOARDING_PAGE_DESIGN.md +260 -0
  8. package/docs/Telemetry.md +136 -0
  9. package/memory-bank/activeContext.md +26 -0
  10. package/memory-bank/decisionLog.md +91 -0
  11. package/memory-bank/productContext.md +41 -0
  12. package/memory-bank/progress.md +35 -0
  13. package/memory-bank/systemPatterns.md +10 -0
  14. package/package.json +1 -5
  15. package/src/cli/commands/install.ts +139 -0
  16. package/src/cli/commands/list.ts +113 -0
  17. package/src/cli/commands/pull.ts +16 -0
  18. package/src/cli/commands/serve.ts +39 -0
  19. package/src/cli/commands/uninstall.ts +64 -0
  20. package/src/cli/index.ts +82 -0
  21. package/src/core/installers/clients/BaseClientInstaller.ts +341 -0
  22. package/src/core/installers/clients/ClientInstaller.ts +222 -0
  23. package/src/core/installers/clients/ClientInstallerFactory.ts +43 -0
  24. package/src/core/installers/clients/ClineInstaller.ts +35 -0
  25. package/src/core/installers/clients/ExtensionInstaller.ts +165 -0
  26. package/src/core/installers/clients/GithubCopilotInstaller.ts +79 -0
  27. package/src/core/installers/clients/MSRooCodeInstaller.ts +32 -0
  28. package/src/core/installers/index.ts +11 -0
  29. package/src/core/installers/requirements/BaseInstaller.ts +85 -0
  30. package/src/core/installers/requirements/CommandInstaller.ts +231 -0
  31. package/src/core/installers/requirements/GeneralInstaller.ts +133 -0
  32. package/src/core/installers/requirements/InstallerFactory.ts +114 -0
  33. package/src/core/installers/requirements/NpmInstaller.ts +271 -0
  34. package/src/core/installers/requirements/NugetInstaller.ts +203 -0
  35. package/src/core/installers/requirements/PipInstaller.ts +207 -0
  36. package/src/core/installers/requirements/RequirementInstaller.ts +42 -0
  37. package/src/core/loaders/ConfigurationLoader.ts +298 -0
  38. package/src/core/loaders/ConfigurationProvider.ts +462 -0
  39. package/src/core/loaders/InstallOperationManager.ts +367 -0
  40. package/src/core/loaders/ServerSchemaLoader.ts +117 -0
  41. package/src/core/loaders/ServerSchemaProvider.ts +99 -0
  42. package/src/core/loaders/SystemSettingsManager.ts +278 -0
  43. package/src/core/metadatas/constants.ts +122 -0
  44. package/src/core/metadatas/recordingConstants.ts +65 -0
  45. package/src/core/metadatas/types.ts +202 -0
  46. package/src/core/onboard/FeedOnboardService.ts +501 -0
  47. package/src/core/onboard/OnboardProcessor.ts +356 -0
  48. package/src/core/onboard/OnboardStatus.ts +60 -0
  49. package/src/core/onboard/OnboardStatusManager.ts +416 -0
  50. package/src/core/validators/FeedValidator.ts +135 -0
  51. package/src/core/validators/IServerValidator.ts +21 -0
  52. package/src/core/validators/SSEServerValidator.ts +43 -0
  53. package/src/core/validators/ServerValidatorFactory.ts +51 -0
  54. package/src/core/validators/StdioServerValidator.ts +313 -0
  55. package/src/index.ts +44 -0
  56. package/src/services/InstallationService.ts +102 -0
  57. package/src/services/MCPManager.ts +249 -0
  58. package/src/services/RequirementService.ts +627 -0
  59. package/src/services/ServerService.ts +161 -0
  60. package/src/services/TelemetryService.ts +59 -0
  61. package/src/utils/UpdateCheckTracker.ts +86 -0
  62. package/src/utils/adoUtils.ts +293 -0
  63. package/src/utils/clientUtils.ts +72 -0
  64. package/src/utils/feedUtils.ts +31 -0
  65. package/src/utils/githubAuth.ts +212 -0
  66. package/src/utils/githubUtils.ts +164 -0
  67. package/src/utils/logger.ts +195 -0
  68. package/src/utils/macroExpressionUtils.ts +104 -0
  69. package/src/utils/osUtils.ts +700 -0
  70. package/src/utils/versionUtils.ts +114 -0
  71. package/src/web/contract/serverContract.ts +74 -0
  72. package/src/web/public/css/detailsWidget.css +235 -0
  73. package/src/web/public/css/modal.css +757 -0
  74. package/src/web/public/css/notifications.css +101 -0
  75. package/src/web/public/css/onboard.css +107 -0
  76. package/src/web/public/css/serverCategoryList.css +120 -0
  77. package/src/web/public/css/serverDetails.css +139 -0
  78. package/src/web/public/index.html +359 -0
  79. package/src/web/public/js/api.js +132 -0
  80. package/src/web/public/js/detailsWidget.js +264 -0
  81. package/src/web/public/js/flights/flights.js +127 -0
  82. package/src/web/public/js/modal/index.js +52 -0
  83. package/src/web/public/js/modal/installModal.js +162 -0
  84. package/src/web/public/js/modal/installation.js +266 -0
  85. package/src/web/public/js/modal/loadingModal.js +182 -0
  86. package/src/web/public/js/modal/modalSetup.js +595 -0
  87. package/src/web/public/js/modal/modalUtils.js +37 -0
  88. package/src/web/public/js/modal/versionUtils.js +20 -0
  89. package/src/web/public/js/modal.js +42 -0
  90. package/src/web/public/js/notifications.js +137 -0
  91. package/src/web/public/js/onboard/formProcessor.js +1037 -0
  92. package/src/web/public/js/onboard/index.js +374 -0
  93. package/src/web/public/js/onboard/publishHandler.js +172 -0
  94. package/src/web/public/js/onboard/state.js +76 -0
  95. package/src/web/public/js/onboard/templates.js +342 -0
  96. package/src/web/public/js/onboard/uiHandlers.js +1076 -0
  97. package/src/web/public/js/onboard/validationHandlers.js +493 -0
  98. package/src/web/public/js/serverCategoryDetails.js +364 -0
  99. package/src/web/public/js/serverCategoryList.js +241 -0
  100. package/src/web/public/js/settings.js +314 -0
  101. package/src/web/public/modal.html +84 -0
  102. package/src/web/public/onboard.html +296 -0
  103. package/src/web/public/settings.html +135 -0
  104. package/src/web/public/styles.css +277 -0
  105. package/src/web/server.ts +478 -0
  106. package/tsconfig.json +18 -0
  107. package/wiki/Installation.md +3 -0
  108. package/wiki/Publish.md +3 -0
  109. package/dist/cli/commands/install.js.map +0 -1
  110. package/dist/cli/commands/list.js.map +0 -1
  111. package/dist/cli/commands/pull.js.map +0 -1
  112. package/dist/cli/commands/serve.js.map +0 -1
  113. package/dist/cli/commands/start.js.map +0 -1
  114. package/dist/cli/commands/sync.js.map +0 -1
  115. package/dist/cli/commands/uninstall.js.map +0 -1
  116. package/dist/cli/index.js.map +0 -1
  117. package/dist/core/ConfigurationLoader.js.map +0 -1
  118. package/dist/core/ConfigurationProvider.js.map +0 -1
  119. package/dist/core/InstallationService.js.map +0 -1
  120. package/dist/core/MCPManager.js.map +0 -1
  121. package/dist/core/RequirementService.js.map +0 -1
  122. package/dist/core/ServerSchemaLoader.js.map +0 -1
  123. package/dist/core/ServerSchemaProvider.js.map +0 -1
  124. package/dist/core/constants.js.map +0 -1
  125. package/dist/core/installers/BaseInstaller.js.map +0 -1
  126. package/dist/core/installers/ClientInstaller.js.map +0 -1
  127. package/dist/core/installers/CommandInstaller.js.map +0 -1
  128. package/dist/core/installers/GeneralInstaller.js.map +0 -1
  129. package/dist/core/installers/InstallerFactory.js.map +0 -1
  130. package/dist/core/installers/NpmInstaller.js.map +0 -1
  131. package/dist/core/installers/PipInstaller.js.map +0 -1
  132. package/dist/core/installers/RequirementInstaller.js.map +0 -1
  133. package/dist/core/installers/clients/BaseClientInstaller.js.map +0 -1
  134. package/dist/core/installers/clients/ClientInstaller.js.map +0 -1
  135. package/dist/core/installers/clients/ClientInstallerFactory.js.map +0 -1
  136. package/dist/core/installers/clients/ClineInstaller.js.map +0 -1
  137. package/dist/core/installers/clients/ExtensionInstaller.js.map +0 -1
  138. package/dist/core/installers/clients/GithubCopilotInstaller.js.map +0 -1
  139. package/dist/core/installers/clients/MSRooCodeInstaller.js.map +0 -1
  140. package/dist/core/installers/index.js.map +0 -1
  141. package/dist/core/installers/requirements/BaseInstaller.js.map +0 -1
  142. package/dist/core/installers/requirements/CommandInstaller.js.map +0 -1
  143. package/dist/core/installers/requirements/GeneralInstaller.js.map +0 -1
  144. package/dist/core/installers/requirements/InstallerFactory.js.map +0 -1
  145. package/dist/core/installers/requirements/NpmInstaller.js.map +0 -1
  146. package/dist/core/installers/requirements/NugetInstaller.js.map +0 -1
  147. package/dist/core/installers/requirements/PipInstaller.js.map +0 -1
  148. package/dist/core/installers/requirements/RequirementInstaller.js.map +0 -1
  149. package/dist/core/loaders/ConfigurationLoader.js.map +0 -1
  150. package/dist/core/loaders/ConfigurationProvider.js.map +0 -1
  151. package/dist/core/loaders/InstallOperationManager.js.map +0 -1
  152. package/dist/core/loaders/ServerSchemaLoader.js.map +0 -1
  153. package/dist/core/loaders/ServerSchemaProvider.js.map +0 -1
  154. package/dist/core/loaders/SystemSettingsManager.js.map +0 -1
  155. package/dist/core/metadatas/constants.js.map +0 -1
  156. package/dist/core/metadatas/recordingConstants.js.map +0 -1
  157. package/dist/core/metadatas/types.js.map +0 -1
  158. package/dist/core/onboard/FeedOnboardService.js.map +0 -1
  159. package/dist/core/onboard/OnboardProcessor.js.map +0 -1
  160. package/dist/core/onboard/OnboardStatus.js.map +0 -1
  161. package/dist/core/onboard/OnboardStatusManager.js.map +0 -1
  162. package/dist/core/types.js.map +0 -1
  163. package/dist/core/validators/FeedValidator.js.map +0 -1
  164. package/dist/core/validators/IServerValidator.js.map +0 -1
  165. package/dist/core/validators/SSEServerValidator.js.map +0 -1
  166. package/dist/core/validators/ServerValidatorFactory.js.map +0 -1
  167. package/dist/core/validators/StdioServerValidator.js.map +0 -1
  168. package/dist/index.js.map +0 -1
  169. package/dist/services/InstallRequestValidator.js.map +0 -1
  170. package/dist/services/InstallationService.js.map +0 -1
  171. package/dist/services/MCPManager.js.map +0 -1
  172. package/dist/services/RequirementService.js.map +0 -1
  173. package/dist/services/ServerService.js.map +0 -1
  174. package/dist/services/TelemetryService.js.map +0 -1
  175. package/dist/utils/UpdateCheckTracker.js.map +0 -1
  176. package/dist/utils/adoUtils.js.map +0 -1
  177. package/dist/utils/clientUtils.js.map +0 -1
  178. package/dist/utils/feedUtils.js.map +0 -1
  179. package/dist/utils/githubAuth.js.map +0 -1
  180. package/dist/utils/githubUtils.js.map +0 -1
  181. package/dist/utils/logger.js.map +0 -1
  182. package/dist/utils/macroExpressionUtils.js.map +0 -1
  183. package/dist/utils/osUtils.js.map +0 -1
  184. package/dist/utils/versionUtils.js.map +0 -1
  185. package/dist/web/contract/serverContract.js.map +0 -1
  186. package/dist/web/server.js.map +0 -1
@@ -0,0 +1,91 @@
1
+ # Decision Log
2
+
3
+ This file records significant architectural or technical decisions, including rationale and implications.
4
+ Update this file with a timestamped entry whenever a major decision is made.
5
+
6
+ ---
7
+
8
+ ---
9
+
10
+ [2025-05-15 19:56:12] - Memory Bank updated to reflect onboarding page architecture and features as described in [`docs/ONBOARDING_PAGE_DESIGN.md`](../docs/ONBOARDING_PAGE_DESIGN.md).
11
+
12
+ - Modular JS architecture for onboarding UI, form-to-JSON, validation, publishing, and state.
13
+ - Central `FeedConfiguration` model for category/server/requirement data.
14
+ - Enhanced UX: dynamic sections, toggling, notifications, robust validation/publishing.
15
+ - Recent improvements: server visibility, requirement lookup, async feedback, tab/view handling.
16
+ [2025-05-15 20:48:27] - Implemented MCP Server Duplication Feature.
17
+ - Added a duplicate button to the right of the delete button in the server item template (`src/web/public/js/onboard/templates.js`).
18
+ - Modified `duplicateServer` function in `src/web/public/js/onboard/uiHandlers.js` to correctly retrieve data from the server to be duplicated, even if it's read-only. This was achieved by temporarily enabling form fields of the source server item before calling `getFormData`.
19
+ - Ensured that the duplicated server is always created as a new, editable server, and all its content (including environment variables and requirements) is copied from the original server.
20
+ - The `populateServerManually` function ensures that sub-items (env vars, requirements) of the duplicated server are also created in an editable state.
21
+ - This functionality applies to both "Create New Category" and "Create Server in Existing Category" tabs.
22
+ - Fixed the error "Could not retrieve data for the server to duplicate" when duplicating read-only servers.
23
+
24
+ [2025-05-16 00:34:40] - [Fixed duplicate server functionality]
25
+ - Issue: Duplicating non-first servers failed with "Could not retrieve data" error
26
+ - Fix: Modified duplicateServer() to temporarily enable ALL disabled fields before form submission
27
+ - Impact: Ensures complete server data is captured regardless of position in list
28
+ - Files affected: src/web/public/js/onboard/uiHandlers.js
29
+ [2025-05-16 13:27:43] - Refactored requirement management logic from `InstallationService` into a new dedicated `RequirementService`. `InstallationService` now delegates requirement-related tasks (checking status, installing, updating) to `RequirementService`. This improves separation of concerns and modularity.
30
+
31
+ [2025-05-16 16:07:20] - Redesigned the operation status and polling mechanism for Installation in both frontend and backend. This involved creating a new InstallOperationManager, new types for operation details, an API endpoint for status retrieval, and integrating step recording into InstallationService, RequirementService, and BaseClientInstaller. This provides more granular tracking of installation progress.
32
+
33
+ [2025-05-16 16:50:05] - Added 'overallStatus' to InstallOperationDetails and updated InstallOperationManager to manage it. Modified frontend polling in 'src/web/public/js/modal/installation.js' to use the new installation status API and display detailed steps.
34
+
35
+ [2025-05-16 17:03:17] - Enhanced the display of installation steps in the loading modal. Modified 'messageQueue.js' to support step-specific formatting (icons, success/failure states) and updated 'installation.js' to pass these options. Added CSS in 'modal.css' for the new step display styles.
36
+
37
+ [2025-05-16 17:08:31] - Refined installation step display: made fonts smaller, increased compactness, and added timestamps for each step. Updated 'modal.css' and 'messageQueue.js' accordingly. 'installation.js' now passes the timestamp.
38
+
39
+ [2025-05-16 17:19:37] - Overhauled the installation loading modal UI. 'loadingModal.js' now dynamically creates a new structure with an overall status (icon + text) and a detailed steps list. 'installation.js' was updated to use new functions in 'loadingModal.js' for status and step updates. 'messageQueue.js' was simplified as direct DOM manipulation for steps is now in 'loadingModal.js'. Added extensive CSS in 'modal.css' for the new layout and styling.
40
+
41
+ [2025-05-16 17:23:42] - Fixed error caused by removed 'delayedAppendInstallLoadingMessage'. Updated 'modalSetup.js' and 'installation.js' (uninstallTools function) to use the new 'updateOverallInstallStatus' from 'loadingModal.js' for general status messages during uninstallation.
42
+
43
+ [2025-05-16 17:26:13] - Final fix for 'delayedAppendInstallLoadingMessage' error: removed unused import from 'installModal.js'.
44
+
45
+ [2025-05-16 17:29:59] - Corrected 'src/web/public/js/modal/index.js' barrel file: removed imports and re-exports of 'delayedAppendInstallLoadingMessage' and 'appendInstallLoadingMessage' as they no longer exist. Added new exports for 'updateOverallInstallStatus' and 'addInstallationStep'.
46
+
47
+ [2025-05-16 17:31:35] - Corrected 'src/web/public/js/modal.js' (another barrel file): removed import and global assignment of 'appendInstallLoadingMessage'. Added missing exports for 'showInstallLoadingModal' and 'hideInstallLoadingModal'.
48
+
49
+ [2025-05-16 17:46:59] - Implemented reset of installation operation status. Added `resetOperation` method to `InstallOperationManager.ts` to delete existing status for a server. Called this method at the beginning of `InstallationService.ts#install` to ensure a clean state for new installations.
50
+
51
+ [2025-05-16 17:51:01] - UI adjustments for installation loading modal:
52
+ - Added a close button (X) to the top-right corner with functionality to hide the modal.
53
+ - Ensured installation steps are explicitly left-aligned using `justify-content: flex-start`.
54
+ - Modified the 'completed' status icon to be a checkmark within a green circle.
55
+ - Reviewed and confirmed the 'in-progress' spinner icon.
56
+
57
+ [2025-05-16 17:53:42] - Refined step message alignment in installation loading modal: Added `align-items: flex-start` and `text-align: left` to `.step-info`, and `text-align: left` with `width: 100%` to `.step-message` in `modal.css` to ensure text content is fully left-aligned.
58
+
59
+ [2025-05-16 17:55:32] - UI adjustment for installation loading modal: Removed the "Details" header text from above the steps list in `loadingModal.js`.
60
+
61
+ [2025-05-16 17:57:02] - Corrected removal of "Details" header in installation loading modal: Entire line `<div class="steps-list-header">Details</div>` was removed from `loadingModal.js` instead of being commented out with an invalid HTML comment.
62
+
63
+ [2025-05-17 00:26:02] - Refactored InstallOperationManager to require categoryName and serverName in the constructor, removed singleton/static pattern, and changed status file storage to per-category/server at Settings_Dir/InstallOperationStatus/CategoryName/ServerName.json. This enables instance-based management and more granular status persistence.
64
+
65
+ [2025-05-17 15:02:27] - Refactored `RequirementService.ts` to use instance-based `InstallOperationManager`.
66
+ - The `processRequirementUpdates` and `checkAndInstallRequirements` (including its helper `installRequirementsInBackground`) methods in [`src/services/RequirementService.ts`](src/services/RequirementService.ts:0) were updated.
67
+ - They now obtain an `InstallOperationManager` instance using `InstallOperationManager.getInstance(categoryName, serverName)`.
68
+ - The core logic within these methods, and the individual requirement processing loops, are now wrapped with `iom.recording()` or `iom.recordingAsync()` for robust step tracking and error handling.
69
+ - This change aligns `RequirementService.ts` with the new instance-based, per-category/server architecture of `InstallOperationManager` introduced in [2025-05-17 00:26:02].
70
+ - Rationale: Simplifies step recording, centralizes status management within the `InstallOperationManager` instance, and improves consistency across services.
71
+ - Implications: Removed direct calls to the deprecated global `installOperationManager.recordStep` and adopted the more structured `recording` pattern.
72
+
73
+ [2025-05-17 15:26:09] - Updated all requirement installer classes and interface to support step recording via InstallOperationManager. All install methods now accept an optional recorder and record critical steps using recordStep/recording.
74
+
75
+ [2025-05-18 13:21:30] - Implemented main modal refresh on loading modal close, replacing page reload.
76
+ - Rationale: Improve UX by maintaining main modal context and avoiding disruptive page reloads after installation/uninstallation operations shown in the loading modal.
77
+ - Implementation Details:
78
+ - `src/web/public/js/modal/loadingModal.js`: Modified `hideInstallLoadingModal` to dispatch a custom event `refreshMainModalContent` instead of causing a page reload.
79
+ - `src/web/public/js/modal/installation.js`: Modified `handleBulkClientInstall` to store `categoryName` as `lastSelectedCategory` and `serverName` as `lastSelectedServerName` in `localStorage` when an installation process begins. This ensures the context is available for the refresh.
80
+ - `src/web/public/js/modal.js`: Added an event listener for `refreshMainModalContent`. This listener retrieves `lastSelectedCategory` and `lastSelectedServerName` from `localStorage`. If both are valid, it calls `window.showInstallModal(lastSelectedCategory, lastSelectedServerName)` to refresh the content of the main installation modal.
81
+ - Debugging: Iteratively refined the logic in `modal.js` to correctly handle and validate `lastSelectedCategory` and `lastSelectedServerName` to prevent errors when calling `showInstallModal`. This was crucial for ensuring `showInstallModal` received the necessary `serverName` argument, resolving "Server configuration not found" errors.
82
+ [2025-05-18 11:33:12] - Added `src/core/metadatas/recordingConstants.ts` as the canonical source for all step recording names used in installation and onboarding operations. This file centralizes all static step names as constants and documents dynamic step name patterns, improving consistency and discoverability for step-based operation tracking across backend and frontend.
83
+
84
+ [2025-05-18 20:46:46] - Reduced the height and key size in the System Environment Variables section of the settings UI for a more compact and modern appearance. This involved decreasing row padding, shrinking the key column width, and reducing the key font size in `src/web/public/js/settings.js`.
85
+
86
+ [2025-05-18 21:00:26] - Macro resolution logic updated: Now resolves macro values (${PYTHON_PACKAGE}, ${NPMPATH}, ${BROWSER_PATH}) by first checking SystemSettingsManager (system settings), and only falls back to previous behavior if not found. This centralizes macro configuration and improves consistency across the system.
87
+
88
+ [2025-05-19 00:14:06] - Updated settings page UI and functionality:
89
+ - Removed "NPM Global Package Path" field from `src/web/public/settings.html` and `src/web/public/js/settings.js`.
90
+ - Added a descriptive prompt "Stored and used for mcp server installation environments." with a question icon (`bx-help-circle`) on the same line as the "User Configurations" title in `src/web/public/settings.html`.
91
+ - Modified `src/web/public/js/settings.js` to render user configuration values as `type="password"` if the key contains "key". Added an eye icon button *inside* the value input field to toggle visibility for these password fields, maintaining original input box sizes.
@@ -0,0 +1,41 @@
1
+ # Product Context
2
+
3
+ This file contains the high-level project description, goals, features, and overall architecture for the onboarding page and related systems.
4
+
5
+ ---
6
+
7
+ ## Onboarding Page Overview
8
+
9
+ - **Purpose:** Dynamic onboarding UI for configuring new server categories and MCP servers.
10
+ - **Frontend Structure:** Modular JavaScript in [`src/web/public/js/onboard/`](src/web/public/js/onboard):
11
+ - `index.js`: Entry point, tab switching, event listeners, loading/editing categories.
12
+ - `formProcessor.js`: Converts form ↔ JSON (`FeedConfiguration`), validation, populating UI.
13
+ - `uiHandlers.js`: Dynamic UI (add/remove servers, env vars, requirements), view toggling, section collapsing.
14
+ - `templates.js`: HTML templates for servers, env vars, requirements.
15
+ - `state.js`: Tracks counters for dynamic elements.
16
+ - `validationHandlers.js`: Validation logic, polling, progress display.
17
+ - `publishHandler.js`: Handles publishing, status polling, and feedback.
18
+
19
+ ---
20
+
21
+ ## Core Data Model
22
+
23
+ - **FeedConfiguration** (see [`src/core/types.ts`](src/core/types.ts)):
24
+ - `name`, `displayName`, `description`, `repository`
25
+ - `mcpServers`: Array of server configs (mode, install, env, dependencies)
26
+ - `requirements`: Unique, fully defined requirements (type, name, version, registry, alias)
27
+
28
+ ---
29
+
30
+ ## Key Features
31
+
32
+ - Dynamic form sections for servers, environment variables, and requirements.
33
+ - Toggle between form and JSON editor views.
34
+ - Robust validation and publishing flows with polling and progress UI.
35
+ - Custom notification system for user feedback.
36
+ - Enhanced UX for editing, tab switching, and error handling.
37
+ - All code and UI logic is aligned with [`docs/ONBOARDING_PAGE_DESIGN.md`](../docs/ONBOARDING_PAGE_DESIGN.md).
38
+
39
+ ---
40
+
41
+ _Last updated: 2025-05-15_
@@ -0,0 +1,35 @@
1
+ # Progress Log
2
+
3
+ - [YYYY-MM-DD HH:MM:SS] - Initializing Memory Bank.
4
+
5
+ - [2025-05-16 09:22:36] - Completed: Made "IMCP Server Manager" title clickable in `src/web/public/index.html`.
6
+ - [2025-05-16 13:28:10] - Completed: Refactored requirement management from `InstallationService` to `RequirementService`. Fixed `reqConfig` scoping and type fallbacks in `RequirementService.processRequirementUpdates`.
7
+
8
+ [2025-05-16 16:07:34] - Completed: Redesign installation operation status and polling mechanism.
9
+ - Added `InstallOperationDetails` type to `src/core/metadatas/types.ts`.
10
+ - Created `InstallOperationManager` in `src/core/loaders/InstallOperationManager.ts`.
11
+ - Added API endpoint for installation status in `src/web/server.ts`.
12
+ - Integrated `recordStep` in `InstallationService`, `RequirementService`, and `BaseClientInstaller`.
13
+
14
+ [2025-05-16 16:50:21] - Enhanced installation status:
15
+ - Added `overallStatus` to `InstallOperationDetails` in `src/core/metadatas/types.ts`.
16
+ - Updated `InstallOperationManager` in `src/core/loaders/InstallOperationManager.ts` to manage `overallStatus`.
17
+ - Modified frontend polling in `src/web/public/js/modal/installation.js` to use the new API `/api/categories/:categoryName/servers/:serverName/installation/status` and display detailed steps.
18
+
19
+ [2025-05-17 00:26:16] - Began refactoring InstallOperationManager to be instance-based per category/server, with new file structure for status. Memory bank updated to reflect architectural and pattern changes.
20
+
21
+ [2025-05-17 15:02:44] - Completed: Refactored `RequirementService.ts` to use instance-based `InstallOperationManager` and its `recording`/`recordingAsync` methods. This involved updating `processRequirementUpdates`, `checkAndInstallRequirements`, and `installRequirementsInBackground`.
22
+
23
+ [2025-05-18 11:33:23] - Completed: Standardized step recording names by creating `src/core/metadatas/recordingConstants.ts`. This centralizes static step names and documents dynamic patterns for installation/onboarding operations.
24
+
25
+ [2025-05-18 13:21:30] - Completed: Implemented main modal refresh logic to replace page reload.
26
+ - `loadingModal.js`: Dispatches `refreshMainModalContent` event on close.
27
+ - `installation.js`: Stores `categoryName` and `serverName` in `localStorage`.
28
+ - `modal.js`: Listens for event, retrieves context from `localStorage`, and calls `showInstallModal` with both `categoryName` and `serverName`.
29
+ - This resolves "Server configuration not found" errors and improves UX.
30
+ [2025-05-17 15:26:15] - Refactored all requirement installer classes and factory to support InstallOperationManager step recording. All install methods now accept a recorder and log critical steps.
31
+
32
+ [2025-05-19 00:14:13] - Completed: Updated settings page (`src/web/public/settings.html` and `src/web/public/js/settings.js`):
33
+ - Removed "NPM Global Package Path" display.
34
+ - Added prompt with a question icon for User Configurations, displayed on the same line as the section title.
35
+ - Implemented secret input type for keys containing "key" in User Configurations, with an eye icon button *inside* the value input field to toggle visibility (maintaining original input box sizes).
@@ -0,0 +1,10 @@
1
+ # System Patterns
2
+
3
+ - [YYYY-MM-DD HH:MM:SS] - Initializing Memory Bank.
4
+
5
+ [2025-05-18 13:21:30] - Implemented an event-driven modal refresh pattern for the installation UI.
6
+ - Pattern: Instead of page reloads, the loading modal (`loadingModal.js`) dispatches a custom DOM event (`refreshMainModalContent`) upon closing.
7
+ - Context Persistence: The initiating action (e.g., in `installation.js`) stores necessary context (like `lastSelectedCategory` and `lastSelectedServerName`) in `localStorage`.
8
+ - Event Handling: The main modal controller (`modal.js`) listens for this event, retrieves context from `localStorage`, and re-initializes/refreshes its content (`showInstallModal`) with the persisted context.
9
+ - Benefit: This decouples the loading modal from the main modal, allows for non-disruptive UI updates, and maintains user context effectively.
10
+ [2025-05-17 00:26:06] - Changed InstallOperationManager from singleton/static to instance-based, with per-category/server file storage pattern: Settings_Dir/InstallOperationStatus/CategoryName/ServerName.json. This introduces a more granular, object-oriented persistence and management pattern for install operation status.
package/package.json CHANGED
@@ -1,16 +1,12 @@
1
1
  {
2
2
  "name": "imcp",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Node.js SDK for Model Context Protocol (MCP)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "bin": {
8
8
  "imcp": "./dist/cli/index.js"
9
9
  },
10
- "files": [
11
- "dist",
12
- "README.md"
13
- ],
14
10
  "scripts": {
15
11
  "build": "tsc && npm run copy-public",
16
12
  "dev": "tsc -w",
@@ -0,0 +1,139 @@
1
+ import { Command } from 'commander';
2
+ import { serverService } from '../../services/ServerService.js';
3
+ import { Logger } from '../../utils/logger.js';
4
+ import { hasLocalFeeds } from '../../utils/feedUtils.js';
5
+ import { ServerInstallOptions } from '../../core/metadatas/types.js';
6
+ import { SUPPORTED_CLIENT_NAMES } from '../../core/metadatas/constants.js';
7
+ import { mcpManager } from '../../services/MCPManager.js';
8
+
9
+ export function createInstallCommand(): Command {
10
+ return new Command('install')
11
+ .description('Install specific MCP servers')
12
+ .addHelpText('after', `
13
+ Examples:
14
+ # Install a server
15
+ $ imcp install --category ai-coder-tools --name github-tools
16
+
17
+ # Install with specific client targets (semicolon separated)
18
+ $ imcp install --category ai-coder-tools --name github-tools --clients "MSRooCode;GithubCopilot"
19
+
20
+ # Install with environment variables
21
+ $ imcp install --category ai-coder-tools --name github-tools --envs "GITHUB_TOKEN=abc123;API_KEY=xyz789"
22
+ `)
23
+ .requiredOption(
24
+ '--category <category>',
25
+ 'Server category'
26
+ )
27
+ .requiredOption(
28
+ '--name <name>',
29
+ 'Server name to install'
30
+ )
31
+ .option(
32
+ '--clients <clients>',
33
+ 'Target clients (semicolon separated). Supported values: Cline, MSRooCode, GithubCopilot. If not specified, installs for all clients'
34
+ )
35
+ .option(
36
+ '--envs <envs>',
37
+ 'Environment variables (semicolon separated key=value pairs)'
38
+ )
39
+ .action(async (options: {
40
+ category: string;
41
+ name: string;
42
+ clients?: string;
43
+ envs?: string;
44
+ verbose?: boolean;
45
+ }) => {
46
+ try {
47
+ // Check for local feeds existence at the start
48
+ const feedsExist = await hasLocalFeeds();
49
+ if (!feedsExist) {
50
+ Logger.log('Local feeds not found, syncing from remote...');
51
+ await serverService.syncFeeds();
52
+ }
53
+ await mcpManager.initialize();
54
+ const { category, name, verbose, clients, envs } = options;
55
+
56
+ Logger.debug(`Install options: ${JSON.stringify({ category, name, verbose, clients, envs })}`);
57
+
58
+ const serverName = name.trim();
59
+ Logger.debug(`Server name: ${serverName}`);
60
+
61
+ if (!await serverService.validateServerName(category, serverName)) {
62
+ Logger.error(
63
+ 'Invalid server name or category provided.\n' +
64
+ 'This could be because:\n' +
65
+ ' 1. The server name or category is misspelled\n' +
66
+ ' 2. Your local feeds are outdated\n\n' +
67
+ 'Try running "imcp pull" to update your local feeds from remote.',
68
+ { category, serverName }
69
+ );
70
+ process.exit(1);
71
+ }
72
+
73
+ // Parse and validate clients
74
+ const parsedClients = clients ? clients.split(';')
75
+ .map((c: string) => c.trim())
76
+ .filter(Boolean)
77
+ .map((c: string) => {
78
+ const clientName = c.toLowerCase();
79
+ const validClient = SUPPORTED_CLIENT_NAMES.find((name: string) => name.toLowerCase() === clientName);
80
+ if (!validClient) {
81
+ Logger.error(`Invalid client name: ${c}`);
82
+ return null;
83
+ }
84
+ return validClient;
85
+ })
86
+ .filter((c: string | null): c is string => c !== null) : undefined;
87
+
88
+ if (parsedClients && parsedClients.length > 0) {
89
+ Logger.debug(`Target clients: ${JSON.stringify(parsedClients)}`);
90
+ }
91
+
92
+ // Parse environment variables
93
+ const parsedEnvs: Record<string, string> = {};
94
+ if (envs) {
95
+ const pairs = envs.split(';');
96
+ for (const pair of pairs) {
97
+ const [key, value] = pair.split('=').map((s: string) => s.trim());
98
+ if (key && value) {
99
+ parsedEnvs[key] = value;
100
+ } else {
101
+ Logger.error(`Invalid environment variable format: ${pair}`);
102
+ }
103
+ }
104
+ }
105
+
106
+ if (Object.keys(parsedEnvs).length > 0) {
107
+ Logger.debug(`Environment variables: ${JSON.stringify(parsedEnvs)}`);
108
+ }
109
+
110
+ Logger.log(`Installing server: ${serverName}`);
111
+
112
+ const installOptions: ServerInstallOptions = {
113
+ force: false,
114
+ ...(parsedClients?.length && { targetClients: parsedClients }),
115
+ ...(Object.keys(parsedEnvs).length > 0 && { env: parsedEnvs })
116
+ };
117
+
118
+ const results = [await serverService.installMcpServer(category, serverName, installOptions)];
119
+
120
+ const { success, messages } = serverService.formatOperationResults(results);
121
+
122
+ messages.forEach((message: string) => {
123
+ if (success) {
124
+ Logger.log(`✓ ${message}`);
125
+ } else {
126
+ Logger.error(`✗ ${message}`);
127
+ }
128
+ });
129
+
130
+ if (!success) {
131
+ process.exit(1);
132
+ }
133
+ } catch (error: unknown) {
134
+ const message = error instanceof Error ? error.message : 'Unknown error';
135
+ Logger.error('Installation failed:', message);
136
+ process.exit(1);
137
+ }
138
+ });
139
+ }
@@ -0,0 +1,113 @@
1
+ import { Command } from 'commander';
2
+ import fs from 'fs/promises';
3
+ import path from 'path';
4
+ import { LOCAL_FEEDS_DIR } from '../../core/metadatas/constants.js';
5
+ import { mcpManager } from '../../services/MCPManager.js';
6
+ import { Logger } from '../../utils/logger.js';
7
+
8
+ interface SimplifiedServer {
9
+ name: string;
10
+ description: string;
11
+ }
12
+
13
+ interface SimplifiedFeed {
14
+ name: string;
15
+ displayName: string;
16
+ description: string;
17
+ mcpServers: SimplifiedServer[];
18
+ }
19
+
20
+ export function createListCommand(): Command {
21
+ return new Command('list')
22
+ .description('List all available MCP servers from feeds')
23
+ .option('--pull', 'Sync with remote feeds before listing')
24
+ .action(async (options) => {
25
+ try {
26
+ Logger.debug({
27
+ action: 'list_command_started',
28
+ options
29
+ });
30
+
31
+ // If sync flag is provided, try to sync first
32
+ if (options.pull) {
33
+ try {
34
+ await mcpManager.syncFeeds();
35
+ } catch (syncError) {
36
+ Logger.error('Failed to sync feeds, falling back to local feeds', syncError);
37
+ }
38
+ }
39
+ await mcpManager.initialize();
40
+
41
+ Logger.debug({
42
+ action: 'ensuring_feeds_directory',
43
+ path: LOCAL_FEEDS_DIR
44
+ });
45
+
46
+ // Ensure feeds directory exists
47
+ await fs.mkdir(LOCAL_FEEDS_DIR, { recursive: true });
48
+
49
+ // Read all json files from feeds directory
50
+ Logger.debug('Reading feed files from directory...');
51
+ const files = await fs.readdir(LOCAL_FEEDS_DIR);
52
+ const jsonFiles = files.filter(file => file.endsWith('.json'));
53
+
54
+ Logger.debug({
55
+ action: 'found_feed_files',
56
+ count: jsonFiles.length,
57
+ files: jsonFiles
58
+ });
59
+
60
+ const feeds: SimplifiedFeed[] = [];
61
+
62
+ // Process each json file
63
+ for (const file of jsonFiles) {
64
+ Logger.debug(`Processing feed file: ${file}`);
65
+ try {
66
+ const filePath = path.join(LOCAL_FEEDS_DIR, file);
67
+ const content = await fs.readFile(filePath, 'utf8');
68
+ const feedConfig = JSON.parse(content);
69
+
70
+ Logger.debug({
71
+ action: 'processing_feed',
72
+ file,
73
+ feedName: feedConfig.name,
74
+ serverCount: feedConfig.mcpServers?.length ?? 0
75
+ });
76
+
77
+ // Extract only needed information
78
+ const simplifiedFeed: SimplifiedFeed = {
79
+ name: feedConfig.name,
80
+ displayName: feedConfig.displayName,
81
+ description: feedConfig.description,
82
+ mcpServers: feedConfig.mcpServers.map((server: any) => ({
83
+ name: server.name,
84
+ description: server.description
85
+ }))
86
+ };
87
+
88
+ feeds.push(simplifiedFeed);
89
+ Logger.debug(`Successfully processed feed: ${feedConfig.name}`);
90
+ } catch (error) {
91
+ Logger.error(`Failed to process feed file: ${file}`, error);
92
+ }
93
+ }
94
+
95
+ if (feeds.length === 0) {
96
+ Logger.log('No feeds found.');
97
+ return;
98
+ }
99
+
100
+ Logger.debug({
101
+ action: 'completed_processing',
102
+ totalFeeds: feeds.length,
103
+ totalServers: feeds.reduce((acc, feed) => acc + feed.mcpServers.length, 0)
104
+ });
105
+
106
+ // Output as formatted JSON
107
+ console.log(JSON.stringify(feeds, null, 2));
108
+ } catch (error) {
109
+ Logger.error('Failed to list servers', error);
110
+ process.exit(1);
111
+ }
112
+ });
113
+ }
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander';
2
+ import { serverService } from '../../services/ServerService.js';
3
+
4
+ export function createPullCommand(): Command {
5
+ return new Command('pull')
6
+ .description('Pull MCP server configurations from remote feed source')
7
+ .action(async () => {
8
+ try {
9
+ await serverService.syncFeeds();
10
+ } catch (error) {
11
+ const message = error instanceof Error ? error.message : 'Unknown error';
12
+ console.error('Error syncing configurations:', message);
13
+ process.exit(1);
14
+ }
15
+ });
16
+ }
@@ -0,0 +1,39 @@
1
+ import { Command } from 'commander';
2
+ import { startWebServer } from '../../web/server.js';
3
+ import { mcpManager } from '../../services/MCPManager.js';
4
+ import { checkGithubAuth } from '../../utils/githubAuth.js';
5
+ import { Logger } from '../../utils/logger.js';
6
+
7
+ export function createServeCommand(): Command {
8
+ return new Command('serve')
9
+ .description('Serve local web interface')
10
+ .option('-p, --port <port>', 'Port to run the server on', '3000')
11
+ .option('-f, --feed-file <filepath>', 'Path to a custom feed configuration file')
12
+ .option('-s, --schemas-directory <path>', 'Path to a directory containing adhoc schema files')
13
+ .action(async (options) => {
14
+ try {
15
+ // Sync feeds before start the local UI
16
+ await mcpManager.syncFeeds();
17
+
18
+ // Ensure MCP manager is initialized before starting the web server
19
+ await mcpManager.initialize(options.feedFile, options.schemasDirectory);
20
+
21
+ const port = parseInt(options.port, 10);
22
+ if (isNaN(port) || port < 1 || port > 65535) {
23
+ throw new Error('Invalid port number');
24
+ }
25
+
26
+ await startWebServer(port);
27
+
28
+ // The server is running, keep the process alive
29
+ process.on('SIGINT', () => {
30
+ console.log('\nShutting down server...');
31
+ process.exit(0);
32
+ });
33
+ } catch (error) {
34
+ const message = error instanceof Error ? error.message : 'Unknown error';
35
+ console.error('Failed to start web server:', message);
36
+ process.exit(1);
37
+ }
38
+ });
39
+ }
@@ -0,0 +1,64 @@
1
+ import { Command } from 'commander';
2
+ import { serverService } from '../../services/ServerService.js';
3
+
4
+ export function createUninstallCommand(): Command {
5
+ return new Command('uninstall')
6
+ .description('Uninstall specific MCP servers')
7
+ .requiredOption(
8
+ '--category <category>',
9
+ 'Server category'
10
+ )
11
+ .requiredOption(
12
+ '--names <names>',
13
+ 'Server names (semicolon separated)'
14
+ )
15
+ .requiredOption(
16
+ '--targets <targets>',
17
+ 'Target clients to uninstall from (semicolon separated)'
18
+ )
19
+ .option(
20
+ '--remove-data',
21
+ 'Remove all associated data',
22
+ true // Change default to true to ensure cleanup happens
23
+ )
24
+ .action(async (options) => {
25
+ try {
26
+ const serverNames = options.names.split(';').map((name: string) => name.trim());
27
+
28
+ const validNames = await serverService.validateServerName(options.category, serverNames);
29
+ if (!validNames) {
30
+ console.error('Invalid server names provided');
31
+ process.exit(1);
32
+ }
33
+
34
+ console.log(`Uninstalling servers: ${serverNames.join(', ')}`);
35
+
36
+ const results = await Promise.all(
37
+ serverNames.map((serverName: string) => {
38
+ const targets = options.targets ? options.targets.split(';').map((t: string) => t.trim()) : [];
39
+ return serverService.uninstallMcpServer(options.category, serverName, {
40
+ removeData: options.removeData,
41
+ targets: targets
42
+ });
43
+ })
44
+ );
45
+
46
+ const { success, messages } = serverService.formatOperationResults(results);
47
+ messages.forEach(message => {
48
+ if (success) {
49
+ console.log(`✓ ${message}`);
50
+ } else {
51
+ console.error(`✗ ${message}`);
52
+ }
53
+ });
54
+
55
+ if (!success) {
56
+ process.exit(1);
57
+ }
58
+ } catch (error) {
59
+ const message = error instanceof Error ? error.message : 'Unknown error';
60
+ console.error('Uninstallation failed:', message);
61
+ process.exit(1);
62
+ }
63
+ });
64
+ }
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import { createServeCommand } from './commands/serve.js';
5
+ import { createListCommand } from './commands/list.js';
6
+ import { createInstallCommand } from './commands/install.js';
7
+ import { createUninstallCommand } from './commands/uninstall.js';
8
+ import { createPullCommand } from './commands/pull.js';
9
+ import { mcpManager } from '../services/MCPManager.js';
10
+ import { Logger } from '../utils/logger.js';
11
+ import { checkForUpdates } from '../utils/versionUtils.js';
12
+
13
+ // Custom error interface for Commander.js errors
14
+ interface CommanderError extends Error {
15
+ code?: string;
16
+ }
17
+
18
+ async function main(): Promise<void> {
19
+ // Initialize the MCP manager
20
+ // await mcpManager.initialize();
21
+
22
+ const program = new Command();
23
+ program
24
+ .name('imcp')
25
+ .description('IMCP (Install Model Context Protocol) CLI')
26
+ .option('--verbose', 'Show detailed logs for all commands');
27
+
28
+ // Parse global options first
29
+ program.parseOptions(process.argv);
30
+ const opts = program.opts();
31
+ Logger.setVerbose(!!opts.verbose);
32
+
33
+ // Add all commands
34
+ program.addCommand(createServeCommand());
35
+ // program.addCommand(createListCommand());
36
+ // program.addCommand(createInstallCommand());
37
+ // program.addCommand(createUninstallCommand());
38
+ // program.addCommand(createPullCommand());
39
+
40
+ // Error handling for the entire CLI
41
+ program.exitOverride();
42
+
43
+ // Check for updates
44
+ await checkForUpdates();
45
+
46
+ try {
47
+ await program.parseAsync(process.argv);
48
+ } catch (error) {
49
+ const commanderError = error as CommanderError;
50
+
51
+ if (commanderError.code === 'commander.help') {
52
+ // Help was displayed, exit normally
53
+ process.exit(0);
54
+ } else if (commanderError.code === 'commander.version') {
55
+ // Version was displayed, exit normally
56
+ process.exit(0);
57
+ } else {
58
+ console.error('Error:', commanderError.message || 'An unknown error occurred');
59
+ process.exit(1);
60
+ }
61
+ }
62
+ }
63
+
64
+ // Handle unhandled promise rejections
65
+ process.on('unhandledRejection', (error: unknown) => {
66
+ if (error instanceof Error) {
67
+ console.error('Unhandled promise rejection:', error.message);
68
+ } else {
69
+ console.error('Unhandled promise rejection:', error);
70
+ }
71
+ process.exit(1);
72
+ });
73
+
74
+ // Start the CLI
75
+ main().catch((error: unknown) => {
76
+ if (error instanceof Error) {
77
+ console.error('Fatal error:', error.message);
78
+ } else {
79
+ console.error('Fatal error:', error);
80
+ }
81
+ process.exit(1);
82
+ });