@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.
- package/CHANGELOG.md +76 -0
- package/README.md +181 -56
- package/dist/bin/pascal-mcp.js +9 -3
- package/dist/bridge/agent-session.d.ts +18 -0
- package/dist/bridge/agent-session.d.ts.map +1 -0
- package/dist/bridge/agent-session.js +15 -0
- package/dist/bridge/index.d.ts +1 -1
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/scene-bridge.d.ts +42 -6
- package/dist/bridge/scene-bridge.d.ts.map +1 -1
- package/dist/bridge/scene-bridge.js +232 -45
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lib/safe-fetch.d.ts +22 -4
- package/dist/lib/safe-fetch.d.ts.map +1 -1
- package/dist/lib/safe-fetch.js +233 -134
- package/dist/operations/scene-operations.d.ts +41 -3
- package/dist/operations/scene-operations.d.ts.map +1 -1
- package/dist/operations/scene-operations.js +42 -1
- package/dist/prompts/from-brief.d.ts +1 -1
- package/dist/prompts/from-brief.d.ts.map +1 -1
- package/dist/prompts/from-brief.js +3 -3
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/iterate-on-feedback.d.ts +1 -1
- package/dist/prompts/iterate-on-feedback.d.ts.map +1 -1
- package/dist/prompts/iterate-on-feedback.js +3 -3
- package/dist/prompts/renovation-from-photos.d.ts +1 -1
- package/dist/prompts/renovation-from-photos.d.ts.map +1 -1
- package/dist/prompts/renovation-from-photos.js +2 -2
- package/dist/prompts/scene-guidance.d.ts.map +1 -1
- package/dist/prompts/scene-guidance.js +13 -6
- package/dist/resources/agent-guide.d.ts +1 -1
- package/dist/resources/agent-guide.d.ts.map +1 -1
- package/dist/resources/agent-guide.js +62 -33
- package/dist/resources/catalog-items.d.ts +5 -6
- package/dist/resources/catalog-items.d.ts.map +1 -1
- package/dist/resources/catalog-items.js +7 -9
- package/dist/resources/constraints.d.ts +1 -1
- package/dist/resources/constraints.d.ts.map +1 -1
- package/dist/resources/constraints.js +1 -1
- package/dist/resources/design-schema.d.ts +9 -0
- package/dist/resources/design-schema.d.ts.map +1 -0
- package/dist/resources/design-schema.js +21 -0
- package/dist/resources/index.d.ts +4 -2
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +5 -2
- package/dist/resources/scene-current.d.ts +1 -1
- package/dist/resources/scene-current.d.ts.map +1 -1
- package/dist/resources/scene-summary.d.ts +1 -1
- package/dist/resources/scene-summary.d.ts.map +1 -1
- package/dist/server.d.ts +25 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +71 -25
- package/dist/storage/disk-artifact-store.d.ts +9 -0
- package/dist/storage/disk-artifact-store.d.ts.map +1 -0
- package/dist/storage/disk-artifact-store.js +46 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +1 -0
- package/dist/storage/sqlite-scene-store.d.ts +3 -3
- package/dist/storage/sqlite-scene-store.d.ts.map +1 -1
- package/dist/storage/sqlite-scene-store.js +4 -3
- package/dist/storage/types.d.ts +36 -7
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/types.js +12 -0
- package/dist/templates/empty-studio.d.ts +3 -3
- package/dist/templates/empty-studio.d.ts.map +1 -1
- package/dist/templates/garden-house.d.ts +3 -3
- package/dist/templates/garden-house.d.ts.map +1 -1
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/two-bedroom.d.ts +3 -3
- package/dist/templates/two-bedroom.d.ts.map +1 -1
- package/dist/tools/add-column.d.ts +5 -0
- package/dist/tools/add-column.d.ts.map +1 -0
- package/dist/tools/add-column.js +59 -0
- package/dist/tools/add-object.d.ts +76 -0
- package/dist/tools/add-object.d.ts.map +1 -0
- package/dist/tools/add-object.js +187 -0
- package/dist/tools/annotations.d.ts.map +1 -1
- package/dist/tools/apply-patch.d.ts +9 -2
- package/dist/tools/apply-patch.d.ts.map +1 -1
- package/dist/tools/apply-patch.js +36 -5
- package/dist/tools/asset-catalog.d.ts +9 -5
- package/dist/tools/asset-catalog.d.ts.map +1 -1
- package/dist/tools/asset-catalog.js +33 -12
- package/dist/tools/author-scene.d.ts +10 -0
- package/dist/tools/author-scene.d.ts.map +1 -0
- package/dist/tools/author-scene.js +140 -0
- package/dist/tools/check-collisions.d.ts +7 -7
- package/dist/tools/check-collisions.d.ts.map +1 -1
- package/dist/tools/check-collisions.js +7 -8
- package/dist/tools/clear-scene.d.ts +9 -0
- package/dist/tools/clear-scene.d.ts.map +1 -0
- package/dist/tools/clear-scene.js +59 -0
- package/dist/tools/collections.d.ts +4 -0
- package/dist/tools/collections.d.ts.map +1 -0
- package/dist/tools/collections.js +53 -0
- package/dist/tools/construction-tools.d.ts +12 -88
- package/dist/tools/construction-tools.d.ts.map +1 -1
- package/dist/tools/construction-tools.js +122 -381
- package/dist/tools/create-unit.d.ts +5 -3
- package/dist/tools/create-unit.d.ts.map +1 -1
- package/dist/tools/create-unit.js +2 -2
- package/dist/tools/errors.d.ts +15 -4
- package/dist/tools/errors.d.ts.map +1 -1
- package/dist/tools/errors.js +14 -4
- package/dist/tools/export-glb.d.ts +1 -1
- package/dist/tools/export-glb.d.ts.map +1 -1
- package/dist/tools/export-glb.js +2 -2
- package/dist/tools/export-json.d.ts +1 -1
- package/dist/tools/export-json.d.ts.map +1 -1
- package/dist/tools/export-json.js +2 -2
- package/dist/tools/geometry-script-worker.d.ts +2 -0
- package/dist/tools/geometry-script-worker.d.ts.map +1 -0
- package/dist/tools/geometry-script-worker.js +21 -0
- package/dist/tools/get-scene.d.ts +2 -1
- package/dist/tools/get-scene.d.ts.map +1 -1
- package/dist/tools/get-scene.js +5 -3
- package/dist/tools/honest-patch-guard.d.ts +2 -0
- package/dist/tools/honest-patch-guard.d.ts.map +1 -0
- package/dist/tools/honest-patch-guard.js +32 -0
- package/dist/tools/hosted-services.d.ts +4 -0
- package/dist/tools/hosted-services.d.ts.map +1 -0
- package/dist/tools/hosted-services.js +40 -0
- package/dist/tools/index.d.ts +12 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +18 -32
- package/dist/tools/level-height-guard.d.ts +2 -0
- package/dist/tools/level-height-guard.d.ts.map +1 -0
- package/dist/tools/level-height-guard.js +11 -0
- package/dist/tools/list-units.d.ts +2 -2
- package/dist/tools/list-units.d.ts.map +1 -1
- package/dist/tools/list-units.js +2 -2
- package/dist/tools/live-sync.d.ts +25 -6
- package/dist/tools/live-sync.d.ts.map +1 -1
- package/dist/tools/live-sync.js +48 -27
- package/dist/tools/local-geometry-scripts.d.ts +8 -0
- package/dist/tools/local-geometry-scripts.d.ts.map +1 -0
- package/dist/tools/local-geometry-scripts.js +67 -0
- package/dist/tools/measure.d.ts +7 -1
- package/dist/tools/measure.d.ts.map +1 -1
- package/dist/tools/measure.js +38 -70
- package/dist/tools/measurement.d.ts +1 -36
- package/dist/tools/measurement.d.ts.map +1 -1
- package/dist/tools/measurement.js +2 -94
- package/dist/tools/node-world-point.d.ts +37 -0
- package/dist/tools/node-world-point.d.ts.map +1 -0
- package/dist/tools/node-world-point.js +457 -0
- package/dist/tools/normalize-schema-dialect.d.ts +1 -1
- package/dist/tools/normalize-schema-dialect.d.ts.map +1 -1
- package/dist/tools/normalize-schema-dialect.js +22 -3
- package/dist/tools/patch-guards.d.ts +60 -0
- package/dist/tools/patch-guards.d.ts.map +1 -0
- package/dist/tools/patch-guards.js +256 -0
- package/dist/tools/photo-to-scene/index.d.ts +1 -1
- package/dist/tools/photo-to-scene/index.d.ts.map +1 -1
- package/dist/tools/photo-to-scene/photo-to-scene.d.ts +3 -3
- package/dist/tools/photo-to-scene/photo-to-scene.d.ts.map +1 -1
- package/dist/tools/photo-to-scene/photo-to-scene.js +10 -9
- package/dist/tools/project-files.d.ts +4 -0
- package/dist/tools/project-files.d.ts.map +1 -0
- package/dist/tools/project-files.js +30 -0
- package/dist/tools/redo.d.ts +4 -2
- package/dist/tools/redo.d.ts.map +1 -1
- package/dist/tools/redo.js +4 -4
- package/dist/tools/retired-tools.d.ts +10 -0
- package/dist/tools/retired-tools.d.ts.map +1 -0
- package/dist/tools/retired-tools.js +22 -0
- package/dist/tools/roof-level-guard.d.ts +2 -0
- package/dist/tools/roof-level-guard.d.ts.map +1 -0
- package/dist/tools/roof-level-guard.js +22 -0
- package/dist/tools/room-tools.d.ts +36 -98
- package/dist/tools/room-tools.d.ts.map +1 -1
- package/dist/tools/room-tools.js +130 -565
- package/dist/tools/scene-lifecycle/create-project.d.ts +1 -1
- package/dist/tools/scene-lifecycle/create-project.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/create-project.js +31 -6
- package/dist/tools/scene-lifecycle/delete-scene.d.ts +3 -1
- package/dist/tools/scene-lifecycle/delete-scene.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/delete-scene.js +10 -9
- package/dist/tools/scene-lifecycle/get-project-status.d.ts +1 -1
- package/dist/tools/scene-lifecycle/get-project-status.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/get-project-status.js +6 -6
- package/dist/tools/scene-lifecycle/index.d.ts +1 -1
- package/dist/tools/scene-lifecycle/index.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/list-scenes.d.ts +1 -1
- package/dist/tools/scene-lifecycle/list-scenes.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/list-scenes.js +4 -4
- package/dist/tools/scene-lifecycle/load-scene.d.ts +2 -2
- package/dist/tools/scene-lifecycle/load-scene.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/load-scene.js +5 -5
- package/dist/tools/scene-lifecycle/metadata.d.ts +1 -1
- package/dist/tools/scene-lifecycle/rename-scene.d.ts +1 -1
- package/dist/tools/scene-lifecycle/rename-scene.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/rename-scene.js +6 -6
- package/dist/tools/scene-lifecycle/save-scene.d.ts +6 -3
- package/dist/tools/scene-lifecycle/save-scene.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/save-scene.js +124 -16
- package/dist/tools/scene-lifecycle/test-utils.d.ts +3 -3
- package/dist/tools/scene-lifecycle/test-utils.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/test-utils.js +2 -1
- package/dist/tools/set-unit-members.d.ts +4 -2
- package/dist/tools/set-unit-members.d.ts.map +1 -1
- package/dist/tools/set-unit-members.js +6 -6
- package/dist/tools/set-zone.d.ts +4 -2
- package/dist/tools/set-zone.d.ts.map +1 -1
- package/dist/tools/set-zone.js +30 -18
- package/dist/tools/shared-tools.d.ts +40 -0
- package/dist/tools/shared-tools.d.ts.map +1 -0
- package/dist/tools/shared-tools.js +574 -0
- package/dist/tools/structure-tools.d.ts +57 -0
- package/dist/tools/structure-tools.d.ts.map +1 -0
- package/dist/tools/structure-tools.js +57 -0
- package/dist/tools/templates/create-from-template.d.ts +2 -2
- package/dist/tools/templates/create-from-template.d.ts.map +1 -1
- package/dist/tools/templates/create-from-template.js +6 -6
- package/dist/tools/templates/create-house-from-brief.d.ts +1 -1
- package/dist/tools/templates/create-house-from-brief.d.ts.map +1 -1
- package/dist/tools/templates/create-house-from-brief.js +6 -6
- package/dist/tools/templates/index.d.ts +1 -1
- package/dist/tools/templates/index.d.ts.map +1 -1
- package/dist/tools/templates/list-templates.d.ts +1 -1
- package/dist/tools/templates/list-templates.d.ts.map +1 -1
- package/dist/tools/templates/list-templates.js +2 -2
- package/dist/tools/undo.d.ts +4 -2
- package/dist/tools/undo.d.ts.map +1 -1
- package/dist/tools/undo.js +4 -4
- package/dist/tools/unit-members.d.ts.map +1 -1
- package/dist/tools/unit-members.js +6 -6
- package/dist/tools/variants/generate-variants.d.ts +6 -6
- package/dist/tools/variants/generate-variants.d.ts.map +1 -1
- package/dist/tools/variants/generate-variants.js +6 -6
- package/dist/tools/variants/index.d.ts +1 -1
- package/dist/tools/variants/index.d.ts.map +1 -1
- package/dist/tools/variants/mutations.js +1 -1
- package/dist/tools/view-scene.d.ts +44 -0
- package/dist/tools/view-scene.d.ts.map +1 -0
- package/dist/tools/view-scene.js +75 -0
- package/dist/tools/vision/analyze-floorplan-image.d.ts +1 -1
- package/dist/tools/vision/analyze-floorplan-image.d.ts.map +1 -1
- package/dist/tools/vision/analyze-floorplan-image.js +7 -7
- package/dist/tools/vision/analyze-room-photo.d.ts +1 -1
- package/dist/tools/vision/analyze-room-photo.d.ts.map +1 -1
- package/dist/tools/vision/analyze-room-photo.js +7 -7
- package/dist/tools/vision/index.d.ts +1 -1
- package/dist/tools/vision/index.d.ts.map +1 -1
- package/dist/transports/http.d.ts +8 -2
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +9 -3
- package/dist/transports/stdio.d.ts +15 -9
- package/dist/transports/stdio.d.ts.map +1 -1
- package/dist/transports/stdio.js +18 -11
- package/dist/version.d.ts +5 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +17 -3
- package/examples/coordinate-conventions-demo.md +12 -13
- package/examples/embed-in-agent.ts +6 -7
- package/examples/generate-apartment.md +13 -15
- package/examples/photo-to-scene.md +3 -4
- package/examples/renovate-from-photos.md +6 -9
- package/package.json +19 -9
- package/dist/tools/create-level.d.ts +0 -21
- package/dist/tools/create-level.d.ts.map +0 -1
- package/dist/tools/create-level.js +0 -63
- package/dist/tools/create-wall.d.ts +0 -22
- package/dist/tools/create-wall.d.ts.map +0 -1
- package/dist/tools/create-wall.js +0 -57
- package/dist/tools/cut-opening.d.ts +0 -25
- package/dist/tools/cut-opening.d.ts.map +0 -1
- package/dist/tools/cut-opening.js +0 -61
- package/dist/tools/delete-node.d.ts +0 -19
- package/dist/tools/delete-node.d.ts.map +0 -1
- package/dist/tools/delete-node.js +0 -40
- package/dist/tools/describe-node.d.ts +0 -17
- package/dist/tools/describe-node.d.ts.map +0 -1
- package/dist/tools/describe-node.js +0 -97
- package/dist/tools/door-clearance.d.ts +0 -135
- package/dist/tools/door-clearance.d.ts.map +0 -1
- package/dist/tools/door-clearance.js +0 -334
- package/dist/tools/duplicate-level.d.ts +0 -19
- package/dist/tools/duplicate-level.d.ts.map +0 -1
- package/dist/tools/duplicate-level.js +0 -60
- package/dist/tools/find-nodes.d.ts +0 -32
- package/dist/tools/find-nodes.d.ts.map +0 -1
- package/dist/tools/find-nodes.js +0 -107
- package/dist/tools/geometry.d.ts +0 -24
- package/dist/tools/geometry.d.ts.map +0 -1
- package/dist/tools/geometry.js +0 -94
- package/dist/tools/get-node.d.ts +0 -11
- package/dist/tools/get-node.d.ts.map +0 -1
- package/dist/tools/get-node.js +0 -29
- package/dist/tools/layout-clearance.d.ts +0 -105
- package/dist/tools/layout-clearance.d.ts.map +0 -1
- package/dist/tools/layout-clearance.js +0 -190
- package/dist/tools/place-item.d.ts +0 -22
- package/dist/tools/place-item.d.ts.map +0 -1
- package/dist/tools/place-item.js +0 -89
- package/dist/tools/scene-query.d.ts +0 -62
- package/dist/tools/scene-query.d.ts.map +0 -1
- package/dist/tools/scene-query.js +0 -670
- package/dist/tools/validate-scene.d.ts +0 -19
- package/dist/tools/validate-scene.d.ts.map +0 -1
- package/dist/tools/validate-scene.js +0 -28
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
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
|
|
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":"
|
|
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"}
|
package/dist/transports/http.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomUUID, timingSafeEqual } from 'node:crypto';
|
|
2
2
|
import { createServer } from 'node:http';
|
|
3
|
-
import {
|
|
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
|
|
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
|
|
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/
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
+
import { type ServeStdioOptions, type StdioServerHandle } from '@modelcontextprotocol/server/stdio';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
+
* Serve Pascal over stdio from a server factory.
|
|
4
5
|
*
|
|
5
|
-
* The
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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(
|
|
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,
|
|
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"}
|
package/dist/transports/stdio.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { serveStdio, } from '@modelcontextprotocol/server/stdio';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Serve Pascal over stdio from a server factory.
|
|
4
4
|
*
|
|
5
|
-
* The
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
|
14
|
-
|
|
15
|
-
|
|
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
|
package/dist/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
23
|
-
|
|
24
|
-
| Reference compass at the origin
|
|
25
|
-
| **Demo A** at world `(18, 0)`
|
|
26
|
-
| **Demo B** at world `(18, 10)`
|
|
27
|
-
| **Demo C** at world `(0, 22)` and `(10, 22)`
|
|
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.
|
|
29
|
-
| Takeaway band on the south edge
|
|
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 `
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
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: '
|
|
42
|
+
name: 'find_by_type',
|
|
44
43
|
arguments: { type: 'level' },
|
|
45
44
|
})
|
|
46
|
-
const levelId = (levels.structuredContent as {
|
|
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: '
|
|
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
|
|
67
|
-
console.log('
|
|
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 `
|
|
161
|
-
|
|
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:
|
|
164
|
+
// tool: add_window (called once per window)
|
|
165
165
|
{
|
|
166
|
-
"name": "
|
|
166
|
+
"name": "add_window",
|
|
167
167
|
"arguments": {
|
|
168
168
|
"wallId": "wall-south", // perimeter wall [0,0] → [10,0]
|
|
169
|
-
"
|
|
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
|
-
// → { "
|
|
174
|
+
// → { "windowId": "window-south-1", ... }
|
|
176
175
|
```
|
|
177
176
|
|
|
178
177
|
```jsonc
|
|
179
178
|
{
|
|
180
|
-
"name": "
|
|
179
|
+
"name": "add_door",
|
|
181
180
|
"arguments": {
|
|
182
181
|
"wallId": "wall-bed1", // partition wall to Bedroom 1
|
|
183
|
-
"
|
|
184
|
-
"position": 0.4,
|
|
182
|
+
"t": 0.4,
|
|
185
183
|
"width": 0.9,
|
|
186
184
|
"height": 2.1
|
|
187
185
|
}
|
|
188
186
|
}
|
|
189
|
-
// → { "
|
|
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:
|
|
199
|
-
{ "name": "
|
|
196
|
+
// tool: verify_scene
|
|
197
|
+
{ "name": "verify_scene", "arguments": {} }
|
|
200
198
|
```
|
|
201
199
|
|
|
202
200
|
Response:
|
|
203
201
|
|
|
204
202
|
```jsonc
|
|
205
|
-
{ "valid": true, "
|
|
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
|
-
(`
|
|
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
|
-
(`
|
|
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 `
|
|
113
|
-
wall, and issues `
|
|
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 `
|
|
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": "
|
|
136
|
+
"name": "add_window",
|
|
138
137
|
"arguments": {
|
|
139
138
|
"wallId": "wall-south",
|
|
140
|
-
"
|
|
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:
|
|
182
|
-
{ "name": "
|
|
183
|
-
// → { "valid": true, "
|
|
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
|
+
"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.
|
|
65
|
+
"@pascal-app/core": "^1.0.5"
|
|
60
66
|
},
|
|
61
67
|
"dependencies": {
|
|
62
|
-
"@
|
|
63
|
-
"@
|
|
64
|
-
"
|
|
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
|
-
"@
|
|
76
|
+
"@modelcontextprotocol/client": "^2.3.1",
|
|
77
|
+
"@pascal-app/core": "^1.0.5",
|
|
68
78
|
"@pascal/typescript-config": "*",
|
|
69
|
-
"@types/node": "^
|
|
70
|
-
"typescript": "
|
|
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"}
|