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,106 +0,0 @@
|
|
|
1
|
-
# Deploy to Cloudflare Workers
|
|
2
|
-
|
|
3
|
-
The quickest route from nothing to a live `https://` MCP URL. Free tier, no credit card to get going, two commands to ship.
|
|
4
|
-
|
|
5
|
-
**Trade-off:** This is a Workers-native scaffold, not a deploy target for the Express scaffold in `remote-http-scaffold.md` — it's a different runtime. If you want portability across hosts, stay with Express. If you just want it live, begin here.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Bootstrap
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm create cloudflare@latest -- my-mcp-server \
|
|
13
|
-
--template=cloudflare/ai/demos/remote-mcp-authless
|
|
14
|
-
cd my-mcp-server
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
This grabs a minimal template with the right deps (`agents`, `zod`) and a ready-to-go `wrangler.jsonc`.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## `src/index.ts`
|
|
22
|
-
|
|
23
|
-
Swap the template's calculator example for your own tools. Use `registerTool()` (the same API as the Express scaffold — the `McpServer` instance is identical):
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
27
|
-
import { McpAgent } from "agents/mcp";
|
|
28
|
-
import { z } from "zod";
|
|
29
|
-
|
|
30
|
-
export class MyMCP extends McpAgent {
|
|
31
|
-
server = new McpServer(
|
|
32
|
-
{ name: "my-service", version: "0.1.0" },
|
|
33
|
-
{ instructions: "Prefer search_items before get_item — IDs aren't guessable." },
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
async init() {
|
|
37
|
-
this.server.registerTool(
|
|
38
|
-
"search_items",
|
|
39
|
-
{
|
|
40
|
-
description: "Search items by keyword. Returns up to `limit` matches.",
|
|
41
|
-
inputSchema: {
|
|
42
|
-
query: z.string().describe("Search keywords"),
|
|
43
|
-
limit: z.number().int().min(1).max(50).default(10),
|
|
44
|
-
},
|
|
45
|
-
annotations: { readOnlyHint: true },
|
|
46
|
-
},
|
|
47
|
-
async ({ query, limit }) => {
|
|
48
|
-
const results = await upstreamApi.search(query, limit);
|
|
49
|
-
return { content: [{ type: "text", text: JSON.stringify(results, null, 2) }] };
|
|
50
|
-
},
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export default {
|
|
56
|
-
fetch(request: Request, env: Env, ctx: ExecutionContext) {
|
|
57
|
-
const url = new URL(request.url);
|
|
58
|
-
if (url.pathname === "/mcp") {
|
|
59
|
-
return MyMCP.serve("/mcp").fetch(request, env, ctx);
|
|
60
|
-
}
|
|
61
|
-
return new Response("Not found", { status: 404 });
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
`McpAgent` is Cloudflare's wrapper — it takes care of the streamable-HTTP transport, session routing, and Durable Object plumbing. Your code only ever touches `this.server`, which is the very same `McpServer` class from the SDK, so everything in `tool-design.md` and `server-capabilities.md` carries over unchanged.
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## `wrangler.jsonc`
|
|
71
|
-
|
|
72
|
-
The template includes this. The Durable Objects block is **boilerplate** — `McpAgent` relies on DO for session state, but you never deal with it directly.
|
|
73
|
-
|
|
74
|
-
```jsonc
|
|
75
|
-
{
|
|
76
|
-
"name": "my-mcp-server",
|
|
77
|
-
"main": "src/index.ts",
|
|
78
|
-
"compatibility_date": "2025-03-10",
|
|
79
|
-
"compatibility_flags": ["nodejs_compat"],
|
|
80
|
-
"migrations": [{ "new_sqlite_classes": ["MyMCP"], "tag": "v1" }],
|
|
81
|
-
"durable_objects": {
|
|
82
|
-
"bindings": [{ "class_name": "MyMCP", "name": "MCP_OBJECT" }]
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
If you rename the `MyMCP` class, keep both `new_sqlite_classes` and `class_name` in sync with it.
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## Run and deploy
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
npx wrangler dev # → http://localhost:8787/mcp
|
|
95
|
-
npx wrangler deploy # → https://my-mcp-server.<account>.workers.dev/mcp
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
`wrangler deploy` prints the live URL — that's exactly what users paste into WormClaude.
|
|
99
|
-
|
|
100
|
-
Secrets (upstream API keys): run `npx wrangler secret put UPSTREAM_API_KEY`, then read `env.UPSTREAM_API_KEY` inside `init()`.
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## OAuth
|
|
105
|
-
|
|
106
|
-
Cloudflare provides `@cloudflare/workers-oauth-provider` — a drop-in that covers the authorization-server side (CIMD/DCR endpoints, token issuance, consent UI). It wraps your `McpAgent` and puts `/mcp` behind a token check. See `auth.md` for the protocol details; the CF template `cloudflare/ai/demos/remote-mcp-github-oauth` demonstrates the wiring.
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# Elicitation — spec-native user input
|
|
2
|
-
|
|
3
|
-
Elicitation lets a server pause partway through a tool call and ask the user for structured input. The client draws a native form (no iframe, no HTML), the user fills it in, and the server picks up where it left off.
|
|
4
|
-
|
|
5
|
-
**This is the right call for simple input.** Widgets (`build-mcp-app`) are for cases that need rich UI — charts, searchable lists, visual previews. When all you need is a confirmation, a chosen option, or a handful of form fields, elicitation is simpler, spec-native, and runs in any compliant host.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## ⚠️ Check capability first — support is new
|
|
10
|
-
|
|
11
|
-
Host support landed only recently:
|
|
12
|
-
|
|
13
|
-
| Host | Status |
|
|
14
|
-
|---|---|
|
|
15
|
-
| Claude Code | ✅ since v2.1.76 (both `form` and `url` modes) |
|
|
16
|
-
| WormClaude Desktop | Unconfirmed — probably not yet, or only just |
|
|
17
|
-
| claude.ai | Unknown |
|
|
18
|
-
|
|
19
|
-
**The SDK raises `CapabilityNotSupported` whenever the client doesn't advertise elicitation.** Nothing degrades gracefully on its own, so you MUST check first and keep a fallback ready.
|
|
20
|
-
|
|
21
|
-
### The canonical pattern
|
|
22
|
-
|
|
23
|
-
```typescript
|
|
24
|
-
server.registerTool("delete_all", {
|
|
25
|
-
description: "Delete all items after confirmation",
|
|
26
|
-
inputSchema: {},
|
|
27
|
-
}, async ({}, extra) => {
|
|
28
|
-
const caps = server.getClientCapabilities();
|
|
29
|
-
if (caps?.elicitation) {
|
|
30
|
-
const r = await server.elicitInput({
|
|
31
|
-
mode: "form",
|
|
32
|
-
message: "Delete all items? This cannot be undone.",
|
|
33
|
-
requestedSchema: {
|
|
34
|
-
type: "object",
|
|
35
|
-
properties: { confirm: { type: "boolean", title: "Confirm deletion" } },
|
|
36
|
-
required: ["confirm"],
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
if (r.action === "accept" && r.content?.confirm) {
|
|
40
|
-
await deleteAll();
|
|
41
|
-
return { content: [{ type: "text", text: "Deleted." }] };
|
|
42
|
-
}
|
|
43
|
-
return { content: [{ type: "text", text: "Cancelled." }] };
|
|
44
|
-
}
|
|
45
|
-
// Fallback: return text asking Claude to relay the question
|
|
46
|
-
return { content: [{ type: "text", text: "Confirmation required. Please ask the user: 'Delete all items? This cannot be undone.' Then call this tool again with their answer." }] };
|
|
47
|
-
});
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
```python
|
|
51
|
-
# fastmcp
|
|
52
|
-
from fastmcp import Context
|
|
53
|
-
from fastmcp.exceptions import CapabilityNotSupported
|
|
54
|
-
|
|
55
|
-
@mcp.tool
|
|
56
|
-
async def delete_all(ctx: Context) -> str:
|
|
57
|
-
try:
|
|
58
|
-
result = await ctx.elicit("Delete all items? This cannot be undone.", response_type=bool)
|
|
59
|
-
if result.action == "accept" and result.data:
|
|
60
|
-
await do_delete()
|
|
61
|
-
return "Deleted."
|
|
62
|
-
return "Cancelled."
|
|
63
|
-
except CapabilityNotSupported:
|
|
64
|
-
return "Confirmation required. Ask the user to confirm deletion, then retry."
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Schema constraints
|
|
70
|
-
|
|
71
|
-
Elicitation schemas are intentionally restricted — keep your forms simple:
|
|
72
|
-
|
|
73
|
-
- **Flat objects only** — no nesting, no arrays of objects
|
|
74
|
-
- **Primitives only** — `string`, `number`, `integer`, `boolean`, `enum`
|
|
75
|
-
- String formats are limited to `email`, `uri`, `date`, `date-time`
|
|
76
|
-
- Put `title` and `description` on each property — they become the form labels
|
|
77
|
-
|
|
78
|
-
When your data won't fit inside these limits, that's your cue to move up to a widget.
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## Three-state response
|
|
83
|
-
|
|
84
|
-
| Action | Meaning | `content` present? |
|
|
85
|
-
|---|---|---|
|
|
86
|
-
| `accept` | User submitted the form | ✅ validated against your schema |
|
|
87
|
-
| `decline` | User explicitly said no | ❌ |
|
|
88
|
-
| `cancel` | User dismissed (escape, clicked away) | ❌ |
|
|
89
|
-
|
|
90
|
-
Handle `decline` and `cancel` differently when it matters — `decline` is deliberate, while `cancel` may well be an accident.
|
|
91
|
-
|
|
92
|
-
The TS SDK's `server.elicitInput()` validates `accept` responses against your schema with Ajv automatically. fastmcp's `ctx.elicit()` hands back a typed discriminated union (`AcceptedElicitation[T] | DeclinedElicitation | CancelledElicitation`).
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
## fastmcp response_type shorthand
|
|
97
|
-
|
|
98
|
-
```python
|
|
99
|
-
await ctx.elicit("Pick a color", response_type=["red", "green", "blue"]) # enum
|
|
100
|
-
await ctx.elicit("Enter email", response_type=str) # string
|
|
101
|
-
await ctx.elicit("Confirm?", response_type=bool) # boolean
|
|
102
|
-
|
|
103
|
-
@dataclass
|
|
104
|
-
class ContactInfo:
|
|
105
|
-
name: str
|
|
106
|
-
email: str
|
|
107
|
-
await ctx.elicit("Contact details", response_type=ContactInfo) # flat dataclass
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Accepts: primitives, `list[str]` (becomes enum), dataclass, TypedDict, Pydantic BaseModel. All must be flat.
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Security
|
|
115
|
-
|
|
116
|
-
**You MUST NOT ask for passwords, API keys, or tokens through elicitation** — this is a spec requirement. Those belong in OAuth or in `user_config` with `sensitive: true` (MCPB), never in runtime forms.
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## When to escalate to widgets
|
|
121
|
-
|
|
122
|
-
Elicitation covers confirm dialogs, enum pickers, and short flat forms.
|
|
123
|
-
|
|
124
|
-
Move up to `build-mcp-app` widgets when you need:
|
|
125
|
-
- Nested or complex data structures
|
|
126
|
-
- Scrollable/searchable lists (100+ items)
|
|
127
|
-
- Visual preview before choosing (image thumbnails, file tree)
|
|
128
|
-
- Live-updating progress or streaming content
|
|
129
|
-
- Custom layouts, charts, maps
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
# Remote Streamable-HTTP MCP Server — Scaffold
|
|
2
|
-
|
|
3
|
-
Bare-bones working servers in both recommended frameworks. Begin here, then layer on tools.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## TypeScript SDK (`@modelcontextprotocol/sdk`)
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm init -y
|
|
11
|
-
npm install @modelcontextprotocol/sdk zod express
|
|
12
|
-
npm install -D typescript @types/express @types/node tsx
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
**`src/server.ts`**
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
19
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
20
|
-
import express from "express";
|
|
21
|
-
import { z } from "zod";
|
|
22
|
-
|
|
23
|
-
const server = new McpServer(
|
|
24
|
-
{ name: "my-service", version: "0.1.0" },
|
|
25
|
-
{ instructions: "Prefer search_items before calling get_item directly — IDs aren't guessable." },
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
// Pattern A: one tool per action
|
|
29
|
-
server.registerTool(
|
|
30
|
-
"search_items",
|
|
31
|
-
{
|
|
32
|
-
description: "Search items by keyword. Returns up to `limit` matches ranked by relevance.",
|
|
33
|
-
inputSchema: {
|
|
34
|
-
query: z.string().describe("Search keywords"),
|
|
35
|
-
limit: z.number().int().min(1).max(50).default(10),
|
|
36
|
-
},
|
|
37
|
-
annotations: { readOnlyHint: true },
|
|
38
|
-
},
|
|
39
|
-
async ({ query, limit }, extra) => {
|
|
40
|
-
// extra.signal is an AbortSignal — check it in long loops for cancellation
|
|
41
|
-
const results = await upstreamApi.search(query, limit);
|
|
42
|
-
return {
|
|
43
|
-
content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
|
|
44
|
-
};
|
|
45
|
-
},
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
server.registerTool(
|
|
49
|
-
"get_item",
|
|
50
|
-
{
|
|
51
|
-
description: "Fetch a single item by its ID.",
|
|
52
|
-
inputSchema: { id: z.string() },
|
|
53
|
-
annotations: { readOnlyHint: true },
|
|
54
|
-
},
|
|
55
|
-
async ({ id }) => {
|
|
56
|
-
const item = await upstreamApi.get(id);
|
|
57
|
-
return { content: [{ type: "text", text: JSON.stringify(item) }] };
|
|
58
|
-
},
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
// Streamable HTTP transport (stateless mode — simplest)
|
|
62
|
-
const app = express();
|
|
63
|
-
app.use(express.json());
|
|
64
|
-
|
|
65
|
-
app.post("/mcp", async (req, res) => {
|
|
66
|
-
const transport = new StreamableHTTPServerTransport({
|
|
67
|
-
sessionIdGenerator: undefined, // stateless
|
|
68
|
-
});
|
|
69
|
-
res.on("close", () => transport.close());
|
|
70
|
-
await server.connect(transport);
|
|
71
|
-
await transport.handleRequest(req, res, req.body);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
app.listen(process.env.PORT ?? 3000);
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Stateless vs stateful:** The snippet above spins up a fresh transport for each request (stateless), which is fine for most API-wrapping servers. When tools genuinely need to share state across calls within a session (rare), switch to a session-keyed transport map — see the SDK's `examples/server/simpleStreamableHttp.ts`.
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## FastMCP 3.x (Python)
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
pip install fastmcp
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**`server.py`**
|
|
88
|
-
|
|
89
|
-
```python
|
|
90
|
-
from fastmcp import FastMCP
|
|
91
|
-
|
|
92
|
-
mcp = FastMCP(
|
|
93
|
-
name="my-service",
|
|
94
|
-
instructions="Prefer search_items before calling get_item directly — IDs aren't guessable.",
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
@mcp.tool(annotations={"readOnlyHint": True})
|
|
98
|
-
def search_items(query: str, limit: int = 10) -> list[dict]:
|
|
99
|
-
"""Search items by keyword. Returns up to `limit` matches ranked by relevance."""
|
|
100
|
-
return upstream_api.search(query, limit)
|
|
101
|
-
|
|
102
|
-
@mcp.tool(annotations={"readOnlyHint": True})
|
|
103
|
-
def get_item(id: str) -> dict:
|
|
104
|
-
"""Fetch a single item by its ID."""
|
|
105
|
-
return upstream_api.get(id)
|
|
106
|
-
|
|
107
|
-
if __name__ == "__main__":
|
|
108
|
-
mcp.run(transport="http", host="0.0.0.0", port=3000)
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
FastMCP builds the JSON schema from the type hints, and the docstring turns into the tool description. Keep docstrings short and action-oriented — they land in WormClaude's context window word for word.
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## Search + execute pattern (large API surface)
|
|
116
|
-
|
|
117
|
-
When you're wrapping 50+ endpoints, skip registering each one. Use two tools:
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
const CATALOG = loadActionCatalog(); // { id, description, paramSchema }[]
|
|
121
|
-
|
|
122
|
-
server.registerTool(
|
|
123
|
-
"search_actions",
|
|
124
|
-
{
|
|
125
|
-
description: "Find available actions matching an intent. Call this first to discover what's possible. Returns action IDs, descriptions, and parameter schemas.",
|
|
126
|
-
inputSchema: { intent: z.string().describe("What you want to do, in plain English") },
|
|
127
|
-
annotations: { readOnlyHint: true },
|
|
128
|
-
},
|
|
129
|
-
async ({ intent }) => {
|
|
130
|
-
const matches = rankActions(CATALOG, intent).slice(0, 10);
|
|
131
|
-
return { content: [{ type: "text", text: JSON.stringify(matches, null, 2) }] };
|
|
132
|
-
},
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
server.registerTool(
|
|
136
|
-
"execute_action",
|
|
137
|
-
{
|
|
138
|
-
description: "Execute an action by ID. Get the ID and params schema from search_actions first.",
|
|
139
|
-
inputSchema: {
|
|
140
|
-
action_id: z.string(),
|
|
141
|
-
params: z.record(z.unknown()),
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
async ({ action_id, params }) => {
|
|
145
|
-
const action = CATALOG.find(a => a.id === action_id);
|
|
146
|
-
if (!action) throw new Error(`Unknown action: ${action_id}`);
|
|
147
|
-
validate(params, action.paramSchema);
|
|
148
|
-
const result = await dispatch(action, params);
|
|
149
|
-
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
150
|
-
},
|
|
151
|
-
);
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
`rankActions` can start as plain keyword matching. Graduate to embeddings when precision becomes important.
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## Test it
|
|
159
|
-
|
|
160
|
-
The MCP Inspector hooks up to any transport and lets you exercise tools interactively.
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
# Interactive — opens a UI on localhost:6274
|
|
164
|
-
npx @modelcontextprotocol/inspector
|
|
165
|
-
# → select "Streamable HTTP", paste http://localhost:3000/mcp, Connect
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
For scripted checks (CI, smoke tests):
|
|
169
|
-
|
|
170
|
-
```bash
|
|
171
|
-
npx @modelcontextprotocol/inspector --cli http://localhost:3000/mcp \
|
|
172
|
-
--transport http --method tools/list
|
|
173
|
-
|
|
174
|
-
npx @modelcontextprotocol/inspector --cli http://localhost:3000/mcp \
|
|
175
|
-
--transport http --method tools/call --tool-name search_items --tool-arg query=test
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
## Connect users
|
|
181
|
-
|
|
182
|
-
Once it's deployed, users just add the URL directly — there's no install step.
|
|
183
|
-
|
|
184
|
-
| Surface | How |
|
|
185
|
-
|---|---|
|
|
186
|
-
| **Claude Code** | `claude mcp add --transport http <name> <url>` (add `--scope user` for global, `--header "Authorization: Bearer ..."` for auth) |
|
|
187
|
-
| **WormClaude Desktop / Claude.ai** | Settings → Connectors → Add custom connector. **Not** `claude_desktop_config.json` — remote servers configured there are ignored. |
|
|
188
|
-
| **Connector directory** | WormClaude maintains a submission guide for getting listed in the public connector directory. |
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
## Deploy
|
|
193
|
-
|
|
194
|
-
**Fastest path:** Cloudflare Workers — two commands take you from zero to a live `https://` URL on the free tier. It uses a Workers-native scaffold (not Express). → `deploy-cloudflare-workers.md`
|
|
195
|
-
|
|
196
|
-
**This Express scaffold** runs on any Node host — Render, Railway, Fly.io, a VPS. Containerize it (`node:20-slim`, copy, `npm ci`, `node dist/server.js`) and ship it. FastMCP follows the same playbook with a Python base image.
|
|
197
|
-
|
|
198
|
-
---
|
|
199
|
-
|
|
200
|
-
## Deployment checklist
|
|
201
|
-
|
|
202
|
-
- [ ] `POST /mcp` responds to `initialize` with server capabilities
|
|
203
|
-
- [ ] `tools/list` returns your tools with complete schemas
|
|
204
|
-
- [ ] Errors return structured MCP errors, not HTTP 500s with HTML bodies
|
|
205
|
-
- [ ] CORS headers set if browser clients will connect
|
|
206
|
-
- [ ] `Origin` header validated on `/mcp` (spec MUST — DNS rebinding prevention)
|
|
207
|
-
- [ ] `MCP-Protocol-Version` header honored (return 400 for unsupported versions)
|
|
208
|
-
- [ ] `instructions` field set if tool-use needs hints
|
|
209
|
-
- [ ] Health check endpoint separate from `/mcp` (hosts poll it)
|
|
210
|
-
- [ ] Secrets from env vars, never hardcoded
|
|
211
|
-
- [ ] If OAuth: CIMD or DCR endpoint implemented — see `auth.md`
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
# Resources & Prompts — the other two primitives
|
|
2
|
-
|
|
3
|
-
MCP defines three server-side primitives. Tools are model-controlled (WormClaude decides when to call them). The other two work differently:
|
|
4
|
-
|
|
5
|
-
- **Resources** are application-controlled — the host chooses what to pull into context
|
|
6
|
-
- **Prompts** are user-controlled — surfaced as slash commands or menu items
|
|
7
|
-
|
|
8
|
-
Most servers get by with tools alone. Reach for these when your integration doesn't fit the "WormClaude calls a function" mold.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Resources
|
|
13
|
-
|
|
14
|
-
A resource is data named by a URI. Unlike a tool, you don't *call* it — you *read* it. The host browses the available resources and picks which ones to load into context.
|
|
15
|
-
|
|
16
|
-
**When a resource wins over a tool:**
|
|
17
|
-
- Large reference data (docs, schemas, configs) that WormClaude should be able to browse
|
|
18
|
-
- Content that changes on its own, independent of the conversation (log files, live data)
|
|
19
|
-
- Anything where "WormClaude decides to fetch" is the wrong mental model
|
|
20
|
-
|
|
21
|
-
**When a tool is the better fit:**
|
|
22
|
-
- The operation has side effects
|
|
23
|
-
- The result hinges on parameters WormClaude chooses
|
|
24
|
-
- You want WormClaude — not the host UI — deciding when to bring it in
|
|
25
|
-
|
|
26
|
-
### Static resources
|
|
27
|
-
|
|
28
|
-
```typescript
|
|
29
|
-
// TypeScript SDK
|
|
30
|
-
server.registerResource(
|
|
31
|
-
"config",
|
|
32
|
-
"config://app/settings",
|
|
33
|
-
{ name: "App Settings", description: "Current configuration", mimeType: "application/json" },
|
|
34
|
-
async (uri) => ({
|
|
35
|
-
contents: [{ uri: uri.href, mimeType: "application/json", text: JSON.stringify(config) }],
|
|
36
|
-
}),
|
|
37
|
-
);
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
```python
|
|
41
|
-
# fastmcp
|
|
42
|
-
@mcp.resource("config://app/settings")
|
|
43
|
-
def get_settings() -> str:
|
|
44
|
-
"""Current application configuration."""
|
|
45
|
-
return json.dumps(config)
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Dynamic resources (URI templates)
|
|
49
|
-
|
|
50
|
-
RFC 6570 templates let a single registration cover many URIs:
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
54
|
-
|
|
55
|
-
server.registerResource(
|
|
56
|
-
"file",
|
|
57
|
-
new ResourceTemplate("file:///{path}", { list: undefined }),
|
|
58
|
-
{ name: "File", description: "Read a file from the workspace" },
|
|
59
|
-
async (uri, { path }) => ({
|
|
60
|
-
contents: [{ uri: uri.href, text: await fs.readFile(path, "utf8") }],
|
|
61
|
-
}),
|
|
62
|
-
);
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
```python
|
|
66
|
-
@mcp.resource("file:///{path}")
|
|
67
|
-
def read_file(path: str) -> str:
|
|
68
|
-
return Path(path).read_text()
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Subscriptions
|
|
72
|
-
|
|
73
|
-
Resources can tell the client when they've changed. Set `subscribe: true` in capabilities, then emit `notifications/resources/updated` and the host re-reads. Handy for log tails, live dashboards, and watched files.
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## Prompts
|
|
78
|
-
|
|
79
|
-
A prompt is a parameterized message template. The host exposes it as a slash command or menu item; the user selects it, fills in the arguments, and the resulting messages drop into the conversation.
|
|
80
|
-
|
|
81
|
-
**When to use:** canned workflows users run again and again — `/summarize-thread`, `/draft-reply`, `/explain-error`. Almost no code, big UX payoff.
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
server.registerPrompt(
|
|
85
|
-
"summarize",
|
|
86
|
-
{
|
|
87
|
-
title: "Summarize document",
|
|
88
|
-
description: "Generate a concise summary of the given text",
|
|
89
|
-
argsSchema: { text: z.string(), max_words: z.string().optional() },
|
|
90
|
-
},
|
|
91
|
-
({ text, max_words }) => ({
|
|
92
|
-
messages: [{
|
|
93
|
-
role: "user",
|
|
94
|
-
content: { type: "text", text: `Summarize in ${max_words ?? "100"} words:\n\n${text}` },
|
|
95
|
-
}],
|
|
96
|
-
}),
|
|
97
|
-
);
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
```python
|
|
101
|
-
@mcp.prompt
|
|
102
|
-
def summarize(text: str, max_words: str = "100") -> str:
|
|
103
|
-
"""Generate a concise summary of the given text."""
|
|
104
|
-
return f"Summarize in {max_words} words:\n\n{text}"
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**Constraints:**
|
|
108
|
-
- Arguments are **string-only** (no numbers, booleans, or objects) — do the conversion inside the handler
|
|
109
|
-
- Returns a `messages[]` array — it can carry embedded resources/images, not only text
|
|
110
|
-
- No side effects — the handler merely assembles a message, it doesn't *do* anything
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Quick decision table
|
|
115
|
-
|
|
116
|
-
| You want to... | Use |
|
|
117
|
-
|---|---|
|
|
118
|
-
| Let WormClaude fetch something on demand, with parameters | **Tool** |
|
|
119
|
-
| Expose browsable context (files, docs, schemas) | **Resource** |
|
|
120
|
-
| Expose a dynamic family of things (`db://{table}`) | **Resource template** |
|
|
121
|
-
| Give users a one-click workflow | **Prompt** |
|
|
122
|
-
| Ask the user something mid-tool | **Elicitation** (see `elicitation.md`) |
|