Skip to content

Commit 05c8fc5

Browse files
Add support for Model Context Protocol
- Add new package to start a MCP server as part of the GLSP server -- Start MCP HTTP server for client connections on GLSP server start -- Provide some default tools and resources -- Expose functionality as custom module - Extend examples to use GLSP MCP Server Part of eclipse-glsp/glsp#1546
1 parent 7b1fdd9 commit 05c8fc5

21 files changed

+2054
-23
lines changed

examples/workflow-server/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"dependencies": {
5959
"@eclipse-glsp/layout-elk": "2.6.0-next",
6060
"@eclipse-glsp/server": "2.6.0-next",
61+
"@eclipse-glsp/server-mcp": "2.6.0-next",
6162
"inversify": "^6.1.3"
6263
},
6364
"devDependencies": {

examples/workflow-server/src/common/workflow-diagram-module.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
ContextMenuItemProvider,
2222
DiagramConfiguration,
2323
EdgeCreationChecker,
24-
GLSPServer,
24+
GLSPServerInitContribution,
2525
GModelDiagramModule,
2626
InstanceMultiBinding,
2727
LabelEditValidator,
@@ -57,13 +57,13 @@ import { TaskEditContextActionProvider } from './taskedit/task-edit-context-prov
5757
import { TaskEditValidator } from './taskedit/task-edit-validator';
5858
import { WorkflowDiagramConfiguration } from './workflow-diagram-configuration';
5959
import { WorkflowEdgeCreationChecker } from './workflow-edge-creation-checker';
60-
import { WorkflowGLSPServer } from './workflow-glsp-server';
60+
import { CustomArgsInitContribution } from './workflow-glsp-server';
6161
import { WorkflowPopupFactory } from './workflow-popup-factory';
6262

6363
@injectable()
6464
export class WorkflowServerModule extends ServerModule {
65-
protected override bindGLSPServer(): BindingTarget<GLSPServer> {
66-
return WorkflowGLSPServer;
65+
protected override configureGLSPServerInitContributions(binding: MultiBinding<GLSPServerInitContribution>): void {
66+
binding.add(CustomArgsInitContribution);
6767
}
6868
}
6969

examples/workflow-server/src/common/workflow-glsp-server.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,32 @@
1313
*
1414
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
1515
********************************************************************************/
16-
import { Args, ArgsUtil, DefaultGLSPServer, InitializeResult, Logger, MaybePromise } from '@eclipse-glsp/server';
16+
import {
17+
ArgsUtil,
18+
GLSPServer,
19+
GLSPServerInitContribution,
20+
InitializeParameters,
21+
InitializeResult,
22+
Logger,
23+
MaybePromise
24+
} from '@eclipse-glsp/server';
1725
import { inject, injectable } from 'inversify';
1826

1927
@injectable()
20-
export class WorkflowGLSPServer extends DefaultGLSPServer {
28+
export class CustomArgsInitContribution implements GLSPServerInitContribution {
2129
MESSAGE_KEY = 'message';
2230
TIMESTAMP_KEY = 'timestamp';
2331

24-
@inject(Logger)
25-
protected override logger: Logger;
32+
@inject(Logger) protected logger: Logger;
2633

27-
protected override handleInitializeArgs(result: InitializeResult, args: Args | undefined): MaybePromise<InitializeResult> {
28-
if (!args) {
34+
initializeServer(server: GLSPServer, params: InitializeParameters, result: InitializeResult): MaybePromise<InitializeResult> {
35+
if (!params.args) {
2936
return result;
3037
}
31-
const timestamp = ArgsUtil.get(args, this.TIMESTAMP_KEY);
32-
const message = ArgsUtil.get(args, this.MESSAGE_KEY);
38+
const timestamp = ArgsUtil.get(params.args, this.TIMESTAMP_KEY);
39+
const message = ArgsUtil.get(params.args, this.MESSAGE_KEY);
3340

34-
this.logger.debug(`${timestamp}: ${message}`);
41+
this.logger.info(`${timestamp}: ${message}`);
3542
return result;
3643
}
3744
}

examples/workflow-server/src/node/app.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
import 'reflect-metadata';
1717

1818
import { configureELKLayoutModule } from '@eclipse-glsp/layout-elk';
19-
import { createAppModule, GModelStorage, Logger, SocketServerLauncher, WebSocketServerLauncher } from '@eclipse-glsp/server/node';
19+
import { GModelStorage, Logger, SocketServerLauncher, WebSocketServerLauncher, createAppModule } from '@eclipse-glsp/server/node';
2020
import { Container } from 'inversify';
2121

22+
import { configureMcpModule } from '@eclipse-glsp/server-mcp';
2223
import { WorkflowLayoutConfigurator } from '../common/layout/workflow-layout-configurator';
2324
import { WorkflowDiagramModule, WorkflowServerModule } from '../common/workflow-diagram-module';
2425
import { createWorkflowCliParser } from './workflow-cli-parser';
@@ -40,14 +41,14 @@ async function launch(argv?: string[]): Promise<void> {
4041

4142
const elkLayoutModule = configureELKLayoutModule({ algorithms: ['layered'], layoutConfigurator: WorkflowLayoutConfigurator });
4243
const serverModule = new WorkflowServerModule().configureDiagramModule(new WorkflowDiagramModule(() => GModelStorage), elkLayoutModule);
43-
44+
const mcpModule = configureMcpModule();
4445
if (options.webSocket) {
4546
const launcher = appContainer.resolve(WebSocketServerLauncher);
46-
launcher.configure(serverModule);
47+
launcher.configure(serverModule, mcpModule);
4748
await launcher.start({ port: options.port, host: options.host, path: 'workflow' });
4849
} else {
4950
const launcher = appContainer.resolve(SocketServerLauncher);
50-
launcher.configure(serverModule);
51+
launcher.configure(serverModule, mcpModule);
5152
await launcher.start({ port: options.port, host: options.host });
5253
}
5354
}

examples/workflow-server/tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
{
1313
"path": "../../packages/server"
1414
},
15+
{
16+
"path": "../../packages/server-mcp"
17+
},
1518
{
1619
"path": "../../packages/layout-elk"
1720
}

packages/server-mcp/.eslintrc.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/** @type {import('eslint').Linter.Config} */
2+
module.exports = {
3+
extends: '../../.eslintrc.js',
4+
rules: {
5+
'import/no-unresolved': [
6+
'error',
7+
{
8+
ignore: ['^@modelcontextprotocol/sdk/']
9+
}
10+
]
11+
}
12+
};

packages/server-mcp/package.json

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"name": "@eclipse-glsp/server-mcp",
3+
"version": "2.6.0-next",
4+
"description": "Extension of the GLSP Node Server for the Model Context Protocol",
5+
"keywords": [
6+
"eclipse",
7+
"graphics",
8+
"diagram",
9+
"modeling",
10+
"visualization",
11+
"glsp",
12+
"diagram editor",
13+
"mcp"
14+
],
15+
"homepage": "https://www.eclipse.org/glsp/",
16+
"bugs": "https://github.com/eclipse-glsp/glsp/issues",
17+
"repository": {
18+
"type": "git",
19+
"url": "https://github.com/eclipse-glsp/glsp-server-node.git"
20+
},
21+
"license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)",
22+
"author": {
23+
"name": "Eclipse GLSP"
24+
},
25+
"contributors": [
26+
{
27+
"name": "Eclipse GLSP Project",
28+
"email": "[email protected]",
29+
"url": "https://projects.eclipse.org/projects/ecd.glsp"
30+
}
31+
],
32+
"main": "lib/index",
33+
"types": "lib/index",
34+
"files": [
35+
"lib",
36+
"src"
37+
],
38+
"scripts": {
39+
"build": "tsc -b",
40+
"clean": "rimraf lib *.tsbuildinfo coverage .nyc_output",
41+
"generate:index": "glsp generateIndex src -f -s",
42+
"lint": "eslint --ext .ts,.tsx ./src",
43+
"test": "mocha --config ../../.mocharc \"./src/**/*.spec.?(ts|tsx)\"",
44+
"test:ci": "yarn test --reporter mocha-ctrf-json-reporter",
45+
"test:coverage": "nyc yarn test",
46+
"watch": "tsc -w"
47+
},
48+
"dependencies": {
49+
"@eclipse-glsp/server": "2.6.0-next",
50+
"@modelcontextprotocol/sdk": "^1.25.1",
51+
"express": "^5.2.1"
52+
},
53+
"devDependencies": {
54+
"@types/express": "^5.0.6"
55+
},
56+
"peerDependencies": {
57+
"inversify": "^6.1.3"
58+
},
59+
"publishConfig": {
60+
"access": "public"
61+
}
62+
}

0 commit comments

Comments
 (0)