@womp/mcp-ui 0.1.7 → 0.1.8

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/README.md CHANGED
@@ -17,6 +17,8 @@ add_to_cart ──► ui://womp/cart-<version>.html (260 KB) cart rows +
17
17
  view_cart ──► ui://womp/cart-<version>.html (self-fills thumbnails via app-callable view_cart)
18
18
  get_print_order ──► ui://womp/order-<version>.html (258 KB) status chips, tracking, diff-charge strip
19
19
  list_print_orders ─► ui://womp/order-<version>.html
20
+ create_upload ──► ui://womp/upload-<version>.html (266 KB) drop zone: the user's mesh file goes to the ticket URL from the chat
21
+ get_upload ──► ui://womp/upload-<version>.html (app-callable — the card polls it)
20
22
  ```
21
23
 
22
24
  ## What it exports
@@ -30,6 +32,7 @@ const {
30
32
  PRINT_APP_URI, PRINT_APP_CSP, PRINT_APP_HTML,
31
33
  CART_APP_URI, CART_APP_CSP, CART_APP_HTML,
32
34
  ORDER_APP_URI, ORDER_APP_CSP, ORDER_APP_HTML,
35
+ UPLOAD_APP_URI, UPLOAD_APP_CSP, UPLOAD_APP_HTML,
33
36
  APP_MIME_TYPE,
34
37
  } = require("@womp/mcp-ui");
35
38
  ```
@@ -229,6 +232,35 @@ The stub takes three switches for the states a default account never shows:
229
232
  `FAKE_ENTERPRISE=1` (Enterprise materials orderable), `FAKE_PRO=1` (hollow
230
233
  priced as available), `FAKE_REPAIRED=1` (the repaired / non-manifold callouts).
231
234
 
235
+ ### The upload card sends bytes from inside the iframe
236
+
237
+ `src/upload/` exists because MCP has no client→server file channel and a chat
238
+ host's sandbox usually cannot reach Womp — so a file the user had just attached
239
+ to the chat could only reach the print pipeline via a womp.com page. The card
240
+ is that page, in the conversation: drop zone + picker, XHR `PUT` of the raw file
241
+ to the ticket URL swan-backend minted (`create_upload`), progress, the server's
242
+ own refusal text on 4xx, 409/410 terminal. It never touches the model: the
243
+ bytes go disk → API.
244
+
245
+ Two things outside this repo make that PUT possible, and both fail as a bare
246
+ network error inside the card if missing (which it turns into an "open the
247
+ upload page instead" button rather than a dead end):
248
+
249
+ - **`connectDomains` must name the API origin**, and the origin differs per
250
+ environment — so `bake-html.mjs` bakes `{}` for this card and swan-backend
251
+ completes the CSP with its own origin at read time. The dev stub does the
252
+ same with `http://localhost:3001`.
253
+ - **The backend answers with open CORS on `/mcp/v1/uploads`** because a
254
+ sandboxed iframe's origin is opaque (`Origin: null`). The ticket in the URL is
255
+ the security boundary, not the origin.
256
+
257
+ While pending the card polls the app-callable `get_upload`, so a file the agent
258
+ pushed itself (`curl -T` from a shell that has it) flips the card to done
259
+ instead of leaving a drop zone for a file that already landed. The dev stub
260
+ (`dev/server.mjs`) carries `create_upload` / `get_upload` and a `PUT
261
+ /mcp/v1/uploads/:token` sink with the GLB-magic sniff, so the refusal strip is
262
+ reachable locally too.
263
+
232
264
  ## Development
233
265
 
234
266
  **Do not iterate through Claude.** A card change reaches a connector only after
package/dist/index.d.ts CHANGED
@@ -26,3 +26,7 @@ export declare const CART_APP_HTML: string;
26
26
  export declare const ORDER_APP_URI: string;
27
27
  export declare const ORDER_APP_CSP: AppCsp;
28
28
  export declare const ORDER_APP_HTML: string;
29
+
30
+ export declare const UPLOAD_APP_URI: string;
31
+ export declare const UPLOAD_APP_CSP: AppCsp;
32
+ export declare const UPLOAD_APP_HTML: string;