wormclaude 1.0.119 → 1.0.121
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/dist/theme.js +1 -1
- package/dist/tui.js +6 -1
- package/package.json +1 -1
- package/skills/build-mcp-app/SKILL.md +0 -393
- package/skills/build-mcp-app/references/abuse-protection.md +0 -60
- package/skills/build-mcp-app/references/apps-sdk-messages.md +0 -227
- package/skills/build-mcp-app/references/directory-checklist.md +0 -18
- package/skills/build-mcp-app/references/iframe-sandbox.md +0 -164
- package/skills/build-mcp-app/references/payload-budgeting.md +0 -54
- package/skills/build-mcp-app/references/widget-templates.md +0 -249
- package/skills/build-mcp-server/SKILL.md +0 -222
- package/skills/build-mcp-server/references/auth.md +0 -108
- package/skills/build-mcp-server/references/deploy-cloudflare-workers.md +0 -106
- package/skills/build-mcp-server/references/elicitation.md +0 -129
- package/skills/build-mcp-server/references/remote-http-scaffold.md +0 -211
- package/skills/build-mcp-server/references/resources-and-prompts.md +0 -122
- package/skills/build-mcp-server/references/server-capabilities.md +0 -164
- package/skills/build-mcp-server/references/tool-design.md +0 -189
- package/skills/build-mcp-server/references/versions.md +0 -25
- package/skills/build-mcpb/SKILL.md +0 -200
- package/skills/build-mcpb/references/local-security.md +0 -149
- package/skills/build-mcpb/references/manifest-schema.md +0 -156
- package/skills/docx/script/__init__.py +0 -1
- package/skills/docx/script/accept_chages.py +0 -135
- package/skills/docx/script/comment.py +0 -318
- package/skills/docx/script/office/helpers/__init__.py +0 -0
- package/skills/docx/script/office/helpers/merge_runs.py +0 -199
- package/skills/docx/script/office/helpers/simplify_redlines.py +0 -197
- package/skills/docx/script/office/pack.py +0 -159
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/skills/docx/script/office/schemas/mce/mc.xsd +0 -75
- package/skills/docx/script/office/schemas/microsoft/wml-2010.xsd +0 -560
- package/skills/docx/script/office/schemas/microsoft/wml-2012.xsd +0 -67
- package/skills/docx/script/office/schemas/microsoft/wml-2018.xsd +0 -14
- package/skills/docx/script/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/skills/docx/script/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/skills/docx/script/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/skills/docx/script/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/skills/docx/script/office/soffice.py +0 -183
- package/skills/docx/script/office/unpack.py +0 -132
- package/skills/docx/script/office/validate.py +0 -117
- package/skills/docx/script/office/validators/__init__.py +0 -15
- package/skills/docx/script/office/validators/base.py +0 -851
- package/skills/docx/script/office/validators/docx.py +0 -446
- package/skills/docx/script/office/validators/pptx.py +0 -275
- package/skills/docx/script/office/validators/redlining.py +0 -247
- package/skills/docx/script/templates/comments.xml +0 -3
- package/skills/docx/script/templates/commentsExtended.xml +0 -3
- package/skills/docx/script/templates/commentsExtensible.xml +0 -3
- package/skills/docx/script/templates/commentsIds.xml +0 -3
- package/skills/docx/script/templates/people.xml +0 -3
- package/skills/docx/skill.md +0 -593
- package/skills/explain.md +0 -14
- package/skills/frontend-design/SKILL.md +0 -42
- package/skills/pdf/FORMS.md +0 -294
- package/skills/pdf/REFERENCE.md +0 -612
- package/skills/pdf/SKILL.md +0 -314
- package/skills/pdf/scripts/check_bounding_boxes.py +0 -65
- package/skills/pdf/scripts/check_fillable_fields.py +0 -11
- package/skills/pdf/scripts/convert_pdf_to_images.py +0 -33
- package/skills/pdf/scripts/create_validation_image.py +0 -37
- package/skills/pdf/scripts/extract_form_field_info.py +0 -122
- package/skills/pdf/scripts/extract_form_structure.py +0 -115
- package/skills/pdf/scripts/fill_fillable_fields.py +0 -98
- package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
- package/skills/playground/SKILL.md +0 -77
- package/skills/playground/templates/code-map.md +0 -158
- package/skills/playground/templates/concept-map.md +0 -73
- package/skills/playground/templates/data-explorer.md +0 -67
- package/skills/playground/templates/design-playground.md +0 -67
- package/skills/playground/templates/diff-review.md +0 -179
- package/skills/playground/templates/document-critique.md +0 -171
- package/skills/pptx/SKILL.md +0 -230
- package/skills/pptx/editing.md +0 -205
- package/skills/pptx/pptxgenjs.md +0 -437
- package/skills/pptx/scripts/__init__.py +0 -0
- package/skills/pptx/scripts/add_slide.py +0 -195
- package/skills/pptx/scripts/clean.py +0 -286
- package/skills/pptx/scripts/office/helpers/__init__.py +0 -0
- package/skills/pptx/scripts/office/helpers/merge_runs.py +0 -199
- package/skills/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
- package/skills/pptx/scripts/office/pack.py +0 -159
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/skills/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
- package/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
- package/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
- package/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
- package/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/skills/pptx/scripts/office/soffice.py +0 -183
- package/skills/pptx/scripts/office/unpack.py +0 -132
- package/skills/pptx/scripts/office/validate.py +0 -117
- package/skills/pptx/scripts/office/validators/__init__.py +0 -15
- package/skills/pptx/scripts/office/validators/base.py +0 -851
- package/skills/pptx/scripts/office/validators/docx.py +0 -446
- package/skills/pptx/scripts/office/validators/pptx.py +0 -275
- package/skills/pptx/scripts/office/validators/redlining.py +0 -247
- package/skills/pptx/scripts/thumbnail.py +0 -289
- package/skills/recon.md +0 -16
- package/skills/security-audit/SKILL.md +0 -26
- package/skills/talent-creator/SKILL.md +0 -486
- package/skills/talent-creator/agents/analyzer.md +0 -274
- package/skills/talent-creator/agents/comparator.md +0 -202
- package/skills/talent-creator/agents/grader.md +0 -223
- package/skills/talent-creator/assets/eval_review.html +0 -146
- package/skills/talent-creator/eval-viewer/generate_review.py +0 -471
- package/skills/talent-creator/eval-viewer/viewer.html +0 -1325
- package/skills/talent-creator/references/schemas.md +0 -430
- package/skills/talent-creator/scripts/__init__.py +0 -0
- package/skills/talent-creator/scripts/aggregate_benchmark.py +0 -401
- package/skills/talent-creator/scripts/generate_report.py +0 -326
- package/skills/talent-creator/scripts/improve_description.py +0 -247
- package/skills/talent-creator/scripts/package_skill.py +0 -136
- package/skills/talent-creator/scripts/quick_validate.py +0 -146
- package/skills/talent-creator/scripts/run_eval.py +0 -310
- package/skills/talent-creator/scripts/run_loop.py +0 -328
- package/skills/talent-creator/scripts/utils.py +0 -47
- package/skills/xlsx/SKILL.md +0 -300
- package/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
- package/skills/xlsx/scripts/office/helpers/merge_runs.py +0 -199
- package/skills/xlsx/scripts/office/helpers/simplify_redlines.py +0 -197
- package/skills/xlsx/scripts/office/pack.py +0 -159
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/skills/xlsx/scripts/office/schemas/mce/mc.xsd +0 -75
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/skills/xlsx/scripts/office/soffice.py +0 -183
- package/skills/xlsx/scripts/office/unpack.py +0 -132
- package/skills/xlsx/scripts/office/validate.py +0 -117
- package/skills/xlsx/scripts/office/validators/__init__.py +0 -15
- package/skills/xlsx/scripts/office/validators/base.py +0 -851
- package/skills/xlsx/scripts/office/validators/docx.py +0 -446
- package/skills/xlsx/scripts/office/validators/pptx.py +0 -275
- package/skills/xlsx/scripts/office/validators/redlining.py +0 -247
- package/skills/xlsx/scripts/recalc.py +0 -184
|
@@ -1,149 +0,0 @@
|
|
|
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
|
|
@@ -1,156 +0,0 @@
|
|
|
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.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1,135 +0,0 @@
|
|
|
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)
|