@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.
Files changed (303) hide show
  1. package/LICENSE +642 -0
  2. package/README.md +57 -0
  3. package/lib/index.d.ts +23 -0
  4. package/lib/index.d.ts.map +1 -0
  5. package/lib/index.js +41 -0
  6. package/lib/index.js.map +1 -0
  7. package/lib/prompts/handlers/describe-diagram-mcp-prompt-handler.d.ts +43 -0
  8. package/lib/prompts/handlers/describe-diagram-mcp-prompt-handler.d.ts.map +1 -0
  9. package/lib/prompts/handlers/describe-diagram-mcp-prompt-handler.js +96 -0
  10. package/lib/prompts/handlers/describe-diagram-mcp-prompt-handler.js.map +1 -0
  11. package/lib/prompts/handlers/suggest-improvements-mcp-prompt-handler.d.ts +43 -0
  12. package/lib/prompts/handlers/suggest-improvements-mcp-prompt-handler.d.ts.map +1 -0
  13. package/lib/prompts/handlers/suggest-improvements-mcp-prompt-handler.js +95 -0
  14. package/lib/prompts/handlers/suggest-improvements-mcp-prompt-handler.js.map +1 -0
  15. package/lib/prompts/index.d.ts +18 -0
  16. package/lib/prompts/index.d.ts.map +1 -0
  17. package/lib/prompts/index.js +34 -0
  18. package/lib/prompts/index.js.map +1 -0
  19. package/lib/resources/handlers/diagram-png-mcp-resource-handler.d.ts +81 -0
  20. package/lib/resources/handlers/diagram-png-mcp-resource-handler.d.ts.map +1 -0
  21. package/lib/resources/handlers/diagram-png-mcp-resource-handler.js +174 -0
  22. package/lib/resources/handlers/diagram-png-mcp-resource-handler.js.map +1 -0
  23. package/lib/resources/handlers/diagram-svg-mcp-resource-handler.d.ts +52 -0
  24. package/lib/resources/handlers/diagram-svg-mcp-resource-handler.d.ts.map +1 -0
  25. package/lib/resources/handlers/diagram-svg-mcp-resource-handler.js +96 -0
  26. package/lib/resources/handlers/diagram-svg-mcp-resource-handler.js.map +1 -0
  27. package/lib/resources/index.d.ts +20 -0
  28. package/lib/resources/index.d.ts.map +1 -0
  29. package/lib/resources/index.js +36 -0
  30. package/lib/resources/index.js.map +1 -0
  31. package/lib/resources/services/element-types-provider.d.ts +65 -0
  32. package/lib/resources/services/element-types-provider.d.ts.map +1 -0
  33. package/lib/resources/services/element-types-provider.js +81 -0
  34. package/lib/resources/services/element-types-provider.js.map +1 -0
  35. package/lib/resources/services/mcp-model-serializer.d.ts +78 -0
  36. package/lib/resources/services/mcp-model-serializer.d.ts.map +1 -0
  37. package/lib/resources/services/mcp-model-serializer.js +188 -0
  38. package/lib/resources/services/mcp-model-serializer.js.map +1 -0
  39. package/lib/server/glsp-mcp-server.d.ts +82 -0
  40. package/lib/server/glsp-mcp-server.d.ts.map +1 -0
  41. package/lib/server/glsp-mcp-server.js +140 -0
  42. package/lib/server/glsp-mcp-server.js.map +1 -0
  43. package/lib/server/index.d.ts +37 -0
  44. package/lib/server/index.d.ts.map +1 -0
  45. package/lib/server/index.js +57 -0
  46. package/lib/server/index.js.map +1 -0
  47. package/lib/server/lru-event-store.d.ts +53 -0
  48. package/lib/server/lru-event-store.d.ts.map +1 -0
  49. package/lib/server/lru-event-store.js +100 -0
  50. package/lib/server/lru-event-store.js.map +1 -0
  51. package/lib/server/mcp-diagram-handler-dispatcher.d.ts +144 -0
  52. package/lib/server/mcp-diagram-handler-dispatcher.d.ts.map +1 -0
  53. package/lib/server/mcp-diagram-handler-dispatcher.js +382 -0
  54. package/lib/server/mcp-diagram-handler-dispatcher.js.map +1 -0
  55. package/lib/server/mcp-diagram-module.d.ts +123 -0
  56. package/lib/server/mcp-diagram-module.d.ts.map +1 -0
  57. package/lib/server/mcp-diagram-module.js +186 -0
  58. package/lib/server/mcp-diagram-module.js.map +1 -0
  59. package/lib/server/mcp-diagram-prompt-handler-registry.d.ts +33 -0
  60. package/lib/server/mcp-diagram-prompt-handler-registry.d.ts.map +1 -0
  61. package/lib/server/mcp-diagram-prompt-handler-registry.js +76 -0
  62. package/lib/server/mcp-diagram-prompt-handler-registry.js.map +1 -0
  63. package/lib/server/mcp-diagram-resource-handler-registry.d.ts +35 -0
  64. package/lib/server/mcp-diagram-resource-handler-registry.d.ts.map +1 -0
  65. package/lib/server/mcp-diagram-resource-handler-registry.js +94 -0
  66. package/lib/server/mcp-diagram-resource-handler-registry.js.map +1 -0
  67. package/lib/server/mcp-diagram-tool-handler-registry.d.ts +57 -0
  68. package/lib/server/mcp-diagram-tool-handler-registry.d.ts.map +1 -0
  69. package/lib/server/mcp-diagram-tool-handler-registry.js +111 -0
  70. package/lib/server/mcp-diagram-tool-handler-registry.js.map +1 -0
  71. package/lib/server/mcp-handler-shared.d.ts +142 -0
  72. package/lib/server/mcp-handler-shared.d.ts.map +1 -0
  73. package/lib/server/mcp-handler-shared.js +199 -0
  74. package/lib/server/mcp-handler-shared.js.map +1 -0
  75. package/lib/server/mcp-http-transport.d.ts +93 -0
  76. package/lib/server/mcp-http-transport.d.ts.map +1 -0
  77. package/lib/server/mcp-http-transport.js +350 -0
  78. package/lib/server/mcp-http-transport.js.map +1 -0
  79. package/lib/server/mcp-id-alias-service.d.ts +70 -0
  80. package/lib/server/mcp-id-alias-service.d.ts.map +1 -0
  81. package/lib/server/mcp-id-alias-service.js +85 -0
  82. package/lib/server/mcp-id-alias-service.js.map +1 -0
  83. package/lib/server/mcp-input-schemas.d.ts +73 -0
  84. package/lib/server/mcp-input-schemas.d.ts.map +1 -0
  85. package/lib/server/mcp-input-schemas.js +67 -0
  86. package/lib/server/mcp-input-schemas.js.map +1 -0
  87. package/lib/server/mcp-label-provider.d.ts +45 -0
  88. package/lib/server/mcp-label-provider.d.ts.map +1 -0
  89. package/lib/server/mcp-label-provider.js +42 -0
  90. package/lib/server/mcp-label-provider.js.map +1 -0
  91. package/lib/server/mcp-log-level-registry.d.ts +54 -0
  92. package/lib/server/mcp-log-level-registry.d.ts.map +1 -0
  93. package/lib/server/mcp-log-level-registry.js +80 -0
  94. package/lib/server/mcp-log-level-registry.js.map +1 -0
  95. package/lib/server/mcp-logger.d.ts +59 -0
  96. package/lib/server/mcp-logger.d.ts.map +1 -0
  97. package/lib/server/mcp-logger.js +104 -0
  98. package/lib/server/mcp-logger.js.map +1 -0
  99. package/lib/server/mcp-mime-types.d.ts +28 -0
  100. package/lib/server/mcp-mime-types.d.ts.map +1 -0
  101. package/lib/server/mcp-mime-types.js +18 -0
  102. package/lib/server/mcp-mime-types.js.map +1 -0
  103. package/lib/server/mcp-options.d.ts +39 -0
  104. package/lib/server/mcp-options.d.ts.map +1 -0
  105. package/lib/server/mcp-options.js +53 -0
  106. package/lib/server/mcp-options.js.map +1 -0
  107. package/lib/server/mcp-progress-reporter.d.ts +48 -0
  108. package/lib/server/mcp-progress-reporter.d.ts.map +1 -0
  109. package/lib/server/mcp-progress-reporter.js +66 -0
  110. package/lib/server/mcp-progress-reporter.js.map +1 -0
  111. package/lib/server/mcp-prompt-handler.d.ts +120 -0
  112. package/lib/server/mcp-prompt-handler.d.ts.map +1 -0
  113. package/lib/server/mcp-prompt-handler.js +131 -0
  114. package/lib/server/mcp-prompt-handler.js.map +1 -0
  115. package/lib/server/mcp-request-context.d.ts +37 -0
  116. package/lib/server/mcp-request-context.d.ts.map +1 -0
  117. package/lib/server/mcp-request-context.js +37 -0
  118. package/lib/server/mcp-request-context.js.map +1 -0
  119. package/lib/server/mcp-resource-handler.d.ts +212 -0
  120. package/lib/server/mcp-resource-handler.d.ts.map +1 -0
  121. package/lib/server/mcp-resource-handler.js +298 -0
  122. package/lib/server/mcp-resource-handler.js.map +1 -0
  123. package/lib/server/mcp-server-launcher.d.ts +143 -0
  124. package/lib/server/mcp-server-launcher.d.ts.map +1 -0
  125. package/lib/server/mcp-server-launcher.js +355 -0
  126. package/lib/server/mcp-server-launcher.js.map +1 -0
  127. package/lib/server/mcp-server-module.d.ts +143 -0
  128. package/lib/server/mcp-server-module.d.ts.map +1 -0
  129. package/lib/server/mcp-server-module.js +249 -0
  130. package/lib/server/mcp-server-module.js.map +1 -0
  131. package/lib/server/mcp-session.d.ts +44 -0
  132. package/lib/server/mcp-session.d.ts.map +1 -0
  133. package/lib/server/mcp-session.js +18 -0
  134. package/lib/server/mcp-session.js.map +1 -0
  135. package/lib/server/mcp-tool-handler.d.ts +259 -0
  136. package/lib/server/mcp-tool-handler.d.ts.map +1 -0
  137. package/lib/server/mcp-tool-handler.js +355 -0
  138. package/lib/server/mcp-tool-handler.js.map +1 -0
  139. package/lib/tools/handlers/count-elements-mcp-tool-handler.d.ts +46 -0
  140. package/lib/tools/handlers/count-elements-mcp-tool-handler.d.ts.map +1 -0
  141. package/lib/tools/handlers/count-elements-mcp-tool-handler.js +76 -0
  142. package/lib/tools/handlers/count-elements-mcp-tool-handler.js.map +1 -0
  143. package/lib/tools/handlers/create-edges-mcp-tool-handler.d.ts +112 -0
  144. package/lib/tools/handlers/create-edges-mcp-tool-handler.d.ts.map +1 -0
  145. package/lib/tools/handlers/create-edges-mcp-tool-handler.js +190 -0
  146. package/lib/tools/handlers/create-edges-mcp-tool-handler.js.map +1 -0
  147. package/lib/tools/handlers/create-nodes-mcp-tool-handler.d.ts +81 -0
  148. package/lib/tools/handlers/create-nodes-mcp-tool-handler.d.ts.map +1 -0
  149. package/lib/tools/handlers/create-nodes-mcp-tool-handler.js +123 -0
  150. package/lib/tools/handlers/create-nodes-mcp-tool-handler.js.map +1 -0
  151. package/lib/tools/handlers/delete-elements-mcp-tool-handler.d.ts +52 -0
  152. package/lib/tools/handlers/delete-elements-mcp-tool-handler.d.ts.map +1 -0
  153. package/lib/tools/handlers/delete-elements-mcp-tool-handler.js +73 -0
  154. package/lib/tools/handlers/delete-elements-mcp-tool-handler.js.map +1 -0
  155. package/lib/tools/handlers/diagram-model-mcp-tool-handler.d.ts +59 -0
  156. package/lib/tools/handlers/diagram-model-mcp-tool-handler.d.ts.map +1 -0
  157. package/lib/tools/handlers/diagram-model-mcp-tool-handler.js +78 -0
  158. package/lib/tools/handlers/diagram-model-mcp-tool-handler.js.map +1 -0
  159. package/lib/tools/handlers/element-types-mcp-tool-handler.d.ts +97 -0
  160. package/lib/tools/handlers/element-types-mcp-tool-handler.d.ts.map +1 -0
  161. package/lib/tools/handlers/element-types-mcp-tool-handler.js +155 -0
  162. package/lib/tools/handlers/element-types-mcp-tool-handler.js.map +1 -0
  163. package/lib/tools/handlers/get-selection-mcp-tool-handler.d.ts +43 -0
  164. package/lib/tools/handlers/get-selection-mcp-tool-handler.d.ts.map +1 -0
  165. package/lib/tools/handlers/get-selection-mcp-tool-handler.js +68 -0
  166. package/lib/tools/handlers/get-selection-mcp-tool-handler.js.map +1 -0
  167. package/lib/tools/handlers/layout-mcp-tool-handler.d.ts +43 -0
  168. package/lib/tools/handlers/layout-mcp-tool-handler.d.ts.map +1 -0
  169. package/lib/tools/handlers/layout-mcp-tool-handler.js +71 -0
  170. package/lib/tools/handlers/layout-mcp-tool-handler.js.map +1 -0
  171. package/lib/tools/handlers/modify-edges-mcp-tool-handler.d.ts +78 -0
  172. package/lib/tools/handlers/modify-edges-mcp-tool-handler.d.ts.map +1 -0
  173. package/lib/tools/handlers/modify-edges-mcp-tool-handler.js +136 -0
  174. package/lib/tools/handlers/modify-edges-mcp-tool-handler.js.map +1 -0
  175. package/lib/tools/handlers/modify-nodes-mcp-tool-handler.d.ts +92 -0
  176. package/lib/tools/handlers/modify-nodes-mcp-tool-handler.d.ts.map +1 -0
  177. package/lib/tools/handlers/modify-nodes-mcp-tool-handler.js +125 -0
  178. package/lib/tools/handlers/modify-nodes-mcp-tool-handler.js.map +1 -0
  179. package/lib/tools/handlers/query-elements-mcp-tool-handler.d.ts +102 -0
  180. package/lib/tools/handlers/query-elements-mcp-tool-handler.d.ts.map +1 -0
  181. package/lib/tools/handlers/query-elements-mcp-tool-handler.js +158 -0
  182. package/lib/tools/handlers/query-elements-mcp-tool-handler.js.map +1 -0
  183. package/lib/tools/handlers/redo-mcp-tool-handler.d.ts +45 -0
  184. package/lib/tools/handlers/redo-mcp-tool-handler.d.ts.map +1 -0
  185. package/lib/tools/handlers/redo-mcp-tool-handler.js +73 -0
  186. package/lib/tools/handlers/redo-mcp-tool-handler.js.map +1 -0
  187. package/lib/tools/handlers/save-model-mcp-tool-handler.d.ts +55 -0
  188. package/lib/tools/handlers/save-model-mcp-tool-handler.d.ts.map +1 -0
  189. package/lib/tools/handlers/save-model-mcp-tool-handler.js +91 -0
  190. package/lib/tools/handlers/save-model-mcp-tool-handler.js.map +1 -0
  191. package/lib/tools/handlers/session-info-mcp-tool-handler.d.ts +65 -0
  192. package/lib/tools/handlers/session-info-mcp-tool-handler.d.ts.map +1 -0
  193. package/lib/tools/handlers/session-info-mcp-tool-handler.js +108 -0
  194. package/lib/tools/handlers/session-info-mcp-tool-handler.js.map +1 -0
  195. package/lib/tools/handlers/set-selection-mcp-tool-handler.d.ts +60 -0
  196. package/lib/tools/handlers/set-selection-mcp-tool-handler.d.ts.map +1 -0
  197. package/lib/tools/handlers/set-selection-mcp-tool-handler.js +103 -0
  198. package/lib/tools/handlers/set-selection-mcp-tool-handler.js.map +1 -0
  199. package/lib/tools/handlers/set-view-mcp-tool-handler.d.ts +110 -0
  200. package/lib/tools/handlers/set-view-mcp-tool-handler.d.ts.map +1 -0
  201. package/lib/tools/handlers/set-view-mcp-tool-handler.js +142 -0
  202. package/lib/tools/handlers/set-view-mcp-tool-handler.js.map +1 -0
  203. package/lib/tools/handlers/undo-mcp-tool-handler.d.ts +45 -0
  204. package/lib/tools/handlers/undo-mcp-tool-handler.d.ts.map +1 -0
  205. package/lib/tools/handlers/undo-mcp-tool-handler.js +74 -0
  206. package/lib/tools/handlers/undo-mcp-tool-handler.js.map +1 -0
  207. package/lib/tools/handlers/validate-diagram-mcp-tool-handler.d.ts +66 -0
  208. package/lib/tools/handlers/validate-diagram-mcp-tool-handler.d.ts.map +1 -0
  209. package/lib/tools/handlers/validate-diagram-mcp-tool-handler.js +0 -0
  210. package/lib/tools/handlers/validate-diagram-mcp-tool-handler.js.map +1 -0
  211. package/lib/tools/index.d.ts +34 -0
  212. package/lib/tools/index.d.ts.map +1 -0
  213. package/lib/tools/index.js +50 -0
  214. package/lib/tools/index.js.map +1 -0
  215. package/lib/util/index.d.ts +18 -0
  216. package/lib/util/index.d.ts.map +1 -0
  217. package/lib/util/index.js +34 -0
  218. package/lib/util/index.js.map +1 -0
  219. package/lib/util/markdown-util.d.ts +20 -0
  220. package/lib/util/markdown-util.d.ts.map +1 -0
  221. package/lib/util/markdown-util.js +45 -0
  222. package/lib/util/markdown-util.js.map +1 -0
  223. package/lib/util/mcp-util.d.ts +22 -0
  224. package/lib/util/mcp-util.d.ts.map +1 -0
  225. package/lib/util/mcp-util.js +29 -0
  226. package/lib/util/mcp-util.js.map +1 -0
  227. package/package.json +63 -0
  228. package/src/index.ts +24 -0
  229. package/src/prompts/handlers/describe-diagram-mcp-prompt-handler.ts +89 -0
  230. package/src/prompts/handlers/suggest-improvements-mcp-prompt-handler.ts +86 -0
  231. package/src/prompts/index.ts +18 -0
  232. package/src/resources/handlers/diagram-png-mcp-resource-handler.ts +181 -0
  233. package/src/resources/handlers/diagram-svg-mcp-resource-handler.ts +89 -0
  234. package/src/resources/index.ts +20 -0
  235. package/src/resources/services/element-types-provider.ts +105 -0
  236. package/src/resources/services/mcp-model-serializer.ts +211 -0
  237. package/src/server/glsp-mcp-server.spec.ts +73 -0
  238. package/src/server/glsp-mcp-server.ts +196 -0
  239. package/src/server/index.ts +42 -0
  240. package/src/server/lru-event-store.spec.ts +121 -0
  241. package/src/server/lru-event-store.ts +112 -0
  242. package/src/server/mcp-diagram-handler-dispatcher.spec.ts +231 -0
  243. package/src/server/mcp-diagram-handler-dispatcher.ts +459 -0
  244. package/src/server/mcp-diagram-module.ts +248 -0
  245. package/src/server/mcp-diagram-prompt-handler-registry.ts +59 -0
  246. package/src/server/mcp-diagram-resource-handler-registry.ts +73 -0
  247. package/src/server/mcp-diagram-tool-handler-registry.ts +97 -0
  248. package/src/server/mcp-handler-shared.spec.ts +53 -0
  249. package/src/server/mcp-handler-shared.ts +247 -0
  250. package/src/server/mcp-http-transport-e2e.spec.ts +151 -0
  251. package/src/server/mcp-http-transport.spec.ts +385 -0
  252. package/src/server/mcp-http-transport.ts +368 -0
  253. package/src/server/mcp-id-alias-service.spec.ts +106 -0
  254. package/src/server/mcp-id-alias-service.ts +104 -0
  255. package/src/server/mcp-input-schemas.ts +82 -0
  256. package/src/server/mcp-label-provider.ts +52 -0
  257. package/src/server/mcp-log-level-registry.spec.ts +75 -0
  258. package/src/server/mcp-log-level-registry.ts +90 -0
  259. package/src/server/mcp-logger.spec.ts +227 -0
  260. package/src/server/mcp-logger.ts +91 -0
  261. package/src/server/mcp-mime-types.ts +31 -0
  262. package/src/server/mcp-options.ts +43 -0
  263. package/src/server/mcp-progress-reporter.spec.ts +93 -0
  264. package/src/server/mcp-progress-reporter.ts +67 -0
  265. package/src/server/mcp-prompt-handler.ts +157 -0
  266. package/src/server/mcp-request-context.ts +39 -0
  267. package/src/server/mcp-resource-handler.ts +389 -0
  268. package/src/server/mcp-server-launcher.spec.ts +173 -0
  269. package/src/server/mcp-server-launcher.ts +369 -0
  270. package/src/server/mcp-server-module.ts +287 -0
  271. package/src/server/mcp-session.ts +45 -0
  272. package/src/server/mcp-tool-handler.spec.ts +182 -0
  273. package/src/server/mcp-tool-handler.ts +431 -0
  274. package/src/server/raw-http.spec.ts +59 -0
  275. package/src/tools/handlers/count-elements-mcp-tool-handler.spec.ts +99 -0
  276. package/src/tools/handlers/count-elements-mcp-tool-handler.ts +66 -0
  277. package/src/tools/handlers/create-edges-mcp-tool-handler.spec.ts +196 -0
  278. package/src/tools/handlers/create-edges-mcp-tool-handler.ts +205 -0
  279. package/src/tools/handlers/create-nodes-mcp-tool-handler.spec.ts +197 -0
  280. package/src/tools/handlers/create-nodes-mcp-tool-handler.ts +131 -0
  281. package/src/tools/handlers/delete-elements-mcp-tool-handler.ts +73 -0
  282. package/src/tools/handlers/diagram-model-mcp-tool-handler.ts +66 -0
  283. package/src/tools/handlers/element-types-mcp-tool-handler.ts +151 -0
  284. package/src/tools/handlers/get-selection-mcp-tool-handler.ts +54 -0
  285. package/src/tools/handlers/layout-mcp-tool-handler.ts +56 -0
  286. package/src/tools/handlers/modify-edges-mcp-tool-handler.ts +148 -0
  287. package/src/tools/handlers/modify-nodes-mcp-tool-handler.ts +140 -0
  288. package/src/tools/handlers/query-elements-mcp-tool-handler.spec.ts +210 -0
  289. package/src/tools/handlers/query-elements-mcp-tool-handler.ts +161 -0
  290. package/src/tools/handlers/redo-mcp-tool-handler.ts +62 -0
  291. package/src/tools/handlers/save-model-mcp-tool-handler.ts +71 -0
  292. package/src/tools/handlers/session-info-mcp-tool-handler.spec.ts +152 -0
  293. package/src/tools/handlers/session-info-mcp-tool-handler.ts +97 -0
  294. package/src/tools/handlers/set-selection-mcp-tool-handler.spec.ts +118 -0
  295. package/src/tools/handlers/set-selection-mcp-tool-handler.ts +90 -0
  296. package/src/tools/handlers/set-view-mcp-tool-handler.ts +162 -0
  297. package/src/tools/handlers/undo-mcp-tool-handler.ts +61 -0
  298. package/src/tools/handlers/validate-diagram-mcp-tool-handler.ts +0 -0
  299. package/src/tools/index.ts +34 -0
  300. package/src/tools/tool-annotations.spec.ts +141 -0
  301. package/src/util/index.ts +18 -0
  302. package/src/util/markdown-util.ts +44 -0
  303. package/src/util/mcp-util.ts +25 -0
@@ -0,0 +1,369 @@
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 {
18
+ ClientSessionListener,
19
+ ClientSessionManager,
20
+ Disposable,
21
+ DisposableCollection,
22
+ GLSPServer,
23
+ GLSPServerInitializer,
24
+ GLSPServerListener,
25
+ InitializeParameters,
26
+ InitializeResult,
27
+ Logger,
28
+ McpInitializeParameters,
29
+ McpInitializeResult,
30
+ McpServerConfiguration,
31
+ McpServerInitOptions
32
+ } from '@eclipse-glsp/server';
33
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
34
+ import { ServerCapabilities, SetLevelRequestSchema } from '@modelcontextprotocol/sdk/types.js';
35
+ import { inject, injectable, multiInject, optional } from 'inversify';
36
+ import { version as packageVersion } from '../../package.json';
37
+ import { GLSPMcpServer, GLSPMcpServerFactory } from './glsp-mcp-server';
38
+ import { McpDiagramHandlerDispatcher } from './mcp-diagram-handler-dispatcher';
39
+ import { McpHttpTransport } from './mcp-http-transport';
40
+ import { McpLogLevelRegistry } from './mcp-log-level-registry';
41
+ import { McpServerDefaults, McpServerOptions } from './mcp-options';
42
+ import { McpPromptHandler } from './mcp-prompt-handler';
43
+ import { McpResourceHandler } from './mcp-resource-handler';
44
+ import { McpSession } from './mcp-session';
45
+ import { McpToolHandler } from './mcp-tool-handler';
46
+
47
+ /**
48
+ * Stdout tag used to announce the started MCP server so IDE integrations can pick up the URL
49
+ * automatically. The full line is `MCP_SERVER_READY_MSG + JSON.stringify({name, url, route})`,
50
+ * mirroring how the GLSP server itself announces its port via `START_UP_COMPLETE_MSG`.
51
+ */
52
+ export const MCP_SERVER_READY_MSG = '[GLSP-MCP-Server]:Ready. ';
53
+
54
+ /**
55
+ * Server version reported in MCP `initialize` handshake responses (the SDK's `serverInfo.version`
56
+ * field). Sourced from the package's own `package.json` so adopters and clients can tell builds
57
+ * apart without the server author having to remember to bump a literal.
58
+ */
59
+ export const SERVER_VERSION: string = packageVersion;
60
+
61
+ /**
62
+ * Launcher's internal handoff shape: everything from the public {@link McpServerConfiguration}
63
+ * with all fields resolved, plus `host`. `host` is deliberately *not* in the public protocol's
64
+ * init schema — it lives on `McpServerDeployOptions` (deploy-only) rather than
65
+ * `McpServerInitOptions` (init-controllable). The launcher reads it from the adopter-supplied
66
+ * defaults via `McpServerOptions.values.host` (whose ship default lives in
67
+ * `DefaultMcpServerModule.DEFAULT_OPTIONS`). The init/deploy split limits blast radius:
68
+ * MCP clients can negotiate behavioral fields like `port` over the wire, but security-sensitive
69
+ * fields like the bind interface are settable only by the adopter at process start.
70
+ */
71
+ export type FullMcpServerConfiguration = Required<McpServerConfiguration> & { host: string };
72
+
73
+ /**
74
+ * Defense-in-depth filter for the init-side options payload. The static type already rules
75
+ * out deploy-only fields (`host`, `allowedHosts`, `allowedOrigins`, `acknowledgedNoAuth`) on
76
+ * `McpServerConfiguration.options`, but the wire payload is JSON, so a malformed or
77
+ * malicious client could smuggle extra keys. Destructure-based pick drops anything outside
78
+ * the allowed set so deploy-only fields are sourced *only* from adopter defaults.
79
+ *
80
+ * **Update this allowlist when adding a field to `McpServerInitOptions`** — the destructure
81
+ * below is the single source of truth for which init-side fields cross the wire.
82
+ *
83
+ * Exported for regression-test access only; not part of the public package surface.
84
+ */
85
+ export function pickInitOptions(options: McpServerInitOptions): McpServerInitOptions {
86
+ const { dataMode, agentPersona, eventStoreLimit } = options;
87
+ const picked: McpServerInitOptions = {};
88
+ if (dataMode !== undefined) picked.dataMode = dataMode;
89
+ if (agentPersona !== undefined) picked.agentPersona = agentPersona;
90
+ if (eventStoreLimit !== undefined) picked.eventStoreLimit = eventStoreLimit;
91
+ return picked;
92
+ }
93
+
94
+ /**
95
+ * Returns true iff `host` is a loopback bind: `localhost`, `::1`, or any IPv4 in
96
+ * `127.0.0.0/8`. Any other value (`0.0.0.0`, `::`, LAN/public addresses) is non-loopback.
97
+ * Used by {@link assertLoopbackOrAcknowledged} for the auth-footgun runtime check.
98
+ */
99
+ export function isLoopbackHost(host: string): boolean {
100
+ return host === 'localhost' || host === '::1' || /^127\./.test(host);
101
+ }
102
+
103
+ /**
104
+ * Refuse to bind on a non-loopback host unless the operator has acknowledged that traffic is
105
+ * authenticated externally (reverse proxy, mTLS, ACL). The MCP server has no built-in auth.
106
+ * Exported for regression tests only; not part of the public surface.
107
+ */
108
+ export function assertLoopbackOrAcknowledged(host: string, acknowledgedNoAuth: boolean | undefined): void {
109
+ if (isLoopbackHost(host) || acknowledgedNoAuth === true) {
110
+ return;
111
+ }
112
+ throw new Error(
113
+ `Refusing to bind MCP server to non-loopback host '${host}' without authentication. ` +
114
+ 'The MCP server has no built-in auth; binding to a non-loopback interface exposes an ' +
115
+ 'unauthenticated MCP endpoint to the network. If this is intentional (e.g., the endpoint ' +
116
+ 'is fronted by a reverse proxy, mTLS, or a network ACL that authenticates traffic), set ' +
117
+ '`acknowledgedNoAuth: true` on the McpServerDefaults you pass to the server module.'
118
+ );
119
+ }
120
+
121
+ /**
122
+ * Boots the embedded MCP HTTP server when a GLSP `initialize` call carries an `mcpServer`
123
+ * configuration. Runs in-process via the {@link GLSPServerInitializer} lifecycle — not a
124
+ * separate process runner. Diagram-scope handler discovery and dispatch are delegated to
125
+ * {@link McpDiagramHandlerDispatcher}.
126
+ */
127
+ @injectable()
128
+ export class McpServerLauncher implements GLSPServerInitializer, GLSPServerListener, Disposable {
129
+ @inject(Logger) protected logger: Logger;
130
+
131
+ @inject(McpServerOptions) protected mcpOptions: McpServerOptions;
132
+
133
+ @inject(McpServerDefaults) protected mcpDefaults: McpServerDefaults;
134
+
135
+ @inject(McpHttpTransport) protected transport: McpHttpTransport;
136
+
137
+ @inject(GLSPMcpServerFactory) protected glspMcpServerFactory: GLSPMcpServerFactory;
138
+
139
+ @inject(McpDiagramHandlerDispatcher) protected dispatcher: McpDiagramHandlerDispatcher;
140
+
141
+ @inject(McpLogLevelRegistry) protected logLevelRegistry: McpLogLevelRegistry;
142
+
143
+ @inject(ClientSessionManager) protected clientSessionManager: ClientSessionManager;
144
+
145
+ @multiInject(McpToolHandler) @optional() protected toolHandlers: McpToolHandler[] = [];
146
+
147
+ @multiInject(McpResourceHandler) @optional() protected resourceHandlers: McpResourceHandler[] = [];
148
+
149
+ @multiInject(McpPromptHandler) @optional() protected promptHandlers: McpPromptHandler[] = [];
150
+
151
+ protected toDispose = new DisposableCollection();
152
+ protected serverUrl: string | undefined;
153
+ protected serverConfig: FullMcpServerConfiguration | undefined;
154
+
155
+ /** Per-MCP-session GLSPMcpServer registry — populated on session-init, cleared on session-close. */
156
+ protected readonly sessionServers = new Map<string, GLSPMcpServer>();
157
+
158
+ async initializeServer(server: GLSPServer, params: InitializeParameters, result: InitializeResult): Promise<InitializeResult> {
159
+ const mcpServerParam = McpInitializeParameters.getServerConfig(params);
160
+ if (!mcpServerParam) {
161
+ return result;
162
+ }
163
+
164
+ // Idempotent: subsequent client sessions of the same GLSP server reuse the existing
165
+ // MCP HTTP server. Only the first call starts it.
166
+ if (this.serverUrl && this.serverConfig) {
167
+ return McpInitializeResult.attachServer(result, { name: this.serverConfig.name, url: this.serverUrl });
168
+ }
169
+
170
+ // Port defaults to 0 (random); the resolved URL is announced via the stdout marker
171
+ // below. `host` is intentionally NOT in the init-time schema — it comes from the
172
+ // server module's adopter defaults (no DNS-rebinding foot-gun via the LLM path).
173
+ const { port = 0, route = '/mcp', name = 'glsp', options = {} } = mcpServerParam;
174
+ // Init-time options win per field, but only fields in the init allowlist —
175
+ // `pickInitOptions` strips any wire-smuggled deploy-only keys before merge.
176
+ const mergedOptions = { ...this.mcpDefaults, ...pickInitOptions(options) };
177
+ this.mcpOptions.values = mergedOptions;
178
+ const host = mergedOptions.host ?? '127.0.0.1';
179
+ // Auth-footgun guard: refuse non-loopback bind unless the operator opted in via
180
+ // `acknowledgedNoAuth`. Runs BEFORE the transport binds the socket so a careless
181
+ // `host: '0.0.0.0'` doesn't get a chance to expose an unauthenticated endpoint.
182
+ assertLoopbackOrAcknowledged(host, mergedOptions.acknowledgedNoAuth);
183
+ const mcpServerConfig: FullMcpServerConfiguration = { port, host, route, name, options: mergedOptions };
184
+
185
+ this.dispatcher.harvest();
186
+
187
+ // Capture the per-init subscription disposables so a dispose-then-restart cycle
188
+ // (transport is `inSingletonScope()`) doesn't accumulate stale listeners.
189
+ this.toDispose.push(this.transport.onSessionInitialized(client => this.onSessionInitialized(client, mcpServerConfig)));
190
+ this.toDispose.push(this.transport.onSessionClosed(sessionId => this.onSessionClosed(sessionId)));
191
+ this.toDispose.push(this.transport);
192
+ this.installResourceListChangedNotifier();
193
+
194
+ const endpoint = await this.transport.start(mcpServerConfig);
195
+ this.serverUrl = endpoint.url;
196
+ this.serverConfig = mcpServerConfig;
197
+ this.logger.info(
198
+ `MCP server '${mcpServerConfig.name}' is ready to accept new client requests on: ${this.serverUrl ?? '(no network endpoint)'}`
199
+ );
200
+
201
+ // stdout ready-marker for parent processes to discover the URL. Uses `console.log`
202
+ // (not the GLSP logger) so adopter logger config can never hide it.
203
+ console.log(MCP_SERVER_READY_MSG + JSON.stringify({ name: mcpServerConfig.name, url: this.serverUrl, route }));
204
+ if (endpoint.url) {
205
+ return McpInitializeResult.attachServer(result, {
206
+ name: mcpServerConfig.name,
207
+ url: endpoint.url,
208
+ headers: endpoint.headers
209
+ });
210
+ }
211
+ return result;
212
+ }
213
+
214
+ protected onSessionInitialized(client: McpSession, config: FullMcpServerConfiguration): void {
215
+ this.logger.info(`MCP session initialized with ID: ${client.sessionId}`);
216
+ const glspMcpServer = this.createGlspMcpServer(config);
217
+ this.sessionServers.set(client.sessionId, glspMcpServer);
218
+ this.registerLogLevelHandler(glspMcpServer, client.sessionId);
219
+ // server assumes control of the connection
220
+ glspMcpServer.connect(client);
221
+ }
222
+
223
+ protected onSessionClosed(sessionId: string): void {
224
+ const glspMcpServer = this.sessionServers.get(sessionId);
225
+ if (glspMcpServer) {
226
+ this.sessionServers.delete(sessionId);
227
+ this.logLevelRegistry.clear(sessionId);
228
+ // The transport already closes the client end; close the SDK server end too.
229
+ glspMcpServer.dispose();
230
+ this.logger.info(`MCP session closed: ${sessionId}`);
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Fire `notifications/resources/list_changed` to every connected MCP client when a GLSP
236
+ * session opens or closes — diagram-scope resources aggregate across GLSP sessions, so the
237
+ * visible list mutates with that lifecycle. No-op when no diagram-scope resources are bound.
238
+ */
239
+ protected installResourceListChangedNotifier(): void {
240
+ if (!this.dispatcher.hasDiagramResources()) {
241
+ return;
242
+ }
243
+ const listener: ClientSessionListener = {
244
+ sessionCreated: () => this.broadcastResourceListChanged(),
245
+ sessionDisposed: () => this.broadcastResourceListChanged()
246
+ };
247
+ this.clientSessionManager.addListener(listener);
248
+ this.toDispose.push(Disposable.create(() => this.clientSessionManager.removeListener(listener)));
249
+ }
250
+
251
+ /** Best-effort fan-out — failures on individual MCP sessions (e.g. transport mid-close) are swallowed. */
252
+ protected broadcastResourceListChanged(): void {
253
+ for (const glspMcpServer of this.sessionServers.values()) {
254
+ glspMcpServer
255
+ .getRawServer()
256
+ .server.sendResourceListChanged()
257
+ .catch(err => this.logger.debug('sendResourceListChanged failed:', err));
258
+ }
259
+ }
260
+
261
+ /** Register `logging/setLevel` so a connected MCP client can adjust its message severity threshold. */
262
+ protected registerLogLevelHandler(glspMcpServer: GLSPMcpServer, sessionId: string): void {
263
+ glspMcpServer.getRawServer().server.setRequestHandler(SetLevelRequestSchema, async request => {
264
+ this.logLevelRegistry.setLevel(sessionId, request.params.level);
265
+ return {};
266
+ });
267
+ }
268
+
269
+ protected createGlspMcpServer({ name, options }: FullMcpServerConfiguration): GLSPMcpServer {
270
+ const resourcesAsResources = options.dataMode === 'resources';
271
+ const server = new McpServer(
272
+ { name, version: SERVER_VERSION },
273
+ {
274
+ capabilities: this.buildCapabilities(resourcesAsResources),
275
+ instructions: options.agentPersona
276
+ }
277
+ );
278
+ const glspMcpServer = this.glspMcpServerFactory(server, options);
279
+ this.registerHandlers(glspMcpServer, resourcesAsResources);
280
+ return glspMcpServer;
281
+ }
282
+
283
+ /**
284
+ * Build the MCP capabilities map from what is actually bound. Only declare a key when at
285
+ * least one handler contributes — declaring a capability the SDK never registers a handler
286
+ * for produces `-32601 Method not found` on `<cap>/list`. Resources surfaced as tools
287
+ * (`dataMode === 'tools'`) count toward `tools`, not `resources`.
288
+ */
289
+ protected buildCapabilities(resourcesAsResources: boolean): ServerCapabilities {
290
+ const hasStaticTools = this.toolHandlers.length > 0;
291
+ const hasStaticPrompts = this.promptHandlers.length > 0;
292
+ const hasStaticResources = this.resourceHandlers.length > 0;
293
+ const hasDiagramTools = this.dispatcher.hasDiagramTools();
294
+ const hasDiagramPrompts = this.dispatcher.hasDiagramPrompts();
295
+ const hasDiagramResources = this.dispatcher.hasDiagramResources();
296
+ const anyResources = hasStaticResources || hasDiagramResources;
297
+
298
+ const hasTools = hasStaticTools || hasDiagramTools || (!resourcesAsResources && anyResources);
299
+ const hasPrompts = hasStaticPrompts || hasDiagramPrompts;
300
+ const hasResources = resourcesAsResources && anyResources;
301
+
302
+ return {
303
+ logging: {},
304
+ ...(hasTools ? { tools: { listChanged: false } } : {}),
305
+ // `resources.listChanged: true` iff the catalog contains diagram-scope resources —
306
+ // those aggregate across open GLSP sessions, so the visible list mutates with
307
+ // session add/remove. Server-scope-only catalogs are static, so the flag stays
308
+ // honest at `false` (the SDK reads it; clients refetch only when notified).
309
+ ...(hasResources ? { resources: { listChanged: hasDiagramResources } } : {}),
310
+ ...(hasPrompts ? { prompts: { listChanged: false } } : {})
311
+ };
312
+ }
313
+
314
+ /**
315
+ * Registers tool/resource/prompt handlers against the per-MCP-session GLSP MCP server. Two
316
+ * sources flow into the catalog:
317
+ *
318
+ * 1. **Server-scope handlers**: singletons bound under `McpToolHandler` /
319
+ * `McpResourceHandler` / `McpPromptHandler`. Registered via their `register*(server)`
320
+ * methods — they're already-instantiated objects that close over their own state.
321
+ *
322
+ * 2. **Diagram-scope handlers**: registered by {@link McpDiagramHandlerDispatcher}, which
323
+ * walks the catalogs harvested at server start and dispatches each registered SDK
324
+ * callback by `params.sessionId` → per-GLSP-session container → registry lookup.
325
+ */
326
+ protected registerHandlers(glspMcpServer: GLSPMcpServer, resourcesAsResources: boolean): void {
327
+ this.toolHandlers.forEach(handler => handler.registerTool(glspMcpServer));
328
+ this.promptHandlers.forEach(handler => handler.registerPrompt(glspMcpServer));
329
+ if (resourcesAsResources) {
330
+ this.resourceHandlers.forEach(handler => handler.registerResource(glspMcpServer));
331
+ } else {
332
+ this.resourceHandlers.forEach(handler => handler.registerToolAlternative?.(glspMcpServer));
333
+ }
334
+
335
+ this.dispatcher.registerAll(glspMcpServer, resourcesAsResources);
336
+ this.validatePromptToolReferences(glspMcpServer);
337
+ }
338
+
339
+ /**
340
+ * Warn when a server-scope prompt's {@link AbstractMcpPromptHandler.referencedToolNames}
341
+ * contains a name not registered on this MCP session — catches adopters who unbind a tool
342
+ * a shipped prompt references via `${OtherHandler.NAME}`.
343
+ */
344
+ protected validatePromptToolReferences(glspMcpServer: GLSPMcpServer): void {
345
+ for (const handler of this.promptHandlers) {
346
+ const missing = handler.referencedToolNames().filter(name => !glspMcpServer.hasTool(name));
347
+ if (missing.length > 0) {
348
+ this.logger.warn(
349
+ `Prompt '${handler.name}' references unbound tool(s): ${missing.join(', ')}. ` +
350
+ 'The prompt will still register but its text points at tools the LLM cannot invoke.'
351
+ );
352
+ }
353
+ }
354
+ }
355
+
356
+ serverShutDown(server: GLSPServer): void {
357
+ this.dispose();
358
+ }
359
+
360
+ dispose(): void {
361
+ this.sessionServers.forEach(glspMcpServer => glspMcpServer.dispose());
362
+ this.sessionServers.clear();
363
+ this.toDispose.dispose();
364
+ this.toDispose.clear();
365
+ this.serverUrl = undefined;
366
+ this.serverConfig = undefined;
367
+ this.dispatcher.reset();
368
+ }
369
+ }
@@ -0,0 +1,287 @@
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 { McpServerOptions as McpServerOptionsType } from '@eclipse-glsp/protocol';
18
+ import { BindingContext } from '@eclipse-glsp/protocol/lib/di';
19
+ import {
20
+ AbstractMultiBinding,
21
+ applyBindingTarget,
22
+ BindingTarget,
23
+ GLSPModule,
24
+ GLSPServerInitializer,
25
+ GLSPServerListener,
26
+ Logger
27
+ } from '@eclipse-glsp/server';
28
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
29
+ import { interfaces } from 'inversify';
30
+ import { DescribeDiagramMcpPromptHandler, SuggestImprovementsMcpPromptHandler } from '../prompts';
31
+ import { ElementTypesMcpToolHandler, SessionInfoMcpToolHandler } from '../tools';
32
+ import { DefaultGLSPMcpServer, GLSPMcpServerFactory } from './glsp-mcp-server';
33
+ import { DefaultMcpDiagramHandlerDispatcher, McpDiagramHandlerDispatcher } from './mcp-diagram-handler-dispatcher';
34
+ import { DefaultMcpLogLevelRegistry, McpLogLevelRegistry } from './mcp-log-level-registry';
35
+ import { LruEventStore } from './lru-event-store';
36
+ import { McpHttpTransport } from './mcp-http-transport';
37
+ import { McpLogger } from './mcp-logger';
38
+ import { McpServerDefaults, McpServerOptions } from './mcp-options';
39
+ import { McpProgressReporter } from './mcp-progress-reporter';
40
+ import { McpPromptHandler } from './mcp-prompt-handler';
41
+ import { McpResourceHandler } from './mcp-resource-handler';
42
+ import { McpServerLauncher } from './mcp-server-launcher';
43
+ import { McpToolHandler } from './mcp-tool-handler';
44
+
45
+ /**
46
+ * GLSP-generic default agent persona — adopters typically pass a product-specific persona to
47
+ * the {@link DefaultMcpServerModule} constructor (e.g. workflow-server might say "You are the
48
+ * Workflow Modeling Agent...").
49
+ *
50
+ * **Spec note.** This is wired to the MCP `instructions` field, which the spec describes as
51
+ * "concise instructions". This persona is intentionally verbose (~700 chars of behavior rules)
52
+ * — within the spec's "free-form server-supplied instructions" allowance and adopter-overridable
53
+ * via `mcpDefaults.agentPersona`. Don't trim on autopilot if a "concise" interpretation drifts
54
+ * back: the verbose form materially improves LLM tool-use compliance for graphical modelling.
55
+ */
56
+ const DEFAULT_AGENT_PERSONA = `
57
+ You are the GLSP Modeling Agent. Your primary goal is to assist in the creation and modification of graphical models using the
58
+ GLSP MCP server. You have to adhere to the following principles:
59
+ - MCP-Interaction: Any modeling related activity has to occur using the MCP server.
60
+ - Real Data: The diagram model is the ground truth regarding the existing graphical model. Always query it before modifying the diagram.
61
+ - Real Creation: Consult the available element types before creating elements.
62
+ - Visual Proof: An image of the graphical model can be created, if you deem it useful for calculating or verifying layout decisions.
63
+ - Precision: All IDs and types must be exact.
64
+ - Visualization: When creating nodes, suggest sensible default positions and avoid visual overlapping.
65
+ - Careful: Under no circumstances save the model without explicit instruction. If you deem it sensible, you may ask the user for permission.
66
+ The same goes for Undo/Redo operations.
67
+ - Layouting: If available, make use of automatic layouting when not given explicit custom layouting requirements.
68
+ - Human-friendly references: When mentioning an element in user-visible prose, prefer its label, then its element type
69
+ (the bare ids returned by the tools are internal aliases that mean nothing to the user). Append the alias in parentheses
70
+ so the user can correlate it with follow-up tools. Use the \`set-selection\` tool — or the \`set-view\` tool with
71
+ \`action: "center-on-elements"\` — to point the user at the elements you reference.
72
+ `;
73
+
74
+ /**
75
+ * Multi-binding helper for MCP handler classes. Singleton-scoped sibling of core's
76
+ * `MultiBinding<T>` — same `binding.add(...)` / `binding.rebind(old, new)` adopter shape, but
77
+ * core's plain `MultiBinding` binds in transient scope, while MCP handlers cache deferred
78
+ * resolvers (selection/PNG round-trips) and need singleton scope to keep their state.
79
+ */
80
+ export class McpHandlerMultiBinding<T> extends AbstractMultiBinding<interfaces.Newable<T>> {
81
+ override applyBindings(context: BindingContext): void {
82
+ this.bindings.forEach(handlerClass => {
83
+ if (!context.isBound(handlerClass)) {
84
+ context.bind(handlerClass).toSelf().inSingletonScope();
85
+ }
86
+ context.bind(this.identifier).toService(handlerClass);
87
+ });
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Server-scope DI module for the MCP server. Adopters subclass {@link DefaultMcpServerModule}
93
+ * and override the `bind*` hooks to swap single-instance services or the `configure*` hooks to
94
+ * add/replace handlers in the multi-bindings. Mirrors the `DiagramModule` pattern from core
95
+ * (`bindGModelSerializer()`, `configureActionHandlers(binding)`, etc.).
96
+ *
97
+ * Adopter-provided default option values flow through the constructor — pass a
98
+ * `Partial<McpServerOptions>` to override individual fields. The launcher then merges these
99
+ * defaults with init-time options from the GLSP `initialize` request (init-time wins per field).
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * // Drop-in: GLSP defaults.
104
+ * launcher.configure(serverModule, new DefaultMcpServerModule());
105
+ *
106
+ * // Drop-in with a product-specific override.
107
+ * launcher.configure(serverModule, new DefaultMcpServerModule({ dataMode: 'resources' }));
108
+ *
109
+ * // Subclass when handler customization is needed.
110
+ * class WorkflowMcpServerModule extends DefaultMcpServerModule {
111
+ * constructor() { super({ agentPersona: WORKFLOW_PERSONA }); }
112
+ * protected override configureToolHandlers(binding) {
113
+ * super.configureToolHandlers(binding);
114
+ * binding.add(WorkflowSpecificTool);
115
+ * }
116
+ * }
117
+ * ```
118
+ */
119
+ export abstract class AbstractMcpServerModule extends GLSPModule {
120
+ protected bind!: interfaces.Bind;
121
+ protected rebind!: interfaces.Rebind;
122
+
123
+ constructor(protected readonly defaultOptions: McpServerDefaults = {}) {
124
+ super();
125
+ }
126
+
127
+ protected override configure(
128
+ bind: interfaces.Bind,
129
+ _unbind: interfaces.Unbind,
130
+ isBound: interfaces.IsBound,
131
+ rebind: interfaces.Rebind
132
+ ): void {
133
+ this.bind = bind;
134
+ this.rebind = rebind;
135
+ const context = { bind, isBound };
136
+ applyBindingTarget(context, McpServerLauncher, this.bindMcpServerLauncher()).inSingletonScope();
137
+ // The launcher is bound under two additional service identifiers so core's existing
138
+ // multi-bindings pick it up alongside the rest of the server's contributions/listeners.
139
+ bind(GLSPServerInitializer).toService(McpServerLauncher);
140
+ bind(GLSPServerListener).toService(McpServerLauncher);
141
+ applyBindingTarget(context, McpHttpTransport, this.bindMcpHttpTransport()).inSingletonScope();
142
+ applyBindingTarget(context, McpDiagramHandlerDispatcher, this.bindMcpDiagramHandlerDispatcher()).inSingletonScope();
143
+ applyBindingTarget(context, McpServerOptions, this.bindMcpServerOptions()).inSingletonScope();
144
+ applyBindingTarget(context, McpServerDefaults, this.bindMcpServerDefaults());
145
+ applyBindingTarget(context, McpLogger, this.bindMcpLogger()).inSingletonScope();
146
+ applyBindingTarget(context, McpLogLevelRegistry, this.bindMcpLogLevelRegistry()).inSingletonScope();
147
+ applyBindingTarget(context, McpProgressReporter, this.bindMcpProgressReporter()).inSingletonScope();
148
+ applyBindingTarget(context, GLSPMcpServerFactory, this.bindGLSPMcpServerFactory());
149
+ this.configureMultiBinding(new McpHandlerMultiBinding<McpToolHandler>(McpToolHandler), binding =>
150
+ this.configureToolHandlers(binding as McpHandlerMultiBinding<McpToolHandler>)
151
+ );
152
+ this.configureMultiBinding(new McpHandlerMultiBinding<McpResourceHandler>(McpResourceHandler), binding =>
153
+ this.configureResourceHandlers(binding as McpHandlerMultiBinding<McpResourceHandler>)
154
+ );
155
+ this.configureMultiBinding(new McpHandlerMultiBinding<McpPromptHandler>(McpPromptHandler), binding =>
156
+ this.configurePromptHandlers(binding as McpHandlerMultiBinding<McpPromptHandler>)
157
+ );
158
+ }
159
+
160
+ /**
161
+ * {@link McpServerLauncher} binding. Bound as a singleton AND aliased to
162
+ * `GLSPServerInitializer` + `GLSPServerListener` (the launcher implements both).
163
+ * Override to swap in a custom launcher impl.
164
+ */
165
+ protected bindMcpServerLauncher(): BindingTarget<McpServerLauncher> {
166
+ return McpServerLauncher;
167
+ }
168
+
169
+ /** {@link McpHttpTransport} binding. Override to swap to a different transport implementation. */
170
+ protected bindMcpHttpTransport(): BindingTarget<McpHttpTransport> {
171
+ return McpHttpTransport;
172
+ }
173
+
174
+ /**
175
+ * {@link McpDiagramHandlerDispatcher} binding. Owns diagram-scope handler discovery,
176
+ * SDK registration, and per-call dispatch routing. Override (or `rebind` to a subclass)
177
+ * to customize registration without subclassing the launcher itself.
178
+ */
179
+ protected bindMcpDiagramHandlerDispatcher(): BindingTarget<McpDiagramHandlerDispatcher> {
180
+ return DefaultMcpDiagramHandlerDispatcher;
181
+ }
182
+
183
+ /** {@link McpServerOptions} holder binding. Mutated at init by the launcher. */
184
+ protected bindMcpServerOptions(): BindingTarget<McpServerOptions> {
185
+ return McpServerOptions;
186
+ }
187
+
188
+ /**
189
+ * {@link McpServerDefaults} binding — adopter-supplied default option values flow through
190
+ * the constructor and land here as a constant. The launcher merges these defaults with
191
+ * init-time options at server init (init-time wins per field).
192
+ */
193
+ protected bindMcpServerDefaults(): BindingTarget<McpServerDefaults> {
194
+ return { constantValue: this.defaultOptions };
195
+ }
196
+
197
+ /**
198
+ * {@link McpLogger} binding. Bound on the server container; per-session containers inherit
199
+ * it, so handlers at any scope can inject it; routes through the active MCP request via
200
+ * {@link mcpRequestContext}.
201
+ */
202
+ protected bindMcpLogger(): BindingTarget<McpLogger> {
203
+ return McpLogger;
204
+ }
205
+
206
+ /** {@link McpProgressReporter} binding. Same scope/lifecycle story as {@link bindMcpLogger}. */
207
+ protected bindMcpProgressReporter(): BindingTarget<McpProgressReporter> {
208
+ return McpProgressReporter;
209
+ }
210
+
211
+ /**
212
+ * {@link McpLogLevelRegistry} binding — holds per-MCP-session `logging/setLevel` thresholds
213
+ * read by {@link McpLogger} when filtering `notifications/message`.
214
+ */
215
+ protected bindMcpLogLevelRegistry(): BindingTarget<McpLogLevelRegistry> {
216
+ return DefaultMcpLogLevelRegistry;
217
+ }
218
+
219
+ /**
220
+ * {@link GLSPMcpServerFactory} binding — produces a fresh {@link DefaultGLSPMcpServer} per
221
+ * MCP-session-init call. Override to wrap the SDK `McpServer` differently (e.g. add custom
222
+ * middleware, swap the Proxy strategy).
223
+ */
224
+ protected bindGLSPMcpServerFactory(): BindingTarget<GLSPMcpServerFactory> {
225
+ return {
226
+ dynamicValue: ctx => {
227
+ const logger = ctx.container.get<Logger>(Logger);
228
+ return (mcpServer: McpServer, options: McpServerOptionsType): DefaultGLSPMcpServer =>
229
+ new DefaultGLSPMcpServer(mcpServer, options, logger);
230
+ }
231
+ };
232
+ }
233
+
234
+ /**
235
+ * Override to add or replace tool handlers. Adopters typically `super.configureToolHandlers(binding)`
236
+ * to keep the defaults, then `binding.add(MyTool)` for additions or
237
+ * `binding.rebind(StandardTool, MyTool)` for overrides.
238
+ */
239
+ protected configureToolHandlers(binding: McpHandlerMultiBinding<McpToolHandler>): void {
240
+ binding.add(SessionInfoMcpToolHandler);
241
+ binding.add(ElementTypesMcpToolHandler);
242
+ }
243
+
244
+ /** See {@link configureToolHandlers}. No server-scope resources ship by default. */
245
+ protected configureResourceHandlers(_binding: McpHandlerMultiBinding<McpResourceHandler>): void {
246
+ // empty by default
247
+ }
248
+
249
+ /**
250
+ * See {@link configureToolHandlers}. Server-scope by default because the shipped prompts
251
+ * (`describe-diagram`, `suggest-improvements`) are diagram-type-agnostic and resolve their
252
+ * target session at invocation time — diagram-scope adopters add prompts via
253
+ * {@link DefaultMcpDiagramModule.configurePromptHandlers}.
254
+ */
255
+ protected configurePromptHandlers(binding: McpHandlerMultiBinding<McpPromptHandler>): void {
256
+ binding.add(DescribeDiagramMcpPromptHandler);
257
+ binding.add(SuggestImprovementsMcpPromptHandler);
258
+ }
259
+ }
260
+
261
+ /**
262
+ * Default {@link AbstractMcpServerModule} entry point. Ships GLSP-default option values (see
263
+ * {@link DEFAULT_OPTIONS}) on top of the abstract module's hook defaults. Adopter-provided
264
+ * overrides via the constructor merge on top.
265
+ *
266
+ * @experimental The MCP integration is under active development. Option names, schema shapes,
267
+ * and handler contracts MAY change in minor releases until the feature graduates from
268
+ * experimental status.
269
+ */
270
+ export class DefaultMcpServerModule extends AbstractMcpServerModule {
271
+ static readonly DEFAULT_OPTIONS: McpServerDefaults = {
272
+ host: '127.0.0.1',
273
+ allowedHosts: ['127.0.0.1', 'localhost'],
274
+ // `allowedOrigins` deliberately undefined: accept absent Origin (typical for desktop-IDE
275
+ // MCP clients) and rely on Host validation to gate DNS-rebinding. Adopters whose
276
+ // deployment is browser-fronted set this explicitly to their frontend's origin.
277
+ dataMode: 'tools',
278
+ agentPersona: DEFAULT_AGENT_PERSONA,
279
+ // 10K events per session is generous for typical workloads (a few MB) and large enough
280
+ // that disconnects within seconds recover via `Last-Event-ID` resumability.
281
+ eventStoreLimit: LruEventStore.DEFAULT_LIMIT
282
+ };
283
+
284
+ constructor(overrides: McpServerDefaults = {}) {
285
+ super({ ...DefaultMcpServerModule.DEFAULT_OPTIONS, ...overrides });
286
+ }
287
+ }