@eclipse-glsp/server-mcp 2.7.0-next.9
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/LICENSE +642 -0
- package/README.md +57 -0
- package/lib/index.d.ts +23 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +41 -0
- package/lib/index.js.map +1 -0
- package/lib/prompts/handlers/describe-diagram-mcp-prompt-handler.d.ts +43 -0
- package/lib/prompts/handlers/describe-diagram-mcp-prompt-handler.d.ts.map +1 -0
- package/lib/prompts/handlers/describe-diagram-mcp-prompt-handler.js +96 -0
- package/lib/prompts/handlers/describe-diagram-mcp-prompt-handler.js.map +1 -0
- package/lib/prompts/handlers/suggest-improvements-mcp-prompt-handler.d.ts +43 -0
- package/lib/prompts/handlers/suggest-improvements-mcp-prompt-handler.d.ts.map +1 -0
- package/lib/prompts/handlers/suggest-improvements-mcp-prompt-handler.js +95 -0
- package/lib/prompts/handlers/suggest-improvements-mcp-prompt-handler.js.map +1 -0
- package/lib/prompts/index.d.ts +18 -0
- package/lib/prompts/index.d.ts.map +1 -0
- package/lib/prompts/index.js +34 -0
- package/lib/prompts/index.js.map +1 -0
- package/lib/resources/handlers/diagram-png-mcp-resource-handler.d.ts +81 -0
- package/lib/resources/handlers/diagram-png-mcp-resource-handler.d.ts.map +1 -0
- package/lib/resources/handlers/diagram-png-mcp-resource-handler.js +174 -0
- package/lib/resources/handlers/diagram-png-mcp-resource-handler.js.map +1 -0
- package/lib/resources/handlers/diagram-svg-mcp-resource-handler.d.ts +52 -0
- package/lib/resources/handlers/diagram-svg-mcp-resource-handler.d.ts.map +1 -0
- package/lib/resources/handlers/diagram-svg-mcp-resource-handler.js +96 -0
- package/lib/resources/handlers/diagram-svg-mcp-resource-handler.js.map +1 -0
- package/lib/resources/index.d.ts +20 -0
- package/lib/resources/index.d.ts.map +1 -0
- package/lib/resources/index.js +36 -0
- package/lib/resources/index.js.map +1 -0
- package/lib/resources/services/element-types-provider.d.ts +65 -0
- package/lib/resources/services/element-types-provider.d.ts.map +1 -0
- package/lib/resources/services/element-types-provider.js +81 -0
- package/lib/resources/services/element-types-provider.js.map +1 -0
- package/lib/resources/services/mcp-model-serializer.d.ts +78 -0
- package/lib/resources/services/mcp-model-serializer.d.ts.map +1 -0
- package/lib/resources/services/mcp-model-serializer.js +188 -0
- package/lib/resources/services/mcp-model-serializer.js.map +1 -0
- package/lib/server/glsp-mcp-server.d.ts +82 -0
- package/lib/server/glsp-mcp-server.d.ts.map +1 -0
- package/lib/server/glsp-mcp-server.js +140 -0
- package/lib/server/glsp-mcp-server.js.map +1 -0
- package/lib/server/index.d.ts +37 -0
- package/lib/server/index.d.ts.map +1 -0
- package/lib/server/index.js +57 -0
- package/lib/server/index.js.map +1 -0
- package/lib/server/lru-event-store.d.ts +53 -0
- package/lib/server/lru-event-store.d.ts.map +1 -0
- package/lib/server/lru-event-store.js +100 -0
- package/lib/server/lru-event-store.js.map +1 -0
- package/lib/server/mcp-diagram-handler-dispatcher.d.ts +144 -0
- package/lib/server/mcp-diagram-handler-dispatcher.d.ts.map +1 -0
- package/lib/server/mcp-diagram-handler-dispatcher.js +382 -0
- package/lib/server/mcp-diagram-handler-dispatcher.js.map +1 -0
- package/lib/server/mcp-diagram-module.d.ts +123 -0
- package/lib/server/mcp-diagram-module.d.ts.map +1 -0
- package/lib/server/mcp-diagram-module.js +186 -0
- package/lib/server/mcp-diagram-module.js.map +1 -0
- package/lib/server/mcp-diagram-prompt-handler-registry.d.ts +33 -0
- package/lib/server/mcp-diagram-prompt-handler-registry.d.ts.map +1 -0
- package/lib/server/mcp-diagram-prompt-handler-registry.js +76 -0
- package/lib/server/mcp-diagram-prompt-handler-registry.js.map +1 -0
- package/lib/server/mcp-diagram-resource-handler-registry.d.ts +35 -0
- package/lib/server/mcp-diagram-resource-handler-registry.d.ts.map +1 -0
- package/lib/server/mcp-diagram-resource-handler-registry.js +94 -0
- package/lib/server/mcp-diagram-resource-handler-registry.js.map +1 -0
- package/lib/server/mcp-diagram-tool-handler-registry.d.ts +57 -0
- package/lib/server/mcp-diagram-tool-handler-registry.d.ts.map +1 -0
- package/lib/server/mcp-diagram-tool-handler-registry.js +111 -0
- package/lib/server/mcp-diagram-tool-handler-registry.js.map +1 -0
- package/lib/server/mcp-handler-shared.d.ts +142 -0
- package/lib/server/mcp-handler-shared.d.ts.map +1 -0
- package/lib/server/mcp-handler-shared.js +199 -0
- package/lib/server/mcp-handler-shared.js.map +1 -0
- package/lib/server/mcp-http-transport.d.ts +93 -0
- package/lib/server/mcp-http-transport.d.ts.map +1 -0
- package/lib/server/mcp-http-transport.js +350 -0
- package/lib/server/mcp-http-transport.js.map +1 -0
- package/lib/server/mcp-id-alias-service.d.ts +70 -0
- package/lib/server/mcp-id-alias-service.d.ts.map +1 -0
- package/lib/server/mcp-id-alias-service.js +85 -0
- package/lib/server/mcp-id-alias-service.js.map +1 -0
- package/lib/server/mcp-input-schemas.d.ts +73 -0
- package/lib/server/mcp-input-schemas.d.ts.map +1 -0
- package/lib/server/mcp-input-schemas.js +67 -0
- package/lib/server/mcp-input-schemas.js.map +1 -0
- package/lib/server/mcp-label-provider.d.ts +45 -0
- package/lib/server/mcp-label-provider.d.ts.map +1 -0
- package/lib/server/mcp-label-provider.js +42 -0
- package/lib/server/mcp-label-provider.js.map +1 -0
- package/lib/server/mcp-log-level-registry.d.ts +54 -0
- package/lib/server/mcp-log-level-registry.d.ts.map +1 -0
- package/lib/server/mcp-log-level-registry.js +80 -0
- package/lib/server/mcp-log-level-registry.js.map +1 -0
- package/lib/server/mcp-logger.d.ts +59 -0
- package/lib/server/mcp-logger.d.ts.map +1 -0
- package/lib/server/mcp-logger.js +104 -0
- package/lib/server/mcp-logger.js.map +1 -0
- package/lib/server/mcp-mime-types.d.ts +28 -0
- package/lib/server/mcp-mime-types.d.ts.map +1 -0
- package/lib/server/mcp-mime-types.js +18 -0
- package/lib/server/mcp-mime-types.js.map +1 -0
- package/lib/server/mcp-options.d.ts +39 -0
- package/lib/server/mcp-options.d.ts.map +1 -0
- package/lib/server/mcp-options.js +53 -0
- package/lib/server/mcp-options.js.map +1 -0
- package/lib/server/mcp-progress-reporter.d.ts +48 -0
- package/lib/server/mcp-progress-reporter.d.ts.map +1 -0
- package/lib/server/mcp-progress-reporter.js +66 -0
- package/lib/server/mcp-progress-reporter.js.map +1 -0
- package/lib/server/mcp-prompt-handler.d.ts +120 -0
- package/lib/server/mcp-prompt-handler.d.ts.map +1 -0
- package/lib/server/mcp-prompt-handler.js +131 -0
- package/lib/server/mcp-prompt-handler.js.map +1 -0
- package/lib/server/mcp-request-context.d.ts +37 -0
- package/lib/server/mcp-request-context.d.ts.map +1 -0
- package/lib/server/mcp-request-context.js +37 -0
- package/lib/server/mcp-request-context.js.map +1 -0
- package/lib/server/mcp-resource-handler.d.ts +212 -0
- package/lib/server/mcp-resource-handler.d.ts.map +1 -0
- package/lib/server/mcp-resource-handler.js +298 -0
- package/lib/server/mcp-resource-handler.js.map +1 -0
- package/lib/server/mcp-server-launcher.d.ts +143 -0
- package/lib/server/mcp-server-launcher.d.ts.map +1 -0
- package/lib/server/mcp-server-launcher.js +355 -0
- package/lib/server/mcp-server-launcher.js.map +1 -0
- package/lib/server/mcp-server-module.d.ts +143 -0
- package/lib/server/mcp-server-module.d.ts.map +1 -0
- package/lib/server/mcp-server-module.js +249 -0
- package/lib/server/mcp-server-module.js.map +1 -0
- package/lib/server/mcp-session.d.ts +44 -0
- package/lib/server/mcp-session.d.ts.map +1 -0
- package/lib/server/mcp-session.js +18 -0
- package/lib/server/mcp-session.js.map +1 -0
- package/lib/server/mcp-tool-handler.d.ts +259 -0
- package/lib/server/mcp-tool-handler.d.ts.map +1 -0
- package/lib/server/mcp-tool-handler.js +355 -0
- package/lib/server/mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/count-elements-mcp-tool-handler.d.ts +46 -0
- package/lib/tools/handlers/count-elements-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/count-elements-mcp-tool-handler.js +76 -0
- package/lib/tools/handlers/count-elements-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/create-edges-mcp-tool-handler.d.ts +112 -0
- package/lib/tools/handlers/create-edges-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/create-edges-mcp-tool-handler.js +190 -0
- package/lib/tools/handlers/create-edges-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/create-nodes-mcp-tool-handler.d.ts +81 -0
- package/lib/tools/handlers/create-nodes-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/create-nodes-mcp-tool-handler.js +123 -0
- package/lib/tools/handlers/create-nodes-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/delete-elements-mcp-tool-handler.d.ts +52 -0
- package/lib/tools/handlers/delete-elements-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/delete-elements-mcp-tool-handler.js +73 -0
- package/lib/tools/handlers/delete-elements-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/diagram-model-mcp-tool-handler.d.ts +59 -0
- package/lib/tools/handlers/diagram-model-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/diagram-model-mcp-tool-handler.js +78 -0
- package/lib/tools/handlers/diagram-model-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/element-types-mcp-tool-handler.d.ts +97 -0
- package/lib/tools/handlers/element-types-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/element-types-mcp-tool-handler.js +155 -0
- package/lib/tools/handlers/element-types-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/get-selection-mcp-tool-handler.d.ts +43 -0
- package/lib/tools/handlers/get-selection-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/get-selection-mcp-tool-handler.js +68 -0
- package/lib/tools/handlers/get-selection-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/layout-mcp-tool-handler.d.ts +43 -0
- package/lib/tools/handlers/layout-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/layout-mcp-tool-handler.js +71 -0
- package/lib/tools/handlers/layout-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/modify-edges-mcp-tool-handler.d.ts +78 -0
- package/lib/tools/handlers/modify-edges-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/modify-edges-mcp-tool-handler.js +136 -0
- package/lib/tools/handlers/modify-edges-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/modify-nodes-mcp-tool-handler.d.ts +92 -0
- package/lib/tools/handlers/modify-nodes-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/modify-nodes-mcp-tool-handler.js +125 -0
- package/lib/tools/handlers/modify-nodes-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/query-elements-mcp-tool-handler.d.ts +102 -0
- package/lib/tools/handlers/query-elements-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/query-elements-mcp-tool-handler.js +158 -0
- package/lib/tools/handlers/query-elements-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/redo-mcp-tool-handler.d.ts +45 -0
- package/lib/tools/handlers/redo-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/redo-mcp-tool-handler.js +73 -0
- package/lib/tools/handlers/redo-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/save-model-mcp-tool-handler.d.ts +55 -0
- package/lib/tools/handlers/save-model-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/save-model-mcp-tool-handler.js +91 -0
- package/lib/tools/handlers/save-model-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/session-info-mcp-tool-handler.d.ts +65 -0
- package/lib/tools/handlers/session-info-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/session-info-mcp-tool-handler.js +108 -0
- package/lib/tools/handlers/session-info-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/set-selection-mcp-tool-handler.d.ts +60 -0
- package/lib/tools/handlers/set-selection-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/set-selection-mcp-tool-handler.js +103 -0
- package/lib/tools/handlers/set-selection-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/set-view-mcp-tool-handler.d.ts +110 -0
- package/lib/tools/handlers/set-view-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/set-view-mcp-tool-handler.js +142 -0
- package/lib/tools/handlers/set-view-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/undo-mcp-tool-handler.d.ts +45 -0
- package/lib/tools/handlers/undo-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/undo-mcp-tool-handler.js +74 -0
- package/lib/tools/handlers/undo-mcp-tool-handler.js.map +1 -0
- package/lib/tools/handlers/validate-diagram-mcp-tool-handler.d.ts +66 -0
- package/lib/tools/handlers/validate-diagram-mcp-tool-handler.d.ts.map +1 -0
- package/lib/tools/handlers/validate-diagram-mcp-tool-handler.js +0 -0
- package/lib/tools/handlers/validate-diagram-mcp-tool-handler.js.map +1 -0
- package/lib/tools/index.d.ts +34 -0
- package/lib/tools/index.d.ts.map +1 -0
- package/lib/tools/index.js +50 -0
- package/lib/tools/index.js.map +1 -0
- package/lib/util/index.d.ts +18 -0
- package/lib/util/index.d.ts.map +1 -0
- package/lib/util/index.js +34 -0
- package/lib/util/index.js.map +1 -0
- package/lib/util/markdown-util.d.ts +20 -0
- package/lib/util/markdown-util.d.ts.map +1 -0
- package/lib/util/markdown-util.js +45 -0
- package/lib/util/markdown-util.js.map +1 -0
- package/lib/util/mcp-util.d.ts +22 -0
- package/lib/util/mcp-util.d.ts.map +1 -0
- package/lib/util/mcp-util.js +29 -0
- package/lib/util/mcp-util.js.map +1 -0
- package/package.json +63 -0
- package/src/index.ts +24 -0
- package/src/prompts/handlers/describe-diagram-mcp-prompt-handler.ts +89 -0
- package/src/prompts/handlers/suggest-improvements-mcp-prompt-handler.ts +86 -0
- package/src/prompts/index.ts +18 -0
- package/src/resources/handlers/diagram-png-mcp-resource-handler.ts +181 -0
- package/src/resources/handlers/diagram-svg-mcp-resource-handler.ts +89 -0
- package/src/resources/index.ts +20 -0
- package/src/resources/services/element-types-provider.ts +105 -0
- package/src/resources/services/mcp-model-serializer.ts +211 -0
- package/src/server/glsp-mcp-server.spec.ts +73 -0
- package/src/server/glsp-mcp-server.ts +196 -0
- package/src/server/index.ts +42 -0
- package/src/server/lru-event-store.spec.ts +121 -0
- package/src/server/lru-event-store.ts +112 -0
- package/src/server/mcp-diagram-handler-dispatcher.spec.ts +231 -0
- package/src/server/mcp-diagram-handler-dispatcher.ts +459 -0
- package/src/server/mcp-diagram-module.ts +248 -0
- package/src/server/mcp-diagram-prompt-handler-registry.ts +59 -0
- package/src/server/mcp-diagram-resource-handler-registry.ts +73 -0
- package/src/server/mcp-diagram-tool-handler-registry.ts +97 -0
- package/src/server/mcp-handler-shared.spec.ts +53 -0
- package/src/server/mcp-handler-shared.ts +247 -0
- package/src/server/mcp-http-transport-e2e.spec.ts +151 -0
- package/src/server/mcp-http-transport.spec.ts +385 -0
- package/src/server/mcp-http-transport.ts +368 -0
- package/src/server/mcp-id-alias-service.spec.ts +106 -0
- package/src/server/mcp-id-alias-service.ts +104 -0
- package/src/server/mcp-input-schemas.ts +82 -0
- package/src/server/mcp-label-provider.ts +52 -0
- package/src/server/mcp-log-level-registry.spec.ts +75 -0
- package/src/server/mcp-log-level-registry.ts +90 -0
- package/src/server/mcp-logger.spec.ts +227 -0
- package/src/server/mcp-logger.ts +91 -0
- package/src/server/mcp-mime-types.ts +31 -0
- package/src/server/mcp-options.ts +43 -0
- package/src/server/mcp-progress-reporter.spec.ts +93 -0
- package/src/server/mcp-progress-reporter.ts +67 -0
- package/src/server/mcp-prompt-handler.ts +157 -0
- package/src/server/mcp-request-context.ts +39 -0
- package/src/server/mcp-resource-handler.ts +389 -0
- package/src/server/mcp-server-launcher.spec.ts +173 -0
- package/src/server/mcp-server-launcher.ts +369 -0
- package/src/server/mcp-server-module.ts +287 -0
- package/src/server/mcp-session.ts +45 -0
- package/src/server/mcp-tool-handler.spec.ts +182 -0
- package/src/server/mcp-tool-handler.ts +431 -0
- package/src/server/raw-http.spec.ts +59 -0
- package/src/tools/handlers/count-elements-mcp-tool-handler.spec.ts +99 -0
- package/src/tools/handlers/count-elements-mcp-tool-handler.ts +66 -0
- package/src/tools/handlers/create-edges-mcp-tool-handler.spec.ts +196 -0
- package/src/tools/handlers/create-edges-mcp-tool-handler.ts +205 -0
- package/src/tools/handlers/create-nodes-mcp-tool-handler.spec.ts +197 -0
- package/src/tools/handlers/create-nodes-mcp-tool-handler.ts +131 -0
- package/src/tools/handlers/delete-elements-mcp-tool-handler.ts +73 -0
- package/src/tools/handlers/diagram-model-mcp-tool-handler.ts +66 -0
- package/src/tools/handlers/element-types-mcp-tool-handler.ts +151 -0
- package/src/tools/handlers/get-selection-mcp-tool-handler.ts +54 -0
- package/src/tools/handlers/layout-mcp-tool-handler.ts +56 -0
- package/src/tools/handlers/modify-edges-mcp-tool-handler.ts +148 -0
- package/src/tools/handlers/modify-nodes-mcp-tool-handler.ts +140 -0
- package/src/tools/handlers/query-elements-mcp-tool-handler.spec.ts +210 -0
- package/src/tools/handlers/query-elements-mcp-tool-handler.ts +161 -0
- package/src/tools/handlers/redo-mcp-tool-handler.ts +62 -0
- package/src/tools/handlers/save-model-mcp-tool-handler.ts +71 -0
- package/src/tools/handlers/session-info-mcp-tool-handler.spec.ts +152 -0
- package/src/tools/handlers/session-info-mcp-tool-handler.ts +97 -0
- package/src/tools/handlers/set-selection-mcp-tool-handler.spec.ts +118 -0
- package/src/tools/handlers/set-selection-mcp-tool-handler.ts +90 -0
- package/src/tools/handlers/set-view-mcp-tool-handler.ts +162 -0
- package/src/tools/handlers/undo-mcp-tool-handler.ts +61 -0
- package/src/tools/handlers/validate-diagram-mcp-tool-handler.ts +0 -0
- package/src/tools/index.ts +34 -0
- package/src/tools/tool-annotations.spec.ts +141 -0
- package/src/util/index.ts +18 -0
- package/src/util/markdown-util.ts +44 -0
- package/src/util/mcp-util.ts +25 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { ActionDispatcher, SelectAction, SelectAllAction } from '@eclipse-glsp/server';
|
|
18
|
+
import { inject, injectable } from 'inversify';
|
|
19
|
+
import * as z from 'zod/v4';
|
|
20
|
+
import { AbstractMcpDiagramToolHandler, McpDiagramScopedInputSchema, McpToolResult, elementIds } from '../../server';
|
|
21
|
+
|
|
22
|
+
export const SetSelectionInputSchema = McpDiagramScopedInputSchema.extend({
|
|
23
|
+
selectedElementIds: elementIds
|
|
24
|
+
.optional()
|
|
25
|
+
.describe('Element IDs to select. Pass an empty array (or omit + set `clear: true`) to clear the selection.'),
|
|
26
|
+
deselectedElementIds: elementIds.optional().describe('Element IDs to remove from the selection. Used to subtract without replacing.'),
|
|
27
|
+
clear: z
|
|
28
|
+
.boolean()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe('When true, clear the existing selection before applying `selectedElementIds`. Defaults to false (additive).')
|
|
31
|
+
});
|
|
32
|
+
export type SetSelectionInput = z.infer<typeof SetSelectionInputSchema>;
|
|
33
|
+
|
|
34
|
+
export const SetSelectionOutputSchema = z.object({
|
|
35
|
+
selectedElementIds: z.array(z.string()).describe('Aliased ids requested for selection.'),
|
|
36
|
+
deselectedElementIds: z.array(z.string()).describe('Aliased ids requested for deselection.'),
|
|
37
|
+
cleared: z.boolean().describe('Whether the existing selection was cleared before applying.')
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Pushes a selection change to the client. Counterpart to `get-selection` — useful for the
|
|
42
|
+
* agent to direct a human reviewer's attention to elements it just modified ("here's what I
|
|
43
|
+
* touched"), or to chain follow-up tools that rely on the visible selection.
|
|
44
|
+
*
|
|
45
|
+
* Read-write hint is honest: the viewport selection state is part of the client environment
|
|
46
|
+
* even though the underlying GModel is unaffected.
|
|
47
|
+
*/
|
|
48
|
+
@injectable()
|
|
49
|
+
export class SetSelectionMcpToolHandler extends AbstractMcpDiagramToolHandler<SetSelectionInput> {
|
|
50
|
+
static readonly NAME = 'set-selection';
|
|
51
|
+
readonly name = SetSelectionMcpToolHandler.NAME;
|
|
52
|
+
override readonly title = 'Set Diagram Selection';
|
|
53
|
+
readonly description =
|
|
54
|
+
'Set the selection of elements on the client UI. Useful to direct a reviewer to a ' +
|
|
55
|
+
'set of elements (e.g. those just created or modified). Pass `clear: true` to replace ' +
|
|
56
|
+
'the existing selection rather than add to it.';
|
|
57
|
+
readonly inputSchema = SetSelectionInputSchema;
|
|
58
|
+
override readonly outputSchema = SetSelectionOutputSchema;
|
|
59
|
+
override readonly readOnlyHint = false;
|
|
60
|
+
|
|
61
|
+
@inject(ActionDispatcher) protected actionDispatcher: ActionDispatcher;
|
|
62
|
+
|
|
63
|
+
protected async createResult({ selectedElementIds, deselectedElementIds, clear }: SetSelectionInput): Promise<McpToolResult> {
|
|
64
|
+
const resolvedSelected = this.resolveExistingIds(selectedElementIds);
|
|
65
|
+
const resolvedDeselected = this.resolveExistingIds(deselectedElementIds);
|
|
66
|
+
|
|
67
|
+
if (clear) {
|
|
68
|
+
await this.actionDispatcher.dispatch(SelectAllAction.create(false));
|
|
69
|
+
}
|
|
70
|
+
if (resolvedSelected.length > 0 || resolvedDeselected.length > 0) {
|
|
71
|
+
await this.actionDispatcher.dispatch(
|
|
72
|
+
SelectAction.create({ selectedElementsIDs: resolvedSelected, deselectedElementsIDs: resolvedDeselected })
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return this.success(this.summarize(resolvedSelected, resolvedDeselected, clear ?? false), {
|
|
77
|
+
selectedElementIds: this.encodeIds(resolvedSelected),
|
|
78
|
+
deselectedElementIds: this.encodeIds(resolvedDeselected),
|
|
79
|
+
cleared: clear ?? false
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
protected summarize(selected: string[], deselected: string[], cleared: boolean): string {
|
|
84
|
+
const parts: string[] = [];
|
|
85
|
+
if (cleared) parts.push('Cleared previous selection.');
|
|
86
|
+
if (selected.length > 0) parts.push(`Selected ${selected.length} element${selected.length === 1 ? '' : 's'}.`);
|
|
87
|
+
if (deselected.length > 0) parts.push(`Deselected ${deselected.length} element${deselected.length === 1 ? '' : 's'}.`);
|
|
88
|
+
return parts.length > 0 ? parts.join(' ') : 'Selection unchanged.';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
Action,
|
|
19
|
+
ActionDispatcher,
|
|
20
|
+
CenterAction,
|
|
21
|
+
FitToScreenAction,
|
|
22
|
+
GetViewportAction,
|
|
23
|
+
OriginViewportAction,
|
|
24
|
+
Point,
|
|
25
|
+
SetViewportAction
|
|
26
|
+
} from '@eclipse-glsp/server';
|
|
27
|
+
import { inject, injectable } from 'inversify';
|
|
28
|
+
import * as z from 'zod/v4';
|
|
29
|
+
import {
|
|
30
|
+
McpDiagramScopedInputSchema,
|
|
31
|
+
AbstractMcpDiagramToolHandler,
|
|
32
|
+
McpToolError,
|
|
33
|
+
McpToolResult,
|
|
34
|
+
elementIds,
|
|
35
|
+
position,
|
|
36
|
+
requestActionOrFail
|
|
37
|
+
} from '../../server';
|
|
38
|
+
|
|
39
|
+
export const VIEWPORT_ACTIONS = ['fit-to-screen', 'center-on-elements', 'reset-viewport', 'set-viewport'] as const;
|
|
40
|
+
export type ViewportAction = (typeof VIEWPORT_ACTIONS)[number];
|
|
41
|
+
|
|
42
|
+
export const SetViewInputSchema = McpDiagramScopedInputSchema.extend({
|
|
43
|
+
action: z.enum(VIEWPORT_ACTIONS).describe('The type of viewport change action to be undertaken.'),
|
|
44
|
+
elementIds: elementIds
|
|
45
|
+
.optional()
|
|
46
|
+
.describe(
|
|
47
|
+
"Elements to center on or fit (relevant for 'center-on-elements' and 'fit-to-screen'). Omit to target the whole diagram."
|
|
48
|
+
),
|
|
49
|
+
zoom: z
|
|
50
|
+
.number()
|
|
51
|
+
.min(0.05)
|
|
52
|
+
.max(20)
|
|
53
|
+
.optional()
|
|
54
|
+
.describe(
|
|
55
|
+
"Absolute zoom level for `action: 'set-viewport'` (range 0.05..20, where 1 is 100% / native scale). " +
|
|
56
|
+
'Ignored by other actions. Omit to keep the current zoom while changing scroll.'
|
|
57
|
+
),
|
|
58
|
+
scroll: position
|
|
59
|
+
.optional()
|
|
60
|
+
.describe(
|
|
61
|
+
"Absolute scroll position for `action: 'set-viewport'`, in diagram coordinates (top-left of the visible area). " +
|
|
62
|
+
'Ignored by other actions. Omit to keep the current scroll while changing zoom.'
|
|
63
|
+
)
|
|
64
|
+
});
|
|
65
|
+
export type SetViewInput = z.infer<typeof SetViewInputSchema>;
|
|
66
|
+
|
|
67
|
+
export const SetViewOutputSchema = z.object({
|
|
68
|
+
action: z.enum(VIEWPORT_ACTIONS).describe('Echo of the viewport action that was applied.'),
|
|
69
|
+
targetIds: z
|
|
70
|
+
.array(z.string())
|
|
71
|
+
.optional()
|
|
72
|
+
.describe(
|
|
73
|
+
"Aliased ids the action targeted (resolved from input or fall-back of all elements). Omitted for `'set-viewport'` since that action targets coordinates, not elements."
|
|
74
|
+
),
|
|
75
|
+
viewport: z
|
|
76
|
+
.object({
|
|
77
|
+
scroll: position,
|
|
78
|
+
zoom: z.number()
|
|
79
|
+
})
|
|
80
|
+
.optional()
|
|
81
|
+
.describe("Resolved final viewport when `action: 'set-viewport'` was applied (current values merged with the supplied overrides).")
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
@injectable()
|
|
85
|
+
export class SetViewMcpToolHandler extends AbstractMcpDiagramToolHandler<SetViewInput> {
|
|
86
|
+
/** Timeout (in ms) for the `GetViewportAction` round-trip used by `set-viewport` partial updates. Override via subclass + rebind. */
|
|
87
|
+
protected readonly viewportQueryTimeoutMs: number = 5000;
|
|
88
|
+
|
|
89
|
+
static readonly NAME = 'set-view';
|
|
90
|
+
readonly name = SetViewMcpToolHandler.NAME;
|
|
91
|
+
override readonly title = 'Set Diagram Viewport';
|
|
92
|
+
readonly description =
|
|
93
|
+
"Set the viewport of the session's associated UI client to focus the user's attention. " +
|
|
94
|
+
'`fit-to-screen` zooms+pans so all elements (or the listed `elementIds`) are visible; ' +
|
|
95
|
+
'`center-on-elements` pans without changing zoom, useful to highlight a specific element after creating or modifying it; ' +
|
|
96
|
+
'`reset-viewport` returns the camera to the origin at default zoom; ' +
|
|
97
|
+
'`set-viewport` applies an explicit `zoom` and/or `scroll` (omit either to preserve its current value). ' +
|
|
98
|
+
'Only invoke on explicit user request or when the user clearly benefits from a viewport nudge ' +
|
|
99
|
+
'(e.g. just created an element off-screen). Note this changes client-side viewport state but not the model.';
|
|
100
|
+
readonly inputSchema = SetViewInputSchema;
|
|
101
|
+
override readonly outputSchema = SetViewOutputSchema;
|
|
102
|
+
/** Viewport IS client-side environment; dispatching mutates it, so the read-base default doesn't honestly apply. */
|
|
103
|
+
override readonly readOnlyHint = false;
|
|
104
|
+
|
|
105
|
+
@inject(ActionDispatcher) protected actionDispatcher: ActionDispatcher;
|
|
106
|
+
|
|
107
|
+
protected async createResult({ action, elementIds, zoom, scroll }: SetViewInput): Promise<McpToolResult> {
|
|
108
|
+
if (action === 'set-viewport') {
|
|
109
|
+
return this.applyExplicitViewport(zoom, scroll);
|
|
110
|
+
}
|
|
111
|
+
const resolvedIds = elementIds ? elementIds.map(id => this.aliasService.lookup(id)) : this.modelState.index.allIds();
|
|
112
|
+
const dispatchAction = this.buildIntentAction(action, resolvedIds);
|
|
113
|
+
await this.actionDispatcher.dispatch(dispatchAction);
|
|
114
|
+
return this.success('Viewport successfully changed', { action, targetIds: this.encodeIds(resolvedIds) });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Map an intent-driven viewport action (`fit-to-screen`, `center-on-elements`,
|
|
119
|
+
* `reset-viewport`) to the matching sprotty action. The exhaustive switch lets TypeScript
|
|
120
|
+
* narrow the remaining `'set-viewport'` case out at compile time, so we don't need a
|
|
121
|
+
* runtime guard.
|
|
122
|
+
*/
|
|
123
|
+
protected buildIntentAction(action: Exclude<ViewportAction, 'set-viewport'>, resolvedIds: string[]): Action {
|
|
124
|
+
switch (action) {
|
|
125
|
+
case 'fit-to-screen':
|
|
126
|
+
return FitToScreenAction.create(resolvedIds, { animate: true, padding: 20 });
|
|
127
|
+
case 'center-on-elements':
|
|
128
|
+
return CenterAction.create(resolvedIds, { animate: true, retainZoom: true });
|
|
129
|
+
case 'reset-viewport':
|
|
130
|
+
return OriginViewportAction.create({ animate: true });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Build the merged viewport for `set-viewport`: query the current viewport from the client,
|
|
136
|
+
* overlay the caller's `zoom` / `scroll` overrides, dispatch a {@link SetViewportAction}.
|
|
137
|
+
* Querying lets the LLM specify only one axis of change — the other is preserved instead of
|
|
138
|
+
* snapping to a placeholder default.
|
|
139
|
+
*/
|
|
140
|
+
protected async applyExplicitViewport(zoom: number | undefined, scroll: Point | undefined): Promise<McpToolResult> {
|
|
141
|
+
if (zoom === undefined && scroll === undefined) {
|
|
142
|
+
throw new McpToolError("'set-viewport' requires at least one of `zoom` or `scroll`.");
|
|
143
|
+
}
|
|
144
|
+
const rootId = this.modelState.root.id;
|
|
145
|
+
const current = await requestActionOrFail(
|
|
146
|
+
this.actionDispatcher,
|
|
147
|
+
GetViewportAction.create(),
|
|
148
|
+
this.viewportQueryTimeoutMs,
|
|
149
|
+
this.name
|
|
150
|
+
);
|
|
151
|
+
// Some clients respond before layout completes — fall back to origin / 1× when fields are null.
|
|
152
|
+
const newViewport = {
|
|
153
|
+
scroll: scroll ?? (Point.isValid(current.viewport.scroll) ? current.viewport.scroll : Point.ORIGIN),
|
|
154
|
+
zoom: zoom ?? (Number.isFinite(current.viewport.zoom) ? current.viewport.zoom : 1)
|
|
155
|
+
};
|
|
156
|
+
await this.actionDispatcher.dispatch(SetViewportAction.create(rootId, newViewport, { animate: true }));
|
|
157
|
+
return this.success(`Viewport set to scroll=(${newViewport.scroll.x}, ${newViewport.scroll.y}) zoom=${newViewport.zoom}`, {
|
|
158
|
+
action: 'set-viewport',
|
|
159
|
+
viewport: newViewport
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { CommandStack, UndoAction } from '@eclipse-glsp/server';
|
|
18
|
+
import { inject, injectable } from 'inversify';
|
|
19
|
+
import * as z from 'zod/v4';
|
|
20
|
+
import { McpDiagramScopedInputSchema, McpToolError, McpToolResult, OperationMcpDiagramToolHandler } from '../../server';
|
|
21
|
+
|
|
22
|
+
export const UndoInputSchema = McpDiagramScopedInputSchema.extend({
|
|
23
|
+
commandsToUndo: z.number().min(1).default(1).describe('Number of commands to undo. Defaults to 1 (most recent command).')
|
|
24
|
+
});
|
|
25
|
+
export type UndoInput = z.infer<typeof UndoInputSchema>;
|
|
26
|
+
|
|
27
|
+
export const UndoOutputSchema = z.object({
|
|
28
|
+
commandsUndone: z.number().int().describe('Number of commands actually reverted.')
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Undo a given number of the most recent actions on the command stack.
|
|
33
|
+
*/
|
|
34
|
+
@injectable()
|
|
35
|
+
export class UndoMcpToolHandler extends OperationMcpDiagramToolHandler<UndoInput> {
|
|
36
|
+
static readonly NAME = 'undo';
|
|
37
|
+
readonly name = UndoMcpToolHandler.NAME;
|
|
38
|
+
override readonly title = 'Undo Diagram Commands';
|
|
39
|
+
readonly description =
|
|
40
|
+
"Undo recent commands on the diagram's command stack. " +
|
|
41
|
+
'Defaults to undoing one command — the most recent operation — when `commandsToUndo` is omitted. ' +
|
|
42
|
+
'Note that some tools dispatch multiple commands per call (e.g. `create-nodes` typically dispatches a node + a label command); ' +
|
|
43
|
+
'check the previous tool result for the exact count if you need to reverse more than the last one. ' +
|
|
44
|
+
"Throws when there's nothing on the undo stack. Only do this on an explicit user request.";
|
|
45
|
+
readonly inputSchema = UndoInputSchema;
|
|
46
|
+
override readonly outputSchema = UndoOutputSchema;
|
|
47
|
+
|
|
48
|
+
@inject(CommandStack) protected commandStack: CommandStack;
|
|
49
|
+
|
|
50
|
+
protected async createResult({ commandsToUndo }: UndoInput): Promise<McpToolResult> {
|
|
51
|
+
if (!this.commandStack.canUndo()) {
|
|
52
|
+
throw new McpToolError('Nothing to undo (undo stack is empty; the model is at its initial state for this session).');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < commandsToUndo; i++) {
|
|
56
|
+
await this.actionDispatcher.dispatch(UndoAction.create());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return this.success('Undo successful', { commandsUndone: commandsToUndo });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
export * from './handlers/count-elements-mcp-tool-handler';
|
|
18
|
+
export * from './handlers/create-edges-mcp-tool-handler';
|
|
19
|
+
export * from './handlers/create-nodes-mcp-tool-handler';
|
|
20
|
+
export * from './handlers/delete-elements-mcp-tool-handler';
|
|
21
|
+
export * from './handlers/diagram-model-mcp-tool-handler';
|
|
22
|
+
export * from './handlers/element-types-mcp-tool-handler';
|
|
23
|
+
export * from './handlers/get-selection-mcp-tool-handler';
|
|
24
|
+
export * from './handlers/layout-mcp-tool-handler';
|
|
25
|
+
export * from './handlers/modify-edges-mcp-tool-handler';
|
|
26
|
+
export * from './handlers/modify-nodes-mcp-tool-handler';
|
|
27
|
+
export * from './handlers/query-elements-mcp-tool-handler';
|
|
28
|
+
export * from './handlers/redo-mcp-tool-handler';
|
|
29
|
+
export * from './handlers/save-model-mcp-tool-handler';
|
|
30
|
+
export * from './handlers/session-info-mcp-tool-handler';
|
|
31
|
+
export * from './handlers/set-selection-mcp-tool-handler';
|
|
32
|
+
export * from './handlers/set-view-mcp-tool-handler';
|
|
33
|
+
export * from './handlers/undo-mcp-tool-handler';
|
|
34
|
+
export * from './handlers/validate-diagram-mcp-tool-handler';
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { expect } from 'chai';
|
|
18
|
+
import { interfaces } from 'inversify';
|
|
19
|
+
import { SetViewMcpToolHandler } from './handlers/set-view-mcp-tool-handler';
|
|
20
|
+
import { CreateEdgesMcpToolHandler } from './handlers/create-edges-mcp-tool-handler';
|
|
21
|
+
import { CreateNodesMcpToolHandler } from './handlers/create-nodes-mcp-tool-handler';
|
|
22
|
+
import { DeleteElementsMcpToolHandler } from './handlers/delete-elements-mcp-tool-handler';
|
|
23
|
+
import { QueryElementsMcpToolHandler } from './handlers/query-elements-mcp-tool-handler';
|
|
24
|
+
import { GetSelectionMcpToolHandler } from './handlers/get-selection-mcp-tool-handler';
|
|
25
|
+
import { ModifyEdgesMcpToolHandler } from './handlers/modify-edges-mcp-tool-handler';
|
|
26
|
+
import { ModifyNodesMcpToolHandler } from './handlers/modify-nodes-mcp-tool-handler';
|
|
27
|
+
import { RedoMcpToolHandler } from './handlers/redo-mcp-tool-handler';
|
|
28
|
+
import { SaveModelMcpToolHandler } from './handlers/save-model-mcp-tool-handler';
|
|
29
|
+
import { UndoMcpToolHandler } from './handlers/undo-mcp-tool-handler';
|
|
30
|
+
import { ValidateDiagramMcpToolHandler } from './handlers/validate-diagram-mcp-tool-handler';
|
|
31
|
+
|
|
32
|
+
interface AnnotatedHandler {
|
|
33
|
+
readOnlyHint?: boolean;
|
|
34
|
+
destructiveHint?: boolean;
|
|
35
|
+
idempotentHint?: boolean;
|
|
36
|
+
openWorldHint?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Reads the four annotation hint fields off a freshly `new`-ed handler. Mirrors how the launcher
|
|
41
|
+
* reads metadata via `new Constructor()` at MCP-session-init (see
|
|
42
|
+
* `mcp-server-launcher.ts#registerDiagramScopeTools`); no DI wiring needed because the fields
|
|
43
|
+
* are plain class properties with literal initializers.
|
|
44
|
+
*/
|
|
45
|
+
function hintsOf(Constructor: interfaces.Newable<AnnotatedHandler>): AnnotatedHandler {
|
|
46
|
+
const handler = new Constructor();
|
|
47
|
+
return {
|
|
48
|
+
readOnlyHint: handler.readOnlyHint,
|
|
49
|
+
destructiveHint: handler.destructiveHint,
|
|
50
|
+
idempotentHint: handler.idempotentHint,
|
|
51
|
+
openWorldHint: handler.openWorldHint
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const READ_DEFAULT: AnnotatedHandler = {
|
|
56
|
+
readOnlyHint: true,
|
|
57
|
+
destructiveHint: undefined,
|
|
58
|
+
idempotentHint: undefined,
|
|
59
|
+
openWorldHint: false
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const OPERATION_DEFAULT: AnnotatedHandler = {
|
|
63
|
+
readOnlyHint: false,
|
|
64
|
+
destructiveHint: false,
|
|
65
|
+
idempotentHint: false,
|
|
66
|
+
openWorldHint: false
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
describe('Tool annotations · per-handler matrix', () => {
|
|
70
|
+
describe('read-style handlers (inherit base default)', () => {
|
|
71
|
+
const readStyleHandlers: Array<[string, interfaces.Newable<AnnotatedHandler>]> = [
|
|
72
|
+
['query-elements', QueryElementsMcpToolHandler],
|
|
73
|
+
['get-selection', GetSelectionMcpToolHandler],
|
|
74
|
+
['validate-diagram', ValidateDiagramMcpToolHandler]
|
|
75
|
+
];
|
|
76
|
+
readStyleHandlers.forEach(([name, Constructor]) => {
|
|
77
|
+
it(`${name} matches the read-style default`, () => {
|
|
78
|
+
expect(hintsOf(Constructor)).to.deep.equal(READ_DEFAULT);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('operation-style handlers (override to write defaults)', () => {
|
|
84
|
+
const operationStyleHandlers: Array<[string, interfaces.Newable<AnnotatedHandler>]> = [
|
|
85
|
+
['create-nodes', CreateNodesMcpToolHandler],
|
|
86
|
+
['create-edges', CreateEdgesMcpToolHandler],
|
|
87
|
+
['modify-nodes', ModifyNodesMcpToolHandler],
|
|
88
|
+
['modify-edges', ModifyEdgesMcpToolHandler],
|
|
89
|
+
['undo', UndoMcpToolHandler],
|
|
90
|
+
['redo', RedoMcpToolHandler]
|
|
91
|
+
];
|
|
92
|
+
operationStyleHandlers.forEach(([name, Constructor]) => {
|
|
93
|
+
it(`${name} matches the operation-style default`, () => {
|
|
94
|
+
expect(hintsOf(Constructor)).to.deep.equal(OPERATION_DEFAULT);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('per-handler overrides', () => {
|
|
100
|
+
it('delete-elements is destructiveHint:true (single-flag override)', () => {
|
|
101
|
+
expect(hintsOf(DeleteElementsMcpToolHandler)).to.deep.equal({ ...OPERATION_DEFAULT, destructiveHint: true });
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('save-model is NOT readOnly (writes to disk) and NOT destructive (creative)', () => {
|
|
105
|
+
// Spec: `readOnlyHint` means "does not modify its environment" — disk IS environment.
|
|
106
|
+
// `destructiveHint` is for irreversible deletion / data loss; save is creative.
|
|
107
|
+
// Save-model extends the read base (not the operation base) because it doesn't
|
|
108
|
+
// dispatch a model-mutating Operation, but we override the flat fields explicitly.
|
|
109
|
+
expect(hintsOf(SaveModelMcpToolHandler)).to.deep.equal({
|
|
110
|
+
readOnlyHint: false,
|
|
111
|
+
destructiveHint: false,
|
|
112
|
+
idempotentHint: false,
|
|
113
|
+
openWorldHint: false
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('set-view drops the read-only claim (viewport IS environment)', () => {
|
|
118
|
+
// Inherits from the read base, which would claim readOnlyHint:true. Override flips
|
|
119
|
+
// it: dispatching a viewport action mutates client-side state, even though no
|
|
120
|
+
// diagram model bytes change.
|
|
121
|
+
expect(hintsOf(SetViewMcpToolHandler)).to.deep.equal({
|
|
122
|
+
readOnlyHint: false,
|
|
123
|
+
destructiveHint: undefined,
|
|
124
|
+
idempotentHint: undefined,
|
|
125
|
+
openWorldHint: false
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe('toRegistrationConfig() assembles the annotations object the SDK expects', () => {
|
|
131
|
+
it('aggregates the flat fields into the SDK ToolAnnotations shape', () => {
|
|
132
|
+
const config = new DeleteElementsMcpToolHandler().toRegistrationConfig();
|
|
133
|
+
expect(config.annotations).to.deep.equal({
|
|
134
|
+
readOnlyHint: false,
|
|
135
|
+
destructiveHint: true,
|
|
136
|
+
idempotentHint: false,
|
|
137
|
+
openWorldHint: false
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
export * from './markdown-util';
|
|
18
|
+
export * from './mcp-util';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* This function serializes a given array of objects into a Markdown table string.
|
|
19
|
+
*/
|
|
20
|
+
export function objectArrayToMarkdownTable(data: Record<string, any>[]): string {
|
|
21
|
+
if (!data.length) {
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const headers = Object.keys(data[0]);
|
|
26
|
+
const headerRow = `| ${headers.join(' | ')} |`;
|
|
27
|
+
const separatorRow = `| ${headers.map(() => '---').join(' | ')} |`;
|
|
28
|
+
|
|
29
|
+
const dataRows = data.map((obj: Record<string, any>) => {
|
|
30
|
+
const rowString = headers
|
|
31
|
+
.map(header => {
|
|
32
|
+
const value = obj[header] ?? '';
|
|
33
|
+
if (typeof value === 'object') {
|
|
34
|
+
return JSON.stringify(value).replace(/["{}|]/g, '');
|
|
35
|
+
}
|
|
36
|
+
// Escape pipe characters in scalar values so they don't break the table layout
|
|
37
|
+
return String(value).replace(/\|/g, '\\|');
|
|
38
|
+
})
|
|
39
|
+
.join(' | ');
|
|
40
|
+
return `| ${rowString} |`;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return [headerRow, separatorRow, ...dataRows].join('\n');
|
|
44
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2025-2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Formats a list of per-input notices (errors, warnings, …) as a Markdown bullet list with a
|
|
19
|
+
* leading heading. Returns an empty string when `notices` is empty so callers can append
|
|
20
|
+
* unconditionally.
|
|
21
|
+
*/
|
|
22
|
+
export function formatNoticeList(kind: string, notices: string[]): string {
|
|
23
|
+
if (notices.length === 0) return '';
|
|
24
|
+
return `\nThe following ${kind} occurred:\n${notices.map(notice => `- ${notice}`).join('\n')}`;
|
|
25
|
+
}
|