@theia/ai-registry 1.73.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/lib/browser/ai-registry-frontend-module.d.ts +5 -0
- package/lib/browser/ai-registry-frontend-module.d.ts.map +1 -0
- package/lib/browser/ai-registry-frontend-module.js +45 -0
- package/lib/browser/ai-registry-frontend-module.js.map +1 -0
- package/lib/browser/ai-registry-toolbar-contribution.d.ts +9 -0
- package/lib/browser/ai-registry-toolbar-contribution.d.ts.map +1 -0
- package/lib/browser/ai-registry-toolbar-contribution.js +53 -0
- package/lib/browser/ai-registry-toolbar-contribution.js.map +1 -0
- package/lib/browser/mcp/mcp-entries.d.ts +40 -0
- package/lib/browser/mcp/mcp-entries.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-entries.js +143 -0
- package/lib/browser/mcp/mcp-entries.js.map +1 -0
- package/lib/browser/mcp/mcp-extensions-contribution.d.ts +45 -0
- package/lib/browser/mcp/mcp-extensions-contribution.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-extensions-contribution.js +198 -0
- package/lib/browser/mcp/mcp-extensions-contribution.js.map +1 -0
- package/lib/browser/mcp/mcp-extensions-contribution.spec.d.ts +2 -0
- package/lib/browser/mcp/mcp-extensions-contribution.spec.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-extensions-contribution.spec.js +266 -0
- package/lib/browser/mcp/mcp-extensions-contribution.spec.js.map +1 -0
- package/lib/browser/mcp/mcp-install-service.d.ts +72 -0
- package/lib/browser/mcp/mcp-install-service.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-install-service.js +255 -0
- package/lib/browser/mcp/mcp-install-service.js.map +1 -0
- package/lib/browser/mcp/mcp-install-service.spec.d.ts +2 -0
- package/lib/browser/mcp/mcp-install-service.spec.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-install-service.spec.js +604 -0
- package/lib/browser/mcp/mcp-install-service.spec.js.map +1 -0
- package/lib/browser/mcp/mcp-registry-ui-bridge-impl.d.ts +27 -0
- package/lib/browser/mcp/mcp-registry-ui-bridge-impl.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-registry-ui-bridge-impl.js +136 -0
- package/lib/browser/mcp/mcp-registry-ui-bridge-impl.js.map +1 -0
- package/lib/common/ai-registry-configuration.d.ts +28 -0
- package/lib/common/ai-registry-configuration.d.ts.map +1 -0
- package/lib/common/ai-registry-configuration.js +56 -0
- package/lib/common/ai-registry-configuration.js.map +1 -0
- package/lib/common/mcp/mcp-registry-entry-resolver.d.ts +12 -0
- package/lib/common/mcp/mcp-registry-entry-resolver.d.ts.map +1 -0
- package/lib/common/mcp/mcp-registry-entry-resolver.js +68 -0
- package/lib/common/mcp/mcp-registry-entry-resolver.js.map +1 -0
- package/lib/common/mcp/mcp-registry-entry-resolver.spec.d.ts +2 -0
- package/lib/common/mcp/mcp-registry-entry-resolver.spec.d.ts.map +1 -0
- package/lib/common/mcp/mcp-registry-entry-resolver.spec.js +230 -0
- package/lib/common/mcp/mcp-registry-entry-resolver.spec.js.map +1 -0
- package/lib/common/mcp/mcp-registry-types.d.ts +105 -0
- package/lib/common/mcp/mcp-registry-types.d.ts.map +1 -0
- package/lib/common/mcp/mcp-registry-types.js +18 -0
- package/lib/common/mcp/mcp-registry-types.js.map +1 -0
- package/lib/common/registry-fetch-service.d.ts +24 -0
- package/lib/common/registry-fetch-service.d.ts.map +1 -0
- package/lib/common/registry-fetch-service.js +72 -0
- package/lib/common/registry-fetch-service.js.map +1 -0
- package/lib/common/registry-fetch-service.spec.d.ts +2 -0
- package/lib/common/registry-fetch-service.spec.d.ts.map +1 -0
- package/lib/common/registry-fetch-service.spec.js +129 -0
- package/lib/common/registry-fetch-service.spec.js.map +1 -0
- package/lib/package.spec.d.ts +1 -0
- package/lib/package.spec.d.ts.map +1 -0
- package/lib/package.spec.js +26 -0
- package/lib/package.spec.js.map +1 -0
- package/package.json +50 -0
- package/src/browser/ai-registry-frontend-module.ts +48 -0
- package/src/browser/ai-registry-toolbar-contribution.ts +51 -0
- package/src/browser/mcp/mcp-entries.tsx +288 -0
- package/src/browser/mcp/mcp-extensions-contribution.spec.ts +294 -0
- package/src/browser/mcp/mcp-extensions-contribution.ts +199 -0
- package/src/browser/mcp/mcp-install-service.spec.ts +673 -0
- package/src/browser/mcp/mcp-install-service.ts +300 -0
- package/src/browser/mcp/mcp-registry-ui-bridge-impl.ts +130 -0
- package/src/browser/style/mcp-entries.css +56 -0
- package/src/common/ai-registry-configuration.ts +52 -0
- package/src/common/mcp/mcp-registry-entry-resolver.spec.ts +248 -0
- package/src/common/mcp/mcp-registry-entry-resolver.ts +68 -0
- package/src/common/mcp/mcp-registry-types.ts +119 -0
- package/src/common/registry-fetch-service.spec.ts +136 -0
- package/src/common/registry-fetch-service.ts +78 -0
- 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 @@
|
|
|
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
|