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,164 +0,0 @@
|
|
|
1
|
-
# Server capabilities — the rest of the spec
|
|
2
|
-
|
|
3
|
-
The features that sit beyond the three core primitives. Most are optional, and a few are practically free wins.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## `instructions` — system prompt injection
|
|
8
|
-
|
|
9
|
-
A single line of config that goes straight into WormClaude's system prompt. Use it for tool-use hints that don't belong in any one tool's description.
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
const server = new McpServer(
|
|
13
|
-
{ name: "my-server", version: "1.0.0" },
|
|
14
|
-
{ instructions: "Always call search_items before get_item — IDs aren't guessable." },
|
|
15
|
-
);
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
```python
|
|
19
|
-
mcp = FastMCP("my-server", instructions="Always call search_items before get_item — IDs aren't guessable.")
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
This is the most leverage you'll get from a single line in the spec. When WormClaude keeps misusing your tools, this is where the fix goes.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Sampling — delegate LLM calls to the host
|
|
27
|
-
|
|
28
|
-
When your tool logic needs LLM inference (summarize, classify, generate), don't bundle your own model client — ask the host to handle it.
|
|
29
|
-
|
|
30
|
-
```typescript
|
|
31
|
-
// Inside a tool handler
|
|
32
|
-
const result = await extra.sendRequest({
|
|
33
|
-
method: "sampling/createMessage",
|
|
34
|
-
params: {
|
|
35
|
-
messages: [{ role: "user", content: { type: "text", text: `Summarize: ${doc}` } }],
|
|
36
|
-
maxTokens: 500,
|
|
37
|
-
},
|
|
38
|
-
}, CreateMessageResultSchema);
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
```python
|
|
42
|
-
# fastmcp
|
|
43
|
-
response = await ctx.sample("Summarize this document", context=doc)
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**Requires client support** — test `clientCapabilities.sampling` first. Model preference hints match by substring (`"claude-3-5"` matches any Claude 3.5 variant).
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## Roots — query workspace boundaries
|
|
51
|
-
|
|
52
|
-
Rather than hardcoding a root directory, ask the host which directories the user has approved.
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
const caps = server.getClientCapabilities();
|
|
56
|
-
if (caps?.roots) {
|
|
57
|
-
const { roots } = await server.server.listRoots();
|
|
58
|
-
// roots: [{ uri: "file:///home/user/project", name: "My Project" }]
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
```python
|
|
63
|
-
roots = await ctx.list_roots()
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Especially relevant for MCPB local servers — see `build-mcpb/references/local-security.md`.
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Logging — structured, level-aware
|
|
71
|
-
|
|
72
|
-
A better fit than stderr for remote servers, and the client can filter by level.
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
// In a tool handler
|
|
76
|
-
await extra.sendNotification({
|
|
77
|
-
method: "notifications/message",
|
|
78
|
-
params: { level: "info", logger: "my-tool", data: { msg: "Processing", count: 42 } },
|
|
79
|
-
});
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
```python
|
|
83
|
-
await ctx.info("Processing", count=42) # also: ctx.debug, ctx.warning, ctx.error
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Levels mirror syslog: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`. The client picks the minimum via `logging/setLevel`.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Progress — for long-running tools
|
|
91
|
-
|
|
92
|
-
The client sends a `progressToken` in the request `_meta`, and the server emits progress notifications against it.
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
async (args, extra) => {
|
|
96
|
-
const token = extra._meta?.progressToken;
|
|
97
|
-
for (let i = 0; i < 100; i++) {
|
|
98
|
-
if (token !== undefined) {
|
|
99
|
-
await extra.sendNotification({
|
|
100
|
-
method: "notifications/progress",
|
|
101
|
-
params: { progressToken: token, progress: i, total: 100, message: `Step ${i}` },
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
await doStep(i);
|
|
105
|
-
}
|
|
106
|
-
return { content: [{ type: "text", text: "Done" }] };
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
```python
|
|
111
|
-
async def long_task(ctx: Context) -> str:
|
|
112
|
-
for i in range(100):
|
|
113
|
-
await ctx.report_progress(progress=i, total=100, message=f"Step {i}")
|
|
114
|
-
await do_step(i)
|
|
115
|
-
return "Done"
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## Cancellation — honor the abort signal
|
|
121
|
-
|
|
122
|
-
Long-running tools should watch the SDK-provided `AbortSignal`:
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
async (args, extra) => {
|
|
126
|
-
for (const item of items) {
|
|
127
|
-
if (extra.signal.aborted) throw new Error("Cancelled");
|
|
128
|
-
await process(item);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
fastmcp manages this through asyncio cancellation — no explicit check is needed as long as your handler is properly async.
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## Completion — autocomplete for prompt args
|
|
138
|
-
|
|
139
|
-
If you've registered prompts or resource templates that take arguments, you can also offer autocomplete:
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
server.registerPrompt("query", {
|
|
143
|
-
argsSchema: {
|
|
144
|
-
table: completable(z.string(), async (partial) => tables.filter(t => t.startsWith(partial))),
|
|
145
|
-
},
|
|
146
|
-
}, ...);
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Low priority unless your prompts have a lot of valid values.
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## Which capabilities need client support?
|
|
154
|
-
|
|
155
|
-
| Feature | Server declares | Client must support | Fallback if not |
|
|
156
|
-
|---|---|---|---|
|
|
157
|
-
| `instructions` | implicit | — | — (always works) |
|
|
158
|
-
| Logging | `logging: {}` | — | stderr |
|
|
159
|
-
| Progress | — | sends `progressToken` | silently skip |
|
|
160
|
-
| Sampling | — | `sampling: {}` | bring your own LLM |
|
|
161
|
-
| Elicitation | — | `elicitation: {}` | return text, ask WormClaude to relay |
|
|
162
|
-
| Roots | — | `roots: {}` | config env var |
|
|
163
|
-
|
|
164
|
-
Check client caps via `server.getClientCapabilities()` (TS) or `ctx.session.client_params.capabilities` (fastmcp) before using the bottom three.
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
# Tool Design — Writing Tools WormClaude Uses Correctly
|
|
2
|
-
|
|
3
|
-
Tool schemas and descriptions are a form of prompt engineering. They go straight into WormClaude's context and decide whether it reaches for the right tool with the right arguments. The majority of MCP integration bugs come back to vague descriptions or loose schemas.
|
|
4
|
-
|
|
5
|
-
## WormClaude Directory hard requirements
|
|
6
|
-
|
|
7
|
-
If you plan to submit this server to the WormClaude Directory, the items below are pass/fail review criteria (full list: https://claude.com/docs/connectors/building/review-criteria):
|
|
8
|
-
|
|
9
|
-
- Every tool **must** carry `readOnlyHint`, `destructiveHint`, and `title` annotations — they drive auto-permissions in WormClaude.
|
|
10
|
-
- Tool names **must** stay at or under 64 characters.
|
|
11
|
-
- Reads and writes **must** live in separate tools. A single tool that accepts both GET and POST/PUT/PATCH/DELETE gets rejected — spelling out safe vs unsafe inside one tool's description is not enough.
|
|
12
|
-
- Tool descriptions **must not** tell WormClaude how to behave (e.g. "always do X", "you must call Y first", overriding system instructions, pushing products) — reviewers treat this as prompt injection.
|
|
13
|
-
- Tools that take freeform API endpoints or params **must** point to the target API's documentation in their description.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Descriptions
|
|
18
|
-
|
|
19
|
-
**The description is the contract.** It's the only thing WormClaude looks at before deciding whether to call the tool. Write it like a one-line manpage entry, plus a few hints that disambiguate.
|
|
20
|
-
|
|
21
|
-
### Good
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
search_issues — Search issues by keyword across title and body. Returns up
|
|
25
|
-
to `limit` results ranked by recency. Does NOT search comments or PRs —
|
|
26
|
-
use search_comments / search_prs for those.
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
- States what it does
|
|
30
|
-
- States what it returns
|
|
31
|
-
- States what it *won't* do (heads off wrong-tool calls)
|
|
32
|
-
|
|
33
|
-
### Bad
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
search_issues — Searches for issues.
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
WormClaude will fire this off for anything vaguely search-shaped, including things it can't actually do.
|
|
40
|
-
|
|
41
|
-
### Disambiguate siblings
|
|
42
|
-
|
|
43
|
-
When two tools resemble each other, each description should point to when the *other* one is the right call:
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
get_user — Fetch a user by ID. If you only have an email, use find_user_by_email.
|
|
47
|
-
find_user_by_email — Look up a user by email address. Returns null if not found.
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## Parameter schemas
|
|
53
|
-
|
|
54
|
-
**Tight schemas head off bad calls.** Every constraint you bake into the schema is one less thing that can break at runtime.
|
|
55
|
-
|
|
56
|
-
| Instead of | Use |
|
|
57
|
-
|---|---|
|
|
58
|
-
| `z.string()` for an ID | `z.string().regex(/^usr_[a-z0-9]{12}$/)` |
|
|
59
|
-
| `z.number()` for a limit | `z.number().int().min(1).max(100).default(20)` |
|
|
60
|
-
| `z.string()` for a choice | `z.enum(["open", "closed", "all"])` |
|
|
61
|
-
| optional with no hint | `.optional().describe("Defaults to the caller's workspace")` |
|
|
62
|
-
|
|
63
|
-
**Describe every parameter.** The `.describe()` text appears in the schema WormClaude sees. Skipping it is leaving value on the table.
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
{
|
|
67
|
-
query: z.string().describe("Keywords to search for. Supports quoted phrases."),
|
|
68
|
-
status: z.enum(["open", "closed", "all"]).default("open")
|
|
69
|
-
.describe("Filter by status. Use 'all' to include closed items."),
|
|
70
|
-
limit: z.number().int().min(1).max(50).default(10)
|
|
71
|
-
.describe("Max results. Hard cap at 50."),
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## Return shapes
|
|
78
|
-
|
|
79
|
-
WormClaude reads whatever lands in `content[].text`. Keep it parseable.
|
|
80
|
-
|
|
81
|
-
**Do:**
|
|
82
|
-
- Return JSON for structured data (`JSON.stringify(result, null, 2)`)
|
|
83
|
-
- Return short confirmations for mutations (`"Created issue #123"`)
|
|
84
|
-
- Include the IDs WormClaude will need for follow-up calls
|
|
85
|
-
- Truncate oversized payloads and say so (`"Showing 10 of 847 results. Refine the query to narrow down."`)
|
|
86
|
-
|
|
87
|
-
**Don't:**
|
|
88
|
-
- Return raw HTML
|
|
89
|
-
- Return megabytes of unfiltered API response
|
|
90
|
-
- Return bare success with no identifier (`"ok"` after a create — WormClaude can't reference what it just made)
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## How many tools?
|
|
95
|
-
|
|
96
|
-
| Tool count | Guidance |
|
|
97
|
-
|---|---|
|
|
98
|
-
| 1–15 | One tool per action. Sweet spot. |
|
|
99
|
-
| 15–30 | Still workable. Audit for near-duplicates that could merge. |
|
|
100
|
-
| 30+ | Switch to search + execute. Optionally promote the top 3–5 to dedicated tools. |
|
|
101
|
-
|
|
102
|
-
The ceiling isn't a hard protocol limit — it's context-window economics. Every tool schema costs tokens that WormClaude pays *every turn*. Thirty tools with rich schemas can burn 3–5k tokens before the conversation has even begun.
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## Errors
|
|
107
|
-
|
|
108
|
-
Return MCP tool errors rather than exceptions that take down the transport. Give enough detail for WormClaude to recover or retry a different way.
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
if (!item) {
|
|
112
|
-
return {
|
|
113
|
-
isError: true,
|
|
114
|
-
content: [{
|
|
115
|
-
type: "text",
|
|
116
|
-
text: `Item ${id} not found. Use search_items to find valid IDs.`,
|
|
117
|
-
}],
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
That hint ("use search_items…") turns a dead end into a next step.
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## Tool annotations
|
|
127
|
-
|
|
128
|
-
Hints the host uses for UX — red confirm button for destructive, auto-approve for readonly. All default to unset (host assumes worst case).
|
|
129
|
-
|
|
130
|
-
| Annotation | Meaning | Host behavior |
|
|
131
|
-
|---|---|---|
|
|
132
|
-
| `readOnlyHint: true` | No side effects | May auto-approve |
|
|
133
|
-
| `destructiveHint: true` | Deletes/overwrites | Confirmation dialog |
|
|
134
|
-
| `idempotentHint: true` | Safe to retry | May retry on transient error |
|
|
135
|
-
| `openWorldHint: true` | Talks to external world (web, APIs) | May show network indicator |
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
server.registerTool("delete_file", {
|
|
139
|
-
description: "Delete a file",
|
|
140
|
-
inputSchema: { path: z.string() },
|
|
141
|
-
annotations: { destructiveHint: true, idempotentHint: false },
|
|
142
|
-
}, handler);
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
```python
|
|
146
|
-
@mcp.tool(annotations={"destructiveHint": True, "idempotentHint": False})
|
|
147
|
-
def delete_file(path: str) -> str:
|
|
148
|
-
...
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Pair with the read/write split advice in `build-mcpb/references/local-security.md` — mark every read tool `readOnlyHint: true`.
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## Structured output
|
|
156
|
-
|
|
157
|
-
Dropping `JSON.stringify(result)` into a text block works, but the spec offers first-class typed output via `outputSchema` + `structuredContent`, which clients can validate against.
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
server.registerTool("get_weather", {
|
|
161
|
-
description: "Get current weather",
|
|
162
|
-
inputSchema: { city: z.string() },
|
|
163
|
-
outputSchema: { temp: z.number(), conditions: z.string() },
|
|
164
|
-
}, async ({ city }) => {
|
|
165
|
-
const data = await fetchWeather(city);
|
|
166
|
-
return {
|
|
167
|
-
content: [{ type: "text", text: JSON.stringify(data) }], // backward compat
|
|
168
|
-
structuredContent: data, // typed output
|
|
169
|
-
};
|
|
170
|
-
});
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
Always keep the text fallback in place — not every host reads `structuredContent` yet.
|
|
174
|
-
|
|
175
|
-
---
|
|
176
|
-
|
|
177
|
-
## Content types beyond text
|
|
178
|
-
|
|
179
|
-
Tools can return more than strings:
|
|
180
|
-
|
|
181
|
-
| Type | Shape | Use for |
|
|
182
|
-
|---|---|---|
|
|
183
|
-
| `text` | `{ type: "text", text: string }` | Default |
|
|
184
|
-
| `image` | `{ type: "image", data: base64, mimeType }` | Screenshots, charts, diagrams |
|
|
185
|
-
| `audio` | `{ type: "audio", data: base64, mimeType }` | TTS output, recordings |
|
|
186
|
-
| `resource_link` | `{ type: "resource_link", uri, name?, description? }` | Pointer — client fetches later |
|
|
187
|
-
| `resource` (embedded) | `{ type: "resource", resource: { uri, text\|blob, mimeType } }` | Inline the full content |
|
|
188
|
-
|
|
189
|
-
**`resource_link` vs embedded:** link for large payloads or when the client might not need it (let them decide). Embed when it's small and always needed.
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# Version pins
|
|
2
|
-
|
|
3
|
-
Every version-sensitive claim in this skill, in one place. When updating the skill, check these first.
|
|
4
|
-
|
|
5
|
-
| Claim | Where stated | Last verified |
|
|
6
|
-
|---|---|---|
|
|
7
|
-
| `@modelcontextprotocol/ext-apps@1.2.2` CDN pin | `build-mcp-app/SKILL.md`, `build-mcp-app/references/widget-templates.md` (4×) | 2026-03 |
|
|
8
|
-
| Claude Code ≥2.1.76 for elicitation | `elicitation.md:15`, `build-mcp-server/SKILL.md:43,76` | 2026-03 |
|
|
9
|
-
| MCP spec 2025-11-25 CIMD/DCR status | `auth.md:20,24,41` | 2026-03 |
|
|
10
|
-
| MCPB manifest schema v0.4 | `build-mcpb/references/manifest-schema.md` | 2026-03 |
|
|
11
|
-
| CF `agents` SDK / `McpAgent` API | `deploy-cloudflare-workers.md` | 2026-03 |
|
|
12
|
-
| CF template path `cloudflare/ai/demos/remote-mcp-authless` | `deploy-cloudflare-workers.md` | 2026-03 |
|
|
13
|
-
|
|
14
|
-
## How to verify
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
# ext-apps latest
|
|
18
|
-
npm view @modelcontextprotocol/ext-apps version
|
|
19
|
-
|
|
20
|
-
# CF template still exists
|
|
21
|
-
gh api repos/cloudflare/ai/contents/demos/remote-mcp-authless/src/index.ts --jq '.sha'
|
|
22
|
-
|
|
23
|
-
# MCPB schema
|
|
24
|
-
curl -sI https://raw.githubusercontent.com/anthropics/mcpb/main/schemas/mcpb-manifest-v0.4.schema.json | head -1
|
|
25
|
-
```
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: build-mcpb
|
|
3
|
-
description: Reach for this skill when someone wants to "package an MCP server", "bundle an MCP", "make an MCPB", "ship a local MCP server", "distribute a local MCP", talks about ".mcpb files", mentions bundling a Node or Python runtime alongside their MCP server, or needs an MCP server that touches the local filesystem, desktop apps, or OS and has to install without the user having Node/Python set up.
|
|
4
|
-
license: WormClaude
|
|
5
|
-
version: 0.1.0
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Build an MCPB (Bundled Local MCP Server)
|
|
9
|
-
|
|
10
|
-
An MCPB is a local MCP server **shipped together with its runtime**. The user installs a single file and it runs without Node, Python, or any toolchain on their machine. It's the approved way to distribute local MCP servers.
|
|
11
|
-
|
|
12
|
-
> MCPB is the **secondary** distribution path. WormClaude recommends remote MCP servers for directory listing — see https://claude.com/docs/connectors/building/what-to-build.
|
|
13
|
-
|
|
14
|
-
**Use MCPB when the server genuinely has to run on the user's machine** — reading local files, driving a desktop app, talking to localhost services, OS-level APIs. If your server only calls cloud APIs, you almost certainly want a remote HTTP server instead (see `build-mcp-server`). Don't pay the MCPB packaging tax for something that could simply be a URL.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## What an MCPB bundle contains
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
my-server.mcpb (zip archive)
|
|
22
|
-
├── manifest.json ← identity, entry point, config schema, compatibility
|
|
23
|
-
├── server/ ← your MCP server code
|
|
24
|
-
│ ├── index.js
|
|
25
|
-
│ └── node_modules/ ← bundled dependencies (or vendored)
|
|
26
|
-
└── icon.png
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
The host reads `manifest.json`, starts `server.mcp_config.command` as a **stdio** MCP server, and pipes messages back and forth. As far as your code is concerned it's exactly a local stdio server — the only thing that differs is the packaging.
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Manifest
|
|
34
|
-
|
|
35
|
-
```json
|
|
36
|
-
{
|
|
37
|
-
"$schema": "https://raw.githubusercontent.com/anthropics/mcpb/main/schemas/mcpb-manifest-v0.4.schema.json",
|
|
38
|
-
"manifest_version": "0.4",
|
|
39
|
-
"name": "local-files",
|
|
40
|
-
"version": "0.1.0",
|
|
41
|
-
"description": "Read, search, and watch files on the local filesystem.",
|
|
42
|
-
"author": { "name": "Your Name" },
|
|
43
|
-
"server": {
|
|
44
|
-
"type": "node",
|
|
45
|
-
"entry_point": "server/index.js",
|
|
46
|
-
"mcp_config": {
|
|
47
|
-
"command": "node",
|
|
48
|
-
"args": ["${__dirname}/server/index.js"],
|
|
49
|
-
"env": {
|
|
50
|
-
"ROOT_DIR": "${user_config.rootDir}"
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
"user_config": {
|
|
55
|
-
"rootDir": {
|
|
56
|
-
"type": "directory",
|
|
57
|
-
"title": "Root directory",
|
|
58
|
-
"description": "Directory to expose. Defaults to ~/Documents.",
|
|
59
|
-
"default": "${HOME}/Documents",
|
|
60
|
-
"required": true
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
"compatibility": {
|
|
64
|
-
"claude_desktop": ">=1.0.0",
|
|
65
|
-
"platforms": ["darwin", "win32", "linux"]
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**`server.type`** — `node`, `python`, or `binary`. Informational only; the actual launch is driven by `mcp_config`.
|
|
71
|
-
|
|
72
|
-
**`server.mcp_config`** — the literal command/args/env used to spawn the process. Use `${__dirname}` for bundle-relative paths and `${user_config.<key>}` to drop in install-time config. **There's no auto-prefix** — the env var names your server reads are exactly the ones you write in `env`.
|
|
73
|
-
|
|
74
|
-
**`user_config`** — install-time settings shown in the host's UI. `type: "directory"` draws a native folder picker; `sensitive: true` stashes the value in the OS keychain. See `references/manifest-schema.md` for the full field list.
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Server code: same as local stdio
|
|
79
|
-
|
|
80
|
-
The server itself is just a standard stdio MCP server — there's nothing MCPB-specific in the tool logic.
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
84
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
85
|
-
import { z } from "zod";
|
|
86
|
-
import { readFile, readdir } from "node:fs/promises";
|
|
87
|
-
import { join } from "node:path";
|
|
88
|
-
import { homedir } from "node:os";
|
|
89
|
-
|
|
90
|
-
// ROOT_DIR comes from what you put in manifest's server.mcp_config.env — no auto-prefix
|
|
91
|
-
const ROOT = (process.env.ROOT_DIR ?? join(homedir(), "Documents"));
|
|
92
|
-
|
|
93
|
-
const server = new McpServer({ name: "local-files", version: "0.1.0" });
|
|
94
|
-
|
|
95
|
-
server.registerTool(
|
|
96
|
-
"list_files",
|
|
97
|
-
{
|
|
98
|
-
description: "List files in a directory under the configured root.",
|
|
99
|
-
inputSchema: { path: z.string().default(".") },
|
|
100
|
-
annotations: { readOnlyHint: true },
|
|
101
|
-
},
|
|
102
|
-
async ({ path }) => {
|
|
103
|
-
const entries = await readdir(join(ROOT, path), { withFileTypes: true });
|
|
104
|
-
const list = entries.map(e => ({ name: e.name, dir: e.isDirectory() }));
|
|
105
|
-
return { content: [{ type: "text", text: JSON.stringify(list, null, 2) }] };
|
|
106
|
-
},
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
server.registerTool(
|
|
110
|
-
"read_file",
|
|
111
|
-
{
|
|
112
|
-
description: "Read a file's contents. Path is relative to the configured root.",
|
|
113
|
-
inputSchema: { path: z.string() },
|
|
114
|
-
annotations: { readOnlyHint: true },
|
|
115
|
-
},
|
|
116
|
-
async ({ path }) => {
|
|
117
|
-
const text = await readFile(join(ROOT, path), "utf8");
|
|
118
|
-
return { content: [{ type: "text", text }] };
|
|
119
|
-
},
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
const transport = new StdioServerTransport();
|
|
123
|
-
await server.connect(transport);
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
**Sandboxing is entirely on you.** There's no manifest-level sandbox — the process runs with full user privileges. Validate paths, refuse anything that escapes `ROOT`, and allowlist spawns. See `references/local-security.md`.
|
|
127
|
-
|
|
128
|
-
Before you hardcode `ROOT` from a config env var, check whether the host supports `roots/list` — the spec-native way to obtain user-approved directories. See `references/local-security.md` for the pattern.
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
## Build pipeline
|
|
133
|
-
|
|
134
|
-
### Node
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
npm install
|
|
138
|
-
npx esbuild src/index.ts --bundle --platform=node --outfile=server/index.js
|
|
139
|
-
# or: copy node_modules wholesale if native deps resist bundling
|
|
140
|
-
npx @anthropic-ai/mcpb pack
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
`mcpb pack` zips up the directory and checks `manifest.json` against the schema.
|
|
144
|
-
|
|
145
|
-
### Python
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
pip install -t server/vendor -r requirements.txt
|
|
149
|
-
npx @anthropic-ai/mcpb pack
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Vendor your dependencies into a subdirectory and prepend it to `sys.path` in the entry script. Native extensions (numpy and friends) have to be built per target platform — steer clear of native deps where you can.
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
## MCPB has no sandbox — security is on you
|
|
157
|
-
|
|
158
|
-
Unlike mobile app stores, MCPB does NOT enforce permissions. The manifest has no `permissions` block — the server runs with full user privileges. `references/local-security.md` is required reading, not optional. Every path has to be validated and every spawn allowlisted, because nothing stops you at the platform level.
|
|
159
|
-
|
|
160
|
-
If you arrived expecting the manifest to give you filesystem/network scoping: it doesn't exist. You build that yourself inside the tool handlers.
|
|
161
|
-
|
|
162
|
-
If your server's only job is calling a cloud API, stop — that's a remote server in an MCPB costume. The user gains nothing from running it locally, and you've taken on the local-security burden for no reason.
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## MCPB + UI widgets
|
|
167
|
-
|
|
168
|
-
MCPB servers can serve UI resources just like remote MCP apps — the widget mechanism doesn't care about the transport. Think a local file picker that browses the real disk, or a dialog that controls a native app.
|
|
169
|
-
|
|
170
|
-
Widget authoring lives in the **`build-mcp-app`** skill and works identically here. The only thing that changes is where the server runs.
|
|
171
|
-
|
|
172
|
-
---
|
|
173
|
-
|
|
174
|
-
## Testing
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
# Interactive manifest creation (first time)
|
|
178
|
-
npx @anthropic-ai/mcpb init
|
|
179
|
-
|
|
180
|
-
# Run the server directly over stdio, poke it with the inspector
|
|
181
|
-
npx @modelcontextprotocol/inspector node server/index.js
|
|
182
|
-
|
|
183
|
-
# Validate manifest against schema, then pack
|
|
184
|
-
npx @anthropic-ai/mcpb validate
|
|
185
|
-
npx @anthropic-ai/mcpb pack
|
|
186
|
-
|
|
187
|
-
# Sign for distribution
|
|
188
|
-
npx @anthropic-ai/mcpb sign dist/local-files.mcpb
|
|
189
|
-
|
|
190
|
-
# Install: drag the .mcpb file onto Claude Desktop
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
Test on a machine that **lacks** your dev toolchain before you ship. "Works on my machine" failures in MCPB nearly always come down to a dependency that never actually got bundled.
|
|
194
|
-
|
|
195
|
-
---
|
|
196
|
-
|
|
197
|
-
## Reference files
|
|
198
|
-
|
|
199
|
-
- `references/manifest-schema.md` — full `manifest.json` field reference
|
|
200
|
-
- `references/local-security.md` — path traversal, sandboxing, least privilege
|