@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,247 @@
|
|
|
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
|
+
import { ActionDispatcher, ClientSessionManager, RequestAction, ResponseAction } from '@eclipse-glsp/server';
|
|
18
|
+
import { CallToolResult, GetPromptResult, ReadResourceResult } from '@modelcontextprotocol/sdk/types';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* **Note on terminology** — "session" in this file always refers to a **GLSP client session**
|
|
22
|
+
* (one open diagram, tracked by core's `ClientSessionManager`). It is unrelated to the
|
|
23
|
+
* **MCP session** concept used in {@link mcp-session.ts} and {@link mcp-http-transport.ts}
|
|
24
|
+
* (one MCP client connection to the HTTP endpoint). The two have independent lifetimes — see
|
|
25
|
+
* the docstring at the top of `mcp-session.ts` for the full disambiguation.
|
|
26
|
+
*
|
|
27
|
+
* Diagram-scope handler bases ({@link AbstractMcpDiagramToolHandler} et al.) inject their per-session
|
|
28
|
+
* services directly per GLSP session. The launcher's dispatcher resolves the
|
|
29
|
+
* {@link McpDiagramScopedInput.sessionId} input field via `ClientSessionManager` to route a
|
|
30
|
+
* tool/resource/prompt call to the right per-session handler instance.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
// ─── MCP-protocol type aliases (Mcp prefix on GLSP-side) ─────────────────────
|
|
34
|
+
|
|
35
|
+
/** Result returned from `tools/call`. Aliased so handler signatures read in GLSP terms. */
|
|
36
|
+
export type McpToolResult = CallToolResult;
|
|
37
|
+
/** Result returned from `resources/read`. Aliased so handler signatures read in GLSP terms. */
|
|
38
|
+
export type McpResourceResult = ReadResourceResult;
|
|
39
|
+
/** Result returned from `prompts/get`. Aliased so handler signatures read in GLSP terms. */
|
|
40
|
+
export type McpPromptResult = GetPromptResult;
|
|
41
|
+
/** One content part of a {@link McpToolResult}. Tool results are an array of these. */
|
|
42
|
+
export type McpToolResultContent = CallToolResult['content'][number];
|
|
43
|
+
/** One content part of a {@link McpResourceResult}. Resource reads are an array of these. */
|
|
44
|
+
export type McpResourceResultContent = ReadResourceResult['contents'][number];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Single-content body returned by a session-scope resource handler. The base wraps it with
|
|
48
|
+
* `uri` + the handler's declared `mimeType` to produce the SDK `ReadResourceResult`.
|
|
49
|
+
*
|
|
50
|
+
* `structured` is dual-emit overflow used only when the resource is exposed as a tool
|
|
51
|
+
* (`toolAlternativeInputSchema` set) AND the handler also declares `toolAlternativeOutputSchema`.
|
|
52
|
+
* The framework forwards it to `CallToolResult.structuredContent`. Resource-protocol reads ignore
|
|
53
|
+
* it — the spec has no equivalent slot on `ReadResourceResult`.
|
|
54
|
+
*/
|
|
55
|
+
export type McpResourceContent = ({ text: string } | { blob: string }) & { structured?: McpStructuredContent };
|
|
56
|
+
|
|
57
|
+
/** Structured payload for `CallToolResult.structuredContent`. The MCP spec requires an object. */
|
|
58
|
+
export interface McpStructuredContent {
|
|
59
|
+
[key: string]: unknown;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ─── Errors ──────────────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Throw inside `createResult` to surface an expected, user-facing error to the MCP client.
|
|
66
|
+
* The base class catches it and emits an `isError: true` result. Unexpected errors
|
|
67
|
+
* (non-`McpToolError`) are logged and their extracted message is surfaced too.
|
|
68
|
+
*
|
|
69
|
+
* Use one of the named subclasses (`McpMissingParamError`, `McpSessionNotFoundError`,
|
|
70
|
+
* `McpReadOnlyError`, `McpElementsNotFoundError`, `McpRequestTimeoutError`) where they fit;
|
|
71
|
+
* otherwise throw `new McpToolError('context-specific message')`.
|
|
72
|
+
*/
|
|
73
|
+
export class McpToolError extends Error {
|
|
74
|
+
constructor(
|
|
75
|
+
message: string,
|
|
76
|
+
readonly cause?: unknown
|
|
77
|
+
) {
|
|
78
|
+
super(message);
|
|
79
|
+
this.name = 'McpToolError';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Thrown when a required input parameter is missing or empty. */
|
|
84
|
+
export class McpMissingParamError extends McpToolError {
|
|
85
|
+
constructor(readonly paramName: string) {
|
|
86
|
+
super(`No '${paramName}' provided.`);
|
|
87
|
+
this.name = 'McpMissingParamError';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Thrown when no GLSP client session matches the provided id. */
|
|
92
|
+
export class McpSessionNotFoundError extends McpToolError {
|
|
93
|
+
constructor(readonly sessionId: string) {
|
|
94
|
+
super(`Session not found: ${sessionId}`);
|
|
95
|
+
this.name = 'McpSessionNotFoundError';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Thrown when a write-style operation targets a read-only model. */
|
|
100
|
+
export class McpReadOnlyError extends McpToolError {
|
|
101
|
+
constructor() {
|
|
102
|
+
super('Model is read-only.');
|
|
103
|
+
this.name = 'McpReadOnlyError';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Thrown by handlers that look up elements by id and find some absent from the model. */
|
|
108
|
+
export class McpElementsNotFoundError extends McpToolError {
|
|
109
|
+
constructor(readonly missingIds: readonly string[]) {
|
|
110
|
+
super(`Element(s) not found: ${missingIds.join(', ')}`);
|
|
111
|
+
this.name = 'McpElementsNotFoundError';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Thrown when a request/response round-trip (`ActionDispatcher.requestUntil`) exceeds its timeout. */
|
|
116
|
+
export class McpRequestTimeoutError extends McpToolError {
|
|
117
|
+
constructor(
|
|
118
|
+
readonly operation: string,
|
|
119
|
+
readonly timeoutMs: number
|
|
120
|
+
) {
|
|
121
|
+
super(`${operation} timed out after ${timeoutMs}ms.`);
|
|
122
|
+
this.name = 'McpRequestTimeoutError';
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Catch `McpToolError` thrown by pre-handler routing (e.g. `requireDiagramToolHandler`) and
|
|
130
|
+
* convert it to an `isError: true` tool result. Without this, those throws surface as
|
|
131
|
+
* JSON-RPC `-32603` instead of a self-correctable tool error.
|
|
132
|
+
*/
|
|
133
|
+
export async function runWithToolErrorEnvelope(producer: () => Promise<CallToolResult>): Promise<CallToolResult> {
|
|
134
|
+
try {
|
|
135
|
+
return await producer();
|
|
136
|
+
} catch (err: unknown) {
|
|
137
|
+
if (err instanceof McpToolError) {
|
|
138
|
+
return toolErrorResult(err.message, errorCodeFor(err));
|
|
139
|
+
}
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Stable codes surfaced in `CallToolResult.structuredContent.code` so the LLM can self-correct on a known taxonomy. */
|
|
145
|
+
export const McpToolErrorCodes = {
|
|
146
|
+
/** GLSP session disposed mid-call (server shutdown or session disposal). */
|
|
147
|
+
SessionDisposed: 'session-disposed'
|
|
148
|
+
} as const;
|
|
149
|
+
export type McpToolErrorCode = (typeof McpToolErrorCodes)[keyof typeof McpToolErrorCodes];
|
|
150
|
+
|
|
151
|
+
/** True when `err` is a GLSP-session-disposed rejection from the action dispatcher's dispose hooks. */
|
|
152
|
+
export function isSessionDisposedError(err: unknown): boolean {
|
|
153
|
+
if (!(err instanceof Error)) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
return /ActionDispatcher disposed|cancelled: dispatcher disposed/.test(err.message);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Resolve a known `McpToolErrorCode` for an error, or `undefined` if it is generic. */
|
|
160
|
+
export function errorCodeFor(err: unknown): McpToolErrorCode | undefined {
|
|
161
|
+
if (isSessionDisposedError(err)) {
|
|
162
|
+
return McpToolErrorCodes.SessionDisposed;
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Build an `isError: true` tool result, attaching `structuredContent: { code }` when known. */
|
|
168
|
+
export function toolErrorResult(message: string, code?: McpToolErrorCode): CallToolResult {
|
|
169
|
+
return {
|
|
170
|
+
isError: true,
|
|
171
|
+
content: [{ type: 'text', text: message }],
|
|
172
|
+
...(code ? { structuredContent: { code } } : {})
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Returns a useful message for a value caught from a `throw`. */
|
|
177
|
+
export function extractErrorMessage(error: unknown): string {
|
|
178
|
+
if (error instanceof Error) {
|
|
179
|
+
return error.message;
|
|
180
|
+
}
|
|
181
|
+
if (typeof error === 'string') {
|
|
182
|
+
return error;
|
|
183
|
+
}
|
|
184
|
+
return String(error);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Dispatch a request action and await its response, surfacing failures uniformly.
|
|
189
|
+
*
|
|
190
|
+
* The `ActionDispatcher.requestUntil` API today returns `undefined` on timeout (default
|
|
191
|
+
* `rejectOnTimeout: false`) and throws when the client emits a `RejectAction`. Handlers
|
|
192
|
+
* that consume it have to branch on both. This helper consolidates that branching:
|
|
193
|
+
*
|
|
194
|
+
* - On client-side `RejectAction` → throws `McpToolError` with `${label} failed: <inner>`.
|
|
195
|
+
* - On timeout (undefined return) → throws `McpRequestTimeoutError(label, timeoutMs)`.
|
|
196
|
+
* - Otherwise → returns the typed response.
|
|
197
|
+
*
|
|
198
|
+
* Prefer the base-class methods (`OperationMcpDiagramToolHandler.requestAction` /
|
|
199
|
+
* `AbstractMcpDiagramResourceHandler.requestAction`) over calling this directly — they default
|
|
200
|
+
* the label to the handler's `name` field and pass `this.actionDispatcher`. This free
|
|
201
|
+
* function is the canonical implementation behind both.
|
|
202
|
+
*/
|
|
203
|
+
export async function requestActionOrFail<R extends ResponseAction>(
|
|
204
|
+
dispatcher: ActionDispatcher,
|
|
205
|
+
request: RequestAction<R>,
|
|
206
|
+
timeoutMs: number,
|
|
207
|
+
label: string
|
|
208
|
+
): Promise<R> {
|
|
209
|
+
let response: R | undefined;
|
|
210
|
+
try {
|
|
211
|
+
response = await dispatcher.requestUntil<R>(request, timeoutMs);
|
|
212
|
+
} catch (err: unknown) {
|
|
213
|
+
// Preserve the original rejection error as `cause` so adopters whose `RejectAction`
|
|
214
|
+
// sets `detail` (which core flattens into the message via `${message}: ${detail}`) can
|
|
215
|
+
// still inspect the underlying object — both for diagnostic logging and for an LLM
|
|
216
|
+
// surface that wants to disambiguate transient vs. permanent failures.
|
|
217
|
+
throw new McpToolError(`${label} failed: ${extractErrorMessage(err)}`, err);
|
|
218
|
+
}
|
|
219
|
+
if (!response) {
|
|
220
|
+
throw new McpRequestTimeoutError(label, timeoutMs);
|
|
221
|
+
}
|
|
222
|
+
return response;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Pick a target session for server-scope handlers (e.g. prompts) where `sessionId` is optional.
|
|
227
|
+
* Resolution: explicit id (validated to exist) → single open session → throw with the available
|
|
228
|
+
* ids when ambiguous, throw when none open. Keeps user-invoked entry points like slash-command
|
|
229
|
+
* prompts ergonomic in the common single-diagram case while staying explicit when not.
|
|
230
|
+
*/
|
|
231
|
+
export function resolveActiveSessionId(clientSessionManager: ClientSessionManager, explicitSessionId: string | undefined): string {
|
|
232
|
+
const sessions = clientSessionManager.getSessions();
|
|
233
|
+
if (explicitSessionId) {
|
|
234
|
+
if (!sessions.some(session => session.id === explicitSessionId)) {
|
|
235
|
+
throw new McpToolError(`Unknown sessionId: ${explicitSessionId}`);
|
|
236
|
+
}
|
|
237
|
+
return explicitSessionId;
|
|
238
|
+
}
|
|
239
|
+
if (sessions.length === 0) {
|
|
240
|
+
throw new McpToolError('No open diagram sessions to target.');
|
|
241
|
+
}
|
|
242
|
+
if (sessions.length === 1) {
|
|
243
|
+
return sessions[0].id;
|
|
244
|
+
}
|
|
245
|
+
const ids = sessions.map(session => `'${session.id}'`).join(', ');
|
|
246
|
+
throw new McpToolError(`Multiple sessions open (${ids}); pass \`sessionId\` to disambiguate.`);
|
|
247
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
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 { Logger, NullLogger } from '@eclipse-glsp/server';
|
|
18
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
19
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
20
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
21
|
+
import { expect } from 'chai';
|
|
22
|
+
import { Container, ContainerModule } from 'inversify';
|
|
23
|
+
import * as z from 'zod/v4';
|
|
24
|
+
import { McpHttpTransport } from './mcp-http-transport';
|
|
25
|
+
import { McpServerOptions } from './mcp-options';
|
|
26
|
+
import { rawHttpRequest } from './raw-http.spec';
|
|
27
|
+
|
|
28
|
+
function buildTransport(): McpHttpTransport {
|
|
29
|
+
const container = new Container();
|
|
30
|
+
container.load(
|
|
31
|
+
new ContainerModule(bind => {
|
|
32
|
+
bind(Logger).toConstantValue(new NullLogger());
|
|
33
|
+
const opts = new McpServerOptions();
|
|
34
|
+
opts.values = {};
|
|
35
|
+
bind(McpServerOptions).toConstantValue(opts);
|
|
36
|
+
bind(McpHttpTransport).toSelf().inSingletonScope();
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
return container.get<McpHttpTransport>(McpHttpTransport);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* WN-058 — End-to-end smoke test that boots {@link McpHttpTransport},
|
|
44
|
+
* connects a real SDK MCP client over Streamable HTTP, and exercises a tool
|
|
45
|
+
* round-trip (`echo`). Validates that the transport implements the protocol
|
|
46
|
+
* conformantly without depending on the GLSP handler stack.
|
|
47
|
+
*/
|
|
48
|
+
describe('McpHttpTransport (WN-058 e2e — real MCP SDK client over HTTP)', () => {
|
|
49
|
+
let httpServer: McpHttpTransport | undefined;
|
|
50
|
+
let client: Client | undefined;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Idempotent client close: a test that already tore the SDK client down (e.g. after a
|
|
54
|
+
* spec-mandated DELETE on the same session) leaves the local `client` ref pointing at a
|
|
55
|
+
* closed instance. `Client.close()` is safe to call twice on the SDK side, but we still
|
|
56
|
+
* swallow any throw so afterEach is robust under partial-progress failures too.
|
|
57
|
+
*/
|
|
58
|
+
async function safeClose(target: Client | undefined): Promise<void> {
|
|
59
|
+
if (!target) return;
|
|
60
|
+
try {
|
|
61
|
+
await target.close();
|
|
62
|
+
} catch {
|
|
63
|
+
/* ignore — best effort */
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
afterEach(async () => {
|
|
68
|
+
await safeClose(client);
|
|
69
|
+
client = undefined;
|
|
70
|
+
httpServer?.dispose();
|
|
71
|
+
httpServer = undefined;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('round-trips tools/list and tools/call against a registered echo tool', async () => {
|
|
75
|
+
httpServer = buildTransport();
|
|
76
|
+
|
|
77
|
+
// Wire one fresh `McpServer` per accepted session, register an `echo` tool,
|
|
78
|
+
// and let the server attach to the transport. Mirrors what `McpServerLauncher`
|
|
79
|
+
// does; kept inline here so the test exercises only the transport path.
|
|
80
|
+
httpServer.onSessionInitialized(session => {
|
|
81
|
+
const mcpServer = new McpServer({ name: 'glsp-test', version: '1.0.0' }, { capabilities: {} });
|
|
82
|
+
mcpServer.registerTool(
|
|
83
|
+
'echo',
|
|
84
|
+
{ description: 'Returns the supplied message verbatim.', inputSchema: { message: z.string() } },
|
|
85
|
+
async ({ message }) => ({ content: [{ type: 'text', text: message }] })
|
|
86
|
+
);
|
|
87
|
+
mcpServer.connect(session);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const endpoint = await httpServer.start({
|
|
91
|
+
port: 0,
|
|
92
|
+
host: '127.0.0.1',
|
|
93
|
+
route: '/mcp',
|
|
94
|
+
name: 'glsp-test',
|
|
95
|
+
options: { dataMode: 'tools' }
|
|
96
|
+
});
|
|
97
|
+
expect(endpoint.url, 'transport must report a URL after start()').to.be.a('string');
|
|
98
|
+
|
|
99
|
+
client = new Client({ name: 'wn-058-test-client', version: '1.0.0' });
|
|
100
|
+
await client.connect(new StreamableHTTPClientTransport(new URL(endpoint.url!)));
|
|
101
|
+
|
|
102
|
+
const tools = await client.listTools();
|
|
103
|
+
expect(tools.tools.map(tool => tool.name)).to.include('echo');
|
|
104
|
+
|
|
105
|
+
const result = await client.callTool({ name: 'echo', arguments: { message: 'hello GLSP' } });
|
|
106
|
+
expect(result.isError).to.not.equal(true);
|
|
107
|
+
expect(result.content).to.have.lengthOf(1);
|
|
108
|
+
const [block] = result.content as Array<{ type: string; text?: string }>;
|
|
109
|
+
expect(block.type).to.equal('text');
|
|
110
|
+
expect(block.text).to.equal('hello GLSP');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('DELETE /mcp terminates the session; subsequent POSTs with the same id return 404 (§ #5)', async () => {
|
|
114
|
+
httpServer = buildTransport();
|
|
115
|
+
httpServer.onSessionInitialized(session => {
|
|
116
|
+
const mcpServer = new McpServer({ name: 'glsp-test', version: '1.0.0' }, { capabilities: {} });
|
|
117
|
+
mcpServer.connect(session);
|
|
118
|
+
});
|
|
119
|
+
const endpoint = await httpServer.start({
|
|
120
|
+
port: 0,
|
|
121
|
+
host: '127.0.0.1',
|
|
122
|
+
route: '/mcp',
|
|
123
|
+
name: 'glsp-test',
|
|
124
|
+
options: { dataMode: 'tools' }
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
client = new Client({ name: 'delete-smoke-test', version: '1.0.0' });
|
|
128
|
+
const clientTransport = new StreamableHTTPClientTransport(new URL(endpoint.url!));
|
|
129
|
+
await client.connect(clientTransport);
|
|
130
|
+
const sessionId = clientTransport.sessionId;
|
|
131
|
+
expect(sessionId, 'SDK transport should expose the minted session id after initialize').to.be.a('string');
|
|
132
|
+
|
|
133
|
+
const { port } = await httpServer.getAddress();
|
|
134
|
+
|
|
135
|
+
// 1. Spec § Session Management #5 — DELETE terminates the session.
|
|
136
|
+
const deleteRes = await rawHttpRequest(port, 'DELETE', { 'mcp-session-id': sessionId! });
|
|
137
|
+
expect(deleteRes.status, 'DELETE should succeed for an active session').to.be.lessThan(300);
|
|
138
|
+
|
|
139
|
+
// 2. After termination, the same id MUST be rejected with 404 (§ #3) — proves the
|
|
140
|
+
// session was actually removed, not just acked.
|
|
141
|
+
const followUp = await rawHttpRequest(
|
|
142
|
+
port,
|
|
143
|
+
'POST',
|
|
144
|
+
{ 'mcp-session-id': sessionId! },
|
|
145
|
+
{ jsonrpc: '2.0', id: 1, method: 'tools/list', params: {} }
|
|
146
|
+
);
|
|
147
|
+
expect(followUp.status).to.equal(404);
|
|
148
|
+
const payload = JSON.parse(followUp.body);
|
|
149
|
+
expect(payload.error.code).to.equal(-32001);
|
|
150
|
+
});
|
|
151
|
+
});
|