@pascal-app/mcp 1.0.3 → 1.0.5

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 (305) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +181 -56
  3. package/dist/bin/pascal-mcp.js +9 -3
  4. package/dist/bridge/agent-session.d.ts +18 -0
  5. package/dist/bridge/agent-session.d.ts.map +1 -0
  6. package/dist/bridge/agent-session.js +15 -0
  7. package/dist/bridge/index.d.ts +1 -1
  8. package/dist/bridge/index.d.ts.map +1 -1
  9. package/dist/bridge/scene-bridge.d.ts +42 -6
  10. package/dist/bridge/scene-bridge.d.ts.map +1 -1
  11. package/dist/bridge/scene-bridge.js +232 -45
  12. package/dist/index.d.ts +3 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/lib/safe-fetch.d.ts +22 -4
  16. package/dist/lib/safe-fetch.d.ts.map +1 -1
  17. package/dist/lib/safe-fetch.js +233 -134
  18. package/dist/operations/scene-operations.d.ts +41 -3
  19. package/dist/operations/scene-operations.d.ts.map +1 -1
  20. package/dist/operations/scene-operations.js +42 -1
  21. package/dist/prompts/from-brief.d.ts +1 -1
  22. package/dist/prompts/from-brief.d.ts.map +1 -1
  23. package/dist/prompts/from-brief.js +3 -3
  24. package/dist/prompts/index.d.ts +1 -1
  25. package/dist/prompts/index.d.ts.map +1 -1
  26. package/dist/prompts/iterate-on-feedback.d.ts +1 -1
  27. package/dist/prompts/iterate-on-feedback.d.ts.map +1 -1
  28. package/dist/prompts/iterate-on-feedback.js +3 -3
  29. package/dist/prompts/renovation-from-photos.d.ts +1 -1
  30. package/dist/prompts/renovation-from-photos.d.ts.map +1 -1
  31. package/dist/prompts/renovation-from-photos.js +2 -2
  32. package/dist/prompts/scene-guidance.d.ts.map +1 -1
  33. package/dist/prompts/scene-guidance.js +13 -6
  34. package/dist/resources/agent-guide.d.ts +1 -1
  35. package/dist/resources/agent-guide.d.ts.map +1 -1
  36. package/dist/resources/agent-guide.js +62 -33
  37. package/dist/resources/catalog-items.d.ts +5 -6
  38. package/dist/resources/catalog-items.d.ts.map +1 -1
  39. package/dist/resources/catalog-items.js +7 -9
  40. package/dist/resources/constraints.d.ts +1 -1
  41. package/dist/resources/constraints.d.ts.map +1 -1
  42. package/dist/resources/constraints.js +1 -1
  43. package/dist/resources/design-schema.d.ts +9 -0
  44. package/dist/resources/design-schema.d.ts.map +1 -0
  45. package/dist/resources/design-schema.js +21 -0
  46. package/dist/resources/index.d.ts +4 -2
  47. package/dist/resources/index.d.ts.map +1 -1
  48. package/dist/resources/index.js +5 -2
  49. package/dist/resources/scene-current.d.ts +1 -1
  50. package/dist/resources/scene-current.d.ts.map +1 -1
  51. package/dist/resources/scene-summary.d.ts +1 -1
  52. package/dist/resources/scene-summary.d.ts.map +1 -1
  53. package/dist/server.d.ts +25 -1
  54. package/dist/server.d.ts.map +1 -1
  55. package/dist/server.js +71 -25
  56. package/dist/storage/disk-artifact-store.d.ts +9 -0
  57. package/dist/storage/disk-artifact-store.d.ts.map +1 -0
  58. package/dist/storage/disk-artifact-store.js +46 -0
  59. package/dist/storage/index.d.ts +1 -0
  60. package/dist/storage/index.d.ts.map +1 -1
  61. package/dist/storage/index.js +1 -0
  62. package/dist/storage/sqlite-scene-store.d.ts +3 -3
  63. package/dist/storage/sqlite-scene-store.d.ts.map +1 -1
  64. package/dist/storage/sqlite-scene-store.js +4 -3
  65. package/dist/storage/types.d.ts +36 -7
  66. package/dist/storage/types.d.ts.map +1 -1
  67. package/dist/storage/types.js +12 -0
  68. package/dist/templates/empty-studio.d.ts +3 -3
  69. package/dist/templates/empty-studio.d.ts.map +1 -1
  70. package/dist/templates/garden-house.d.ts +3 -3
  71. package/dist/templates/garden-house.d.ts.map +1 -1
  72. package/dist/templates/index.d.ts.map +1 -1
  73. package/dist/templates/two-bedroom.d.ts +3 -3
  74. package/dist/templates/two-bedroom.d.ts.map +1 -1
  75. package/dist/tools/add-column.d.ts +5 -0
  76. package/dist/tools/add-column.d.ts.map +1 -0
  77. package/dist/tools/add-column.js +59 -0
  78. package/dist/tools/add-object.d.ts +76 -0
  79. package/dist/tools/add-object.d.ts.map +1 -0
  80. package/dist/tools/add-object.js +187 -0
  81. package/dist/tools/annotations.d.ts.map +1 -1
  82. package/dist/tools/apply-patch.d.ts +9 -2
  83. package/dist/tools/apply-patch.d.ts.map +1 -1
  84. package/dist/tools/apply-patch.js +36 -5
  85. package/dist/tools/asset-catalog.d.ts +9 -5
  86. package/dist/tools/asset-catalog.d.ts.map +1 -1
  87. package/dist/tools/asset-catalog.js +33 -12
  88. package/dist/tools/author-scene.d.ts +10 -0
  89. package/dist/tools/author-scene.d.ts.map +1 -0
  90. package/dist/tools/author-scene.js +140 -0
  91. package/dist/tools/check-collisions.d.ts +7 -7
  92. package/dist/tools/check-collisions.d.ts.map +1 -1
  93. package/dist/tools/check-collisions.js +7 -8
  94. package/dist/tools/clear-scene.d.ts +9 -0
  95. package/dist/tools/clear-scene.d.ts.map +1 -0
  96. package/dist/tools/clear-scene.js +59 -0
  97. package/dist/tools/collections.d.ts +4 -0
  98. package/dist/tools/collections.d.ts.map +1 -0
  99. package/dist/tools/collections.js +53 -0
  100. package/dist/tools/construction-tools.d.ts +12 -88
  101. package/dist/tools/construction-tools.d.ts.map +1 -1
  102. package/dist/tools/construction-tools.js +122 -381
  103. package/dist/tools/create-unit.d.ts +5 -3
  104. package/dist/tools/create-unit.d.ts.map +1 -1
  105. package/dist/tools/create-unit.js +2 -2
  106. package/dist/tools/errors.d.ts +15 -4
  107. package/dist/tools/errors.d.ts.map +1 -1
  108. package/dist/tools/errors.js +14 -4
  109. package/dist/tools/export-glb.d.ts +1 -1
  110. package/dist/tools/export-glb.d.ts.map +1 -1
  111. package/dist/tools/export-glb.js +2 -2
  112. package/dist/tools/export-json.d.ts +1 -1
  113. package/dist/tools/export-json.d.ts.map +1 -1
  114. package/dist/tools/export-json.js +2 -2
  115. package/dist/tools/geometry-script-worker.d.ts +2 -0
  116. package/dist/tools/geometry-script-worker.d.ts.map +1 -0
  117. package/dist/tools/geometry-script-worker.js +21 -0
  118. package/dist/tools/get-scene.d.ts +2 -1
  119. package/dist/tools/get-scene.d.ts.map +1 -1
  120. package/dist/tools/get-scene.js +5 -3
  121. package/dist/tools/honest-patch-guard.d.ts +2 -0
  122. package/dist/tools/honest-patch-guard.d.ts.map +1 -0
  123. package/dist/tools/honest-patch-guard.js +32 -0
  124. package/dist/tools/hosted-services.d.ts +4 -0
  125. package/dist/tools/hosted-services.d.ts.map +1 -0
  126. package/dist/tools/hosted-services.js +40 -0
  127. package/dist/tools/index.d.ts +12 -2
  128. package/dist/tools/index.d.ts.map +1 -1
  129. package/dist/tools/index.js +18 -32
  130. package/dist/tools/level-height-guard.d.ts +2 -0
  131. package/dist/tools/level-height-guard.d.ts.map +1 -0
  132. package/dist/tools/level-height-guard.js +11 -0
  133. package/dist/tools/list-units.d.ts +2 -2
  134. package/dist/tools/list-units.d.ts.map +1 -1
  135. package/dist/tools/list-units.js +2 -2
  136. package/dist/tools/live-sync.d.ts +25 -6
  137. package/dist/tools/live-sync.d.ts.map +1 -1
  138. package/dist/tools/live-sync.js +48 -27
  139. package/dist/tools/local-geometry-scripts.d.ts +8 -0
  140. package/dist/tools/local-geometry-scripts.d.ts.map +1 -0
  141. package/dist/tools/local-geometry-scripts.js +67 -0
  142. package/dist/tools/measure.d.ts +7 -1
  143. package/dist/tools/measure.d.ts.map +1 -1
  144. package/dist/tools/measure.js +38 -70
  145. package/dist/tools/measurement.d.ts +1 -36
  146. package/dist/tools/measurement.d.ts.map +1 -1
  147. package/dist/tools/measurement.js +2 -94
  148. package/dist/tools/node-world-point.d.ts +37 -0
  149. package/dist/tools/node-world-point.d.ts.map +1 -0
  150. package/dist/tools/node-world-point.js +457 -0
  151. package/dist/tools/normalize-schema-dialect.d.ts +1 -1
  152. package/dist/tools/normalize-schema-dialect.d.ts.map +1 -1
  153. package/dist/tools/normalize-schema-dialect.js +22 -3
  154. package/dist/tools/patch-guards.d.ts +60 -0
  155. package/dist/tools/patch-guards.d.ts.map +1 -0
  156. package/dist/tools/patch-guards.js +256 -0
  157. package/dist/tools/photo-to-scene/index.d.ts +1 -1
  158. package/dist/tools/photo-to-scene/index.d.ts.map +1 -1
  159. package/dist/tools/photo-to-scene/photo-to-scene.d.ts +3 -3
  160. package/dist/tools/photo-to-scene/photo-to-scene.d.ts.map +1 -1
  161. package/dist/tools/photo-to-scene/photo-to-scene.js +10 -9
  162. package/dist/tools/project-files.d.ts +4 -0
  163. package/dist/tools/project-files.d.ts.map +1 -0
  164. package/dist/tools/project-files.js +30 -0
  165. package/dist/tools/redo.d.ts +4 -2
  166. package/dist/tools/redo.d.ts.map +1 -1
  167. package/dist/tools/redo.js +4 -4
  168. package/dist/tools/retired-tools.d.ts +10 -0
  169. package/dist/tools/retired-tools.d.ts.map +1 -0
  170. package/dist/tools/retired-tools.js +22 -0
  171. package/dist/tools/roof-level-guard.d.ts +2 -0
  172. package/dist/tools/roof-level-guard.d.ts.map +1 -0
  173. package/dist/tools/roof-level-guard.js +22 -0
  174. package/dist/tools/room-tools.d.ts +36 -98
  175. package/dist/tools/room-tools.d.ts.map +1 -1
  176. package/dist/tools/room-tools.js +130 -565
  177. package/dist/tools/scene-lifecycle/create-project.d.ts +1 -1
  178. package/dist/tools/scene-lifecycle/create-project.d.ts.map +1 -1
  179. package/dist/tools/scene-lifecycle/create-project.js +31 -6
  180. package/dist/tools/scene-lifecycle/delete-scene.d.ts +3 -1
  181. package/dist/tools/scene-lifecycle/delete-scene.d.ts.map +1 -1
  182. package/dist/tools/scene-lifecycle/delete-scene.js +10 -9
  183. package/dist/tools/scene-lifecycle/get-project-status.d.ts +1 -1
  184. package/dist/tools/scene-lifecycle/get-project-status.d.ts.map +1 -1
  185. package/dist/tools/scene-lifecycle/get-project-status.js +6 -6
  186. package/dist/tools/scene-lifecycle/index.d.ts +1 -1
  187. package/dist/tools/scene-lifecycle/index.d.ts.map +1 -1
  188. package/dist/tools/scene-lifecycle/list-scenes.d.ts +1 -1
  189. package/dist/tools/scene-lifecycle/list-scenes.d.ts.map +1 -1
  190. package/dist/tools/scene-lifecycle/list-scenes.js +4 -4
  191. package/dist/tools/scene-lifecycle/load-scene.d.ts +2 -2
  192. package/dist/tools/scene-lifecycle/load-scene.d.ts.map +1 -1
  193. package/dist/tools/scene-lifecycle/load-scene.js +5 -5
  194. package/dist/tools/scene-lifecycle/metadata.d.ts +1 -1
  195. package/dist/tools/scene-lifecycle/rename-scene.d.ts +1 -1
  196. package/dist/tools/scene-lifecycle/rename-scene.d.ts.map +1 -1
  197. package/dist/tools/scene-lifecycle/rename-scene.js +6 -6
  198. package/dist/tools/scene-lifecycle/save-scene.d.ts +6 -3
  199. package/dist/tools/scene-lifecycle/save-scene.d.ts.map +1 -1
  200. package/dist/tools/scene-lifecycle/save-scene.js +124 -16
  201. package/dist/tools/scene-lifecycle/test-utils.d.ts +3 -3
  202. package/dist/tools/scene-lifecycle/test-utils.d.ts.map +1 -1
  203. package/dist/tools/scene-lifecycle/test-utils.js +2 -1
  204. package/dist/tools/set-unit-members.d.ts +4 -2
  205. package/dist/tools/set-unit-members.d.ts.map +1 -1
  206. package/dist/tools/set-unit-members.js +6 -6
  207. package/dist/tools/set-zone.d.ts +4 -2
  208. package/dist/tools/set-zone.d.ts.map +1 -1
  209. package/dist/tools/set-zone.js +30 -18
  210. package/dist/tools/shared-tools.d.ts +40 -0
  211. package/dist/tools/shared-tools.d.ts.map +1 -0
  212. package/dist/tools/shared-tools.js +574 -0
  213. package/dist/tools/structure-tools.d.ts +57 -0
  214. package/dist/tools/structure-tools.d.ts.map +1 -0
  215. package/dist/tools/structure-tools.js +57 -0
  216. package/dist/tools/templates/create-from-template.d.ts +2 -2
  217. package/dist/tools/templates/create-from-template.d.ts.map +1 -1
  218. package/dist/tools/templates/create-from-template.js +6 -6
  219. package/dist/tools/templates/create-house-from-brief.d.ts +1 -1
  220. package/dist/tools/templates/create-house-from-brief.d.ts.map +1 -1
  221. package/dist/tools/templates/create-house-from-brief.js +6 -6
  222. package/dist/tools/templates/index.d.ts +1 -1
  223. package/dist/tools/templates/index.d.ts.map +1 -1
  224. package/dist/tools/templates/list-templates.d.ts +1 -1
  225. package/dist/tools/templates/list-templates.d.ts.map +1 -1
  226. package/dist/tools/templates/list-templates.js +2 -2
  227. package/dist/tools/undo.d.ts +4 -2
  228. package/dist/tools/undo.d.ts.map +1 -1
  229. package/dist/tools/undo.js +4 -4
  230. package/dist/tools/unit-members.d.ts.map +1 -1
  231. package/dist/tools/unit-members.js +6 -6
  232. package/dist/tools/variants/generate-variants.d.ts +6 -6
  233. package/dist/tools/variants/generate-variants.d.ts.map +1 -1
  234. package/dist/tools/variants/generate-variants.js +6 -6
  235. package/dist/tools/variants/index.d.ts +1 -1
  236. package/dist/tools/variants/index.d.ts.map +1 -1
  237. package/dist/tools/variants/mutations.js +1 -1
  238. package/dist/tools/view-scene.d.ts +44 -0
  239. package/dist/tools/view-scene.d.ts.map +1 -0
  240. package/dist/tools/view-scene.js +75 -0
  241. package/dist/tools/vision/analyze-floorplan-image.d.ts +1 -1
  242. package/dist/tools/vision/analyze-floorplan-image.d.ts.map +1 -1
  243. package/dist/tools/vision/analyze-floorplan-image.js +7 -7
  244. package/dist/tools/vision/analyze-room-photo.d.ts +1 -1
  245. package/dist/tools/vision/analyze-room-photo.d.ts.map +1 -1
  246. package/dist/tools/vision/analyze-room-photo.js +7 -7
  247. package/dist/tools/vision/index.d.ts +1 -1
  248. package/dist/tools/vision/index.d.ts.map +1 -1
  249. package/dist/transports/http.d.ts +8 -2
  250. package/dist/transports/http.d.ts.map +1 -1
  251. package/dist/transports/http.js +9 -3
  252. package/dist/transports/stdio.d.ts +15 -9
  253. package/dist/transports/stdio.d.ts.map +1 -1
  254. package/dist/transports/stdio.js +18 -11
  255. package/dist/version.d.ts +5 -0
  256. package/dist/version.d.ts.map +1 -1
  257. package/dist/version.js +17 -3
  258. package/examples/coordinate-conventions-demo.md +12 -13
  259. package/examples/embed-in-agent.ts +6 -7
  260. package/examples/generate-apartment.md +13 -15
  261. package/examples/photo-to-scene.md +3 -4
  262. package/examples/renovate-from-photos.md +6 -9
  263. package/package.json +19 -9
  264. package/dist/tools/create-level.d.ts +0 -21
  265. package/dist/tools/create-level.d.ts.map +0 -1
  266. package/dist/tools/create-level.js +0 -63
  267. package/dist/tools/create-wall.d.ts +0 -22
  268. package/dist/tools/create-wall.d.ts.map +0 -1
  269. package/dist/tools/create-wall.js +0 -57
  270. package/dist/tools/cut-opening.d.ts +0 -25
  271. package/dist/tools/cut-opening.d.ts.map +0 -1
  272. package/dist/tools/cut-opening.js +0 -61
  273. package/dist/tools/delete-node.d.ts +0 -19
  274. package/dist/tools/delete-node.d.ts.map +0 -1
  275. package/dist/tools/delete-node.js +0 -40
  276. package/dist/tools/describe-node.d.ts +0 -17
  277. package/dist/tools/describe-node.d.ts.map +0 -1
  278. package/dist/tools/describe-node.js +0 -97
  279. package/dist/tools/door-clearance.d.ts +0 -135
  280. package/dist/tools/door-clearance.d.ts.map +0 -1
  281. package/dist/tools/door-clearance.js +0 -334
  282. package/dist/tools/duplicate-level.d.ts +0 -19
  283. package/dist/tools/duplicate-level.d.ts.map +0 -1
  284. package/dist/tools/duplicate-level.js +0 -60
  285. package/dist/tools/find-nodes.d.ts +0 -32
  286. package/dist/tools/find-nodes.d.ts.map +0 -1
  287. package/dist/tools/find-nodes.js +0 -107
  288. package/dist/tools/geometry.d.ts +0 -24
  289. package/dist/tools/geometry.d.ts.map +0 -1
  290. package/dist/tools/geometry.js +0 -94
  291. package/dist/tools/get-node.d.ts +0 -11
  292. package/dist/tools/get-node.d.ts.map +0 -1
  293. package/dist/tools/get-node.js +0 -29
  294. package/dist/tools/layout-clearance.d.ts +0 -105
  295. package/dist/tools/layout-clearance.d.ts.map +0 -1
  296. package/dist/tools/layout-clearance.js +0 -190
  297. package/dist/tools/place-item.d.ts +0 -22
  298. package/dist/tools/place-item.d.ts.map +0 -1
  299. package/dist/tools/place-item.js +0 -89
  300. package/dist/tools/scene-query.d.ts +0 -62
  301. package/dist/tools/scene-query.d.ts.map +0 -1
  302. package/dist/tools/scene-query.js +0 -670
  303. package/dist/tools/validate-scene.d.ts +0 -19
  304. package/dist/tools/validate-scene.d.ts.map +0 -1
  305. package/dist/tools/validate-scene.js +0 -28
@@ -1,4 +1,4 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1
+ import type { McpServer } from '@modelcontextprotocol/server';
2
2
  export type HttpTransportHandle = {
3
3
  /** Host interface the server is listening on. */
4
4
  host: string;
@@ -28,10 +28,16 @@ export type HttpTransportOptions = {
28
28
  /**
29
29
  * Attach an `McpServer` to a Streamable HTTP transport bound to a local port.
30
30
  *
31
- * Uses the SDK's Node-flavored `StreamableHTTPServerTransport`, which accepts
31
+ * Uses the SDK's `NodeStreamableHTTPServerTransport`, which accepts
32
32
  * `IncomingMessage`/`ServerResponse` directly via `handleRequest(req, res)`.
33
33
  * A new session ID is generated per connection (stateful mode).
34
34
  *
35
+ * Serves the 2025 sessionful protocol only: a negotiating client falls back
36
+ * to it, and a client pinned to 2026-07-28 is refused. The SDK serves
37
+ * 2026-07-28 over HTTP per request (`createMcpHandler`), with a fresh server
38
+ * from the factory each time, and every server here owns its own scene, so a
39
+ * session is what keeps one client's scene between calls.
40
+ *
35
41
  * Listens on `127.0.0.1:<port>` (pass `0` for an ephemeral port in tests). The
36
42
  * returned handle exposes the actual bound port and a `close()` that stops
37
43
  * the underlying Node HTTP server. To bind a public interface, pass `host` and
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/transports/http.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAUxE,MAAM,MAAM,mBAAmB,GAAG;IAChC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAA;IACZ,8DAA8D;IAC9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,8EAA8E;IAC9E,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CACjD,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,eAAe,EAAE,MAAM,SAAS,EAChC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA2G9B"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/transports/http.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAS7D,MAAM,MAAM,mBAAmB,GAAG;IAChC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAA;IACZ,8DAA8D;IAC9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,8EAA8E;IAC9E,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CACjD,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,WAAW,CAC/B,eAAe,EAAE,MAAM,SAAS,EAChC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA2G9B"}
@@ -1,6 +1,6 @@
1
1
  import { randomUUID, timingSafeEqual } from 'node:crypto';
2
2
  import { createServer } from 'node:http';
3
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
3
+ import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node';
4
4
  const DEFAULT_HOST = '127.0.0.1';
5
5
  const DEFAULT_RATE_LIMIT_PER_MINUTE = 120;
6
6
  const WINDOW_MS = 60_000;
@@ -9,10 +9,16 @@ const ALLOWED_HEADERS = 'authorization, content-type, mcp-session-id, mcp-protoc
9
9
  /**
10
10
  * Attach an `McpServer` to a Streamable HTTP transport bound to a local port.
11
11
  *
12
- * Uses the SDK's Node-flavored `StreamableHTTPServerTransport`, which accepts
12
+ * Uses the SDK's `NodeStreamableHTTPServerTransport`, which accepts
13
13
  * `IncomingMessage`/`ServerResponse` directly via `handleRequest(req, res)`.
14
14
  * A new session ID is generated per connection (stateful mode).
15
15
  *
16
+ * Serves the 2025 sessionful protocol only: a negotiating client falls back
17
+ * to it, and a client pinned to 2026-07-28 is refused. The SDK serves
18
+ * 2026-07-28 over HTTP per request (`createMcpHandler`), with a fresh server
19
+ * from the factory each time, and every server here owns its own scene, so a
20
+ * session is what keeps one client's scene between calls.
21
+ *
16
22
  * Listens on `127.0.0.1:<port>` (pass `0` for an ephemeral port in tests). The
17
23
  * returned handle exposes the actual bound port and a `close()` that stops
18
24
  * the underlying Node HTTP server. To bind a public interface, pass `host` and
@@ -66,7 +72,7 @@ export async function connectHttp(createMcpServer, port, options = {}) {
66
72
  let transport = sessionId ? transports.get(sessionId) : undefined;
67
73
  if (!transport && req.method === 'POST' && !sessionId) {
68
74
  let createdTransport;
69
- createdTransport = new StreamableHTTPServerTransport({
75
+ createdTransport = new NodeStreamableHTTPServerTransport({
70
76
  sessionIdGenerator: () => randomUUID(),
71
77
  onsessioninitialized: (id) => {
72
78
  transports.set(id, createdTransport);
@@ -1,14 +1,20 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1
+ import type { McpServer } from '@modelcontextprotocol/server';
2
+ import { type ServeStdioOptions, type StdioServerHandle } from '@modelcontextprotocol/server/stdio';
2
3
  /**
3
- * Attach an `McpServer` to the stdio transport.
4
+ * Serve Pascal over stdio from a server factory.
4
5
  *
5
- * The server takes ownership of stdin/stdout for JSON-RPC messaging. Callers
6
- * must send any operator logging to stderr (not stdout) to avoid corrupting
7
- * the protocol stream.
6
+ * The SDK negotiates the protocol era per connection: a client that opens with
7
+ * the 2025 `initialize` handshake and one that opens with the 2026-07-28
8
+ * `server/discover` probe are both served. A server handed to
9
+ * `StdioServerTransport` directly would answer only the first. The factory can
10
+ * be called twice on one connection (a discarded probe instance, then the
11
+ * instance that serves it), so it must build a fresh, unconnected server each
12
+ * time.
8
13
  *
9
- * Resolves once the transport is started. The underlying transport keeps the
10
- * process alive as long as stdin is open, so callers typically just `await`
11
- * this and then let the event loop run.
14
+ * The connection owns stdin/stdout for JSON-RPC messaging. Callers must send
15
+ * any operator logging to stderr (not stdout) to avoid corrupting the protocol
16
+ * stream. The process stays alive while stdin is open; the connection tears
17
+ * itself down when stdin reaches end-of-file.
12
18
  */
13
- export declare function connectStdio(server: McpServer): Promise<void>;
19
+ export declare function connectStdio(createServer: () => McpServer, options?: Pick<ServeStdioOptions, 'transport' | 'onerror'>): StdioServerHandle;
14
20
  //# sourceMappingURL=stdio.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/transports/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnE"}
1
+ {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/transports/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAEvB,MAAM,oCAAoC,CAAA;AAE3C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,MAAM,SAAS,EAC7B,OAAO,GAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,GAAG,SAAS,CAAM,GAC7D,iBAAiB,CAKnB"}
@@ -1,16 +1,23 @@
1
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
1
+ import { serveStdio, } from '@modelcontextprotocol/server/stdio';
2
2
  /**
3
- * Attach an `McpServer` to the stdio transport.
3
+ * Serve Pascal over stdio from a server factory.
4
4
  *
5
- * The server takes ownership of stdin/stdout for JSON-RPC messaging. Callers
6
- * must send any operator logging to stderr (not stdout) to avoid corrupting
7
- * the protocol stream.
5
+ * The SDK negotiates the protocol era per connection: a client that opens with
6
+ * the 2025 `initialize` handshake and one that opens with the 2026-07-28
7
+ * `server/discover` probe are both served. A server handed to
8
+ * `StdioServerTransport` directly would answer only the first. The factory can
9
+ * be called twice on one connection (a discarded probe instance, then the
10
+ * instance that serves it), so it must build a fresh, unconnected server each
11
+ * time.
8
12
  *
9
- * Resolves once the transport is started. The underlying transport keeps the
10
- * process alive as long as stdin is open, so callers typically just `await`
11
- * this and then let the event loop run.
13
+ * The connection owns stdin/stdout for JSON-RPC messaging. Callers must send
14
+ * any operator logging to stderr (not stdout) to avoid corrupting the protocol
15
+ * stream. The process stays alive while stdin is open; the connection tears
16
+ * itself down when stdin reaches end-of-file.
12
17
  */
13
- export async function connectStdio(server) {
14
- const transport = new StdioServerTransport();
15
- await server.connect(transport);
18
+ export function connectStdio(createServer, options = {}) {
19
+ return serveStdio(createServer, {
20
+ onerror: (error) => console.error('[pascal-mcp] stdio transport error', error),
21
+ ...options,
22
+ });
16
23
  }
package/dist/version.d.ts CHANGED
@@ -1,2 +1,7 @@
1
+ /**
2
+ * The package version, for the server's handshake. Read from package.json
3
+ * at runtime under Node (and Bun) without a static `node:fs` import, so the
4
+ * server entry also bundles for the browser, where the editor runs it in-page.
5
+ */
1
6
  export declare const version: string;
2
7
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,QAMT,CAAA"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,OAAO,QACkE,CAAA"}
package/dist/version.js CHANGED
@@ -1,3 +1,17 @@
1
- import { readFileSync } from 'node:fs';
2
- export const version = process.env.PASCAL_MCP_VERSION ??
3
- JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
1
+ /**
2
+ * The package version, for the server's handshake. Read from package.json
3
+ * at runtime under Node (and Bun) without a static `node:fs` import, so the
4
+ * server entry also bundles for the browser, where the editor runs it in-page.
5
+ */
6
+ export const version = (typeof process !== 'undefined' && process.env?.PASCAL_MCP_VERSION) || readVersion();
7
+ function readVersion() {
8
+ try {
9
+ const fs = globalThis.process?.getBuiltinModule?.('node:fs');
10
+ if (!fs)
11
+ return '0.0.0';
12
+ return JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
13
+ }
14
+ catch {
15
+ return '0.0.0';
16
+ }
17
+ }
@@ -19,43 +19,42 @@ A flat ground level with four demos, plus a labelled compass at the
19
19
  origin so the world axes are unambiguous regardless of which viewport
20
20
  you're in.
21
21
 
22
- | Section | What | Why |
23
- |---|---|---|
24
- | Reference compass at the origin | 12 m `+X` and `+Z` axis bars with arrowhead tips, short `-X` / `-Z` stubs, an origin marker, plus zone labels naming each component of `[x, z]`. | Establishes which way `+X` and `+Z` actually point in world space, independent of viewport rotation. |
25
- | **Demo A** at world `(18, 0)` | Axis-aligned 6 m × 4 m rectangle. | Baseline that matches the only example currently in `examples/generate-apartment.md` style (`[0,0] → [10,0]`). |
26
- | **Demo B** at world `(18, 10)` | The proposed README example, **verbatim**: `polygon: [[0,0],[5.196,3.0],[3.196,6.464],[-2.0,3.464]]` at this offset. | Programmatically verified to be a 6 m × 4 m rectangle whose first edge is heading 30° CCW from `+X` (side lengths 6/4/6/4 m to 4 dp, `AB · AD = 0`, heading = 30.0007°). Confirms the README's worked example produces the geometry it claims. |
27
- | **Demo C** at world `(0, 22)` and `(10, 22)` | An **L** authored on a north-up page (page-+x right, page-+y up) drawn at half scale and faded; alongside it, the same L pasted into `[x, z]` **uncorrected**, drawn at full scale and vivid. | Makes the external-coordinate gotcha visual: the author's page-+y direction lands on world +Z, which does not correspond to "screen-up" in any of Pascal's viewports. |
28
- | **Demo D** at world `(22, 22)` and `(32, 22)` | Same pairing for the L with its second coordinate reflected (`z → 5 − z`) before paste. | Makes plain that z-reflection only "corrects" a true mirror; Pascal's viewports apply a *rotation*, so the reflection produces a mirror-image of Demo C rather than a page-correct L. |
29
- | Takeaway band on the south edge | Short labels summarising the convention. | Self-documenting; readable in any viewport without an external README. |
22
+ | Section | What | Why |
23
+ | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
+ | Reference compass at the origin | 12 m `+X` and `+Z` axis bars with arrowhead tips, short `-X` / `-Z` stubs, an origin marker, plus zone labels naming each component of `[x, z]`. | Establishes which way `+X` and `+Z` actually point in world space, independent of viewport rotation. |
25
+ | **Demo A** at world `(18, 0)` | Axis-aligned 6 m × 4 m rectangle. | Baseline that matches the only example currently in `examples/generate-apartment.md` style (`[0,0] → [10,0]`). |
26
+ | **Demo B** at world `(18, 10)` | The proposed README example, **verbatim**: `polygon: [[0,0],[5.196,3.0],[3.196,6.464],[-2.0,3.464]]` at this offset. | Programmatically verified to be a 6 m × 4 m rectangle whose first edge is heading 30° CCW from `+X` (side lengths 6/4/6/4 m to 4 dp, `AB · AD = 0`, heading = 30.0007°). Confirms the README's worked example produces the geometry it claims. |
27
+ | **Demo C** at world `(0, 22)` and `(10, 22)` | An **L** authored on a north-up page (page-+x right, page-+y up) drawn at half scale and faded; alongside it, the same L pasted into `[x, z]` **uncorrected**, drawn at full scale and vivid. | Makes the external-coordinate gotcha visual: the author's page-+y direction lands on world +Z, which does not correspond to "screen-up" in any of Pascal's viewports. |
28
+ | **Demo D** at world `(22, 22)` and `(32, 22)` | Same pairing for the L with its second coordinate reflected (`z → 5 − z`) before paste. | Makes plain that z-reflection only "corrects" a true mirror; Pascal's viewports apply a _rotation_, so the reflection produces a mirror-image of Demo C rather than a page-correct L. |
29
+ | Takeaway band on the south edge | Short labels summarising the convention. | Self-documenting; readable in any viewport without an external README. |
30
30
 
31
31
  ## What it confirms
32
32
 
33
33
  Open the scene in Pascal (or render it from the JSON) and you can read
34
34
  each claim directly off the geometry:
35
-
36
35
  1. **`[x, z] → world (x, 0, z)` is exact, no sign flip.** Demo A and
37
36
  Demo B both sit flat on the floor at Y = 0; their polygon vertices
38
37
  round-trip through `save_scene` / `get_scene` byte-identical to what
39
- was authored (graph hash matches, see `validate_scene` output).
38
+ was authored (graph hash matches, see `save_scene` output).
40
39
 
41
40
  2. **Demo B is the rectangle the README says it is.** A simple analytic
42
41
  check on its 4 vertices yields side lengths 6, 4, 6, 4 m (to 4 dp)
43
42
  with the first edge at 30.0007° from +X and perpendicular adjacent
44
43
  edges. No rendering required.
45
44
 
46
- 3. **External page coordinates *rotate* (not mirror) when pasted as
45
+ 3. **External page coordinates _rotate_ (not mirror) when pasted as
47
46
  `[x, z]` and viewed in Pascal.** Inspecting Demo C in the 2-D plan
48
47
  panel: the page-up L lands rotated 90° clockwise, so the author's
49
48
  "stem-up, foot-bottom-right" reads as "stem-on-right, foot-along-top"
50
49
  on screen. Inspecting Demo D right next to it: the z-reflected
51
- variant lands as the *mirror* of Demo C — neither matches a
50
+ variant lands as the _mirror_ of Demo C — neither matches a
52
51
  page-correct L. That demonstrates why "reflect across the axis" is
53
52
  the wrong corrective for an issue that is, in this viewport, a
54
53
  rotation.
55
54
 
56
55
  4. **The 3-D "top-down" snap is offset 45° from world axes by default.**
57
56
  Viewing the scene in 3-D and snapping to top-down from the default
58
- iso camera shows the rectangular site polygon as a *diamond* (its
57
+ iso camera shows the rectangular site polygon as a _diamond_ (its
59
58
  long edges are diagonals on screen, not axis-aligned). That's the
60
59
  camera's "up" vector being inherited from the iso start; once you
61
60
  orbit to a true axis-aligned top-down it goes away. The label
@@ -10,8 +10,7 @@
10
10
  * bun run packages/mcp/examples/embed-in-agent.ts
11
11
  */
12
12
 
13
- import { Client } from '@modelcontextprotocol/sdk/client/index.js'
14
- import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js'
13
+ import { Client, InMemoryTransport } from '@modelcontextprotocol/client'
15
14
  import { createPascalMcpServer, SceneBridge } from '@pascal-app/mcp'
16
15
 
17
16
  async function main(): Promise<void> {
@@ -40,14 +39,14 @@ async function main(): Promise<void> {
40
39
 
41
40
  // 5. Find the default level, create a 5 m wall, and undo it.
42
41
  const levels = await client.callTool({
43
- name: 'find_nodes',
42
+ name: 'find_by_type',
44
43
  arguments: { type: 'level' },
45
44
  })
46
- const levelId = (levels.structuredContent as { nodes: Array<{ id: string }> }).nodes[0]?.id
45
+ const levelId = (levels.structuredContent as { results: Array<{ id: string }> }).results[0]?.id
47
46
 
48
47
  if (levelId) {
49
48
  const created = await client.callTool({
50
- name: 'create_wall',
49
+ name: 'add_wall',
51
50
  arguments: {
52
51
  levelId,
53
52
  start: [0, 0],
@@ -63,8 +62,8 @@ async function main(): Promise<void> {
63
62
  }
64
63
 
65
64
  // 6. Validate and export.
66
- const validation = await client.callTool({ name: 'validate_scene', arguments: {} })
67
- console.log('validation:', validation.structuredContent)
65
+ const verification = await client.callTool({ name: 'verify_scene', arguments: {} })
66
+ console.log('verification:', verification.structuredContent)
68
67
 
69
68
  const exported = await client.callTool({
70
69
  name: 'export_json',
@@ -157,36 +157,34 @@ them by name:
157
157
 
158
158
  ### 5. Cut doors and windows
159
159
 
160
- The agent uses `cut_opening` to add entry doors on each interior partition
161
- and windows on the south and east façades:
160
+ The agent uses `add_door` for the entry doors on each interior partition and
161
+ `add_window` for the windows on the south and east façades:
162
162
 
163
163
  ```jsonc
164
- // tool: cut_opening (called once per opening)
164
+ // tool: add_window (called once per window)
165
165
  {
166
- "name": "cut_opening",
166
+ "name": "add_window",
167
167
  "arguments": {
168
168
  "wallId": "wall-south", // perimeter wall [0,0] → [10,0]
169
- "type": "window",
170
- "position": 0.25, // 25% along centerline
169
+ "t": 0.25, // 25% along centerline
171
170
  "width": 1.2,
172
171
  "height": 1.2
173
172
  }
174
173
  }
175
- // → { "openingId": "window-south-1" }
174
+ // → { "windowId": "window-south-1", ... }
176
175
  ```
177
176
 
178
177
  ```jsonc
179
178
  {
180
- "name": "cut_opening",
179
+ "name": "add_door",
181
180
  "arguments": {
182
181
  "wallId": "wall-bed1", // partition wall to Bedroom 1
183
- "type": "door",
184
- "position": 0.4,
182
+ "t": 0.4,
185
183
  "width": 0.9,
186
184
  "height": 2.1
187
185
  }
188
186
  }
189
- // → { "openingId": "door-bed1" }
187
+ // → { "doorId": "door-bed1", ... }
190
188
  ```
191
189
 
192
190
  The agent repeats this for Bedroom 2's door, the bathroom door, and two
@@ -195,14 +193,14 @@ more windows on the east façade.
195
193
  ### 6. Validate and report
196
194
 
197
195
  ```jsonc
198
- // tool: validate_scene
199
- { "name": "validate_scene", "arguments": {} }
196
+ // tool: verify_scene
197
+ { "name": "verify_scene", "arguments": {} }
200
198
  ```
201
199
 
202
200
  Response:
203
201
 
204
202
  ```jsonc
205
- { "valid": true, "errors": [] }
203
+ { "valid": true, "issues": [], "hasIssues": false, … }
206
204
  ```
207
205
 
208
206
  The agent then reads the scene summary for its response to the user:
@@ -237,6 +235,6 @@ Zustand store, the user can `undo` the change if they dislike it:
237
235
  - Mutations batch inside a single `apply_patch` so that `undo` rolls back
238
236
  the whole logical change.
239
237
  - Zones are not walls — they're polygon annotations that make later queries
240
- (`find_nodes({ zoneId })`) and planning steps much easier for the agent.
238
+ (`find_by_type({ zoneId })`) and planning steps much easier for the agent.
241
239
  - The agent never needs to speak to `@pascal-app/viewer`: everything the
242
240
  host sees flows through tools + resources + prompts.
@@ -33,7 +33,6 @@ The agent reads the attachment as a data URI and issues a single tool call:
33
33
  ```
34
34
 
35
35
  Optional knobs:
36
-
37
36
  - `save` (default `true`) — if `false`, the response includes `graph`
38
37
  inline instead of persisting to the `SceneStore`.
39
38
  - `defaultWallThickness` (default `0.2` m) — used when the vision model
@@ -56,7 +55,7 @@ Optional knobs:
56
55
  re-parsed with `AnyNode.safeParse`; invalid ones are dropped with a
57
56
  warning appended to `notes`.
58
57
  4. `bridge.setScene(...)` swaps the live scene so any follow-up MCP call
59
- (`find_nodes`, `measure`, `apply_patch`, ...) operates on the new
58
+ (`find_by_type`, `measure`, `apply_patch`, ...) operates on the new
60
59
  geometry.
61
60
  5. If `save: true`, the graph is persisted via `SceneStore.save` and the
62
61
  response carries `sceneId` + `url: /scene/<id>`.
@@ -109,8 +108,8 @@ operate on it without reloading:
109
108
 
110
109
  > **User:** add a door on the south wall between Living and Kitchen.
111
110
 
112
- The agent calls `find_nodes({ type: "wall" })`, picks the appropriate
113
- wall, and issues `cut_opening` — no extra wiring needed.
111
+ The agent calls `find_by_type({ type: "wall" })`, picks the appropriate
112
+ wall, and issues `add_door` — no extra wiring needed.
114
113
 
115
114
  ## Takeaways
116
115
 
@@ -12,7 +12,6 @@ tools to propose a renovation plan grounded in real photos.
12
12
  ## The brief
13
13
 
14
14
  The user drops four photos into the chat:
15
-
16
15
  1. A floorplan PDF page (exported as PNG).
17
16
  2. A photo of the current living room.
18
17
  3. A photo of the current kitchen.
@@ -129,16 +128,15 @@ Bedroom polygons from the floorplan rooms.
129
128
 
130
129
  ### 4. Cut the identified openings
131
130
 
132
- For each window the vision tool reported, the agent calls `cut_opening`
131
+ For each window the vision tool reported, the agent calls `add_window`
133
132
  against the corresponding perimeter wall:
134
133
 
135
134
  ```jsonc
136
135
  {
137
- "name": "cut_opening",
136
+ "name": "add_window",
138
137
  "arguments": {
139
138
  "wallId": "wall-south",
140
- "type": "window",
141
- "position": 0.5,
139
+ "t": 0.5,
142
140
  "width": 1.4,
143
141
  "height": 1.5
144
142
  }
@@ -149,7 +147,6 @@ against the corresponding perimeter wall:
149
147
 
150
148
  Guided by the reference photo's analysis (bright neutrals, open plan,
151
149
  minimal furnishing), the agent proposes a single logical patch:
152
-
153
150
  - Remove the partition wall between Living and Kitchen.
154
151
  - Relocate the kitchen island further west.
155
152
  - Delete the bulky TV unit item; leave the sofa and coffee table.
@@ -178,9 +175,9 @@ The user can walk back with `undo`; `redo` returns them to the proposal.
178
175
  ### 6. Sanity-check
179
176
 
180
177
  ```jsonc
181
- // tool: validate_scene
182
- { "name": "validate_scene", "arguments": {} }
183
- // → { "valid": true, "errors": [] }
178
+ // tool: verify_scene
179
+ { "name": "verify_scene", "arguments": {} }
180
+ // → { "valid": true, "issues": [], "hasIssues": false, … }
184
181
 
185
182
  // tool: check_collisions
186
183
  { "name": "check_collisions", "arguments": { "levelId": "level-1" } }
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@pascal-app/mcp",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Model Context Protocol server for Pascal 3D editor",
5
+ "mcpName": "app.pascal/editor",
5
6
  "type": "module",
6
7
  "main": "./dist/index.js",
7
8
  "types": "./dist/index.d.ts",
@@ -35,6 +36,11 @@
35
36
  "types": "./dist/bridge/index.d.ts",
36
37
  "import": "./dist/bridge/index.js",
37
38
  "default": "./dist/bridge/index.js"
39
+ },
40
+ "./tools/*": {
41
+ "types": "./dist/tools/*.d.ts",
42
+ "import": "./dist/tools/*.js",
43
+ "default": "./dist/tools/*.js"
38
44
  }
39
45
  },
40
46
  "bin": {
@@ -47,7 +53,7 @@
47
53
  "CHANGELOG.md"
48
54
  ],
49
55
  "scripts": {
50
- "build": "tsc --build && bun ../../scripts/fix-node-esm-imports.ts ../core/dist && bun ../../scripts/fix-node-esm-imports.ts dist",
56
+ "build": "tsc --build && bun ../../scripts/fix-node-esm-imports.ts ../core/dist && bun ../../scripts/fix-node-esm-imports.ts ../geometry-script/dist && bun ../../scripts/fix-node-esm-imports.ts dist",
51
57
  "dev": "tsgo --build --watch",
52
58
  "start": "bun dist/bin/pascal-mcp.js",
53
59
  "test": "bun test",
@@ -56,18 +62,22 @@
56
62
  "prepublishOnly": "bun run build && bun test && bun run smoke:node"
57
63
  },
58
64
  "peerDependencies": {
59
- "@pascal-app/core": "^1.0.3"
65
+ "@pascal-app/core": "^1.0.5"
60
66
  },
61
67
  "dependencies": {
62
- "@modelcontextprotocol/sdk": "^1.30.0",
63
- "@pascal-app/lingo": "^0.2.0",
64
- "zod": ">=4.5.4 <4.6"
68
+ "@hono/node-server": "^1.19.15",
69
+ "@modelcontextprotocol/node": "^2.1.1",
70
+ "@modelcontextprotocol/server": "^2.3.1",
71
+ "@pascal-app/geometry-script": "^1.0.5",
72
+ "@pascal-app/lingo": "^0.5.0",
73
+ "zod": ">=4.6.7 <4.7"
65
74
  },
66
75
  "devDependencies": {
67
- "@pascal-app/core": "^1.0.3",
76
+ "@modelcontextprotocol/client": "^2.3.1",
77
+ "@pascal-app/core": "^1.0.5",
68
78
  "@pascal/typescript-config": "*",
69
- "@types/node": "^22.19.20",
70
- "typescript": "6.0.3"
79
+ "@types/node": "^26.6.5",
80
+ "typescript": "7.0.2"
71
81
  },
72
82
  "keywords": [
73
83
  "mcp",
@@ -1,21 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { z } from 'zod';
3
- import type { SceneOperations } from '../operations/index.js';
4
- export declare const createLevelInput: {
5
- buildingId: z.ZodString;
6
- elevation: z.ZodOptional<z.ZodNumber>;
7
- height: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
8
- label: z.ZodOptional<z.ZodString>;
9
- };
10
- export declare const createLevelOutput: {
11
- persistence: z.ZodOptional<z.ZodObject<{
12
- status: z.ZodEnum<{
13
- unbound: "unbound";
14
- events_unsupported: "events_unsupported";
15
- }>;
16
- warning: z.ZodString;
17
- }, z.core.$strip>>;
18
- levelId: z.ZodString;
19
- };
20
- export declare function registerCreateLevel(server: McpServer, bridge: SceneOperations): void;
21
- //# sourceMappingURL=create-level.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-level.d.ts","sourceRoot":"","sources":["../../src/tools/create-level.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAIxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAOpD,eAAO,MAAM,gBAAgB;;;;;CAW5B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;CAG7B,CAAA;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAgDpF"}
@@ -1,63 +0,0 @@
1
- import { DEFAULT_LEVEL_HEIGHT } from '@pascal-app/core';
2
- import { LevelNode } from '@pascal-app/core/schema';
3
- import { z } from 'zod';
4
- import { ADDITIVE_TOOL_ANNOTATIONS } from './annotations.js';
5
- import { ErrorCode, throwMcpError } from './errors.js';
6
- import { liveSyncOutput, persistencePayload, publishLiveSceneSnapshot } from './live-sync.js';
7
- import { measurement } from './measurement.js';
8
- import { NodeIdSchema } from './schemas.js';
9
- export const createLevelInput = {
10
- buildingId: NodeIdSchema,
11
- elevation: z
12
- .number()
13
- .optional()
14
- .describe("Legacy parameter; new levels are appended above the building's current top level."),
15
- height: measurement('length', 'm', {
16
- min: 0,
17
- description: 'Stored floor-to-floor storey height.',
18
- }).optional(),
19
- label: z.string().optional(),
20
- };
21
- export const createLevelOutput = {
22
- levelId: z.string(),
23
- ...liveSyncOutput,
24
- };
25
- export function registerCreateLevel(server, bridge) {
26
- server.registerTool('create_level', {
27
- title: 'Create level',
28
- description: "Append a new level above the given building's current top level. height is stored as the level's floor-to-floor storey height.",
29
- inputSchema: createLevelInput,
30
- outputSchema: createLevelOutput,
31
- annotations: ADDITIVE_TOOL_ANNOTATIONS,
32
- }, async ({ buildingId, height, label }) => {
33
- const parent = bridge.getNode(buildingId);
34
- if (!parent) {
35
- throwMcpError(ErrorCode.InvalidParams, `Building not found: ${buildingId}`);
36
- }
37
- if (parent.type !== 'building') {
38
- throwMcpError(ErrorCode.InvalidParams, `Node ${buildingId} is a ${parent.type}, expected building`);
39
- }
40
- const metadata = {};
41
- if (label !== undefined)
42
- metadata.label = label;
43
- const existingOrdinals = bridge
44
- .getChildren(buildingId)
45
- .filter((node) => node.type === 'level')
46
- .map((node) => node.level);
47
- const nextOrdinal = Math.max(-1, ...existingOrdinals) + 1;
48
- const levelNode = LevelNode.parse({
49
- level: nextOrdinal,
50
- height: height ?? DEFAULT_LEVEL_HEIGHT,
51
- children: [],
52
- ...(Object.keys(metadata).length > 0 ? { metadata } : {}),
53
- ...(label !== undefined ? { name: label } : {}),
54
- });
55
- const id = bridge.createNode(levelNode, buildingId);
56
- const persistence = await publishLiveSceneSnapshot(bridge, 'create_level');
57
- const payload = { levelId: id, ...persistencePayload(persistence) };
58
- return {
59
- content: [{ type: 'text', text: JSON.stringify(payload) }],
60
- structuredContent: payload,
61
- };
62
- });
63
- }
@@ -1,22 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { z } from 'zod';
3
- import type { SceneOperations } from '../operations/index.js';
4
- export declare const createWallInput: {
5
- levelId: z.ZodString;
6
- start: z.ZodArray<z.ZodNumber>;
7
- end: z.ZodArray<z.ZodNumber>;
8
- thickness: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
9
- height: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>>;
10
- };
11
- export declare const createWallOutput: {
12
- persistence: z.ZodOptional<z.ZodObject<{
13
- status: z.ZodEnum<{
14
- unbound: "unbound";
15
- events_unsupported: "events_unsupported";
16
- }>;
17
- warning: z.ZodString;
18
- }, z.core.$strip>>;
19
- wallId: z.ZodString;
20
- };
21
- export declare function registerCreateWall(server: McpServer, bridge: SceneOperations): void;
22
- //# sourceMappingURL=create-wall.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-wall.d.ts","sourceRoot":"","sources":["../../src/tools/create-wall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAOpD,eAAO,MAAM,eAAe;;;;;;CAS3B,CAAA;AAED,eAAO,MAAM,gBAAgB;;;;;;;;;CAG5B,CAAA;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAiDnF"}