wormclaude 1.0.73 → 1.0.75

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 (229) hide show
  1. package/dist/theme.js +4 -4
  2. package/dist/tools.js +19 -0
  3. package/package.json +2 -2
  4. package/skills/build-mcp-app/SKILL.md +393 -0
  5. package/skills/build-mcp-app/references/abuse-protection.md +60 -0
  6. package/skills/build-mcp-app/references/apps-sdk-messages.md +227 -0
  7. package/skills/build-mcp-app/references/directory-checklist.md +18 -0
  8. package/skills/build-mcp-app/references/iframe-sandbox.md +164 -0
  9. package/skills/build-mcp-app/references/payload-budgeting.md +54 -0
  10. package/skills/build-mcp-app/references/widget-templates.md +249 -0
  11. package/skills/build-mcp-server/SKILL.md +222 -0
  12. package/skills/build-mcp-server/references/auth.md +108 -0
  13. package/skills/build-mcp-server/references/deploy-cloudflare-workers.md +106 -0
  14. package/skills/build-mcp-server/references/elicitation.md +129 -0
  15. package/skills/build-mcp-server/references/remote-http-scaffold.md +211 -0
  16. package/skills/build-mcp-server/references/resources-and-prompts.md +122 -0
  17. package/skills/build-mcp-server/references/server-capabilities.md +164 -0
  18. package/skills/build-mcp-server/references/tool-design.md +189 -0
  19. package/skills/build-mcp-server/references/versions.md +25 -0
  20. package/skills/build-mcpb/SKILL.md +200 -0
  21. package/skills/build-mcpb/references/local-security.md +149 -0
  22. package/skills/build-mcpb/references/manifest-schema.md +156 -0
  23. package/skills/docx/script/__init__.py +1 -0
  24. package/skills/docx/script/accept_chages.py +135 -0
  25. package/skills/docx/script/comment.py +318 -0
  26. package/skills/docx/script/office/helpers/__init__.py +0 -0
  27. package/skills/docx/script/office/helpers/merge_runs.py +199 -0
  28. package/skills/docx/script/office/helpers/simplify_redlines.py +197 -0
  29. package/skills/docx/script/office/pack.py +159 -0
  30. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  31. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  32. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  33. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  34. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  35. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  36. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  37. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  38. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  39. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  40. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  41. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  42. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  43. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  44. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  45. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  46. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  47. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  48. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  49. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  50. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  51. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  52. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  53. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  54. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  55. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  56. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  57. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  58. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  59. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  60. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  61. package/skills/docx/script/office/schemas/mce/mc.xsd +75 -0
  62. package/skills/docx/script/office/schemas/microsoft/wml-2010.xsd +560 -0
  63. package/skills/docx/script/office/schemas/microsoft/wml-2012.xsd +67 -0
  64. package/skills/docx/script/office/schemas/microsoft/wml-2018.xsd +14 -0
  65. package/skills/docx/script/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  66. package/skills/docx/script/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  67. package/skills/docx/script/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  68. package/skills/docx/script/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  69. package/skills/docx/script/office/soffice.py +183 -0
  70. package/skills/docx/script/office/unpack.py +132 -0
  71. package/skills/docx/script/office/validate.py +117 -0
  72. package/skills/docx/script/office/validators/__init__.py +15 -0
  73. package/skills/docx/script/office/validators/base.py +851 -0
  74. package/skills/docx/script/office/validators/docx.py +446 -0
  75. package/skills/docx/script/office/validators/pptx.py +275 -0
  76. package/skills/docx/script/office/validators/redlining.py +247 -0
  77. package/skills/docx/script/templates/comments.xml +3 -0
  78. package/skills/docx/script/templates/commentsExtended.xml +3 -0
  79. package/skills/docx/script/templates/commentsExtensible.xml +3 -0
  80. package/skills/docx/script/templates/commentsIds.xml +3 -0
  81. package/skills/docx/script/templates/people.xml +3 -0
  82. package/skills/docx/skill.md +593 -0
  83. package/skills/frontend-design/SKILL.md +42 -0
  84. package/skills/pdf/FORMS.md +294 -0
  85. package/skills/pdf/REFERENCE.md +612 -0
  86. package/skills/pdf/SKILL.md +314 -0
  87. package/skills/pdf/scripts/check_bounding_boxes.py +65 -0
  88. package/skills/pdf/scripts/check_fillable_fields.py +11 -0
  89. package/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
  90. package/skills/pdf/scripts/create_validation_image.py +37 -0
  91. package/skills/pdf/scripts/extract_form_field_info.py +122 -0
  92. package/skills/pdf/scripts/extract_form_structure.py +115 -0
  93. package/skills/pdf/scripts/fill_fillable_fields.py +98 -0
  94. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
  95. package/skills/playground/SKILL.md +77 -0
  96. package/skills/playground/templates/code-map.md +158 -0
  97. package/skills/playground/templates/concept-map.md +73 -0
  98. package/skills/playground/templates/data-explorer.md +67 -0
  99. package/skills/playground/templates/design-playground.md +67 -0
  100. package/skills/playground/templates/diff-review.md +179 -0
  101. package/skills/playground/templates/document-critique.md +171 -0
  102. package/skills/pptx/SKILL.md +230 -0
  103. package/skills/pptx/editing.md +205 -0
  104. package/skills/pptx/pptxgenjs.md +437 -0
  105. package/skills/pptx/scripts/__init__.py +0 -0
  106. package/skills/pptx/scripts/add_slide.py +195 -0
  107. package/skills/pptx/scripts/clean.py +286 -0
  108. package/skills/pptx/scripts/office/helpers/__init__.py +0 -0
  109. package/skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
  110. package/skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
  111. package/skills/pptx/scripts/office/pack.py +159 -0
  112. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  113. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  114. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  115. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  116. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  117. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  118. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  119. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  120. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  121. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  122. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  123. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  124. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  125. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  126. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  127. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  128. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  129. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  130. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  131. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  132. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  133. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  134. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  135. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  136. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  137. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  138. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  139. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  140. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  141. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  142. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  143. package/skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
  144. package/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  145. package/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  146. package/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  147. package/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  148. package/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  149. package/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  150. package/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  151. package/skills/pptx/scripts/office/soffice.py +183 -0
  152. package/skills/pptx/scripts/office/unpack.py +132 -0
  153. package/skills/pptx/scripts/office/validate.py +117 -0
  154. package/skills/pptx/scripts/office/validators/__init__.py +15 -0
  155. package/skills/pptx/scripts/office/validators/base.py +851 -0
  156. package/skills/pptx/scripts/office/validators/docx.py +446 -0
  157. package/skills/pptx/scripts/office/validators/pptx.py +275 -0
  158. package/skills/pptx/scripts/office/validators/redlining.py +247 -0
  159. package/skills/pptx/scripts/thumbnail.py +289 -0
  160. package/skills/talent-creator/SKILL.md +486 -0
  161. package/skills/talent-creator/agents/analyzer.md +274 -0
  162. package/skills/talent-creator/agents/comparator.md +202 -0
  163. package/skills/talent-creator/agents/grader.md +223 -0
  164. package/skills/talent-creator/assets/eval_review.html +146 -0
  165. package/skills/talent-creator/eval-viewer/generate_review.py +471 -0
  166. package/skills/talent-creator/eval-viewer/viewer.html +1325 -0
  167. package/skills/talent-creator/references/schemas.md +430 -0
  168. package/skills/talent-creator/scripts/__init__.py +0 -0
  169. package/skills/talent-creator/scripts/aggregate_benchmark.py +401 -0
  170. package/skills/talent-creator/scripts/generate_report.py +326 -0
  171. package/skills/talent-creator/scripts/improve_description.py +247 -0
  172. package/skills/talent-creator/scripts/package_skill.py +136 -0
  173. package/skills/talent-creator/scripts/quick_validate.py +146 -0
  174. package/skills/talent-creator/scripts/run_eval.py +310 -0
  175. package/skills/talent-creator/scripts/run_loop.py +328 -0
  176. package/skills/talent-creator/scripts/utils.py +47 -0
  177. package/skills/xlsx/SKILL.md +300 -0
  178. package/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  179. package/skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
  180. package/skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
  181. package/skills/xlsx/scripts/office/pack.py +159 -0
  182. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  183. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  184. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  185. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  186. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  187. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  188. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  189. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  190. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  191. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  192. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  193. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  194. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  195. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  196. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  197. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  198. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  199. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  200. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  201. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  202. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  203. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  204. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  205. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  206. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  207. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  208. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  209. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  210. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  211. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  212. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  213. package/skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
  214. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  215. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  216. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  217. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  218. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  219. package/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  220. package/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  221. package/skills/xlsx/scripts/office/soffice.py +183 -0
  222. package/skills/xlsx/scripts/office/unpack.py +132 -0
  223. package/skills/xlsx/scripts/office/validate.py +117 -0
  224. package/skills/xlsx/scripts/office/validators/__init__.py +15 -0
  225. package/skills/xlsx/scripts/office/validators/base.py +851 -0
  226. package/skills/xlsx/scripts/office/validators/docx.py +446 -0
  227. package/skills/xlsx/scripts/office/validators/pptx.py +275 -0
  228. package/skills/xlsx/scripts/office/validators/redlining.py +247 -0
  229. package/skills/xlsx/scripts/recalc.py +184 -0
@@ -0,0 +1,149 @@
1
+ # Local MCP Security
2
+
3
+ **MCPB ships no sandbox.** The manifest has no `permissions` block, no filesystem scoping, and no platform-enforced network allowlist. The server process runs with the user's full privileges — it can read any file they can, spawn any process, and reach any network endpoint.
4
+
5
+ WormClaude is what drives it. That combination means **tool inputs are untrusted**, even though they arrive from an AI the user trusts. A prompt-injected web page can trick WormClaude into calling your `delete_file` tool with a path you never intended.
6
+
7
+ Your tool handlers are the only line of defense. Everything below is about building that defense yourself.
8
+
9
+ ---
10
+
11
+ ## Path traversal
12
+
13
+ The number-one bug in local MCP servers. Whenever you take a path parameter and join it to a root, **resolve it and verify containment**.
14
+
15
+ ```typescript
16
+ import { resolve, relative, isAbsolute } from "node:path";
17
+
18
+ function safeJoin(root: string, userPath: string): string {
19
+ const full = resolve(root, userPath);
20
+ const rel = relative(root, full);
21
+ if (rel.startsWith("..") || isAbsolute(rel)) {
22
+ throw new Error(`Path escapes root: ${userPath}`);
23
+ }
24
+ return full;
25
+ }
26
+ ```
27
+
28
+ `resolve` normalizes `..`, symlink segments, and the like; `relative` tells you whether the result left the root. Don't lean on `String.includes("..")` — it misses encoded and symlink-based escapes.
29
+
30
+ **Python equivalent:**
31
+
32
+ ```python
33
+ from pathlib import Path
34
+
35
+ def safe_join(root: Path, user_path: str) -> Path:
36
+ full = (root / user_path).resolve()
37
+ if not full.is_relative_to(root.resolve()):
38
+ raise ValueError(f"Path escapes root: {user_path}")
39
+ return full
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Roots — ask the host, don't hardcode
45
+
46
+ Before you hardcode `ROOT` from a config env var, check whether the host supports `roots/list`. That's the spec-native way to obtain user-approved workspace boundaries.
47
+
48
+ ```typescript
49
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
50
+
51
+ const server = new McpServer({ name: "...", version: "..." });
52
+
53
+ let allowedRoots: string[] = [];
54
+ server.server.oninitialized = async () => {
55
+ const caps = server.getClientCapabilities();
56
+ if (caps?.roots) {
57
+ const { roots } = await server.server.listRoots();
58
+ allowedRoots = roots.map(r => new URL(r.uri).pathname);
59
+ } else {
60
+ allowedRoots = [process.env.ROOT_DIR ?? process.cwd()];
61
+ }
62
+ };
63
+ ```
64
+
65
+ ```python
66
+ # fastmcp — inside a tool handler
67
+ async def my_tool(ctx: Context) -> str:
68
+ try:
69
+ roots = await ctx.list_roots()
70
+ allowed = [urlparse(r.uri).path for r in roots]
71
+ except Exception:
72
+ allowed = [os.environ.get("ROOT_DIR", os.getcwd())]
73
+ ```
74
+
75
+ When roots are available, use them; when they aren't, fall back to config. Either way, validate every path against the allowed set.
76
+
77
+ ---
78
+
79
+ ## Command injection
80
+
81
+ If you spawn processes, **never route user input through a shell**.
82
+
83
+ ```typescript
84
+ // ❌ catastrophic
85
+ exec(`git log ${branch}`);
86
+
87
+ // ✅ array-args, no shell
88
+ execFile("git", ["log", branch]);
89
+ ```
90
+
91
+ When you're wrapping a CLI, assemble the entire argv as an array. If the tool takes flags at all, check each one against an allowlist.
92
+
93
+ ---
94
+
95
+ ## Read-only by default
96
+
97
+ Split reads and writes into separate tools. Most workflows only ever need reads, and a read-only tool can't be turned into data loss no matter what WormClaude is tricked into passing it.
98
+
99
+ ```
100
+ list_files ← safe to call freely
101
+ read_file ← safe to call freely
102
+ write_file ← separate tool, separate scrutiny
103
+ delete_file ← consider not shipping this at all
104
+ ```
105
+
106
+ Back this up with tool annotations — `readOnlyHint: true` on every read tool, `destructiveHint: true` on delete/overwrite tools. Hosts surface these in their permission UI (auto-approving reads, showing a confirm dialog for destructive ones). See `../build-mcp-server/references/tool-design.md`.
107
+
108
+ If you do ship write/delete, consider requiring explicit confirmation through elicitation (see `../build-mcp-server/references/elicitation.md`) or a confirmation widget (see `build-mcp-app`) so the user signs off on each destructive call.
109
+
110
+ ---
111
+
112
+ ## Resource limits
113
+
114
+ WormClaude will cheerfully ask to read a 4GB log file. Put a cap on everything:
115
+
116
+ ```typescript
117
+ const MAX_BYTES = 1_000_000;
118
+ const buf = await readFile(path);
119
+ if (buf.length > MAX_BYTES) {
120
+ return {
121
+ content: [{
122
+ type: "text",
123
+ text: `File is ${buf.length} bytes — too large. Showing first ${MAX_BYTES}:\n\n`
124
+ + buf.subarray(0, MAX_BYTES).toString("utf8"),
125
+ }],
126
+ };
127
+ }
128
+ ```
129
+
130
+ Do the same for directory listings (cap the entry count), search results (cap the matches), and anything else that's unbounded.
131
+
132
+ ---
133
+
134
+ ## Secrets
135
+
136
+ - **Config secrets** (`sensitive: true` in the manifest's `user_config`): the host keeps them in the OS keychain and delivers them via an env var. Don't log them, and don't put them in tool results.
137
+ - **Never write secrets to plaintext files.** If the host's keychain integration isn't enough, reach for `keytar` (Node) / `keyring` (Python) yourself.
138
+ - **Tool results flow into the chat transcript.** Whatever you return is visible to the user (and to any log export), so redact before returning.
139
+
140
+ ---
141
+
142
+ ## Checklist before shipping
143
+
144
+ - [ ] Every path parameter goes through containment check
145
+ - [ ] No `exec()` / `shell=True` — `execFile` / array-argv only
146
+ - [ ] Write/delete split from read tools; `readOnlyHint`/`destructiveHint` annotations set
147
+ - [ ] Size caps on file reads, listing lengths, search results
148
+ - [ ] Secrets never logged or returned in tool results
149
+ - [ ] Tested with adversarial inputs: `../../etc/passwd`, `; rm -rf ~`, 10GB file
@@ -0,0 +1,156 @@
1
+ # MCPB Manifest Schema (v0.4)
2
+
3
+ Checked against `github.com/anthropics/mcpb/schemas/mcpb-manifest-v0.4.schema.json`. The schema sets `additionalProperties: false`, so any unknown key is rejected. Include `"$schema"` in your manifest to get editor validation.
4
+
5
+ ---
6
+
7
+ ## Top-level fields
8
+
9
+ | Field | Required | Description |
10
+ |---|---|---|
11
+ | `manifest_version` | ✅ | Schema version. Use `"0.4"`. |
12
+ | `name` | ✅ | Package identifier (lowercase, hyphens). Must be unique. |
13
+ | `version` | ✅ | Semver version of YOUR package. |
14
+ | `description` | ✅ | One-line summary. Shown in marketplace. |
15
+ | `author` | ✅ | `{name, email?, url?}` |
16
+ | `server` | ✅ | Entry point and launch config. See below. |
17
+ | `display_name` | | Human-friendly name. Falls back to `name`. |
18
+ | `long_description` | | Markdown. Shown on detail page. |
19
+ | `icon` / `icons` | | Path(s) to icon file(s) in the bundle. |
20
+ | `homepage` / `repository` / `documentation` / `support` | | URLs. |
21
+ | `license` | | SPDX identifier. |
22
+ | `keywords` | | String array for search. |
23
+ | `user_config` | | Install-time config fields. See below. |
24
+ | `compatibility` | | Host/platform/runtime requirements. See below. |
25
+ | `tools` / `prompts` | | Optional declarative list for marketplace display. Not enforced at runtime. |
26
+ | `tools_generated` / `prompts_generated` | | `true` if tools/prompts are dynamic (can't list statically). |
27
+ | `screenshots` | | Array of image paths. |
28
+ | `localization` | | i18n bundles. |
29
+ | `privacy_policies` | | URLs. |
30
+
31
+ ---
32
+
33
+ ## `server` — launch configuration
34
+
35
+ ```json
36
+ "server": {
37
+ "type": "node",
38
+ "entry_point": "server/index.js",
39
+ "mcp_config": {
40
+ "command": "node",
41
+ "args": ["${__dirname}/server/index.js"],
42
+ "env": {
43
+ "API_KEY": "${user_config.apiKey}",
44
+ "ROOT_DIR": "${user_config.rootDir}"
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ | Field | Description |
51
+ |---|---|
52
+ | `type` | `"node"`, `"python"`, or `"binary"` |
53
+ | `entry_point` | Relative path to main file. Informational. |
54
+ | `mcp_config.command` | Executable to launch. |
55
+ | `mcp_config.args` | Argv array. Use `${__dirname}` for bundle-relative paths. |
56
+ | `mcp_config.env` | Environment variables. Use `${user_config.KEY}` to substitute user config. |
57
+
58
+ **Substitution variables** (in `args` and `env` only):
59
+ - `${__dirname}` — absolute path to the unpacked bundle directory
60
+ - `${user_config.<key>}` — value the user entered at install time
61
+ - `${HOME}` — user's home directory
62
+
63
+ **There are no auto-prefixed env vars.** The env var names your server reads are precisely the ones you declare in `mcp_config.env`. Write `"ROOT_DIR": "${user_config.rootDir}"` and your server reads `process.env.ROOT_DIR`.
64
+
65
+ ---
66
+
67
+ ## `user_config` — install-time settings
68
+
69
+ ```json
70
+ "user_config": {
71
+ "apiKey": {
72
+ "type": "string",
73
+ "title": "API Key",
74
+ "description": "Your service API key. Stored encrypted.",
75
+ "sensitive": true,
76
+ "required": true
77
+ },
78
+ "rootDir": {
79
+ "type": "directory",
80
+ "title": "Root directory",
81
+ "description": "Directory to expose to the server.",
82
+ "default": "${HOME}/Documents"
83
+ },
84
+ "maxResults": {
85
+ "type": "number",
86
+ "title": "Max results",
87
+ "description": "Maximum items returned per query.",
88
+ "default": 50,
89
+ "min": 1,
90
+ "max": 500
91
+ }
92
+ }
93
+ ```
94
+
95
+ | Field | Required | Description |
96
+ |---|---|---|
97
+ | `type` | ✅ | `"string"`, `"number"`, `"boolean"`, `"directory"`, `"file"` |
98
+ | `title` | ✅ | Form label. |
99
+ | `description` | ✅ | Help text under the input. |
100
+ | `default` | | Pre-filled value. Supports `${HOME}`. |
101
+ | `required` | | If `true`, install blocks until filled. |
102
+ | `sensitive` | | If `true`, stored in OS keychain + masked in UI. **NOT `secret`** — that field doesn't exist. |
103
+ | `multiple` | | If `true`, user can enter multiple values (array). |
104
+ | `min` / `max` | | Numeric bounds (for `type: "number"`). |
105
+
106
+ The `directory` and `file` types draw native OS pickers — favor them over free-text paths for both UX and validation.
107
+
108
+ ---
109
+
110
+ ## `compatibility` — gate installs
111
+
112
+ ```json
113
+ "compatibility": {
114
+ "claude_desktop": ">=1.0.0",
115
+ "platforms": ["darwin", "win32", "linux"],
116
+ "runtimes": { "node": ">=20" }
117
+ }
118
+ ```
119
+
120
+ | Field | Description |
121
+ |---|---|
122
+ | `claude_desktop` | Semver range. Install blocked if host is older. |
123
+ | `platforms` | OS allowlist. Subset of `["darwin", "win32", "linux"]`. |
124
+ | `runtimes` | Required runtime versions, e.g. `{"node": ">=20"}` or `{"python": ">=3.11"}`. |
125
+
126
+ ---
127
+
128
+ ## Minimal valid manifest
129
+
130
+ ```json
131
+ {
132
+ "$schema": "https://raw.githubusercontent.com/anthropics/mcpb/main/schemas/mcpb-manifest-v0.4.schema.json",
133
+ "manifest_version": "0.4",
134
+ "name": "hello",
135
+ "version": "0.1.0",
136
+ "description": "Minimal MCPB server.",
137
+ "author": { "name": "Your Name" },
138
+ "server": {
139
+ "type": "node",
140
+ "entry_point": "server/index.js",
141
+ "mcp_config": {
142
+ "command": "node",
143
+ "args": ["${__dirname}/server/index.js"]
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ ---
150
+
151
+ ## What MCPB does NOT have
152
+
153
+ - **No `permissions` block.** There's no manifest-level filesystem/network/process scoping. The server runs with full user privileges, so enforce boundaries inside your tool handlers — see `local-security.md`.
154
+ - **No auto env var prefix.** There's no `MCPB_CONFIG_*` convention; you map config → env explicitly in `server.mcp_config.env`.
155
+ - **No `entry` field.** It's `server` with `entry_point` nested inside.
156
+ - **No `minHostVersion`.** Use `compatibility.claude_desktop` instead.
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,135 @@
1
+ """Accept all tracked changes in a DOCX file using LibreOffice.
2
+
3
+ Requires LibreOffice (soffice) to be installed.
4
+ """
5
+
6
+ import argparse
7
+ import logging
8
+ import shutil
9
+ import subprocess
10
+ from pathlib import Path
11
+
12
+ from office.soffice import get_soffice_env
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ LIBREOFFICE_PROFILE = "/tmp/libreoffice_docx_profile"
17
+ MACRO_DIR = f"{LIBREOFFICE_PROFILE}/user/basic/Standard"
18
+
19
+ ACCEPT_CHANGES_MACRO = """<?xml version="1.0" encoding="UTF-8"?>
20
+ <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
21
+ <script:module xmlns:script="http://openoffice.org/2000/script" script:name="Module1" script:language="StarBasic">
22
+ Sub AcceptAllTrackedChanges()
23
+ Dim document As Object
24
+ Dim dispatcher As Object
25
+
26
+ document = ThisComponent.CurrentController.Frame
27
+ dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
28
+
29
+ dispatcher.executeDispatch(document, ".uno:AcceptAllTrackedChanges", "", 0, Array())
30
+ ThisComponent.store()
31
+ ThisComponent.close(True)
32
+ End Sub
33
+ </script:module>"""
34
+
35
+
36
+ def accept_changes(
37
+ input_file: str,
38
+ output_file: str,
39
+ ) -> tuple[None, str]:
40
+ input_path = Path(input_file)
41
+ output_path = Path(output_file)
42
+
43
+ if not input_path.exists():
44
+ return None, f"Error: Input file not found: {input_file}"
45
+
46
+ if not input_path.suffix.lower() == ".docx":
47
+ return None, f"Error: Input file is not a DOCX file: {input_file}"
48
+
49
+ try:
50
+ output_path.parent.mkdir(parents=True, exist_ok=True)
51
+ shutil.copy2(input_path, output_path)
52
+ except Exception as e:
53
+ return None, f"Error: Failed to copy input file to output location: {e}"
54
+
55
+ if not _setup_libreoffice_macro():
56
+ return None, "Error: Failed to setup LibreOffice macro"
57
+
58
+ cmd = [
59
+ "soffice",
60
+ "--headless",
61
+ f"-env:UserInstallation=file://{LIBREOFFICE_PROFILE}",
62
+ "--norestore",
63
+ "vnd.sun.star.script:Standard.Module1.AcceptAllTrackedChanges?language=Basic&location=application",
64
+ str(output_path.absolute()),
65
+ ]
66
+
67
+ try:
68
+ result = subprocess.run(
69
+ cmd,
70
+ capture_output=True,
71
+ text=True,
72
+ timeout=30,
73
+ check=False,
74
+ env=get_soffice_env(),
75
+ )
76
+ except subprocess.TimeoutExpired:
77
+ return (
78
+ None,
79
+ f"Successfully accepted all tracked changes: {input_file} -> {output_file}",
80
+ )
81
+
82
+ if result.returncode != 0:
83
+ return None, f"Error: LibreOffice failed: {result.stderr}"
84
+
85
+ return (
86
+ None,
87
+ f"Successfully accepted all tracked changes: {input_file} -> {output_file}",
88
+ )
89
+
90
+
91
+ def _setup_libreoffice_macro() -> bool:
92
+ macro_dir = Path(MACRO_DIR)
93
+ macro_file = macro_dir / "Module1.xba"
94
+
95
+ if macro_file.exists() and "AcceptAllTrackedChanges" in macro_file.read_text():
96
+ return True
97
+
98
+ if not macro_dir.exists():
99
+ subprocess.run(
100
+ [
101
+ "soffice",
102
+ "--headless",
103
+ f"-env:UserInstallation=file://{LIBREOFFICE_PROFILE}",
104
+ "--terminate_after_init",
105
+ ],
106
+ capture_output=True,
107
+ timeout=10,
108
+ check=False,
109
+ env=get_soffice_env(),
110
+ )
111
+ macro_dir.mkdir(parents=True, exist_ok=True)
112
+
113
+ try:
114
+ macro_file.write_text(ACCEPT_CHANGES_MACRO)
115
+ return True
116
+ except Exception as e:
117
+ logger.warning(f"Failed to setup LibreOffice macro: {e}")
118
+ return False
119
+
120
+
121
+ if __name__ == "__main__":
122
+ parser = argparse.ArgumentParser(
123
+ description="Accept all tracked changes in a DOCX file"
124
+ )
125
+ parser.add_argument("input_file", help="Input DOCX file with tracked changes")
126
+ parser.add_argument(
127
+ "output_file", help="Output DOCX file (clean, no tracked changes)"
128
+ )
129
+ args = parser.parse_args()
130
+
131
+ _, message = accept_changes(args.input_file, args.output_file)
132
+ print(message)
133
+
134
+ if "Error" in message:
135
+ raise SystemExit(1)