@theia/ai-registry 1.73.0-next.2

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 (78) hide show
  1. package/README.md +40 -0
  2. package/lib/browser/ai-registry-frontend-module.d.ts +5 -0
  3. package/lib/browser/ai-registry-frontend-module.d.ts.map +1 -0
  4. package/lib/browser/ai-registry-frontend-module.js +45 -0
  5. package/lib/browser/ai-registry-frontend-module.js.map +1 -0
  6. package/lib/browser/ai-registry-toolbar-contribution.d.ts +9 -0
  7. package/lib/browser/ai-registry-toolbar-contribution.d.ts.map +1 -0
  8. package/lib/browser/ai-registry-toolbar-contribution.js +53 -0
  9. package/lib/browser/ai-registry-toolbar-contribution.js.map +1 -0
  10. package/lib/browser/mcp/mcp-entries.d.ts +40 -0
  11. package/lib/browser/mcp/mcp-entries.d.ts.map +1 -0
  12. package/lib/browser/mcp/mcp-entries.js +143 -0
  13. package/lib/browser/mcp/mcp-entries.js.map +1 -0
  14. package/lib/browser/mcp/mcp-extensions-contribution.d.ts +45 -0
  15. package/lib/browser/mcp/mcp-extensions-contribution.d.ts.map +1 -0
  16. package/lib/browser/mcp/mcp-extensions-contribution.js +198 -0
  17. package/lib/browser/mcp/mcp-extensions-contribution.js.map +1 -0
  18. package/lib/browser/mcp/mcp-extensions-contribution.spec.d.ts +2 -0
  19. package/lib/browser/mcp/mcp-extensions-contribution.spec.d.ts.map +1 -0
  20. package/lib/browser/mcp/mcp-extensions-contribution.spec.js +266 -0
  21. package/lib/browser/mcp/mcp-extensions-contribution.spec.js.map +1 -0
  22. package/lib/browser/mcp/mcp-install-service.d.ts +72 -0
  23. package/lib/browser/mcp/mcp-install-service.d.ts.map +1 -0
  24. package/lib/browser/mcp/mcp-install-service.js +255 -0
  25. package/lib/browser/mcp/mcp-install-service.js.map +1 -0
  26. package/lib/browser/mcp/mcp-install-service.spec.d.ts +2 -0
  27. package/lib/browser/mcp/mcp-install-service.spec.d.ts.map +1 -0
  28. package/lib/browser/mcp/mcp-install-service.spec.js +604 -0
  29. package/lib/browser/mcp/mcp-install-service.spec.js.map +1 -0
  30. package/lib/browser/mcp/mcp-registry-ui-bridge-impl.d.ts +27 -0
  31. package/lib/browser/mcp/mcp-registry-ui-bridge-impl.d.ts.map +1 -0
  32. package/lib/browser/mcp/mcp-registry-ui-bridge-impl.js +136 -0
  33. package/lib/browser/mcp/mcp-registry-ui-bridge-impl.js.map +1 -0
  34. package/lib/common/ai-registry-configuration.d.ts +28 -0
  35. package/lib/common/ai-registry-configuration.d.ts.map +1 -0
  36. package/lib/common/ai-registry-configuration.js +56 -0
  37. package/lib/common/ai-registry-configuration.js.map +1 -0
  38. package/lib/common/mcp/mcp-registry-entry-resolver.d.ts +12 -0
  39. package/lib/common/mcp/mcp-registry-entry-resolver.d.ts.map +1 -0
  40. package/lib/common/mcp/mcp-registry-entry-resolver.js +68 -0
  41. package/lib/common/mcp/mcp-registry-entry-resolver.js.map +1 -0
  42. package/lib/common/mcp/mcp-registry-entry-resolver.spec.d.ts +2 -0
  43. package/lib/common/mcp/mcp-registry-entry-resolver.spec.d.ts.map +1 -0
  44. package/lib/common/mcp/mcp-registry-entry-resolver.spec.js +230 -0
  45. package/lib/common/mcp/mcp-registry-entry-resolver.spec.js.map +1 -0
  46. package/lib/common/mcp/mcp-registry-types.d.ts +105 -0
  47. package/lib/common/mcp/mcp-registry-types.d.ts.map +1 -0
  48. package/lib/common/mcp/mcp-registry-types.js +18 -0
  49. package/lib/common/mcp/mcp-registry-types.js.map +1 -0
  50. package/lib/common/registry-fetch-service.d.ts +24 -0
  51. package/lib/common/registry-fetch-service.d.ts.map +1 -0
  52. package/lib/common/registry-fetch-service.js +72 -0
  53. package/lib/common/registry-fetch-service.js.map +1 -0
  54. package/lib/common/registry-fetch-service.spec.d.ts +2 -0
  55. package/lib/common/registry-fetch-service.spec.d.ts.map +1 -0
  56. package/lib/common/registry-fetch-service.spec.js +129 -0
  57. package/lib/common/registry-fetch-service.spec.js.map +1 -0
  58. package/lib/package.spec.d.ts +1 -0
  59. package/lib/package.spec.d.ts.map +1 -0
  60. package/lib/package.spec.js +26 -0
  61. package/lib/package.spec.js.map +1 -0
  62. package/package.json +50 -0
  63. package/src/browser/ai-registry-frontend-module.ts +48 -0
  64. package/src/browser/ai-registry-toolbar-contribution.ts +51 -0
  65. package/src/browser/mcp/mcp-entries.tsx +288 -0
  66. package/src/browser/mcp/mcp-extensions-contribution.spec.ts +294 -0
  67. package/src/browser/mcp/mcp-extensions-contribution.ts +199 -0
  68. package/src/browser/mcp/mcp-install-service.spec.ts +673 -0
  69. package/src/browser/mcp/mcp-install-service.ts +300 -0
  70. package/src/browser/mcp/mcp-registry-ui-bridge-impl.ts +130 -0
  71. package/src/browser/style/mcp-entries.css +56 -0
  72. package/src/common/ai-registry-configuration.ts +52 -0
  73. package/src/common/mcp/mcp-registry-entry-resolver.spec.ts +248 -0
  74. package/src/common/mcp/mcp-registry-entry-resolver.ts +68 -0
  75. package/src/common/mcp/mcp-registry-types.ts +119 -0
  76. package/src/common/registry-fetch-service.spec.ts +136 -0
  77. package/src/common/registry-fetch-service.ts +78 -0
  78. package/src/package.spec.ts +28 -0
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ <div align='center'>
2
+
3
+ <br />
4
+
5
+ <img src='https://raw.githubusercontent.com/eclipse-theia/theia/master/logo/theia.svg?sanitize=true' alt='theia-ext-logo' width='100px' />
6
+
7
+ <h2>ECLIPSE THEIA - AI REGISTRY EXTENSION</h2>
8
+
9
+ <hr />
10
+
11
+ </div>
12
+
13
+ ## Description
14
+
15
+ The AI Registry package integrates Theia with a remote AI artifact registry (such as `ai-registry-core`). Users can browse approved MCP servers and install them with a single action.
16
+
17
+ ### Features
18
+
19
+ - Contributes registry-approved MCP servers to the Extensions view alongside Open VSX extensions.
20
+ - Detects whether a server is installed from the registry, manually with a matching key, or has drifted from the registry config — and surfaces Install / Link / Update / Fix config / Uninstall accordingly.
21
+ - Installs servers by writing the registry's published config snippet to the existing `ai-features.mcp.mcpServers` preference.
22
+
23
+ ### Product configuration
24
+
25
+ Theia products override the default tool name (`all`) and registry base URL by rebinding `AIRegistryConfiguration` in their frontend module.
26
+
27
+ ## Additional Information
28
+
29
+ - [Theia - GitHub](https://github.com/eclipse-theia/theia)
30
+ - [Theia - Website](https://theia-ide.org/)
31
+
32
+ ## License
33
+
34
+ - [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
35
+ - [GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)
36
+
37
+ ## Trademark
38
+
39
+ "Theia" is a trademark of the Eclipse Foundation
40
+ <https://www.eclipse.org/theia>
@@ -0,0 +1,5 @@
1
+ import '../../src/browser/style/mcp-entries.css';
2
+ import { ContainerModule } from '@theia/core/shared/inversify';
3
+ declare const _default: ContainerModule;
4
+ export default _default;
5
+ //# sourceMappingURL=ai-registry-frontend-module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-registry-frontend-module.d.ts","sourceRoot":"","sources":["../../src/browser/ai-registry-frontend-module.ts"],"names":[],"mappings":"AAgBA,OAAO,yCAAyC,CAAC;AAEjD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;;AAY/D,wBAiBG"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 EclipseSource GmbH.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ require("../../src/browser/style/mcp-entries.css");
19
+ const inversify_1 = require("@theia/core/shared/inversify");
20
+ const tab_bar_toolbar_1 = require("@theia/core/lib/browser/shell/tab-bar-toolbar");
21
+ const extensions_source_contribution_1 = require("@theia/vsx-registry/lib/browser/extensions-source-contribution");
22
+ const mcp_registry_ui_bridge_1 = require("@theia/ai-mcp/lib/browser/mcp-registry-ui-bridge");
23
+ const ai_registry_configuration_1 = require("../common/ai-registry-configuration");
24
+ const mcp_registry_entry_resolver_1 = require("../common/mcp/mcp-registry-entry-resolver");
25
+ const registry_fetch_service_1 = require("../common/registry-fetch-service");
26
+ const mcp_install_service_1 = require("./mcp/mcp-install-service");
27
+ const mcp_extensions_contribution_1 = require("./mcp/mcp-extensions-contribution");
28
+ const mcp_registry_ui_bridge_impl_1 = require("./mcp/mcp-registry-ui-bridge-impl");
29
+ const ai_registry_toolbar_contribution_1 = require("./ai-registry-toolbar-contribution");
30
+ exports.default = new inversify_1.ContainerModule(bind => {
31
+ bind(ai_registry_configuration_1.AIRegistryConfiguration).toSelf().inSingletonScope();
32
+ bind(mcp_registry_entry_resolver_1.MCPRegistryEntryResolverImpl).toSelf().inSingletonScope();
33
+ bind(mcp_registry_entry_resolver_1.MCPRegistryEntryResolver).toService(mcp_registry_entry_resolver_1.MCPRegistryEntryResolverImpl);
34
+ bind(registry_fetch_service_1.RegistryFetchServiceImpl).toSelf().inSingletonScope();
35
+ bind(registry_fetch_service_1.RegistryFetchService).toService(registry_fetch_service_1.RegistryFetchServiceImpl);
36
+ bind(mcp_install_service_1.MCPInstallServiceImpl).toSelf().inSingletonScope();
37
+ bind(mcp_install_service_1.MCPInstallService).toService(mcp_install_service_1.MCPInstallServiceImpl);
38
+ bind(mcp_extensions_contribution_1.MCPExtensionsContribution).toSelf().inSingletonScope();
39
+ bind(extensions_source_contribution_1.ExtensionsSourceContribution).toService(mcp_extensions_contribution_1.MCPExtensionsContribution);
40
+ bind(mcp_registry_ui_bridge_impl_1.MCPRegistryUiBridgeImpl).toSelf().inSingletonScope();
41
+ bind(mcp_registry_ui_bridge_1.MCPRegistryUiBridge).toService(mcp_registry_ui_bridge_impl_1.MCPRegistryUiBridgeImpl);
42
+ bind(ai_registry_toolbar_contribution_1.AIRegistryToolbarContribution).toSelf().inSingletonScope();
43
+ bind(tab_bar_toolbar_1.TabBarToolbarContribution).toService(ai_registry_toolbar_contribution_1.AIRegistryToolbarContribution);
44
+ });
45
+ //# sourceMappingURL=ai-registry-frontend-module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-registry-frontend-module.js","sourceRoot":"","sources":["../../src/browser/ai-registry-frontend-module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,mDAAiD;AAEjD,4DAA+D;AAC/D,mFAA0F;AAC1F,mHAA8G;AAC9G,6FAAuF;AACvF,mFAA8E;AAC9E,2FAAmH;AACnH,6EAAkG;AAClG,mEAAqF;AACrF,mFAA8E;AAC9E,mFAA4E;AAC5E,yFAAmF;AAEnF,kBAAe,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;IACtC,IAAI,CAAC,mDAAuB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC1D,IAAI,CAAC,0DAA4B,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC/D,IAAI,CAAC,sDAAwB,CAAC,CAAC,SAAS,CAAC,0DAA4B,CAAC,CAAC;IACvE,IAAI,CAAC,iDAAwB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC3D,IAAI,CAAC,6CAAoB,CAAC,CAAC,SAAS,CAAC,iDAAwB,CAAC,CAAC;IAC/D,IAAI,CAAC,2CAAqB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACxD,IAAI,CAAC,uCAAiB,CAAC,CAAC,SAAS,CAAC,2CAAqB,CAAC,CAAC;IAEzD,IAAI,CAAC,uDAAyB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC5D,IAAI,CAAC,6DAA4B,CAAC,CAAC,SAAS,CAAC,uDAAyB,CAAC,CAAC;IAExE,IAAI,CAAC,qDAAuB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC1D,IAAI,CAAC,4CAAmB,CAAC,CAAC,SAAS,CAAC,qDAAuB,CAAC,CAAC;IAE7D,IAAI,CAAC,gEAA6B,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAChE,IAAI,CAAC,2CAAyB,CAAC,CAAC,SAAS,CAAC,gEAA6B,CAAC,CAAC;AAC7E,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { CommandRegistry } from '@theia/core';
2
+ import { Widget } from '@theia/core/lib/browser';
3
+ import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
4
+ export declare class AIRegistryToolbarContribution implements TabBarToolbarContribution {
5
+ protected readonly commandRegistry: CommandRegistry;
6
+ registerToolbarItems(registry: TabBarToolbarRegistry): void;
7
+ protected isVsxExtensionsWidget(widget: Widget): boolean;
8
+ }
9
+ //# sourceMappingURL=ai-registry-toolbar-contribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-registry-toolbar-contribution.d.ts","sourceRoot":"","sources":["../../src/browser/ai-registry-toolbar-contribution.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AAMjH,qBACa,6BAA8B,YAAW,yBAAyB;IAG3E,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAEpD,oBAAoB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAgB3D,SAAS,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;CAI3D"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 EclipseSource GmbH.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.AIRegistryToolbarContribution = void 0;
19
+ const tslib_1 = require("tslib");
20
+ const core_1 = require("@theia/core");
21
+ const mcp_configuration_command_contribution_1 = require("@theia/ai-mcp/lib/browser/mcp-configuration-command-contribution");
22
+ const vsx_extensions_view_container_1 = require("@theia/vsx-registry/lib/browser/vsx-extensions-view-container");
23
+ const vsx_extensions_widget_1 = require("@theia/vsx-registry/lib/browser/vsx-extensions-widget");
24
+ const inversify_1 = require("@theia/core/shared/inversify");
25
+ let AIRegistryToolbarContribution = class AIRegistryToolbarContribution {
26
+ registerToolbarItems(registry) {
27
+ registry.registerItem({
28
+ id: 'ai-registry.addMcpServerManually',
29
+ command: mcp_configuration_command_contribution_1.ADD_MCP_SERVER_COMMAND.id,
30
+ group: 'other_1',
31
+ // The view container's own in-container items use `widget === getTabBarDelegate()`,
32
+ // which resolves to either the container itself (multi-part mode) or one of its
33
+ // child parts (single-part modes like Installed / Search). A separate toolbar
34
+ // contribution cannot reach the container instance, so we match both shapes by id
35
+ // and by the part-id prefix produced by `generateExtensionWidgetId`.
36
+ isVisible: (widget) => this.isVsxExtensionsWidget(widget)
37
+ && this.commandRegistry.getCommand(mcp_configuration_command_contribution_1.ADD_MCP_SERVER_COMMAND.id) !== undefined
38
+ });
39
+ }
40
+ isVsxExtensionsWidget(widget) {
41
+ return widget.id === vsx_extensions_view_container_1.VSXExtensionsViewContainer.ID
42
+ || widget.id.startsWith(vsx_extensions_widget_1.VSXExtensionsWidget.ID + ':');
43
+ }
44
+ };
45
+ exports.AIRegistryToolbarContribution = AIRegistryToolbarContribution;
46
+ tslib_1.__decorate([
47
+ (0, inversify_1.inject)(core_1.CommandRegistry),
48
+ tslib_1.__metadata("design:type", core_1.CommandRegistry)
49
+ ], AIRegistryToolbarContribution.prototype, "commandRegistry", void 0);
50
+ exports.AIRegistryToolbarContribution = AIRegistryToolbarContribution = tslib_1.__decorate([
51
+ (0, inversify_1.injectable)()
52
+ ], AIRegistryToolbarContribution);
53
+ //# sourceMappingURL=ai-registry-toolbar-contribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-registry-toolbar-contribution.js","sourceRoot":"","sources":["../../src/browser/ai-registry-toolbar-contribution.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;AAEhF,sCAA8C;AAG9C,6HAA0G;AAC1G,iHAA2G;AAC3G,iGAA4F;AAC5F,4DAAkE;AAG3D,IAAM,6BAA6B,GAAnC,MAAM,6BAA6B;IAKtC,oBAAoB,CAAC,QAA+B;QAChD,QAAQ,CAAC,YAAY,CAAC;YAClB,EAAE,EAAE,kCAAkC;YACtC,OAAO,EAAE,+DAAsB,CAAC,EAAE;YAClC,KAAK,EAAE,SAAS;YAChB,oFAAoF;YACpF,gFAAgF;YAChF,8EAA8E;YAC9E,kFAAkF;YAClF,qEAAqE;YACrE,SAAS,EAAE,CAAC,MAAc,EAAE,EAAE,CAC1B,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC;mBAC/B,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,+DAAsB,CAAC,EAAE,CAAC,KAAK,SAAS;SAClF,CAAC,CAAC;IACP,CAAC;IAES,qBAAqB,CAAC,MAAc;QAC1C,OAAO,MAAM,CAAC,EAAE,KAAK,0DAA0B,CAAC,EAAE;eAC3C,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,2CAAmB,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;IAC9D,CAAC;CACJ,CAAA;AAzBY,sEAA6B;AAGnB;IADlB,IAAA,kBAAM,EAAC,sBAAe,CAAC;sCACY,sBAAe;sEAAC;wCAH3C,6BAA6B;IADzC,IAAA,sBAAU,GAAE;GACA,6BAA6B,CAyBzC"}
@@ -0,0 +1,40 @@
1
+ import * as React from '@theia/core/shared/react';
2
+ import { HoverService } from '@theia/core/lib/browser';
3
+ import { TreeElement } from '@theia/core/lib/browser/source-tree';
4
+ import { MCPServerDescription } from '@theia/ai-mcp/lib/common/mcp-server-manager';
5
+ import { ClassificationResult, ResolvedRegistryEntry } from '../../common/mcp/mcp-registry-types';
6
+ /**
7
+ * Per-entry action callbacks provided by the contribution. Entries close over
8
+ * these so their card render functions can dispatch user actions without
9
+ * pulling the install service through dependency injection at the React level.
10
+ */
11
+ export interface MCPEntryHandlers {
12
+ install(entry: ResolvedRegistryEntry): Promise<void>;
13
+ uninstall(serverKey: string): Promise<void>;
14
+ unlink(serverKey: string): Promise<void>;
15
+ update(entry: ResolvedRegistryEntry): Promise<void>;
16
+ link(entry: ResolvedRegistryEntry): Promise<void>;
17
+ fixConfig(entry: ResolvedRegistryEntry): Promise<void>;
18
+ }
19
+ /** An entry surfacing a locally installed MCP server in the Installed section. */
20
+ export declare class MCPInstalledEntry implements TreeElement {
21
+ readonly local: MCPServerDescription;
22
+ readonly matchedEntry: ResolvedRegistryEntry | undefined;
23
+ readonly state: ClassificationResult;
24
+ readonly handlers: MCPEntryHandlers;
25
+ readonly hoverService: HoverService;
26
+ readonly id: string;
27
+ constructor(local: MCPServerDescription, matchedEntry: ResolvedRegistryEntry | undefined, state: ClassificationResult, handlers: MCPEntryHandlers, hoverService: HoverService);
28
+ render(): React.ReactNode;
29
+ }
30
+ /** An entry surfacing a registry-resolved MCP server in the Search Results section. */
31
+ export declare class MCPSearchResultEntry implements TreeElement {
32
+ readonly entry: ResolvedRegistryEntry;
33
+ readonly state: ClassificationResult;
34
+ readonly handlers: MCPEntryHandlers;
35
+ readonly hoverService: HoverService;
36
+ readonly id: string;
37
+ constructor(entry: ResolvedRegistryEntry, state: ClassificationResult, handlers: MCPEntryHandlers, hoverService: HoverService);
38
+ render(): React.ReactNode;
39
+ }
40
+ //# sourceMappingURL=mcp-entries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-entries.d.ts","sourceRoot":"","sources":["../../../src/browser/mcp/mcp-entries.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,KAAK,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAGlE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAElG;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC7B,OAAO,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,SAAS,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAED,kFAAkF;AAClF,qBAAa,iBAAkB,YAAW,WAAW;IAK7C,QAAQ,CAAC,KAAK,EAAE,oBAAoB;IACpC,QAAQ,CAAC,YAAY,EAAE,qBAAqB,GAAG,SAAS;IACxD,QAAQ,CAAC,KAAK,EAAE,oBAAoB;IACpC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB;IACnC,QAAQ,CAAC,YAAY,EAAE,YAAY;IAPvC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAGP,KAAK,EAAE,oBAAoB,EAC3B,YAAY,EAAE,qBAAqB,GAAG,SAAS,EAC/C,KAAK,EAAE,oBAAoB,EAC3B,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,EAAE,YAAY;IAKvC,MAAM,IAAI,KAAK,CAAC,SAAS;CAkB5B;AAED,uFAAuF;AACvF,qBAAa,oBAAqB,YAAW,WAAW;IAKhD,QAAQ,CAAC,KAAK,EAAE,qBAAqB;IACrC,QAAQ,CAAC,KAAK,EAAE,oBAAoB;IACpC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB;IACnC,QAAQ,CAAC,YAAY,EAAE,YAAY;IANvC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAGP,KAAK,EAAE,qBAAqB,EAC5B,KAAK,EAAE,oBAAoB,EAC3B,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,EAAE,YAAY;IAKvC,MAAM,IAAI,KAAK,CAAC,SAAS;CAa5B"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 EclipseSource GmbH.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.MCPSearchResultEntry = exports.MCPInstalledEntry = void 0;
19
+ const React = require("@theia/core/shared/react");
20
+ const core_1 = require("@theia/core");
21
+ const markdown_rendering_1 = require("@theia/core/lib/common/markdown-rendering");
22
+ const type_badge_1 = require("@theia/vsx-registry/lib/browser/type-badge");
23
+ const extension_card_1 = require("@theia/vsx-registry/lib/browser/extension-card");
24
+ /** An entry surfacing a locally installed MCP server in the Installed section. */
25
+ class MCPInstalledEntry {
26
+ constructor(local, matchedEntry, state, handlers, hoverService) {
27
+ this.local = local;
28
+ this.matchedEntry = matchedEntry;
29
+ this.state = state;
30
+ this.handlers = handlers;
31
+ this.hoverService = hoverService;
32
+ this.id = `mcp-installed-${local.name}`;
33
+ }
34
+ render() {
35
+ const localVersion = this.local.registryMetadata?.version;
36
+ return (React.createElement(MCPCard
37
+ // When the registry knows this server we prefer its display name / description;
38
+ // otherwise fall back to whatever the user-edited local entry has.
39
+ , {
40
+ // When the registry knows this server we prefer its display name / description;
41
+ // otherwise fall back to whatever the user-edited local entry has.
42
+ title: this.matchedEntry?.name ?? this.local.name, description: this.matchedEntry?.description,
43
+ // Show what the user has actually installed; fall back to the registry range
44
+ // for the unusual case where the local entry is missing a recorded version.
45
+ version: localVersion ?? this.matchedEntry?.version, identifier: this.matchedEntry?.serverId ?? this.local.registryMetadata?.serverId, verified: this.matchedEntry?.mcpRegistryVerified, hoverService: this.hoverService, actions: renderActions(this.state, this.matchedEntry, this.local.name, this.handlers, localVersion) }));
46
+ }
47
+ }
48
+ exports.MCPInstalledEntry = MCPInstalledEntry;
49
+ /** An entry surfacing a registry-resolved MCP server in the Search Results section. */
50
+ class MCPSearchResultEntry {
51
+ constructor(entry, state, handlers, hoverService) {
52
+ this.entry = entry;
53
+ this.state = state;
54
+ this.handlers = handlers;
55
+ this.hoverService = hoverService;
56
+ this.id = `mcp-search-${entry.serverId}`;
57
+ }
58
+ render() {
59
+ return (React.createElement(MCPCard, { title: this.entry.name, description: this.entry.description, version: this.entry.version, identifier: this.entry.serverId, verified: this.entry.mcpRegistryVerified, hoverService: this.hoverService, actions: renderActions(this.state, this.entry, this.entry.localName, this.handlers) }));
60
+ }
61
+ }
62
+ exports.MCPSearchResultEntry = MCPSearchResultEntry;
63
+ /** Build the markdown tooltip shown on hover, mirroring the depth of the VSX card's tooltip. */
64
+ function buildHoverContent(props) {
65
+ const lines = [`**${props.title}**`];
66
+ if (props.version) {
67
+ lines.push('', `_${props.version}_`);
68
+ }
69
+ if (props.description) {
70
+ lines.push('', props.description);
71
+ }
72
+ if (props.identifier) {
73
+ lines.push('', `_${props.identifier}_`);
74
+ }
75
+ return new markdown_rendering_1.MarkdownStringImpl(lines.join('\n'));
76
+ }
77
+ /**
78
+ * MCP entry card. Renders against the shared {@link ExtensionCard} shell so MCP entries
79
+ * sit visually alongside extensions in the unified Extensions view, sharing the layout,
80
+ * trust icon and hover tooltip. The MCP-specific bits are the codicon icon, the type
81
+ * badge, the derived trust state and the action set.
82
+ *
83
+ * The trailing invisible settings-gear element reserves the same layout space VSX cards
84
+ * use for their context-menu gear, so MCP and VSX action bars align across the view.
85
+ */
86
+ const MCPCard = props => {
87
+ const trust = props.verified === true ? 'verified' : 'unknown';
88
+ return (React.createElement(extension_card_1.ExtensionCard, { title: props.title, version: props.version, description: props.description, icon: React.createElement("i", { className: "codicon codicon-mcp" }), iconClassName: "theia-mcp-extension-icon", typeBadge: React.createElement(type_badge_1.TypeBadge, { icon: React.createElement("i", { className: "codicon codicon-mcp" }), label: core_1.nls.localizeByDefault('MCP'), variant: "mcp" }), publisher: props.identifier, publisherTitle: props.identifier, trust: trust, hover: { content: buildHoverContent(props), hoverService: props.hoverService }, actions: React.createElement("div", { className: "theia-mcp-extension-actions" },
89
+ props.actions,
90
+ React.createElement("div", { className: "codicon codicon-settings-gear action theia-mcp-extension-gear-placeholder", "aria-hidden": "true" })) }));
91
+ };
92
+ /**
93
+ * Buttons are state-driven and identical in the Installed and Search sections, mirroring
94
+ * how VSX renders extension actions. State conveys itself through which buttons appear:
95
+ *
96
+ * - `not-installed` -> [Install]
97
+ * - `installed-from-registry` -> [Update?] [Uninstall] (Update only when newer version is available)
98
+ * - `installed-manually` -> [Link to registry] (no Uninstall - user wanted only the link affordance)
99
+ * - `fix-config` -> warning [Fix config] [Uninstall]
100
+ * - `installed-link-stale` -> warning "Not in registry" [Unlink] [Uninstall]
101
+ * - `installed-user-added` -> filtered out before reaching this view
102
+ */
103
+ function renderActions(state, registryEntry, localName, handlers, localVersion) {
104
+ switch (state.kind) {
105
+ case 'not-installed':
106
+ return registryEntry && (React.createElement("button", { className: "theia-button prominent action", onClick: () => handlers.install(registryEntry) }, core_1.nls.localizeByDefault('Install')));
107
+ case 'installed-from-registry':
108
+ return (React.createElement(React.Fragment, null,
109
+ state.updateAvailable && registryEntry && (React.createElement("button", { className: "theia-button prominent action", title: registryEntry.version && registryEntry.version !== localVersion
110
+ ? core_1.nls.localize('theia/ai-registry/action/updateTooltip', 'Update from {0} to {1}', localVersion ?? '?', registryEntry.version)
111
+ : core_1.nls.localizeByDefault('Update'), onClick: () => handlers.update(registryEntry) }, core_1.nls.localizeByDefault('Update'))),
112
+ React.createElement("button", { className: "theia-button action", onClick: () => handlers.uninstall(localName) }, core_1.nls.localizeByDefault('Uninstall'))));
113
+ case 'installed-manually':
114
+ // No Uninstall here by design - the only meaningful action is to link
115
+ // the existing local server to the registry so future updates are tracked.
116
+ return registryEntry && (React.createElement("button", { className: "theia-button action", onClick: () => handlers.link(registryEntry) }, core_1.nls.localize('theia/ai-registry/action/link', 'Link to registry')));
117
+ case 'fix-config':
118
+ return (React.createElement(React.Fragment, null,
119
+ React.createElement("i", { className: "codicon codicon-warning theia-mcp-extension-warning", title: core_1.nls.localize('theia/ai-registry/warning/fixConfig', "This server's configuration differs from the registry. Click 'Fix config' to restore it.") }),
120
+ registryEntry && (React.createElement("button", { className: "theia-button prominent action", onClick: () => handlers.fixConfig(registryEntry) }, core_1.nls.localize('theia/ai-registry/action/fix', 'Fix config'))),
121
+ React.createElement("button", { className: "theia-button action", onClick: () => handlers.uninstall(localName) }, core_1.nls.localizeByDefault('Uninstall'))));
122
+ case 'installed-link-stale': {
123
+ // The registry no longer lists the linked serverId. The server itself may
124
+ // still work, so we offer Unlink (drop the registry link, keep the config)
125
+ // as the soft option and keep Uninstall available for users who want the
126
+ // server gone. Wording stays cautious - we don't assert the server works,
127
+ // we let the user decide.
128
+ const tooltip = core_1.nls.localize('theia/ai-registry/warning/linkStale', 'This server was installed from the registry, but the registry no longer lists it. '
129
+ + 'If you are sure you want to keep it and it still works for you, click Unlink to drop '
130
+ + 'the registry link. Otherwise click Uninstall to remove the server.');
131
+ return (React.createElement(React.Fragment, null,
132
+ React.createElement("span", { className: "theia-mcp-extension-link-stale-message", title: tooltip },
133
+ React.createElement("i", { className: "codicon codicon-warning theia-mcp-extension-warning" }),
134
+ core_1.nls.localize('theia/ai-registry/warning/notInRegistry', 'Not in registry')),
135
+ React.createElement("button", { className: "theia-button action", title: tooltip, onClick: () => handlers.unlink(localName) }, core_1.nls.localize('theia/ai-registry/action/unlink', 'Unlink')),
136
+ React.createElement("button", { className: "theia-button action", onClick: () => handlers.uninstall(localName) }, core_1.nls.localizeByDefault('Uninstall'))));
137
+ }
138
+ case 'installed-user-added':
139
+ // Filtered out of resolveInstalled and never returned from search; render nothing defensively.
140
+ return undefined;
141
+ }
142
+ }
143
+ //# sourceMappingURL=mcp-entries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-entries.js","sourceRoot":"","sources":["../../../src/browser/mcp/mcp-entries.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { Disposable, DisposableCollection, Emitter, Event, PreferenceService } from '@theia/core';
2
+ import { HoverService } from '@theia/core/lib/browser';
3
+ import { TreeElement } from '@theia/core/lib/browser/source-tree';
4
+ import { ExtensionsSourceContribution, SearchContext, SearchResult } from '@theia/vsx-registry/lib/browser/extensions-source-contribution';
5
+ import { MCPServerDescription } from '@theia/ai-mcp/lib/common/mcp-server-manager';
6
+ import { MCPServerInstallDialogFactory } from '@theia/ai-mcp/lib/browser/mcp-server-install-dialog';
7
+ import { RegistryFetchService } from '../../common/registry-fetch-service';
8
+ import { ResolvedRegistryEntry } from '../../common/mcp/mcp-registry-types';
9
+ import { MCPInstallService } from './mcp-install-service';
10
+ import { MCPEntryHandlers } from './mcp-entries';
11
+ export declare class MCPExtensionsContribution implements ExtensionsSourceContribution, Disposable {
12
+ readonly type = "mcp-server";
13
+ readonly displayName: string;
14
+ readonly priority = 100;
15
+ protected readonly preferenceService: PreferenceService;
16
+ protected readonly installService: MCPInstallService;
17
+ protected readonly fetchService: RegistryFetchService;
18
+ protected readonly hoverService: HoverService;
19
+ protected readonly installDialogFactory: MCPServerInstallDialogFactory;
20
+ protected readonly onDidChangeEmitter: Emitter<void>;
21
+ readonly onDidChange: Event<void>;
22
+ protected readonly toDispose: DisposableCollection;
23
+ protected handlers: MCPEntryHandlers;
24
+ protected init(): void;
25
+ dispose(): void;
26
+ resolveInstalled(): Promise<Iterable<TreeElement>>;
27
+ resolveSearchResults(query: string, context: SearchContext): Promise<Iterable<SearchResult>>;
28
+ refresh(): Promise<void>;
29
+ /**
30
+ * Returns the raw (untyped) servers preference; per-entry validation happens in
31
+ * `toServerDescription`, which uses the shared `MCPServersPreference.isValue` guard
32
+ * so this view and `McpFrontendApplicationContribution` apply the same value checks.
33
+ */
34
+ protected readStoredServers(): Record<string, unknown>;
35
+ protected safeGetRegistryEntries(): Promise<ResolvedRegistryEntry[]>;
36
+ protected toServerDescription(name: string, stored: unknown): MCPServerDescription | undefined;
37
+ /**
38
+ * Prompts the user for parameters the registry can't decide for them (autostart,
39
+ * auth token) before writing the entry. Cancelling the dialog aborts the install.
40
+ * The dialog is created through an injected factory so this contribution doesn't
41
+ * import the DOM-touching `ReactDialog` chain directly.
42
+ */
43
+ protected confirmAndInstall(entry: ResolvedRegistryEntry): Promise<void>;
44
+ }
45
+ //# sourceMappingURL=mcp-extensions-contribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-extensions-contribution.d.ts","sourceRoot":"","sources":["../../../src/browser/mcp/mcp-extensions-contribution.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,OAAO,EAAE,KAAK,EAAyB,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACzH,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gEAAgE,CAAC;AAE3I,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AAEnF,OAAO,EAAE,6BAA6B,EAAE,MAAM,qDAAqD,CAAC;AACpG,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAA2C,MAAM,eAAe,CAAC;AAI1F,qBACa,yBAA0B,YAAW,4BAA4B,EAAE,UAAU;IAEtF,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,SAAwC;IAC5D,QAAQ,CAAC,QAAQ,OAAO;IAGxB,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAGxD,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,iBAAiB,CAAC;IAGrD,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAGtD,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAG9C,SAAS,CAAC,QAAQ,CAAC,oBAAoB,EAAE,6BAA6B,CAAC;IAEvE,SAAS,CAAC,QAAQ,CAAC,kBAAkB,gBAAuB;IAC5D,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAiC;IAElE,SAAS,CAAC,QAAQ,CAAC,SAAS,uBAAqD;IAEjF,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IAGrC,SAAS,CAAC,IAAI,IAAI,IAAI;IAiBtB,OAAO,IAAI,IAAI;IAIT,gBAAgB,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAyBlD,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAkC5F,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B;;;;OAIG;IACH,SAAS,CAAC,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;cAItC,sBAAsB,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAY1E,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,oBAAoB,GAAG,SAAS;IAW9F;;;;;OAKG;cACa,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAcjF"}
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 EclipseSource GmbH.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.MCPExtensionsContribution = void 0;
19
+ const tslib_1 = require("tslib");
20
+ const inversify_1 = require("@theia/core/shared/inversify");
21
+ const core_1 = require("@theia/core");
22
+ const browser_1 = require("@theia/core/lib/browser");
23
+ const mcp_preferences_1 = require("@theia/ai-mcp/lib/common/mcp-preferences");
24
+ const mcp_servers_preference_1 = require("@theia/ai-mcp/lib/common/mcp-servers-preference");
25
+ const mcp_server_install_dialog_1 = require("@theia/ai-mcp/lib/browser/mcp-server-install-dialog");
26
+ const registry_fetch_service_1 = require("../../common/registry-fetch-service");
27
+ const mcp_install_service_1 = require("./mcp-install-service");
28
+ const mcp_entries_1 = require("./mcp-entries");
29
+ let MCPExtensionsContribution = class MCPExtensionsContribution {
30
+ constructor() {
31
+ this.type = 'mcp-server';
32
+ this.displayName = core_1.nls.localizeByDefault('MCP Servers');
33
+ this.priority = 100;
34
+ this.onDidChangeEmitter = new core_1.Emitter();
35
+ this.onDidChange = this.onDidChangeEmitter.event;
36
+ this.toDispose = new core_1.DisposableCollection(this.onDidChangeEmitter);
37
+ }
38
+ init() {
39
+ this.handlers = {
40
+ install: entry => this.confirmAndInstall(entry),
41
+ uninstall: serverKey => this.installService.uninstall(serverKey),
42
+ unlink: serverKey => this.installService.unlink(serverKey),
43
+ update: entry => this.installService.update(entry),
44
+ link: entry => this.installService.link(entry),
45
+ fixConfig: entry => this.installService.fixConfig(entry)
46
+ };
47
+ this.toDispose.push(this.preferenceService.onPreferenceChanged((change) => {
48
+ if (change.preferenceName === mcp_preferences_1.MCP_SERVERS_PREF) {
49
+ this.onDidChangeEmitter.fire();
50
+ }
51
+ }));
52
+ this.toDispose.push(this.fetchService.onDidChange(() => this.onDidChangeEmitter.fire()));
53
+ }
54
+ dispose() {
55
+ this.toDispose.dispose();
56
+ }
57
+ async resolveInstalled() {
58
+ const stored = this.readStoredServers();
59
+ const registryEntries = await this.safeGetRegistryEntries();
60
+ const byServerId = new Map(registryEntries.map(e => [e.serverId, e]));
61
+ const byName = new Map(registryEntries.map(e => [e.localName, e]));
62
+ const result = [];
63
+ for (const [name, config] of Object.entries(stored)) {
64
+ const local = this.toServerDescription(name, config);
65
+ if (!local) {
66
+ continue;
67
+ }
68
+ const state = this.installService.classifyLocalServer(local, registryEntries);
69
+ // Hand-added local servers belong to the MCP configuration widget, not this view.
70
+ // Stale-linked entries (registryMetadata.serverId set but registry no longer lists
71
+ // it) do belong here so we can surface the warning and offer Unlink / Uninstall.
72
+ if (state.kind === 'installed-user-added') {
73
+ continue;
74
+ }
75
+ const linkedId = local.registryMetadata?.serverId;
76
+ const matchedEntry = (linkedId && byServerId.get(linkedId)) || byName.get(local.name);
77
+ result.push(new mcp_entries_1.MCPInstalledEntry(local, matchedEntry, state, this.handlers, this.hoverService));
78
+ }
79
+ return result;
80
+ }
81
+ async resolveSearchResults(query, context) {
82
+ if (!query.trim()) {
83
+ return [];
84
+ }
85
+ const registryEntries = await this.safeGetRegistryEntries();
86
+ const localDescriptions = [];
87
+ for (const [name, cfg] of Object.entries(this.readStoredServers())) {
88
+ const local = this.toServerDescription(name, cfg);
89
+ if (local) {
90
+ localDescriptions.push(local);
91
+ }
92
+ }
93
+ const result = [];
94
+ for (const entry of registryEntries) {
95
+ // `verifiedOnly` comes from the OVSX-named `extensions.onlyShowVerifiedExtensions`
96
+ // preference. In this contribution "verified" maps to `mcpRegistryVerified`
97
+ // (i.e. approved in the AI registry), piggy-backing on the same toggle.
98
+ if (context.verifiedOnly && !entry.mcpRegistryVerified) {
99
+ continue;
100
+ }
101
+ // Hand all candidates to the view's global fuzzy ranker (`FuzzySearch.filter`
102
+ // in `VSXExtensionsSource.collectSearchResults`). It already discards entries
103
+ // that don't match the query, and a substring pre-filter would drop legitimate
104
+ // fuzzy matches such as "ChroDevTo" → "Chrome DevTools".
105
+ const searchableText = `${entry.name} ${entry.serverId} ${entry.description}`;
106
+ const state = this.installService.classifyRegistryEntry(entry, localDescriptions, registryEntries);
107
+ result.push({
108
+ element: new mcp_entries_1.MCPSearchResultEntry(entry, state, this.handlers, this.hoverService),
109
+ searchableText
110
+ });
111
+ }
112
+ return result;
113
+ }
114
+ async refresh() {
115
+ await this.fetchService.getEntries(true);
116
+ }
117
+ /**
118
+ * Returns the raw (untyped) servers preference; per-entry validation happens in
119
+ * `toServerDescription`, which uses the shared `MCPServersPreference.isValue` guard
120
+ * so this view and `McpFrontendApplicationContribution` apply the same value checks.
121
+ */
122
+ readStoredServers() {
123
+ return this.preferenceService.get(mcp_preferences_1.MCP_SERVERS_PREF, {}) ?? {};
124
+ }
125
+ async safeGetRegistryEntries() {
126
+ try {
127
+ return await this.fetchService.getEntries();
128
+ }
129
+ catch (error) {
130
+ // Without entries, locally-installed servers classify as user-added and the
131
+ // MCP section shows nothing; users can still manage servers from the AI
132
+ // configuration widget directly.
133
+ console.warn('AI registry fetch failed; MCP entries unavailable.', error);
134
+ return [];
135
+ }
136
+ }
137
+ toServerDescription(name, stored) {
138
+ // Reuse the same value guard the MCP frontend contribution applies to the
139
+ // preference, so a `command: 42` (or any non-string) entry is rejected here too
140
+ // instead of being cast straight to `MCPServerDescription`.
141
+ if (!mcp_servers_preference_1.MCPServersPreference.isValue(stored)) {
142
+ console.warn(`Ignoring malformed MCP server "${name}": value does not match the MCP servers preference schema.`);
143
+ return undefined;
144
+ }
145
+ return { name, ...stored };
146
+ }
147
+ /**
148
+ * Prompts the user for parameters the registry can't decide for them (autostart,
149
+ * auth token) before writing the entry. Cancelling the dialog aborts the install.
150
+ * The dialog is created through an injected factory so this contribution doesn't
151
+ * import the DOM-touching `ReactDialog` chain directly.
152
+ */
153
+ async confirmAndInstall(entry) {
154
+ const dialog = this.installDialogFactory({
155
+ name: entry.localName,
156
+ autostart: true,
157
+ // The registry sets `serverAuthToken` to mark auth as part of the connection
158
+ // contract, even with no default value — so we check key presence, not value.
159
+ requireAuthToken: 'serverAuthToken' in entry.config
160
+ });
161
+ const result = await dialog.open();
162
+ if (!result) {
163
+ return;
164
+ }
165
+ await this.installService.install(entry, result);
166
+ }
167
+ };
168
+ exports.MCPExtensionsContribution = MCPExtensionsContribution;
169
+ tslib_1.__decorate([
170
+ (0, inversify_1.inject)(core_1.PreferenceService),
171
+ tslib_1.__metadata("design:type", Object)
172
+ ], MCPExtensionsContribution.prototype, "preferenceService", void 0);
173
+ tslib_1.__decorate([
174
+ (0, inversify_1.inject)(mcp_install_service_1.MCPInstallService),
175
+ tslib_1.__metadata("design:type", Object)
176
+ ], MCPExtensionsContribution.prototype, "installService", void 0);
177
+ tslib_1.__decorate([
178
+ (0, inversify_1.inject)(registry_fetch_service_1.RegistryFetchService),
179
+ tslib_1.__metadata("design:type", Object)
180
+ ], MCPExtensionsContribution.prototype, "fetchService", void 0);
181
+ tslib_1.__decorate([
182
+ (0, inversify_1.inject)(browser_1.HoverService),
183
+ tslib_1.__metadata("design:type", browser_1.HoverService)
184
+ ], MCPExtensionsContribution.prototype, "hoverService", void 0);
185
+ tslib_1.__decorate([
186
+ (0, inversify_1.inject)(mcp_server_install_dialog_1.MCPServerInstallDialogFactory),
187
+ tslib_1.__metadata("design:type", Function)
188
+ ], MCPExtensionsContribution.prototype, "installDialogFactory", void 0);
189
+ tslib_1.__decorate([
190
+ (0, inversify_1.postConstruct)(),
191
+ tslib_1.__metadata("design:type", Function),
192
+ tslib_1.__metadata("design:paramtypes", []),
193
+ tslib_1.__metadata("design:returntype", void 0)
194
+ ], MCPExtensionsContribution.prototype, "init", null);
195
+ exports.MCPExtensionsContribution = MCPExtensionsContribution = tslib_1.__decorate([
196
+ (0, inversify_1.injectable)()
197
+ ], MCPExtensionsContribution);
198
+ //# sourceMappingURL=mcp-extensions-contribution.js.map