wormclaude 1.0.118 → 1.0.120

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 (233) hide show
  1. package/dist/theme.js +1 -1
  2. package/dist/tools.js +14 -5
  3. package/package.json +1 -1
  4. package/skills/scan/SKILL.md +37 -0
  5. package/skills/build-mcp-app/SKILL.md +0 -393
  6. package/skills/build-mcp-app/references/abuse-protection.md +0 -60
  7. package/skills/build-mcp-app/references/apps-sdk-messages.md +0 -227
  8. package/skills/build-mcp-app/references/directory-checklist.md +0 -18
  9. package/skills/build-mcp-app/references/iframe-sandbox.md +0 -164
  10. package/skills/build-mcp-app/references/payload-budgeting.md +0 -54
  11. package/skills/build-mcp-app/references/widget-templates.md +0 -249
  12. package/skills/build-mcp-server/SKILL.md +0 -222
  13. package/skills/build-mcp-server/references/auth.md +0 -108
  14. package/skills/build-mcp-server/references/deploy-cloudflare-workers.md +0 -106
  15. package/skills/build-mcp-server/references/elicitation.md +0 -129
  16. package/skills/build-mcp-server/references/remote-http-scaffold.md +0 -211
  17. package/skills/build-mcp-server/references/resources-and-prompts.md +0 -122
  18. package/skills/build-mcp-server/references/server-capabilities.md +0 -164
  19. package/skills/build-mcp-server/references/tool-design.md +0 -189
  20. package/skills/build-mcp-server/references/versions.md +0 -25
  21. package/skills/build-mcpb/SKILL.md +0 -200
  22. package/skills/build-mcpb/references/local-security.md +0 -149
  23. package/skills/build-mcpb/references/manifest-schema.md +0 -156
  24. package/skills/docx/script/__init__.py +0 -1
  25. package/skills/docx/script/accept_chages.py +0 -135
  26. package/skills/docx/script/comment.py +0 -318
  27. package/skills/docx/script/office/helpers/__init__.py +0 -0
  28. package/skills/docx/script/office/helpers/merge_runs.py +0 -199
  29. package/skills/docx/script/office/helpers/simplify_redlines.py +0 -197
  30. package/skills/docx/script/office/pack.py +0 -159
  31. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  32. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  33. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  34. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  35. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  36. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  37. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  38. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  39. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  40. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  41. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  42. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  43. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  44. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  45. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  46. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  47. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  48. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  49. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  50. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  51. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  52. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  53. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  54. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  55. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  56. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  57. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  58. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  59. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  60. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  61. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  62. package/skills/docx/script/office/schemas/mce/mc.xsd +0 -75
  63. package/skills/docx/script/office/schemas/microsoft/wml-2010.xsd +0 -560
  64. package/skills/docx/script/office/schemas/microsoft/wml-2012.xsd +0 -67
  65. package/skills/docx/script/office/schemas/microsoft/wml-2018.xsd +0 -14
  66. package/skills/docx/script/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  67. package/skills/docx/script/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  68. package/skills/docx/script/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  69. package/skills/docx/script/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  70. package/skills/docx/script/office/soffice.py +0 -183
  71. package/skills/docx/script/office/unpack.py +0 -132
  72. package/skills/docx/script/office/validate.py +0 -117
  73. package/skills/docx/script/office/validators/__init__.py +0 -15
  74. package/skills/docx/script/office/validators/base.py +0 -851
  75. package/skills/docx/script/office/validators/docx.py +0 -446
  76. package/skills/docx/script/office/validators/pptx.py +0 -275
  77. package/skills/docx/script/office/validators/redlining.py +0 -247
  78. package/skills/docx/script/templates/comments.xml +0 -3
  79. package/skills/docx/script/templates/commentsExtended.xml +0 -3
  80. package/skills/docx/script/templates/commentsExtensible.xml +0 -3
  81. package/skills/docx/script/templates/commentsIds.xml +0 -3
  82. package/skills/docx/script/templates/people.xml +0 -3
  83. package/skills/docx/skill.md +0 -593
  84. package/skills/explain.md +0 -14
  85. package/skills/frontend-design/SKILL.md +0 -42
  86. package/skills/pdf/FORMS.md +0 -294
  87. package/skills/pdf/REFERENCE.md +0 -612
  88. package/skills/pdf/SKILL.md +0 -314
  89. package/skills/pdf/scripts/check_bounding_boxes.py +0 -65
  90. package/skills/pdf/scripts/check_fillable_fields.py +0 -11
  91. package/skills/pdf/scripts/convert_pdf_to_images.py +0 -33
  92. package/skills/pdf/scripts/create_validation_image.py +0 -37
  93. package/skills/pdf/scripts/extract_form_field_info.py +0 -122
  94. package/skills/pdf/scripts/extract_form_structure.py +0 -115
  95. package/skills/pdf/scripts/fill_fillable_fields.py +0 -98
  96. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
  97. package/skills/playground/SKILL.md +0 -77
  98. package/skills/playground/templates/code-map.md +0 -158
  99. package/skills/playground/templates/concept-map.md +0 -73
  100. package/skills/playground/templates/data-explorer.md +0 -67
  101. package/skills/playground/templates/design-playground.md +0 -67
  102. package/skills/playground/templates/diff-review.md +0 -179
  103. package/skills/playground/templates/document-critique.md +0 -171
  104. package/skills/pptx/SKILL.md +0 -230
  105. package/skills/pptx/editing.md +0 -205
  106. package/skills/pptx/pptxgenjs.md +0 -437
  107. package/skills/pptx/scripts/__init__.py +0 -0
  108. package/skills/pptx/scripts/add_slide.py +0 -195
  109. package/skills/pptx/scripts/clean.py +0 -286
  110. package/skills/pptx/scripts/office/helpers/__init__.py +0 -0
  111. package/skills/pptx/scripts/office/helpers/merge_runs.py +0 -199
  112. package/skills/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
  113. package/skills/pptx/scripts/office/pack.py +0 -159
  114. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  115. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  116. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  117. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  118. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  119. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  120. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  121. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  122. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  123. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  124. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  125. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  126. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  127. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  128. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  129. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  130. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  131. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  132. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  133. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  134. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  135. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  136. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  137. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  138. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  139. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  140. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  141. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  142. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  143. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  144. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  145. package/skills/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
  146. package/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  147. package/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  148. package/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  149. package/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  150. package/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  151. package/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  152. package/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  153. package/skills/pptx/scripts/office/soffice.py +0 -183
  154. package/skills/pptx/scripts/office/unpack.py +0 -132
  155. package/skills/pptx/scripts/office/validate.py +0 -117
  156. package/skills/pptx/scripts/office/validators/__init__.py +0 -15
  157. package/skills/pptx/scripts/office/validators/base.py +0 -851
  158. package/skills/pptx/scripts/office/validators/docx.py +0 -446
  159. package/skills/pptx/scripts/office/validators/pptx.py +0 -275
  160. package/skills/pptx/scripts/office/validators/redlining.py +0 -247
  161. package/skills/pptx/scripts/thumbnail.py +0 -289
  162. package/skills/recon.md +0 -16
  163. package/skills/security-audit/SKILL.md +0 -26
  164. package/skills/talent-creator/SKILL.md +0 -486
  165. package/skills/talent-creator/agents/analyzer.md +0 -274
  166. package/skills/talent-creator/agents/comparator.md +0 -202
  167. package/skills/talent-creator/agents/grader.md +0 -223
  168. package/skills/talent-creator/assets/eval_review.html +0 -146
  169. package/skills/talent-creator/eval-viewer/generate_review.py +0 -471
  170. package/skills/talent-creator/eval-viewer/viewer.html +0 -1325
  171. package/skills/talent-creator/references/schemas.md +0 -430
  172. package/skills/talent-creator/scripts/__init__.py +0 -0
  173. package/skills/talent-creator/scripts/aggregate_benchmark.py +0 -401
  174. package/skills/talent-creator/scripts/generate_report.py +0 -326
  175. package/skills/talent-creator/scripts/improve_description.py +0 -247
  176. package/skills/talent-creator/scripts/package_skill.py +0 -136
  177. package/skills/talent-creator/scripts/quick_validate.py +0 -146
  178. package/skills/talent-creator/scripts/run_eval.py +0 -310
  179. package/skills/talent-creator/scripts/run_loop.py +0 -328
  180. package/skills/talent-creator/scripts/utils.py +0 -47
  181. package/skills/xlsx/SKILL.md +0 -300
  182. package/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  183. package/skills/xlsx/scripts/office/helpers/merge_runs.py +0 -199
  184. package/skills/xlsx/scripts/office/helpers/simplify_redlines.py +0 -197
  185. package/skills/xlsx/scripts/office/pack.py +0 -159
  186. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  187. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  188. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  189. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  190. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  191. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  192. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  193. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  194. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  195. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  196. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  197. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  198. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  199. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  200. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  201. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  202. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  203. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  204. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  205. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  206. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  207. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  208. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  209. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  210. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  211. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  212. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  213. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  214. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  215. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  216. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  217. package/skills/xlsx/scripts/office/schemas/mce/mc.xsd +0 -75
  218. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  219. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  220. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  221. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  222. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  223. package/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  224. package/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  225. package/skills/xlsx/scripts/office/soffice.py +0 -183
  226. package/skills/xlsx/scripts/office/unpack.py +0 -132
  227. package/skills/xlsx/scripts/office/validate.py +0 -117
  228. package/skills/xlsx/scripts/office/validators/__init__.py +0 -15
  229. package/skills/xlsx/scripts/office/validators/base.py +0 -851
  230. package/skills/xlsx/scripts/office/validators/docx.py +0 -446
  231. package/skills/xlsx/scripts/office/validators/pptx.py +0 -275
  232. package/skills/xlsx/scripts/office/validators/redlining.py +0 -247
  233. package/skills/xlsx/scripts/recalc.py +0 -184
@@ -1,227 +0,0 @@
1
- # ext-apps messaging — widget ↔ host ↔ server
2
-
3
- The `@modelcontextprotocol/ext-apps` package gives you the `App` class (browser side) plus the `registerAppTool`/`registerAppResource` helpers (server side). The messaging is two-way and persistent.
4
-
5
- ## Construction
6
-
7
- ```js
8
- const app = new App(
9
- { name: "MyWidget", version: "1.0.0" },
10
- {}, // capabilities
11
- { autoResize: true }, // options
12
- );
13
- ```
14
-
15
- `autoResize: true` hooks up a `ResizeObserver` that fires `ui/notifications/size-changed` so the host iframe's height follows your rendered content. Without it the frame stays fixed-height and tall renders get clipped — turn it on for any widget whose height depends on the data.
16
-
17
- ---
18
-
19
- ## Widget → Host
20
-
21
- ### `app.sendMessage({ role, content })`
22
-
23
- Push a visible message into the conversation. This is the path by which user actions become conversation turns.
24
-
25
- ```js
26
- app.sendMessage({
27
- role: "user",
28
- content: [{ type: "text", text: "User selected order #1234" }],
29
- });
30
- ```
31
-
32
- The message shows up in chat and WormClaude responds to it. Use `role: "user"` — the widget is speaking on the user's behalf.
33
-
34
- ### `app.updateModelContext({ content })`
35
-
36
- Update WormClaude's context **silently**, with no visible message. Use it for state that's worth knowing but doesn't deserve its own chat bubble.
37
-
38
- ```js
39
- app.updateModelContext({
40
- content: [{ type: "text", text: "Currently viewing: orders from last 30 days" }],
41
- });
42
- ```
43
-
44
- ### `app.callServerTool({ name, arguments })`
45
-
46
- Call a tool on your MCP server directly, going around WormClaude. Returns the tool result.
47
-
48
- ```js
49
- const result = await app.callServerTool({
50
- name: "fetch_order_details",
51
- arguments: { orderId: "1234" },
52
- });
53
- ```
54
-
55
- Use it for data fetches that don't need WormClaude's reasoning — pagination, detail lookups, refreshes.
56
-
57
- ### `app.openLink({ url })`
58
-
59
- Open a URL in a new browser tab, brokered by the host. **Required** for any outbound navigation — the iframe sandbox blocks `window.open()` and `<a target="_blank">`.
60
-
61
- ```js
62
- await app.openLink({ url: "https://example.com/cart" });
63
- ```
64
-
65
- For anchors in rendered HTML, catch the click:
66
-
67
- ```js
68
- card.querySelector("a").addEventListener("click", (e) => {
69
- e.preventDefault();
70
- app.openLink({ url: e.currentTarget.href });
71
- });
72
- ```
73
-
74
- ### `app.downloadFile({ name, mimeType, content })`
75
-
76
- A host-brokered download (the sandbox blocks a direct `<a download>`). `content` is a base64 string.
77
-
78
- ```js
79
- const csv = rows.map((r) => Object.values(r).join(",")).join("\n");
80
- app.downloadFile({
81
- name: "export.csv",
82
- mimeType: "text/csv",
83
- content: btoa(unescape(encodeURIComponent(csv))),
84
- });
85
- ```
86
-
87
- ### `app.requestDisplayMode({ mode })`
88
-
89
- Ask the host to move the widget between `"inline"`, `"pip"`, and `"fullscreen"`. Check `getHostContext().availableDisplayModes` first, and hide the control when a mode isn't on offer. The host answers by firing `onhostcontextchanged` with a new `displayMode` and `containerDimensions` — re-render at the new size.
90
-
91
- ```js
92
- if (app.getHostContext()?.availableDisplayModes?.includes("fullscreen")) {
93
- expandBtn.hidden = false;
94
- expandBtn.onclick = () => app.requestDisplayMode({ mode: "fullscreen" });
95
- }
96
- ```
97
-
98
- ---
99
-
100
- ## Host → Widget
101
-
102
- ### `app.ontoolresult = ({ content }) => {...}`
103
-
104
- Fires when the tool handler's return value is fed to the widget. This is the main data-in path.
105
-
106
- ```js
107
- app.ontoolresult = ({ content }) => {
108
- const data = JSON.parse(content[0].text);
109
- renderUI(data);
110
- };
111
- ```
112
-
113
- **Set this BEFORE `await app.connect()`** — the result can land right after the connection opens.
114
-
115
- ### `app.ontoolinput = ({ arguments }) => {...}`
116
-
117
- Fires with the arguments WormClaude passed to the tool. Handy when the widget needs to know what was asked for (e.g., to highlight the search term).
118
-
119
- ### `app.ontoolinputpartial = ({ arguments }) => {...}` / `app.ontoolcancelled = () => {...}`
120
-
121
- `ontoolinputpartial` fires while WormClaude is still streaming arguments — use it to show a skeleton ("Preparing: <title>…") before the result arrives. `ontoolcancelled` fires when the call is aborted; clear the skeleton then.
122
-
123
- ### `app.getHostContext()` / `app.onhostcontextchanged = (ctx) => {...}`
124
-
125
- Read the host context and subscribe to its changes. Call `getHostContext()` **after** `connect()`, and subscribe for live updates (the user flips on dark mode, expands to fullscreen).
126
-
127
- | `ctx.` field | Use |
128
- |---|---|
129
- | `theme` | `"light"` / `"dark"` — toggle a `.dark` class |
130
- | `styles.variables` | Host CSS tokens — pass to `applyHostStyleVariables()` so colors/fonts match host chrome |
131
- | `displayMode` / `availableDisplayModes` | Current mode and which `requestDisplayMode` targets are valid |
132
- | `containerDimensions.{maxHeight,width}` | Size your render to this instead of hard-coded px |
133
- | `deviceCapabilities.touch` | Switch hover-only affordances to tap (`pointerdown`) |
134
- | `safeAreaInsets` | Padding for notches / composer overlay |
135
-
136
- ```js
137
- const applyTheme = (t) =>
138
- document.documentElement.classList.toggle("dark", t === "dark");
139
-
140
- app.onhostcontextchanged = (ctx) => applyTheme(ctx.theme);
141
- await app.connect();
142
- applyTheme(app.getHostContext()?.theme);
143
- ```
144
-
145
- Keep colors in CSS custom properties with a `:root.dark {}` override block, and set `color-scheme: light | dark` so native form controls follow along.
146
-
147
- ---
148
-
149
- ## Server → Widget (progress)
150
-
151
- For long-running operations, emit progress notifications. The client supplies a `progressToken` in the request's `_meta`, and the server emits against it.
152
-
153
- ```typescript
154
- // In the tool handler
155
- async ({ query }, extra) => {
156
- const token = extra._meta?.progressToken;
157
- for (let i = 0; i < steps.length; i++) {
158
- if (token !== undefined) {
159
- await extra.sendNotification({
160
- method: "notifications/progress",
161
- params: { progressToken: token, progress: i, total: steps.length, message: steps[i].name },
162
- });
163
- }
164
- await steps[i].run();
165
- }
166
- return { content: [{ type: "text", text: "Complete" }] };
167
- }
168
- ```
169
-
170
- No `{ notify }` destructure — `extra` is `RequestHandlerExtra`; progress goes through `sendNotification`.
171
-
172
- ---
173
-
174
- ## Lifecycle
175
-
176
- 1. WormClaude calls a tool that declares `_meta.ui.resourceUri`
177
- 2. The host fetches the resource (your HTML) and mounts a **fresh iframe** for this call
178
- 3. The widget script runs, registers handlers, and calls `await app.connect()`
179
- 4. The host feeds the tool's return value in → `ontoolresult` fires
180
- 5. The widget renders and the user interacts with it
181
- 6. The widget calls `sendMessage` / `updateModelContext` / `callServerTool` as needed
182
- 7. The iframe stays in the transcript; **the next call to the same tool mounts another iframe** beside it
183
-
184
- There's no explicit "submit and close" — each instance is long-lived, and instances are never reused across calls.
185
-
186
- ### Supersession
187
-
188
- Since earlier instances stay mounted, a click on a stale widget can `sendMessage` after a newer one has rendered. Catch this with a `BroadcastChannel` and make the older instances inert:
189
-
190
- ```js
191
- let superseded = false;
192
- const seq = Date.now() + Math.random();
193
- const bc = new BroadcastChannel("my-widget");
194
- bc.onmessage = (e) => {
195
- if (e.data?.seq > seq) {
196
- superseded = true;
197
- document.body.classList.add("superseded"); // opacity:.45; pointer-events:none
198
- }
199
- };
200
- bc.postMessage({ seq });
201
-
202
- // Guard outbound calls:
203
- function safeSend(msg) {
204
- if (!superseded) app.sendMessage(msg);
205
- }
206
- ```
207
-
208
- ---
209
-
210
- ## Sandbox & CSP gotchas
211
-
212
- The iframe runs under both an HTML `sandbox` attribute **and** a strict Content-Security-Policy. In practice almost nothing external gets through — widgets should be fully self-contained.
213
-
214
- | Symptom | Cause | Fix |
215
- |---|---|---|
216
- | Widget is a blank rectangle, nothing renders | CDN `import` of ext-apps blocked (transitive SDK fetches) | **Inline** the `ext-apps/app-with-deps` bundle — see `iframe-sandbox.md` |
217
- | Widget renders but JS doesn't run | Inline event handlers blocked | Use `addEventListener` — never `onclick="..."` in HTML |
218
- | `eval` / `new Function` errors | Script-src restriction | Don't use them; use JSON.parse for data |
219
- | `fetch()` to your API fails | Cross-origin blocked | Route through `app.callServerTool()` instead |
220
- | External CSS doesn't load | `style-src` restriction | Inline styles in a `<style>` tag |
221
- | Fonts don't load | `font-src` restriction | Use system fonts (`font: 14px system-ui`) |
222
- | External `<img src>` broken | CSP `img-src` + referrer hotlink blocking | Fetch server-side, inline as `data:` URL in the tool result payload |
223
- | `window.open()` does nothing | Sandbox lacks `allow-popups` | Use `app.openLink({url})` |
224
- | `<a target="_blank">` does nothing | Same | Intercept click → `preventDefault()` → `app.openLink` |
225
- | Edited HTML doesn't appear in Desktop | Desktop caches UI resources | Fully quit (⌘Q) + relaunch, not just window-close |
226
-
227
- When you're unsure, open the **iframe's own** devtools console (not the main app's) — CSP violations are logged there. See `iframe-sandbox.md` for the bundle-inlining pattern.
@@ -1,18 +0,0 @@
1
- # Connector-directory submission checklist
2
-
3
- Run through this before submitting a remote MCP app to the WormClaude connector
4
- directory. Every item is a hard review criterion.
5
-
6
- | Area | Requirement |
7
- |---|---|
8
- | **Auth** | OAuth (DCR or CIMD) or **`none`** (authless). Static bearer tokens are private-deploy only and block listing. Authless is fine for public-data servers — the server holds any upstream API keys itself. |
9
- | **Tool annotations** | Every tool sets `annotations.title` plus the relevant hints: `readOnlyHint: true` for fetch/search tools, `destructiveHint` / `idempotentHint` for writes, `openWorldHint: true` when the tool reaches an external system. |
10
- | **Tool names** | ≤ 64 characters, snake/kebab case. |
11
- | **Widget layout** | Inline height ≤ 500px, no nested scroll containers, 44pt minimum touch targets, WCAG-AA contrast in both themes. |
12
- | **Theming** | `html, body { background: transparent }`, `<meta name="color-scheme" content="light dark">`, and pull in host CSS tokens via `applyHostStyleVariables`. |
13
- | **External links** | Use `app.openLink`. List each origin (e.g. `https://api.example.com`) in the connector's *Allowed link URIs* so the link skips the confirm modal. |
14
- | **Helper tools** | Widget-only tools (geometry/image fetchers) carry `_meta.ui.visibility: ["app"]` so they stay out of WormClaude's tool list. |
15
- | **Screenshots** | 3–5 PNGs, ≥ 1000px wide, cropped to the app response alone — no prompt text in frame. |
16
-
17
- See `abuse-protection.md` for rate-limit and IP-tiering guidance once the
18
- authless endpoint goes public.
@@ -1,164 +0,0 @@
1
- # Iframe sandbox constraints
2
-
3
- MCP-app widgets run inside a sandboxed `<iframe>` in the host (WormClaude Desktop,
4
- claude.ai). The sandbox and CSP attributes tightly constrain what the widget can
5
- do. Each item below was seen failing as a silently blank iframe until the fix
6
- went in — the error shows up only in the iframe's own devtools console, never
7
- the host's.
8
-
9
- ---
10
-
11
- ## Problem → fix table
12
-
13
- | Symptom | Root cause | Fix |
14
- |---|---|---|
15
- | Widget renders as blank rectangle, no error | CSP `script-src` blocks esm.sh fetching transitive `@modelcontextprotocol/sdk` deps | Inline the `ext-apps/app-with-deps` bundle into the HTML |
16
- | `window.open()` does nothing | Sandbox lacks `allow-popups` | Use `app.openLink({ url })` |
17
- | `<a target="_blank">` does nothing | Same | `e.preventDefault()` + `app.openLink({ url })` on click |
18
- | External `<img src>` broken | CSP `img-src` + referrer hotlink blocking | Fetch server-side, ship as `data:` URL in the tool result payload |
19
- | Widget edits don't appear after server restart | Host caches UI resources | Fully quit the host (⌘Q / Alt+F4) and relaunch |
20
- | Top-level `await` throws | Older iframe contexts | Wrap module body in an async IIFE |
21
-
22
- ---
23
-
24
- ## Inlining the ext-apps bundle
25
-
26
- `@modelcontextprotocol/ext-apps` provides a self-contained browser build via the
27
- `app-with-deps` export (~300KB). It's minified ESM that ends in `export{…}`; to
28
- consume it from an inline `<script type="module">` block, rewrite that export
29
- statement into a global assignment at build time:
30
-
31
- ```ts
32
- import { readFileSync } from "node:fs";
33
- import { createRequire } from "node:module";
34
- const require = createRequire(import.meta.url);
35
-
36
- const bundle = readFileSync(
37
- require.resolve("@modelcontextprotocol/ext-apps/app-with-deps"),
38
- "utf8",
39
- ).replace(/export\{([^}]+)\};?\s*$/, (_, body) =>
40
- "globalThis.ExtApps={" +
41
- body.split(",").map((pair) => {
42
- const [local, exported] = pair.split(" as ").map((s) => s.trim());
43
- return `${exported ?? local}:${local}`;
44
- }).join(",") + "};",
45
- );
46
-
47
- const widgetHtml = readFileSync("./widgets/widget.html", "utf8")
48
- .replace("/*__EXT_APPS_BUNDLE__*/", () => bundle);
49
- ```
50
-
51
- Widget side:
52
-
53
- ```html
54
- <script type="module">
55
- /*__EXT_APPS_BUNDLE__*/
56
- const { App } = globalThis.ExtApps;
57
- (async () => {
58
- const app = new App({ name: "…", version: "…" }, {});
59
- // …
60
- })();
61
- </script>
62
- ```
63
-
64
- Using the `() => bundle` replacer form (instead of a bare string) matters —
65
- `String.replace` treats `$…` sequences specially in a string replacement, and
66
- the minified bundle is packed with them.
67
-
68
- ---
69
-
70
- ## Outbound links
71
-
72
- ```js
73
- // ✗ blocked
74
- window.open(url, "_blank");
75
- // ✗ blocked
76
- <a href="…" target="_blank">…</a>
77
-
78
- // ✓ host-mediated
79
- await app.openLink({ url });
80
- ```
81
-
82
- Intercept anchor clicks:
83
-
84
- ```js
85
- el.addEventListener("click", (e) => {
86
- e.preventDefault();
87
- app.openLink({ url: el.href });
88
- });
89
- ```
90
-
91
- ---
92
-
93
- ## External images
94
-
95
- The default CSP `img-src` (plus many CDN referrer policies) stops
96
- `<img src="https://external-cdn/…">` from loading. Inline them server-side in
97
- the tool handler:
98
-
99
- ```ts
100
- async function toDataUrl(url: string): Promise<string | undefined> {
101
- try {
102
- const res = await fetch(url, { signal: AbortSignal.timeout(5000) });
103
- if (!res.ok) return undefined;
104
- const buf = Buffer.from(await res.arrayBuffer());
105
- const mime = res.headers.get("content-type") ?? "image/jpeg";
106
- return `data:${mime};base64,${buf.toString("base64")}`;
107
- } catch {
108
- return undefined;
109
- }
110
- }
111
-
112
- // in the tool handler
113
- const inlined = await Promise.all(
114
- items.map(async (it) =>
115
- it.thumb ? { ...it, thumb: await toDataUrl(it.thumb) ?? it.thumb } : it,
116
- ),
117
- );
118
- ```
119
-
120
- Add `referrerpolicy="no-referrer"` on the `<img>` as a fallback for any URL
121
- that ends up not inlined.
122
-
123
- ---
124
-
125
- ## Theme & host styles
126
-
127
- The host draws the iframe inside its own card chrome — so paint a **transparent** background and pull in the host CSS tokens so the widget blends in across light/dark and across different hosts.
128
-
129
- ```html
130
- <meta name="color-scheme" content="light dark" />
131
- ```
132
-
133
- ```css
134
- :root {
135
- --ink: var(--color-text-primary, #0f1111);
136
- --sub: var(--color-text-secondary, #5a6270);
137
- --line: var(--color-border-default, #e3e6ea);
138
- }
139
- html, body { background: transparent; color: var(--ink); }
140
- :root.dark .thumb { mix-blend-mode: normal; } /* multiply → images vanish in dark */
141
- ```
142
-
143
- ```js
144
- const { App, applyHostStyleVariables } = globalThis.ExtApps;
145
-
146
- function applyHostContext(ctx) {
147
- document.documentElement.classList.toggle("dark", ctx?.theme === "dark");
148
- if (ctx?.styles?.variables) applyHostStyleVariables(ctx.styles.variables);
149
- }
150
- app.onhostcontextchanged = applyHostContext;
151
- await app.connect();
152
- applyHostContext(app.getHostContext());
153
- ```
154
-
155
- `applyHostStyleVariables` writes the host's `--color-*` / `--font-*` / `--border-radius-*` tokens onto `:root`; the hex values above act as fallbacks for hosts that don't provide them.
156
-
157
- ---
158
-
159
- ## Debugging
160
-
161
- The iframe has a console of its own. In WormClaude Desktop, open DevTools (View →
162
- Toggle Developer Tools), then flip the context dropdown (top-left of the Console
163
- tab) from "top" to the widget's iframe. CSP violations, uncaught exceptions, and
164
- import errors all show up there — the host's main console stays quiet.
@@ -1,54 +0,0 @@
1
- # Payload budgeting
2
-
3
- Hosts cap tool-result text. claude.ai and WormClaude Desktop truncate at roughly
4
- **150,000 characters**; Claude Code at ~25k tokens. Once a tool result goes over
5
- the cap, the host swaps in a file-pointer string in place of your JSON. The
6
- widget then gets non-JSON in `ontoolresult`, `JSON.parse` throws, and the user
7
- sees something like *"Bad payload: SyntaxError: Unexpected token 'E'"* — with no
8
- clue that size was the culprit.
9
-
10
- ## Symptom → cause
11
-
12
- | Symptom | Likely cause |
13
- |---|---|
14
- | Widget shows a JSON parse error on `content[0].text` | Result topped the host cap; the host swapped in a file-pointer string |
15
- | Works for one query, breaks for "all of X" | Row count × column count went past the cap |
16
- | Works in MCP Inspector, breaks in Desktop | The Inspector has no cap; Desktop does |
17
-
18
- ## Strategy
19
-
20
- Cap your own payload at ~130KB and step down in this order:
21
-
22
- 1. **Send full rows** while `JSON.stringify(rows).length` stays under the cap.
23
- 2. **Prune columns** down to the ones the rendering spec actually references.
24
- Scan the spec for both `field: "..."` keys *and* `datum.X` / `datum['X']`
25
- inside expression strings — when the spec aliases a column through a
26
- `calculate` transform, the alias shows up as `field:` but the source column
27
- only appears as `datum.X`, and dropping it leaves the widget with NaN.
28
- 3. **Truncate rows** only as a last resort, and put `{ truncated: N }` in the
29
- payload so the widget can label it.
30
-
31
- ```ts
32
- const MAX = 130_000;
33
- let out = rows;
34
- if (JSON.stringify(out).length > MAX) {
35
- const keep = referencedFields(spec); // field: + datum.X refs
36
- out = rows.map((r) => pick(r, keep));
37
- if (JSON.stringify(out).length > MAX) {
38
- const per = JSON.stringify(out[0] ?? {}).length || 1;
39
- out = out.slice(0, Math.floor(MAX / per));
40
- }
41
- }
42
- ```
43
-
44
- ## Heavy assets go via `callServerTool`, not the result
45
-
46
- Geometry, image bytes, or any blob the widget needs but WormClaude doesn't should
47
- come from a separate tool the widget calls after it mounts:
48
-
49
- ```js
50
- const topo = await app.callServerTool({ name: "get-topojson", arguments: { level } });
51
- ```
52
-
53
- Tag that helper tool with `_meta.ui.visibility: ["app"]` so it stays out of
54
- WormClaude's tool list.