|
1 | 1 | /******************************************************************************** |
2 | | - * Copyright (c) 2021-2024 EclipseSource and others. |
| 2 | + * Copyright (c) 2021-2026 EclipseSource and others. |
3 | 3 | * |
4 | 4 | * This program and the accompanying materials are made available under the |
5 | 5 | * terms of the Eclipse Public License v. 2.0 which is available at |
|
15 | 15 | ********************************************************************************/ |
16 | 16 | import 'reflect-metadata'; |
17 | 17 |
|
18 | | -import { WorkflowDiagramModule, WorkflowLayoutConfigurator, WorkflowServerModule } from '@eclipse-glsp-examples/workflow-server/node'; |
19 | | -import { configureELKLayoutModule } from '@eclipse-glsp/layout-elk'; |
| 18 | +import { |
| 19 | + WorkflowDiagramModule, |
| 20 | + WorkflowLayoutConfigurator, |
| 21 | + WorkflowMcpDiagramModule, |
| 22 | + WorkflowMcpServerModule, |
| 23 | + WorkflowServerModule |
| 24 | +} from '@eclipse-glsp-examples/workflow-server/node'; |
| 25 | +import { ElkLayoutModule } from '@eclipse-glsp/layout-elk'; |
20 | 26 | import { GModelStorage, LogLevel, createAppModule } from '@eclipse-glsp/server/node'; |
21 | 27 | import { |
| 28 | + GlspMcpServerProvider, |
22 | 29 | GlspSocketServerLauncher, |
23 | 30 | GlspVscodeConnector, |
24 | 31 | NavigateAction, |
@@ -58,21 +65,44 @@ export async function activate(context: vscode.ExtensionContext): Promise<void> |
58 | 65 | context.subscriptions.push(serverProcess); |
59 | 66 | await serverProcess.start(); |
60 | 67 | } |
| 68 | + // Presence of `mcpServer` (even an empty `{}`) opts the GLSP server into starting an |
| 69 | + // embedded MCP HTTP server. The custom `name` groups multiple GLSP-based MCP servers |
| 70 | + // in the IDE's MCP server list and matches the `mcpServerDefinitionProviders` id below. |
| 71 | + const mcpServer = { name: 'glsp-workflow' }; |
61 | 72 | // Wrap server with quickstart component |
62 | 73 | const workflowServer = useIntegratedServer |
63 | 74 | ? new NodeGlspVscodeServer({ |
64 | 75 | clientId: 'glsp.workflow', |
65 | 76 | clientName: 'workflow', |
66 | | - serverModules: createServerModules() |
| 77 | + serverModules: createServerModules(), |
| 78 | + mcpServer |
67 | 79 | }) |
68 | 80 | : new SocketGlspVscodeServer({ |
69 | 81 | clientId: 'glsp.workflow', |
70 | 82 | clientName: 'workflow', |
71 | 83 | connectionOptions: { |
72 | 84 | port: serverProcess?.getPort() || JSON.parse(process.env.GLSP_SERVER_PORT || DEFAULT_SERVER_PORT), |
73 | 85 | path: process.env.GLSP_WEBSOCKET_PATH |
74 | | - } |
| 86 | + }, |
| 87 | + mcpServer |
75 | 88 | }); |
| 89 | + |
| 90 | + // Bridge the embedded MCP server's announced URL into VS Code's built-in MCP host. The |
| 91 | + // `glsp-workflow` provider id matches the `mcpServerDefinitionProviders` contribution in |
| 92 | + // this extension's `package.json` and the `mcpServer.name` above. |
| 93 | + const mcpProvider = new GlspMcpServerProvider(); |
| 94 | + context.subscriptions.push(mcpProvider, vscode.lm.registerMcpServerDefinitionProvider(mcpServer.name, mcpProvider)); |
| 95 | + workflowServer.initializeResult.then( |
| 96 | + result => { |
| 97 | + const server = mcpProvider.addServer(result); |
| 98 | + if (server) { |
| 99 | + notifyMcpConnected(server.name, server.url); |
| 100 | + } |
| 101 | + }, |
| 102 | + () => { |
| 103 | + /* GLSP startup error already surfaced by the connector; no MCP server to register. */ |
| 104 | + } |
| 105 | + ); |
76 | 106 | // Initialize GLSP-VSCode connector with server wrapper |
77 | 107 | const glspVscodeConnector = new GlspVscodeConnector({ |
78 | 108 | server: workflowServer, |
@@ -106,9 +136,23 @@ export async function activate(context: vscode.ExtensionContext): Promise<void> |
106 | 136 | ); |
107 | 137 | } |
108 | 138 |
|
| 139 | +/** Info notification with a `Copy URL` action; stays until the user dismisses it. */ |
| 140 | +function notifyMcpConnected(name: string, url: string): void { |
| 141 | + const COPY_URL_ACTION = 'Copy URL'; |
| 142 | + vscode.window.showInformationMessage(`MCP server '${name}' auto-registered at ${url}`, COPY_URL_ACTION).then(action => { |
| 143 | + if (action === COPY_URL_ACTION) { |
| 144 | + vscode.env.clipboard.writeText(url); |
| 145 | + } |
| 146 | + }); |
| 147 | +} |
| 148 | + |
109 | 149 | function createServerModules(): ContainerModule[] { |
110 | 150 | const appModule = createAppModule({ logLevel: LogLevel.info, logDir: LOG_DIR, fileLog: true, consoleLog: false }); |
111 | | - const elkLayoutModule = configureELKLayoutModule({ algorithms: ['layered'], layoutConfigurator: WorkflowLayoutConfigurator }); |
112 | | - const mainModule = new WorkflowServerModule().configureDiagramModule(new WorkflowDiagramModule(() => GModelStorage), elkLayoutModule); |
113 | | - return [appModule, mainModule]; |
| 151 | + const elkLayoutModule = new ElkLayoutModule({ algorithms: ['layered'], layoutConfigurator: WorkflowLayoutConfigurator }); |
| 152 | + const mainModule = new WorkflowServerModule().configureDiagramModule( |
| 153 | + new WorkflowDiagramModule(() => GModelStorage), |
| 154 | + elkLayoutModule, |
| 155 | + new WorkflowMcpDiagramModule() |
| 156 | + ); |
| 157 | + return [appModule, mainModule, new WorkflowMcpServerModule()]; |
114 | 158 | } |
0 commit comments