@frontmcp/skills 1.3.0 → 1.4.0
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/README.md +38 -29
- package/catalog/TEMPLATE.md +26 -0
- package/catalog/create-tool/SKILL.md +318 -0
- package/catalog/create-tool/examples/01-basic-class-tool.md +112 -0
- package/catalog/create-tool/examples/02-basic-function-tool.md +80 -0
- package/catalog/create-tool/examples/03-tool-with-zod-shape-output.md +78 -0
- package/catalog/create-tool/examples/04-tool-with-zod-schema-output.md +97 -0
- package/catalog/create-tool/examples/05-tool-with-primitive-output.md +93 -0
- package/catalog/create-tool/examples/06-tool-with-media-output.md +109 -0
- package/catalog/create-tool/examples/08-tool-with-provider-injection.md +110 -0
- package/catalog/create-tool/examples/09-tool-with-multiple-providers.md +107 -0
- package/catalog/create-tool/examples/11-tool-with-fetch.md +94 -0
- package/catalog/create-tool/examples/12-tool-with-fetch-and-retries.md +115 -0
- package/catalog/create-tool/examples/13-tool-with-single-auth-provider.md +85 -0
- package/catalog/create-tool/examples/14-tool-with-multiple-auth-providers.md +105 -0
- package/catalog/create-tool/examples/15-tool-with-credential-vault.md +115 -0
- package/catalog/create-tool/examples/16-tool-with-rate-limit.md +71 -0
- package/catalog/create-tool/examples/17-tool-with-concurrency-and-timeout.md +101 -0
- package/catalog/create-tool/examples/18-tool-with-progress-and-notify.md +96 -0
- package/catalog/create-tool/examples/19-tool-with-elicitation.md +102 -0
- package/catalog/create-tool/examples/20-tool-with-annotations.md +125 -0
- package/catalog/create-tool/examples/21-tool-with-availability-constraints.md +107 -0
- package/catalog/create-tool/examples/22-tool-with-ui-html-template.md +93 -0
- package/catalog/create-tool/examples/23-tool-with-ui-filesource-tsx.md +112 -0
- package/catalog/create-tool/examples/24-tool-with-ui-csp-and-bridge.md +127 -0
- package/catalog/create-tool/examples/25-tool-handing-off-to-job.md +143 -0
- package/catalog/create-tool/examples/26-tool-with-resource-link-output.md +94 -0
- package/catalog/create-tool/examples/27-tool-with-examples-metadata.md +90 -0
- package/catalog/create-tool/references/annotations.md +96 -0
- package/catalog/create-tool/references/auth-providers.md +167 -0
- package/catalog/create-tool/references/availability.md +106 -0
- package/catalog/create-tool/references/decorator-options.md +95 -0
- package/catalog/create-tool/references/derived-types.md +102 -0
- package/catalog/create-tool/references/elicitation.md +128 -0
- package/catalog/create-tool/references/error-handling.md +128 -0
- package/catalog/create-tool/references/execution-context.md +158 -0
- package/catalog/create-tool/references/file-layout.md +96 -0
- package/catalog/create-tool/references/function-style-builder.md +118 -0
- package/catalog/create-tool/references/input-schema.md +141 -0
- package/catalog/create-tool/references/output-schema.md +175 -0
- package/catalog/create-tool/references/quick-start.md +124 -0
- package/catalog/create-tool/references/registration.md +132 -0
- package/catalog/create-tool/references/remote-and-esm.md +68 -0
- package/catalog/create-tool/references/testing.md +59 -0
- package/catalog/create-tool/references/throttling.md +109 -0
- package/catalog/create-tool/references/ui-widgets.md +198 -0
- package/catalog/create-tool/rules/always-define-output-schema.md +77 -0
- package/catalog/create-tool/rules/derive-execute-types.md +57 -0
- package/catalog/create-tool/rules/input-schema-is-raw-shape.md +76 -0
- package/catalog/create-tool/rules/no-toolcontext-generics.md +50 -0
- package/catalog/create-tool/rules/no-try-catch-around-execute.md +79 -0
- package/catalog/create-tool/rules/register-in-app.md +76 -0
- package/catalog/create-tool/rules/snake-case-tool-names.md +45 -0
- package/catalog/create-tool/rules/use-this-fail-for-business-errors.md +75 -0
- package/catalog/create-tool/rules/widget-paths-anchor-with-import-meta-url.md +76 -0
- package/catalog/create-tool/rules/widget-resource-mode-host-detect.md +61 -0
- package/catalog/frontmcp-auth-ui/SKILL.md +146 -0
- package/catalog/frontmcp-auth-ui/examples/custom-auth-ui/login-slot.md +97 -0
- package/catalog/frontmcp-auth-ui/examples/custom-auth-ui/multi-step-auth-extra.md +133 -0
- package/catalog/frontmcp-auth-ui/references/custom-auth-ui.md +162 -0
- package/catalog/frontmcp-authorities/SKILL.md +55 -18
- package/catalog/frontmcp-authorities/references/authority-profiles.md +25 -1
- package/catalog/frontmcp-authorities/references/custom-evaluators.md +1 -1
- package/catalog/frontmcp-authorities/references/rbac-abac-rebac.md +9 -0
- package/catalog/frontmcp-channels/SKILL.md +7 -1
- package/catalog/frontmcp-config/SKILL.md +9 -2
- package/catalog/frontmcp-config/examples/configure-auth/local-credential-vault.md +94 -0
- package/catalog/frontmcp-config/examples/configure-auth/local-secure-store.md +138 -0
- package/catalog/frontmcp-config/examples/configure-auth/remote-oauth-with-vault.md +45 -23
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-behind-tunnel.md +73 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-consent-enforcement.md +87 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-dcr-control.md +67 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-minimal.md +62 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-multi-provider-orchestration.md +93 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +18 -20
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-single-operator.md +66 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +37 -23
- package/catalog/frontmcp-config/examples/configure-http/custom-http-routes.md +98 -0
- package/catalog/frontmcp-config/examples/configure-skills-http/audit-log-redis.md +17 -9
- package/catalog/frontmcp-config/references/configure-auth-modes.md +86 -23
- package/catalog/frontmcp-config/references/configure-auth.md +296 -50
- package/catalog/frontmcp-config/references/configure-http.md +149 -15
- package/catalog/frontmcp-deployment/SKILL.md +15 -13
- package/catalog/frontmcp-deployment/references/deploy-manifest-yaml.md +308 -0
- package/catalog/frontmcp-deployment/references/deploy-to-cloudflare-skills-only.md +174 -0
- package/catalog/frontmcp-deployment/references/mcp-client-integration.md +38 -2
- package/catalog/frontmcp-development/SKILL.md +30 -44
- package/catalog/frontmcp-development/references/decorators-guide.md +15 -15
- package/catalog/frontmcp-extensibility/SKILL.md +1 -1
- package/catalog/frontmcp-extensibility/examples/skill-audit-log/verify-chain.md +8 -6
- package/catalog/frontmcp-extensibility/references/skill-audit-log.md +7 -2
- package/catalog/frontmcp-guides/SKILL.md +1 -1
- package/catalog/frontmcp-observability/SKILL.md +1 -1
- package/catalog/frontmcp-production-readiness/SKILL.md +1 -1
- package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +3 -2
- package/catalog/frontmcp-setup/SKILL.md +1 -1
- package/catalog/frontmcp-setup/examples/multi-app-composition/per-app-auth-and-isolation.md +7 -4
- package/catalog/frontmcp-setup/references/multi-app-composition.md +6 -5
- package/catalog/frontmcp-testing/SKILL.md +9 -1
- package/catalog/frontmcp-testing/references/test-auth.md +24 -0
- package/catalog/skills-manifest.json +653 -149
- package/package.json +1 -1
- package/src/manifest.d.ts +72 -1
- package/src/manifest.js +4 -1
- package/src/manifest.js.map +1 -1
- package/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md +0 -80
- package/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md +0 -132
- package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +0 -110
- package/catalog/frontmcp-development/examples/create-tool-annotations/destructive-delete-tool.md +0 -92
- package/catalog/frontmcp-development/examples/create-tool-annotations/readonly-query-tool.md +0 -59
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/primitive-and-media-outputs.md +0 -101
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-raw-shape-output.md +0 -62
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-schema-advanced-output.md +0 -101
- package/catalog/frontmcp-development/references/create-tool-annotations.md +0 -48
- package/catalog/frontmcp-development/references/create-tool-output-schema-types.md +0 -71
- package/catalog/frontmcp-development/references/create-tool.md +0 -806
|
@@ -1,10 +1,512 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"skills": [
|
|
4
|
+
{
|
|
5
|
+
"name": "create-tool",
|
|
6
|
+
"category": "development/create",
|
|
7
|
+
"description": "ALWAYS use this skill when the user asks to build, modify, or audit a FrontMCP tool. Covers @Tool({...}) end-to-end: class and function-style tools, Zod input/output schemas with derived execute() types, dependency injection, error handling, throttling (rate-limit / concurrency / timeout), auth providers, availability constraints, elicitation, interactive UI widgets (MCP Apps / SEP-1865 — including .tsx FileSource, CSP, window.FrontMcpBridge, host-detect resourceMode), annotations, examples metadata, registration in @App, and per-tool unit testing.",
|
|
8
|
+
"path": "create-tool",
|
|
9
|
+
"targets": ["all"],
|
|
10
|
+
"hasResources": true,
|
|
11
|
+
"layout": "component",
|
|
12
|
+
"tags": [
|
|
13
|
+
"development",
|
|
14
|
+
"tool",
|
|
15
|
+
"create-tool",
|
|
16
|
+
"decorator",
|
|
17
|
+
"input-schema",
|
|
18
|
+
"output-schema",
|
|
19
|
+
"ToolContext",
|
|
20
|
+
"ui",
|
|
21
|
+
"mcp-apps",
|
|
22
|
+
"annotations",
|
|
23
|
+
"throttling",
|
|
24
|
+
"auth-providers",
|
|
25
|
+
"availability",
|
|
26
|
+
"elicitation"
|
|
27
|
+
],
|
|
28
|
+
"bundle": ["recommended", "minimal", "full"],
|
|
29
|
+
"priority": 10,
|
|
30
|
+
"references": [
|
|
31
|
+
{
|
|
32
|
+
"name": "quick-start",
|
|
33
|
+
"description": "60-second tour — minimal tool, schemas, registration, calling it."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "decorator-options",
|
|
37
|
+
"description": "Every field on `@Tool({...})` — what it does, default, when to set it."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "input-schema",
|
|
41
|
+
"description": "Define the tool's input contract — raw Zod shapes, refinements, defaults, optional fields."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "output-schema",
|
|
45
|
+
"description": "Define the tool's output contract — Zod shape, primitives, media, multi-content arrays."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "derived-types",
|
|
49
|
+
"description": "Derive execute() parameter and return types from the schemas via ToolInputOf / ToolOutputOf."
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "execution-context",
|
|
53
|
+
"description": "What ToolContext provides at runtime — this.get, this.fetch, this.notify, this.context."
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "error-handling",
|
|
57
|
+
"description": "this.fail, MCP error classes, error flow — when to throw vs fail."
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "throttling",
|
|
61
|
+
"description": "rateLimit, concurrency, timeout — semantics, interaction, defaults."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "auth-providers",
|
|
65
|
+
"description": "authProviders shorthand vs full mapping, scopes, alias, credential vault basics."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "availability",
|
|
69
|
+
"description": "availableWhen axes (os / runtime / deployment / provider / target / surface / env), missingAxes, isPlatform."
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "elicitation",
|
|
73
|
+
"description": "this.elicit — request interactive input mid-execution. Server enable + accept/decline/cancel flow."
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "ui-widgets",
|
|
77
|
+
"description": "@Tool({ ui }) — template formats, servingMode, host-detect resourceMode, CSP, widgetAccessible, MCP Apps spec."
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "annotations",
|
|
81
|
+
"description": "readOnlyHint, destructiveHint, idempotentHint, openWorldHint, title — behavioral hints for clients."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "function-style-builder",
|
|
85
|
+
"description": "tool({...})(handler) — when to pick over a class, register, ctx parameter."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"name": "remote-and-esm",
|
|
89
|
+
"description": "Tool.esm / Tool.remote — load tools from ESM URLs or remote MCP servers."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "registration",
|
|
93
|
+
"description": "@App({ tools }) vs @FrontMcp({ tools }), multi-app composition."
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "file-layout",
|
|
97
|
+
"description": "Flat sibling vs folder-per-tool layouts. <name>.schema.ts / <name>.tool.ts / <name>.tool.spec.ts."
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "testing",
|
|
101
|
+
"description": "Per-tool unit tests — @frontmcp/testing, mocking DI, asserting output validation."
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
"examples": [
|
|
105
|
+
{
|
|
106
|
+
"name": "01-basic-class-tool",
|
|
107
|
+
"level": "basic",
|
|
108
|
+
"description": "Minimal class-based tool with Zod input/output schemas and types derived from the schemas. The foundation every other example builds on.",
|
|
109
|
+
"tags": ["foundation", "class-tool", "output-schema", "derived-types"],
|
|
110
|
+
"features": [
|
|
111
|
+
"Extending `ToolContext` (no generics) and implementing `execute()`",
|
|
112
|
+
"Hoisting `inputSchema` / `outputSchema` to a sibling `.schema.ts` file",
|
|
113
|
+
"Deriving the `execute()` parameter and return types via `ToolInputOf<>` / `ToolOutputOf<>`",
|
|
114
|
+
"Using a Zod raw shape for `inputSchema` (not `z.object(...)`)",
|
|
115
|
+
"Always defining `outputSchema` so the tool can't accidentally leak extra fields",
|
|
116
|
+
"Registering the tool in an `@App({ tools })`"
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "02-basic-function-tool",
|
|
121
|
+
"level": "basic",
|
|
122
|
+
"description": "Function-style `tool({...})(handler)` for a tiny pure-input tool — pick this over a class only when the tool needs no DI / lifecycle / UI.",
|
|
123
|
+
"tags": ["foundation", "function-tool", "tool-builder"],
|
|
124
|
+
"features": [
|
|
125
|
+
"Using the `tool({...})(handler)` builder for a one-liner",
|
|
126
|
+
"Returning a primitive via `outputSchema: 'number'`",
|
|
127
|
+
"Registering the function-style tool in `@App({ tools })` exactly like a class tool",
|
|
128
|
+
"When function-style is the right choice (and when it isn't)"
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"name": "03-tool-with-zod-shape-output",
|
|
133
|
+
"level": "basic",
|
|
134
|
+
"description": "Tool returning structured JSON declared via a Zod raw shape outputSchema — the recommended pattern for any complex output.",
|
|
135
|
+
"tags": ["output-schema", "zod-shape", "structured-output"],
|
|
136
|
+
"features": [
|
|
137
|
+
"Declaring `outputSchema` as a Zod raw shape `{ field: z.string(), … }`",
|
|
138
|
+
"Constraining values with `.int().min(0)` so invalid output is rejected at the boundary",
|
|
139
|
+
"Letting unrelated fields returned by the implementation (e.g. an upstream API's extras) be stripped silently",
|
|
140
|
+
"Deriving `OrderSummaryOutput` once so the type and runtime contract can't drift"
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"name": "04-tool-with-zod-schema-output",
|
|
145
|
+
"level": "advanced",
|
|
146
|
+
"description": "Tool returning a discriminated union via a full `z.discriminatedUnion(...)` outputSchema — for outputs that branch on a kind field.",
|
|
147
|
+
"tags": ["output-schema", "zod-schema", "discriminated-union"],
|
|
148
|
+
"features": [
|
|
149
|
+
"Using a full Zod schema (`z.discriminatedUnion(...)`) as `outputSchema` instead of a raw shape",
|
|
150
|
+
"Branching the runtime output on a discriminant `kind` literal",
|
|
151
|
+
"Letting TypeScript narrow the return type per branch (via `as const` on the discriminant)",
|
|
152
|
+
"Knowing when full Zod schemas are the right pick (unions, transforms) and when a raw shape is enough"
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"name": "05-tool-with-primitive-output",
|
|
157
|
+
"level": "basic",
|
|
158
|
+
"description": "Tool returning a single primitive — `outputSchema: 'string' | 'number' | 'boolean' | 'date'` for single-value outputs.",
|
|
159
|
+
"tags": ["output-schema", "primitive-output"],
|
|
160
|
+
"features": [
|
|
161
|
+
"Using a primitive literal (`'string'`, `'number'`, `'boolean'`, `'date'`) for `outputSchema`",
|
|
162
|
+
"Returning the bare value directly from `execute()` instead of wrapping it",
|
|
163
|
+
"Picking primitive literals over a one-field Zod shape for ergonomic clarity",
|
|
164
|
+
"Four concrete tools in one file (`fmt_currency`, `add`, `is_palindrome`, `now`) demonstrating each primitive form"
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"name": "06-tool-with-media-output",
|
|
169
|
+
"level": "intermediate",
|
|
170
|
+
"description": "Tool returning binary content (image / audio) or a multi-content array of `[text, image]` — for outputs that aren't plain JSON.",
|
|
171
|
+
"tags": ["output-schema", "media-output", "image", "multi-content"],
|
|
172
|
+
"features": [
|
|
173
|
+
"Returning a base64-encoded image with `outputSchema: 'image'` and `{ type: 'image', data, mimeType }`",
|
|
174
|
+
"Returning audio with `outputSchema: 'audio'` (same `{ type: 'audio', data, mimeType }` shape, audio MIME types)",
|
|
175
|
+
"Returning multi-content via `outputSchema: ['string', 'image']` — text summary + annotated image in one response",
|
|
176
|
+
"When to pick a media literal vs `'resource_link'` (host-fetched URI)"
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"name": "08-tool-with-provider-injection",
|
|
181
|
+
"level": "intermediate",
|
|
182
|
+
"description": "Tool that resolves a DI-registered service via `this.get(TOKEN)` and uses it to power `execute()` — the standard pattern for tools that talk to a database or external API.",
|
|
183
|
+
"tags": ["di", "provider", "this.get", "error-handling"],
|
|
184
|
+
"features": [
|
|
185
|
+
"Defining a typed DI token with `Symbol('UserService')` and `Token<UserService>`",
|
|
186
|
+
"Implementing a `@Provider` and registering it in the same `@App` as the tool",
|
|
187
|
+
"Resolving the service inside `execute()` via `this.get(USER_SERVICE)` (throws when missing)",
|
|
188
|
+
"Translating \"not found\" into `ResourceNotFoundError` via `this.fail(...)` so the client gets a proper MCP error code (-32002)"
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"name": "09-tool-with-multiple-providers",
|
|
193
|
+
"level": "intermediate",
|
|
194
|
+
"description": "Tool composing three DI services — config (env-only), cache (optional, `tryGet`), and database (required) — the realistic shape for a production tool.",
|
|
195
|
+
"tags": ["di", "multiple-providers", "cache-aside", "tryGet"],
|
|
196
|
+
"features": [
|
|
197
|
+
"Resolving multiple providers via `this.get(TOKEN)` and `this.tryGet(TOKEN)`",
|
|
198
|
+
"Cache-aside pattern — check `tryGet(CACHE)` first, fall back to the database",
|
|
199
|
+
"Reading typed config from a `CONFIG` token vs `process.env` directly",
|
|
200
|
+
"Letting the tool work in production (with cache) AND in test (without it)"
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"name": "11-tool-with-fetch",
|
|
205
|
+
"level": "intermediate",
|
|
206
|
+
"description": "Tool calling an external HTTP API with `this.fetch` — context propagation, status-code handling, and bounding the call with a tool `timeout`.",
|
|
207
|
+
"tags": ["fetch", "http", "external-api", "error-handling"],
|
|
208
|
+
"features": [
|
|
209
|
+
"Using `this.fetch(url, init?)` so trace context propagates to the upstream service",
|
|
210
|
+
"Translating non-2xx HTTP responses into `PublicMcpError` so the MCP client gets a clean error",
|
|
211
|
+
"Bounding the call with a tool `timeout` (and `this.fetch`'s built-in per-request timeout) — without relying on a non-existent context abort signal",
|
|
212
|
+
"Letting genuine network errors (DNS failure, ECONNREFUSED) propagate to the framework's error flow"
|
|
213
|
+
]
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"name": "12-tool-with-fetch-and-retries",
|
|
217
|
+
"level": "advanced",
|
|
218
|
+
"description": "Tool calling a flaky external API with exponential backoff retries, an Idempotency-Key for safety, and respect for `Retry-After` on 429s.",
|
|
219
|
+
"tags": ["fetch", "retries", "exponential-backoff", "idempotency-key", "429-rate-limit"],
|
|
220
|
+
"features": [
|
|
221
|
+
"Retrying on transient errors (5xx + 429) with exponential backoff plus jitter",
|
|
222
|
+
"Generating an `Idempotency-Key` so retried POSTs don't duplicate side effects on the upstream",
|
|
223
|
+
"Respecting an upstream `Retry-After` header on 429 responses instead of guessing",
|
|
224
|
+
"Capping the total retry budget with `timeout: { executeMs }` so a wedged upstream can't hang the call indefinitely"
|
|
225
|
+
]
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"name": "13-tool-with-single-auth-provider",
|
|
229
|
+
"level": "intermediate",
|
|
230
|
+
"description": "Tool requiring a single OAuth provider via the `authProviders: ['github']` string shorthand — credentials loaded before `execute()` runs.",
|
|
231
|
+
"tags": ["auth-providers", "oauth", "github", "this.authProviders"],
|
|
232
|
+
"features": [
|
|
233
|
+
"Declaring a single required OAuth provider with the `authProviders: ['github']` shorthand",
|
|
234
|
+
"Reading pre-formatted credentials via `await this.authProviders.headers('github')`",
|
|
235
|
+
"Letting the framework reject calls whose required credential is missing **before** `execute()` runs — a JSON-RPC `-32001` (MCP `UNAUTHORIZED`) error whose `data` carries `{ tool, providers: ['github'], authUrl }` (no auth-check boilerplate)",
|
|
236
|
+
"Trusting the framework to handle token refresh, expiration, and the connect/authorize URL"
|
|
237
|
+
]
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"name": "14-tool-with-multiple-auth-providers",
|
|
241
|
+
"level": "advanced",
|
|
242
|
+
"description": "Tool with the full `authProviders` mapping form — one required provider with explicit scopes, one optional provider with an alias, and graceful degradation when the optional creds are missing.",
|
|
243
|
+
"tags": ["auth-providers", "oauth", "scopes", "optional-auth", "this.authProviders.headers"],
|
|
244
|
+
"features": [
|
|
245
|
+
"Using the object form of `authProviders` to set `required`, `scopes`, and `alias`",
|
|
246
|
+
"Declaring required OAuth scopes that the server advertises in its Protected Resource Metadata (`scopes_supported`) so clients request them",
|
|
247
|
+
"Resolving an optional provider via `await this.authProviders.headers('cloud')` (returns an empty object `{}` when absent)",
|
|
248
|
+
"Branching the tool's behavior — full deploy when both providers are present; preview-only when the cloud provider is missing",
|
|
249
|
+
"The required `github` provider gating the call: when its credential is missing the framework aborts before `execute()` with `-32001` and `data: { tool, providers: ['github'], authUrl }`; the optional `aws`/`cloud` provider never gates"
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"name": "15-tool-with-credential-vault",
|
|
254
|
+
"level": "advanced",
|
|
255
|
+
"description": "Tool that reads a user-supplied static credential (a Slack webhook URL) from the per-session encrypted credential vault — the pattern for credentials that aren't OAuth.",
|
|
256
|
+
"tags": ["auth-providers", "credential-vault", "slack-webhook", "encryption-at-rest"],
|
|
257
|
+
"features": [
|
|
258
|
+
"Declaring a vault-backed auth provider with `authProviders: ['slack-webhook']`",
|
|
259
|
+
"Reading the user's pasted-in credential via `await this.authProviders.headers('slack-webhook')` — same API as OAuth",
|
|
260
|
+
"Letting the framework handle per-session AES-256-GCM encryption at rest (Redis or memory store)",
|
|
261
|
+
"Knowing when to pick the vault (static secrets the user knows) vs OAuth (delegated identity)"
|
|
262
|
+
]
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"name": "16-tool-with-rate-limit",
|
|
266
|
+
"level": "intermediate",
|
|
267
|
+
"description": "Tool with `rateLimit: { maxRequests, windowMs }` capping invocations per session per minute — the protection for expensive / external-API-billed operations.",
|
|
268
|
+
"tags": ["throttling", "rate-limit", "abuse-protection"],
|
|
269
|
+
"features": [
|
|
270
|
+
"Capping the tool to N invocations per windowMs, partitioned per session via `partitionBy: 'session'`",
|
|
271
|
+
"Letting the framework reject over-limit calls with `RateLimitError` (code `'RATE_LIMIT_EXCEEDED'`, HTTP status 429) carrying a retry-after hint in its message that clients can back off against",
|
|
272
|
+
"Combining `rateLimit` with `annotations.openWorldHint: true` so clients know the tool talks to billed external services",
|
|
273
|
+
"Sizing the limit against upstream quota / billing — not just \"what feels reasonable\""
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"name": "17-tool-with-concurrency-and-timeout",
|
|
278
|
+
"level": "advanced",
|
|
279
|
+
"description": "Tool with `concurrency` + `timeout` for a real bottleneck (PDF rendering) — caps simultaneous in-flight work AND hard-caps per-call duration.",
|
|
280
|
+
"tags": ["throttling", "concurrency", "timeout"],
|
|
281
|
+
"features": [
|
|
282
|
+
"Capping simultaneous in-flight executions with `concurrency: { maxConcurrent }` (server-wide by default)",
|
|
283
|
+
"Hard-bounding any single call with `timeout: { executeMs }` so a wedged invocation can't hold a concurrency slot indefinitely",
|
|
284
|
+
"Giving long child work its own deadline, since `timeout` bounds `execute()` but does not pass an abort signal into it",
|
|
285
|
+
"Combining `rateLimit` + `concurrency` + `timeout` as a production triple"
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
"name": "18-tool-with-progress-and-notify",
|
|
290
|
+
"level": "intermediate",
|
|
291
|
+
"description": "Long-running tool emitting progress updates (`this.progress`), log notifications (`this.notify`), and stage markers (`this.mark`) — the standard pattern for jobs you don't want to feel hung.",
|
|
292
|
+
"tags": ["progress", "notifications", "mark", "long-running"],
|
|
293
|
+
"features": [
|
|
294
|
+
"Emitting per-item progress with `await this.progress(current, total, message)`",
|
|
295
|
+
"Sending free-form log notifications at `info` / `warning` / `error` levels with `await this.notify(message, level)`",
|
|
296
|
+
"Marking execution stages with `this.mark(stage)` so observability tools have breadcrumbs",
|
|
297
|
+
"Letting `this.progress(...)` return `false` cheaply when no progress token was provided (zero-cost when nobody's listening)"
|
|
298
|
+
]
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"name": "19-tool-with-elicitation",
|
|
302
|
+
"level": "advanced",
|
|
303
|
+
"description": "Tool that pauses mid-execution to ask the user for confirmation + extra input via `this.elicit(...)` — the safe pattern for destructive or expensive actions.",
|
|
304
|
+
"tags": ["elicitation", "this.elicit", "destructive-action", "confirmation"],
|
|
305
|
+
"features": [
|
|
306
|
+
"Calling `this.elicit(message, z.object({ ... }))` to request interactive input mid-`execute()`",
|
|
307
|
+
"Branching on `result.status` — `accept` / `decline` / `cancel` — and matching the early returns against `outputSchema`",
|
|
308
|
+
"Pairing elicitation with `annotations.destructiveHint: true` so clients know to render the confirmation prominently",
|
|
309
|
+
"Requiring `elicitation: { enabled: true }` at the `@FrontMcp({...})` server level — and what fails when it isn't"
|
|
310
|
+
]
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"name": "20-tool-with-annotations",
|
|
314
|
+
"level": "basic",
|
|
315
|
+
"description": "Four tools showing the standard annotation combinations — read-only query, destructive delete, send-email side-effecting, external-API search — and the client behavior each combination opts into.",
|
|
316
|
+
"tags": ["annotations", "readOnlyHint", "destructiveHint", "idempotentHint", "openWorldHint"],
|
|
317
|
+
"features": [
|
|
318
|
+
"Setting `readOnlyHint` / `destructiveHint` / `idempotentHint` / `openWorldHint` to opt into specific client behaviors (auto-retry, confirmation gating, parallelization)",
|
|
319
|
+
"Providing a human-readable `title` that overrides the snake_case `name` in client UIs",
|
|
320
|
+
"Picking the conservative defaults when the annotations aren't obvious (omitting fields is safer than guessing)",
|
|
321
|
+
"Why `send_email` sets `idempotentHint: false` (each call sends a new email) while `delete_user` sets it to `true` (deleting twice still leaves the user deleted)"
|
|
322
|
+
]
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"name": "21-tool-with-availability-constraints",
|
|
326
|
+
"level": "advanced",
|
|
327
|
+
"description": "Three tools showing the `availableWhen` axes — macOS-only OS gate, production+Node runtime gate, and a `surface` gate that allows agent + job invocation but blocks direct MCP-client calls.",
|
|
328
|
+
"tags": ["availableWhen", "os", "runtime", "surface", "EntryUnavailableError"],
|
|
329
|
+
"features": [
|
|
330
|
+
"Restricting a tool to macOS with `availableWhen: { os: ['darwin'] }`",
|
|
331
|
+
"Composing constraints — `runtime: ['node']` AND `env: ['production']` — both must match for the tool to be available",
|
|
332
|
+
"Using the `surface` axis to expose an internal tool to agents and jobs while hiding it from direct user invocation",
|
|
333
|
+
"Knowing what happens on mismatch — `EntryUnavailableError` (`-32003` FORBIDDEN) with `data.missingAxes` so clients show the right \"not available here\" reason"
|
|
334
|
+
]
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"name": "22-tool-with-ui-html-template",
|
|
338
|
+
"level": "intermediate",
|
|
339
|
+
"description": "Tool with an inline HTML function template — `ui: { template: (ctx) => '<div>…</div>' }` — for a quick widget that doesn't need a separate `.tsx` file.",
|
|
340
|
+
"tags": ["ui", "ui-widgets", "html-template", "escapeHtml", "TemplateContext"],
|
|
341
|
+
"features": [
|
|
342
|
+
"Adding a `ui:` block with a function template `(ctx: TemplateContext<In, Out>) => string`",
|
|
343
|
+
"Annotating `ctx` explicitly to dodge the TS7006 inference gap on the union `ui.template` type",
|
|
344
|
+
"Always escaping user-controlled output with `ctx.helpers.escapeHtml(...)` so the widget can't XSS itself",
|
|
345
|
+
"Reading from `ctx.output` and `ctx.helpers` — the typed runtime context the template renderer hands you"
|
|
346
|
+
]
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
"name": "23-tool-with-ui-filesource-tsx",
|
|
350
|
+
"level": "advanced",
|
|
351
|
+
"description": "Tool with a `.tsx` widget in a separate file via the `FileSource` form — the recommended pattern for any React widget. Path anchored with `import.meta.url` so it survives any cwd.",
|
|
352
|
+
"tags": ["ui", "ui-widgets", "FileSource", "tsx", "import.meta.url", "host-detect"],
|
|
353
|
+
"features": [
|
|
354
|
+
"Pointing `template` at a sibling `.tsx` file via the `FileSource` form `{ file: ... }`",
|
|
355
|
+
"Anchoring the path to the tool source with `fileURLToPath(new URL('./...widget.tsx', import.meta.url))` so `process.cwd()` doesn't matter",
|
|
356
|
+
"Leaving `resourceMode` unset — the framework host-detects (`'inline'` for Claude, `'cdn'` for others)",
|
|
357
|
+
"Naming the widget `*.widget.tsx` so the scaffolded `tsconfig.json`'s `exclude` keeps it out of the server typecheck"
|
|
358
|
+
]
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"name": "24-tool-with-ui-csp-and-bridge",
|
|
362
|
+
"level": "advanced",
|
|
363
|
+
"description": "Interactive tool widget that fetches from an allow-listed CSP origin and invokes another tool via `window.FrontMcpBridge.callTool` — the full pattern for live-data widgets that need cross-tool composition.",
|
|
364
|
+
"tags": ["ui", "csp", "widgetAccessible", "FrontMcpBridge", "interactive-widget"],
|
|
365
|
+
"features": [
|
|
366
|
+
"Restricting the widget's outbound `fetch` via `ui.csp.connectDomains` (emitted on the resource per #455)",
|
|
367
|
+
"Opting the widget into cross-tool calls with `widgetAccessible: true` and using `window.FrontMcpBridge.callTool(name, args)` instead of host-specific APIs",
|
|
368
|
+
"Embedding initial data into the widget's inline `<script>` safely via `ctx.helpers.jsonEmbed(...)` (escapes `</script>`)",
|
|
369
|
+
"Surfacing in-flight status via `invocationStatus.invoking` / `invoked` so the host UI shows feedback"
|
|
370
|
+
]
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"name": "25-tool-handing-off-to-job",
|
|
374
|
+
"level": "advanced",
|
|
375
|
+
"description": "Thin tool that validates input and enqueues a `@Job` to do the heavy lifting — the right pattern for any operation that takes more than a few seconds.",
|
|
376
|
+
"tags": ["composition", "jobs", "job-handoff", "hideFromDiscovery"],
|
|
377
|
+
"features": [
|
|
378
|
+
"Splitting a long-running operation into a thin tool (validates, enqueues, returns a tracking handle) plus a `@Job` (does the work)",
|
|
379
|
+
"Returning the job ID + status URL from the tool so the client can poll or stream updates",
|
|
380
|
+
"Using `availableWhen: { surface: ['mcp', 'agent'] }` on the tool while leaving the heavy `@Job` invisible to direct invocation",
|
|
381
|
+
"Why this beats running the heavy work inside `execute()` (avoids tool-call timeout limits, lets the job retry independently)"
|
|
382
|
+
]
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
"name": "26-tool-with-resource-link-output",
|
|
386
|
+
"level": "advanced",
|
|
387
|
+
"description": "Tool returning `outputSchema: 'resource_link'` — the URI is sent to the client; the client fetches the body via `resources/read`. The right pattern for large or cacheable payloads.",
|
|
388
|
+
"tags": ["output-schema", "resource_link", "large-payload", "caching"],
|
|
389
|
+
"features": [
|
|
390
|
+
"Returning `outputSchema: 'resource_link'` from a tool — `{ type: 'resource_link', uri }`, body fetched separately",
|
|
391
|
+
"Pairing the tool with a matching `@Resource({ uri: 'export://{exportId}.csv' })` URI template that resolves to the actual body",
|
|
392
|
+
"When `'resource_link'` beats `'image'` / `'audio'` / a raw byte response (large payloads, cacheable URIs, deferred fetch)",
|
|
393
|
+
"Cross-linking to the `create-resource` skill for the URI-template resource on the other end"
|
|
394
|
+
]
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
"name": "27-tool-with-examples-metadata",
|
|
398
|
+
"level": "basic",
|
|
399
|
+
"description": "Tool with the `examples: [...]` field on `@Tool({...})` — concrete input (and optional expected output) examples consumed by the CodeCall `codecall:describe` tool to give agents accurate usage examples.",
|
|
400
|
+
"tags": ["examples-metadata", "codecall", "describe"],
|
|
401
|
+
"features": [
|
|
402
|
+
"Adding `examples: [{ description, input, output? }]` to `@Tool({...})` so `codecall:describe` surfaces canned invocations",
|
|
403
|
+
"Writing realistic example inputs so the generated describe output is concrete, not abstract",
|
|
404
|
+
"Including `output?` for examples where showing the expected result helps an agent understand the tool",
|
|
405
|
+
"Why `examples` are advisory metadata — not emitted in `tools/list`, only consumed by `codecall:describe`"
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
],
|
|
409
|
+
"rules": [
|
|
410
|
+
{
|
|
411
|
+
"name": "always-define-output-schema",
|
|
412
|
+
"constraint": "Every `@Tool` defines `outputSchema`.",
|
|
413
|
+
"severity": "required"
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"name": "derive-execute-types",
|
|
417
|
+
"constraint": "`execute()` parameter and return types come from `ToolInputOf<>` / `ToolOutputOf<>` — never duplicated inline.",
|
|
418
|
+
"severity": "required"
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"name": "input-schema-is-raw-shape",
|
|
422
|
+
"constraint": "`inputSchema` is a raw Zod shape, never `z.object(...)`.",
|
|
423
|
+
"severity": "required"
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"name": "no-toolcontext-generics",
|
|
427
|
+
"constraint": "`class MyTool extends ToolContext` — never `extends ToolContext<typeof inputSchema>`.",
|
|
428
|
+
"severity": "required"
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
"name": "no-try-catch-around-execute",
|
|
432
|
+
"constraint": "Do not wrap the body of `execute()` in `try/catch`. The framework owns the error flow.",
|
|
433
|
+
"severity": "required"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
"name": "register-in-app",
|
|
437
|
+
"constraint": "Register tools in `@App({ tools })`, not directly on `@FrontMcp({ tools })` (the latter is the simple-server escape hatch).",
|
|
438
|
+
"severity": "recommended"
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
"name": "snake-case-tool-names",
|
|
442
|
+
"constraint": "Tool `name:` field is always `snake_case` (e.g. `get_weather`, not `getWeather`).",
|
|
443
|
+
"severity": "required"
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
"name": "use-this-fail-for-business-errors",
|
|
447
|
+
"constraint": "`this.fail(new SomeMcpError(...))` for business-logic errors — never raw `throw new Error(...)`.",
|
|
448
|
+
"severity": "required"
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
"name": "widget-paths-anchor-with-import-meta-url",
|
|
452
|
+
"constraint": "`.tsx` widget paths in `ui.template: { file }` are anchored via `fileURLToPath(new URL(...))`, never bare relative.",
|
|
453
|
+
"severity": "required"
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
"name": "widget-resource-mode-host-detect",
|
|
457
|
+
"constraint": "Leave `ui.resourceMode` unset — the framework host-detects (`inline` for Claude, `cdn` for others).",
|
|
458
|
+
"severity": "recommended"
|
|
459
|
+
}
|
|
460
|
+
]
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
"name": "frontmcp-auth-ui",
|
|
464
|
+
"category": "config",
|
|
465
|
+
"description": "Use when customizing, branding, or replacing the built-in FrontMCP OAuth pages (the login, consent, federated-select, incremental-authorization, and error pages) with your own React components. Covers the auth.ui slot-to-file map and auth.extras name-to-handler map on the auth config (no decorator, no class); the @frontmcp/ui/auth React hooks, the AuthPageWrapper component, and mountAuthPage (client-rendered via an esm.sh import-map plus a per-file server-side transform, with no bundling and no SSR); and the framework-owned CSRF and CSP. Triggers: custom login page, brand the consent screen, replace the OAuth UI, custom authorization UI, style the auth pages, multi-step login. The skill for CUSTOM AUTHORIZATION UI (distinct from auth config in frontmcp-config and permissions in frontmcp-authorities).",
|
|
466
|
+
"path": "frontmcp-auth-ui",
|
|
467
|
+
"targets": ["all"],
|
|
468
|
+
"hasResources": true,
|
|
469
|
+
"tags": ["auth", "auth-ui", "login", "consent", "custom-ui", "react", "oauth", "guide"],
|
|
470
|
+
"bundle": ["full"],
|
|
471
|
+
"references": [
|
|
472
|
+
{
|
|
473
|
+
"name": "custom-auth-ui",
|
|
474
|
+
"description": "Replace FrontMCP's built-in OAuth pages with custom React components using the auth.ui slot→file map and auth.extras name→handler map (no decorator, no class) plus the @frontmcp/ui/auth hooks.",
|
|
475
|
+
"examples": [
|
|
476
|
+
{
|
|
477
|
+
"name": "login-slot",
|
|
478
|
+
"description": "Replace the built-in login page with a custom React component via auth.ui: { login: './login.tsx' } and useAuthFlow, while the framework keeps owning CSRF and CSP.",
|
|
479
|
+
"level": "intermediate",
|
|
480
|
+
"tags": ["auth", "auth-ui", "login", "custom-ui", "react", "client-rendered"],
|
|
481
|
+
"features": [
|
|
482
|
+
"Mapping a slot to a `.tsx` file with `auth.ui: { login: './login.tsx' }` (the supported render path)",
|
|
483
|
+
"Using a RELATIVE path auto-anchored to the config file — no `fileURLToPath`, no decorator, no class",
|
|
484
|
+
"Reading the injected `AuthFlowState` via `useAuthFlow()` and submitting with `<form onSubmit={submitFinish}>`",
|
|
485
|
+
"Letting `<AuthPageWrapper>` render the enclosing finish `<form>` with the `pending_auth_id` + `csrf` hidden fields",
|
|
486
|
+
"The SDK transpiling the `.tsx` server-side and inlining it as an ES module (deps from esm.sh via an import-map) + appending the `mountAuthPage` call automatically"
|
|
487
|
+
]
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
"name": "multi-step-auth-extra",
|
|
491
|
+
"description": "Add a server-validated multi-step field to a custom login page with auth.extras: { 'envs:add': fn }, useExtraField, and useAddedItems — accepted rows accumulate server-side and reflect back without a reload.",
|
|
492
|
+
"level": "advanced",
|
|
493
|
+
"tags": ["auth", "auth-ui", "auth-extras", "useExtraField", "useAddedItems", "multi-step", "react"],
|
|
494
|
+
"features": [
|
|
495
|
+
"Declaring a server-validated field as an `auth.extras['envs:add']` handler fn returning `{ ok, error?, addedItems? }`",
|
|
496
|
+
"Rejecting bad input and duplicates using `ctx.current` (the items already accepted for this extra in this flow)",
|
|
497
|
+
"Binding the add-row form to `useExtraField('envs:add').onSubmit` (POSTs to `/oauth/ui/extra` with `pending_auth_id` + `csrf` attached)",
|
|
498
|
+
"Reflecting the server-side accumulator reactively with `useAddedItems('envs:add')` after each successful add",
|
|
499
|
+
"Declaring both the `auth.ui` slot and the `auth.extras` handler under `auth`: `@FrontMcp({ auth: { mode, ui, extras } })`"
|
|
500
|
+
]
|
|
501
|
+
}
|
|
502
|
+
]
|
|
503
|
+
}
|
|
504
|
+
]
|
|
505
|
+
},
|
|
4
506
|
{
|
|
5
507
|
"name": "frontmcp-config",
|
|
6
508
|
"category": "config",
|
|
7
|
-
"description": "Use when
|
|
509
|
+
"description": "Use when configuring a FrontMCP server through frontmcp.config or the @FrontMcp options. Covers auth modes (public, transparent, local, remote), OAuth plus credential vault and secureStore, CORS, HTTP port / entry-path prefix / unix socket, security headers (CSP, HSTS, X-Frame-Options, X-Content-Type-Options), rate limiting / throttling / concurrency / timeout / IP filtering (GuardConfig), session storage (Redis, Vercel KV), client transport protocols (SSE, Streamable HTTP, stateless, protocol presets), elicitation, multi-target build config, and skillsConfig (HTTP catalog, caching, audit log, instruction injection). Triggers: configure auth, set up CORS, add rate limiting, throttle requests, manage sessions, choose transport, set HTTP options, configure JWT or OAuth. The skill for server CONFIGURATION.",
|
|
8
510
|
"path": "frontmcp-config",
|
|
9
511
|
"targets": ["all"],
|
|
10
512
|
"hasResources": true,
|
|
@@ -15,29 +517,109 @@
|
|
|
15
517
|
"name": "configure-auth-modes",
|
|
16
518
|
"description": "Detailed comparison of public, transparent, local, and remote auth modes",
|
|
17
519
|
"examples": [
|
|
520
|
+
{
|
|
521
|
+
"name": "local-minimal",
|
|
522
|
+
"description": "Stand up the built-in local OAuth 2.1 server with the minimum configuration: HS256 signing via JWT_SECRET and in-memory token storage.",
|
|
523
|
+
"level": "basic",
|
|
524
|
+
"tags": ["config", "auth", "local", "hs256", "auth-modes", "modes"],
|
|
525
|
+
"features": [
|
|
526
|
+
"Using `mode: 'local'` with no other auth options to run the built-in OAuth 2.1 server",
|
|
527
|
+
"Relying on `JWT_SECRET` for HS256 token signing (symmetric secret, no key pair)",
|
|
528
|
+
"Accepting the default in-memory `tokenStorage` for local development (state is lost on restart)"
|
|
529
|
+
]
|
|
530
|
+
},
|
|
18
531
|
{
|
|
19
532
|
"name": "local-self-signed-tokens",
|
|
20
|
-
"description": "Configure a server that signs its own
|
|
533
|
+
"description": "Configure a local-mode server that signs its own HS256 JWTs and persists auth state across restarts with SQLite or Redis.",
|
|
21
534
|
"level": "intermediate",
|
|
22
|
-
"tags": ["config", "auth", "
|
|
535
|
+
"tags": ["config", "auth", "local", "sqlite", "redis", "auth-modes", "modes"],
|
|
23
536
|
"features": [
|
|
24
|
-
"Using `mode: 'local'` so the server signs its own JWTs",
|
|
537
|
+
"Using `mode: 'local'` so the server signs its own HS256 JWTs (symmetric `JWT_SECRET`, no key pair)",
|
|
25
538
|
"Setting `local.issuer` and `expectedAudience` to control token claims",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
539
|
+
"Persisting authorization codes and refresh tokens with `tokenStorage: { sqlite: { path } }` so they survive restart",
|
|
540
|
+
"Switching the same `tokenStorage` to `{ redis }` for multi-instance deployments",
|
|
541
|
+
"Enabling `consent` so login renders a tool-selection screen and the chosen tools are enforced at call time"
|
|
542
|
+
]
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
"name": "local-single-operator",
|
|
546
|
+
"description": "Run local mode for a single operator (e.g. Claude Code) by skipping the email prompt and minting a stable anonymous subject.",
|
|
547
|
+
"level": "basic",
|
|
548
|
+
"tags": ["config", "auth", "local", "single-operator", "claude-code", "auth-modes"],
|
|
549
|
+
"features": [
|
|
550
|
+
"Setting `requireEmail: false` so the login callback mints a code without prompting for an email",
|
|
551
|
+
"Setting `anonymousSubject` so the single operator gets a stable `sub` across logins",
|
|
552
|
+
"Persisting tokens with SQLite so the operator stays logged in across restarts"
|
|
553
|
+
]
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
"name": "local-consent-enforcement",
|
|
557
|
+
"description": "Enable consent in local mode to render a tool-selection screen at login and enforce the chosen tools at call time, keeping essential tools always available via excludedTools.",
|
|
558
|
+
"level": "intermediate",
|
|
559
|
+
"tags": ["config", "auth", "local", "consent", "tool-authorization", "auth-modes"],
|
|
560
|
+
"features": [
|
|
561
|
+
"Setting `consent.enabled` so login renders a tool-selection screen and the chosen tools are enforced on every tools/call",
|
|
562
|
+
"Listing `excludedTools` so essential tools are never offered and are always available",
|
|
563
|
+
"Honoring `requireSelection` / `defaultSelectedTools` to require a non-empty selection and pre-check tools",
|
|
564
|
+
"Pinning `rememberConsent: false` to re-show the screen on every login (the default `true` reuses a prior per-(user, client) selection and only re-prompts when a NEW tool appears)"
|
|
565
|
+
]
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
"name": "local-behind-tunnel",
|
|
569
|
+
"description": "Expose a local-mode server through a tunnel or TLS proxy by aligning the token issuer with the public URL clients actually reach.",
|
|
570
|
+
"level": "intermediate",
|
|
571
|
+
"tags": ["config", "auth", "local", "tunnel", "proxy", "issuer", "auth-modes"],
|
|
572
|
+
"features": [
|
|
573
|
+
"Relying on request-host-derived OAuth discovery, which works behind a tunnel or under an http.entryPath without extra config",
|
|
574
|
+
"Setting `local.issuer` to a full public HTTPS URL so the token `iss` matches what clients reach through the proxy",
|
|
575
|
+
"Knowing `FRONTMCP_PUBLIC_HOST` overrides only the discovery host (scheme/port still come from the HTTP config or local.issuer)"
|
|
576
|
+
]
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
"name": "local-multi-provider-orchestration",
|
|
580
|
+
"description": "Orchestrate multiple upstream OAuth providers (GitHub + Slack) in local mode, gate the JWT until they are linked, and read downstream tokens in tools via this.orchestration.",
|
|
581
|
+
"level": "advanced",
|
|
582
|
+
"tags": [
|
|
583
|
+
"config",
|
|
584
|
+
"auth",
|
|
585
|
+
"local",
|
|
586
|
+
"orchestration",
|
|
587
|
+
"federated",
|
|
588
|
+
"providers",
|
|
589
|
+
"multi-provider",
|
|
590
|
+
"auth-modes"
|
|
591
|
+
],
|
|
592
|
+
"features": [
|
|
593
|
+
"Declaring an `auth.providers` array so FrontMCP federates GitHub + Slack at /oauth/authorize and stores their tokens encrypted server-side",
|
|
594
|
+
"Using `authorizeUrl`/`tokenUrl` aliases and letting the per-provider callback URL be auto-computed as ${issuer}/oauth/provider/${id}/callback",
|
|
595
|
+
"Gating JWT issuance with `federatedAuth.minProviders` / `requiredProviders` so no token is minted until the linked-provider threshold is met",
|
|
596
|
+
"Reading downstream provider tokens in a tool via `this.orchestration.getToken(id)` / `tryGetToken(id)` without exposing them to the LLM"
|
|
597
|
+
]
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
"name": "local-dcr-control",
|
|
601
|
+
"description": "Lock down the built-in Dynamic Client Registration endpoint with the auth.dcr control surface: disable open registration, allowlist redirect URIs and client ids, and seed a pre-registered trusted client.",
|
|
602
|
+
"level": "intermediate",
|
|
603
|
+
"tags": ["config", "auth", "local", "dcr", "dynamic-client-registration", "security", "auth-modes"],
|
|
604
|
+
"features": [
|
|
605
|
+
"Setting `dcr.enabled: false` so `POST /oauth/register` returns 404 and `registration_endpoint` is dropped from AS metadata",
|
|
606
|
+
"Constraining `dcr.allowedRedirectUris` (exact or `*` glob) so unlisted redirect URIs are rejected at both register and authorize",
|
|
607
|
+
"Constraining `dcr.allowedClientIds` so only known client ids may use `/oauth/authorize`",
|
|
608
|
+
"Seeding `dcr.clients` so a trusted client is accepted without any DCR round-trip"
|
|
29
609
|
]
|
|
30
610
|
},
|
|
31
611
|
{
|
|
32
612
|
"name": "remote-enterprise-oauth",
|
|
33
|
-
"description": "
|
|
613
|
+
"description": "Proxy authentication to one mandatory upstream IdP, mint a FrontMCP session, and read the upstream token in tools.",
|
|
34
614
|
"level": "advanced",
|
|
35
615
|
"tags": ["config", "oauth", "auth", "redis", "remote", "auth-modes"],
|
|
36
616
|
"features": [
|
|
37
|
-
"Using `mode: 'remote'` to
|
|
617
|
+
"Using `mode: 'remote'` to proxy authentication to a single mandatory upstream IdP",
|
|
38
618
|
"Loading `clientId` and `clientSecret` from environment variables (never hardcoded)",
|
|
39
619
|
"Configuring Redis-backed token storage for production persistence",
|
|
40
|
-
"
|
|
620
|
+
"`GET /oauth/authorize` redirects straight to the upstream IdP (no in-tree login page)",
|
|
621
|
+
"Session identity (sub/email/name) is derived from the upstream user",
|
|
622
|
+
"Tools read the upstream token via `this.orchestration.getToken(providerId)`"
|
|
41
623
|
]
|
|
42
624
|
},
|
|
43
625
|
{
|
|
@@ -81,13 +663,37 @@
|
|
|
81
663
|
},
|
|
82
664
|
{
|
|
83
665
|
"name": "remote-oauth-with-vault",
|
|
84
|
-
"description": "Configure a FrontMCP server with
|
|
666
|
+
"description": "Configure a FrontMCP server with local OAuth orchestration of an upstream provider and read the downstream provider token in a tool via this.orchestration.getToken.",
|
|
667
|
+
"level": "intermediate",
|
|
668
|
+
"tags": ["config", "oauth", "auth", "orchestration", "providers"],
|
|
669
|
+
"features": [
|
|
670
|
+
"Declaring an upstream provider in top-level `auth.providers` so FrontMCP orchestrates its OAuth flow",
|
|
671
|
+
"Loading `clientId`/`clientSecret` from environment variables instead of hardcoding",
|
|
672
|
+
"Reading the downstream provider token in a tool via `this.orchestration.getToken('github')`"
|
|
673
|
+
]
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
"name": "local-credential-vault",
|
|
677
|
+
"description": "Persist a per-session credential from a local authenticate() verifier into the built-in encrypted vault and read it from a tool via this.credentials.",
|
|
678
|
+
"level": "intermediate",
|
|
679
|
+
"tags": ["config", "auth", "local", "vault", "credentials", "this-credentials"],
|
|
680
|
+
"features": [
|
|
681
|
+
"Returning `credentials: [{ key, secret, metadata? }]` from `authenticate()` so FrontMCP persists them encrypted, keyed by the minted `sub`",
|
|
682
|
+
"Reading a per-session credential from a tool via `this.credentials.get(key)` (no `this.authProviders` wiring needed)",
|
|
683
|
+
"Prompting the agent to connect a missing credential mid-session with `this.credentials.requireConnect({ key })` (framework-signed `/oauth/connect` URL)",
|
|
684
|
+
"Understanding per-session rotation: a reconnect yields an empty vault and old ciphertext is undecryptable"
|
|
685
|
+
]
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
"name": "local-secure-store",
|
|
689
|
+
"description": "Configure the general session secure-secret store (this.secureStore) with a pluggable backing (memory / sqlite / redis / custom OS-keychain) and read/write user-typed secrets from a tool.",
|
|
85
690
|
"level": "intermediate",
|
|
86
|
-
"tags": ["config", "
|
|
691
|
+
"tags": ["config", "auth", "local", "secure-store", "secrets", "this-secure-store", "keychain"],
|
|
87
692
|
"features": [
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
693
|
+
"Selecting the secure-store backing via `auth.secureStore` (memory / sqlite / redis / custom backend) plus a namespace `scope`",
|
|
694
|
+
"Reading/writing arbitrary user-typed secrets from a tool via `this.secureStore.set/get/list/delete` (JSON-serialized, scoped to the session/subject)",
|
|
695
|
+
"Backing the store with an OS keychain by supplying a `SecureStoreBackend` — no native dependency is bundled by the framework",
|
|
696
|
+
"Understanding scope: `user` (keyed by sub, default), `session` (keyed by sessionId), `global` (server-wide)"
|
|
91
697
|
]
|
|
92
698
|
}
|
|
93
699
|
]
|
|
@@ -166,7 +772,7 @@
|
|
|
166
772
|
},
|
|
167
773
|
{
|
|
168
774
|
"name": "configure-http",
|
|
169
|
-
"description": "Configure HTTP server port, CORS policy, unix sockets,
|
|
775
|
+
"description": "Configure HTTP server port, CORS policy, unix sockets, entry path prefix, request body limits, and custom HTTP routes",
|
|
170
776
|
"examples": [
|
|
171
777
|
{
|
|
172
778
|
"name": "cors-restricted-origins",
|
|
@@ -180,6 +786,19 @@
|
|
|
180
786
|
"Reading port from an environment variable with a fallback"
|
|
181
787
|
]
|
|
182
788
|
},
|
|
789
|
+
{
|
|
790
|
+
"name": "custom-http-routes",
|
|
791
|
+
"description": "Mount first-class custom HTTP routes (download, secret-validation POST, auth-gated webhook) on the MCP listener via http.routes.",
|
|
792
|
+
"level": "intermediate",
|
|
793
|
+
"tags": ["config", "http", "routes", "custom", "webhook", "download", "auth"],
|
|
794
|
+
"features": [
|
|
795
|
+
"Registering custom HTTP endpoints with `http.routes` — no tool/resource/prompt needed",
|
|
796
|
+
"A POST endpoint that validates a user-entered secret server-side (the `/connect-env` pattern)",
|
|
797
|
+
"Overriding the default `application/json` Content-Type for binary/HTML delivery",
|
|
798
|
+
"Gating a route behind the MCP `session:verify` flow with `auth: true`",
|
|
799
|
+
"Avoiding reserved paths (`/sse`, `/message`, `/oauth/*`, `/.well-known/*`, `/health`, `/metrics`)"
|
|
800
|
+
]
|
|
801
|
+
},
|
|
183
802
|
{
|
|
184
803
|
"name": "entry-path-reverse-proxy",
|
|
185
804
|
"description": "Mount the MCP server under a URL prefix for reverse proxy or multi-service setups.",
|
|
@@ -483,7 +1102,7 @@
|
|
|
483
1102
|
{
|
|
484
1103
|
"name": "frontmcp-deployment",
|
|
485
1104
|
"category": "deployment",
|
|
486
|
-
"description": "Use when
|
|
1105
|
+
"description": "Use when deploying, building for production, packaging, or shipping a FrontMCP server. Covers build targets (node, cli SEA binary, browser, embeddable SDK, mcpb archive for Claude Desktop, serverless) and deploying to Vercel (with Vercel KV), AWS Lambda (API Gateway, SAM, CDK), Cloudflare Workers (KV, D1, Durable Objects, v1.3 skills-only), and Node (multi-stage Docker, docker-compose, PM2, nginx). Also the frontmcp.deploy.yaml manifest plus GitHub Action push-resync, and MCP client integration / .mcp.json for Claude Desktop, Claude Code, Cursor, and VS Code over stdio or HTTP. Triggers: deploy, build for production, dockerize, containerize, serverless, edge runtime, go live, ship it.",
|
|
487
1106
|
"path": "frontmcp-deployment",
|
|
488
1107
|
"targets": ["all"],
|
|
489
1108
|
"hasResources": true,
|
|
@@ -613,6 +1232,14 @@
|
|
|
613
1232
|
}
|
|
614
1233
|
]
|
|
615
1234
|
},
|
|
1235
|
+
{
|
|
1236
|
+
"name": "deploy-to-cloudflare-skills-only",
|
|
1237
|
+
"description": "Deploy a FrontMCP server to Cloudflare Workers using the v1.3 skills-only model — OpenAPI as capability inventory, AgentScript with namespaced bindings, four meta-tools, hot-reload via GitHub Action and a signed-bundle webhook."
|
|
1238
|
+
},
|
|
1239
|
+
{
|
|
1240
|
+
"name": "deploy-manifest-yaml",
|
|
1241
|
+
"description": "The frontmcp.deploy.yaml v1 schema — declarative manifest the GitHub Action consumes on every push to build, sign, and hot-reload the Cloudflare Worker."
|
|
1242
|
+
},
|
|
616
1243
|
{
|
|
617
1244
|
"name": "deploy-to-cloudflare",
|
|
618
1245
|
"description": "Deploy a FrontMCP server to Cloudflare Workers with KV, D1, and Durable Objects",
|
|
@@ -872,7 +1499,7 @@
|
|
|
872
1499
|
{
|
|
873
1500
|
"name": "frontmcp-development",
|
|
874
1501
|
"category": "development",
|
|
875
|
-
"description": "Use when
|
|
1502
|
+
"description": "Use when building any FrontMCP server component other than a tool (for tools, use create-tool). Covers @Resource static resources and parameterized URI templates; @Prompt reusable prompts (RAG, multi-turn); @Provider singleton dependency-injection providers (database pools, API clients); @Agent autonomous LLM agents (Anthropic, OpenAI) and swarms; @Job background jobs (retry, progress, permissions) and @Workflow DAG pipelines; framework adapters and the OpenAPI adapter (turn OpenAPI 3.x specs into MCP tools with auth, polling, transforms); plugins, plugin lifecycle hooks (before / after / around / stage), and the official plugins; instruction-only skills and skills that reference tools; and the hierarchical decorator system from @FrontMcp down to @App. Triggers: create a resource, build a prompt, write a provider, add an agent, job, workflow, plugin, adapter, or OpenAPI integration.",
|
|
876
1503
|
"path": "frontmcp-development",
|
|
877
1504
|
"targets": ["all"],
|
|
878
1505
|
"hasResources": true,
|
|
@@ -1314,129 +1941,6 @@
|
|
|
1314
1941
|
}
|
|
1315
1942
|
]
|
|
1316
1943
|
},
|
|
1317
|
-
{
|
|
1318
|
-
"name": "create-tool-annotations",
|
|
1319
|
-
"description": "Reference for MCP tool annotation hints like readOnly, destructive, and idempotent",
|
|
1320
|
-
"examples": [
|
|
1321
|
-
{
|
|
1322
|
-
"name": "destructive-delete-tool",
|
|
1323
|
-
"description": "Demonstrates annotating a tool that deletes data, enabling MCP clients to warn users before execution.",
|
|
1324
|
-
"level": "intermediate",
|
|
1325
|
-
"tags": ["development", "elicitation", "tool", "annotations", "destructive", "delete"],
|
|
1326
|
-
"features": [
|
|
1327
|
-
"Setting `destructiveHint: true` on the delete tool so MCP clients can trigger confirmation warnings",
|
|
1328
|
-
"Setting `idempotentHint: true` on the delete tool because deleting the same user twice produces the same outcome",
|
|
1329
|
-
"Setting `openWorldHint: true` on the email tool because it interacts with an external SMTP service",
|
|
1330
|
-
"Setting `idempotentHint: false` on the email tool because each call sends a new email",
|
|
1331
|
-
"How different annotation combinations express different behavioral contracts"
|
|
1332
|
-
]
|
|
1333
|
-
},
|
|
1334
|
-
{
|
|
1335
|
-
"name": "readonly-query-tool",
|
|
1336
|
-
"description": "Demonstrates annotating a tool that only reads data, signaling to MCP clients that it has no side effects and is safe to retry.",
|
|
1337
|
-
"level": "basic",
|
|
1338
|
-
"tags": ["development", "database", "local", "tool", "annotations", "readonly"],
|
|
1339
|
-
"features": [
|
|
1340
|
-
"Setting `readOnlyHint: true` to indicate the tool performs no mutations",
|
|
1341
|
-
"Setting `destructiveHint: false` to tell clients no data will be deleted or overwritten",
|
|
1342
|
-
"Setting `idempotentHint: true` because repeated calls with the same input produce the same result",
|
|
1343
|
-
"Setting `openWorldHint: false` because the tool only accesses local database data",
|
|
1344
|
-
"Using `title` to provide a human-friendly display name for MCP client UIs"
|
|
1345
|
-
]
|
|
1346
|
-
}
|
|
1347
|
-
]
|
|
1348
|
-
},
|
|
1349
|
-
{
|
|
1350
|
-
"name": "create-tool-output-schema-types",
|
|
1351
|
-
"description": "Reference for all supported outputSchema types including Zod shapes and JSON Schema",
|
|
1352
|
-
"examples": [
|
|
1353
|
-
{
|
|
1354
|
-
"name": "primitive-and-media-outputs",
|
|
1355
|
-
"description": "Demonstrates using primitive string literals and media types as `outputSchema` for tools that return plain text, images, or multi-content arrays.",
|
|
1356
|
-
"level": "intermediate",
|
|
1357
|
-
"tags": ["development", "output-schema", "tool", "output", "schema", "types"],
|
|
1358
|
-
"features": [
|
|
1359
|
-
"Using `'string'` literal to return plain text output",
|
|
1360
|
-
"Using `'image'` literal to return base64 image data",
|
|
1361
|
-
"Using `['string', 'image']` array to return multi-content (text plus image) in a single response",
|
|
1362
|
-
"Other available primitives: `'number'`, `'boolean'`, `'date'`",
|
|
1363
|
-
"Other available media types: `'audio'`, `'resource'`, `'resource_link'`"
|
|
1364
|
-
]
|
|
1365
|
-
},
|
|
1366
|
-
{
|
|
1367
|
-
"name": "zod-raw-shape-output",
|
|
1368
|
-
"description": "Demonstrates the recommended approach of using a Zod raw shape as `outputSchema` for structured, validated JSON output.",
|
|
1369
|
-
"level": "basic",
|
|
1370
|
-
"tags": ["development", "codecall", "output-schema", "tool", "output", "schema"],
|
|
1371
|
-
"features": [
|
|
1372
|
-
"Using a Zod raw shape (plain object with Zod types) as `outputSchema` for structured output",
|
|
1373
|
-
"The output is validated at runtime against the schema before being returned to the client",
|
|
1374
|
-
"This is the recommended pattern for CodeCall compatibility and data leak prevention",
|
|
1375
|
-
"The `execute()` return type is automatically inferred from the output schema"
|
|
1376
|
-
]
|
|
1377
|
-
},
|
|
1378
|
-
{
|
|
1379
|
-
"name": "zod-schema-advanced-output",
|
|
1380
|
-
"description": "Demonstrates using full Zod schema objects (not raw shapes) as `outputSchema`, including `z.object()`, `z.array()`, `z.union()`, and `z.discriminatedUnion()`.",
|
|
1381
|
-
"level": "advanced",
|
|
1382
|
-
"tags": ["development", "output-schema", "tool", "output", "schema", "types"],
|
|
1383
|
-
"features": [
|
|
1384
|
-
"Using `z.object()` for structured output with nested arrays and nullable fields",
|
|
1385
|
-
"Using `z.discriminatedUnion()` to return different output shapes based on a discriminant field",
|
|
1386
|
-
"Full Zod schemas provide the same validation as raw shapes but support more complex types",
|
|
1387
|
-
"Output is validated at runtime -- mismatched return values trigger validation errors"
|
|
1388
|
-
]
|
|
1389
|
-
}
|
|
1390
|
-
]
|
|
1391
|
-
},
|
|
1392
|
-
{
|
|
1393
|
-
"name": "create-tool",
|
|
1394
|
-
"description": "Build MCP tools with Zod input/output validation and dependency injection",
|
|
1395
|
-
"examples": [
|
|
1396
|
-
{
|
|
1397
|
-
"name": "basic-class-tool",
|
|
1398
|
-
"description": "A minimal tool using the class-based pattern with Zod input validation, output schema, and types derived from the schemas.",
|
|
1399
|
-
"level": "basic",
|
|
1400
|
-
"tags": ["development", "tool", "class"],
|
|
1401
|
-
"features": [
|
|
1402
|
-
"Extending `ToolContext` and implementing the `execute()` method",
|
|
1403
|
-
"Using a Zod raw shape for `inputSchema` (not wrapped in `z.object()`)",
|
|
1404
|
-
"Defining `outputSchema` to validate and restrict output fields",
|
|
1405
|
-
"Deriving `execute()` input/output types from the schemas via `ToolInputOf<>` / `ToolOutputOf<>` (no duplicated annotation)",
|
|
1406
|
-
"Co-locating schema and tool in sibling files (`<name>.schema.ts` / `<name>.tool.ts`)",
|
|
1407
|
-
"Registering the tool in an `@App` via the `tools` array"
|
|
1408
|
-
]
|
|
1409
|
-
},
|
|
1410
|
-
{
|
|
1411
|
-
"name": "tool-with-di-and-errors",
|
|
1412
|
-
"description": "A tool that resolves a database service via DI and uses `this.fail()` for business-logic errors, with `execute()` types derived from the schemas.",
|
|
1413
|
-
"level": "intermediate",
|
|
1414
|
-
"tags": ["development", "database", "tool", "di", "errors"],
|
|
1415
|
-
"features": [
|
|
1416
|
-
"Defining a typed DI token with `Token<T>` and resolving it via `this.get()`",
|
|
1417
|
-
"Using `this.fail()` with `ResourceNotFoundError` for MCP-compliant error responses",
|
|
1418
|
-
"Letting infrastructure errors (database failures) propagate naturally to the framework",
|
|
1419
|
-
"Deriving `execute()` types from `inputSchema` / `outputSchema` via `ToolInputOf<>` / `ToolOutputOf<>`",
|
|
1420
|
-
"Folder-per-tool layout (`tools/delete-record/{schema,tool,index}.ts`) for tools with local helpers or error types",
|
|
1421
|
-
"Registering both the provider and tool in the same `@App`"
|
|
1422
|
-
]
|
|
1423
|
-
},
|
|
1424
|
-
{
|
|
1425
|
-
"name": "tool-with-rate-limiting-and-progress",
|
|
1426
|
-
"description": "A batch processing tool that uses rate limiting, concurrency control, progress notifications, and annotations, with `execute()` types derived from the schemas.",
|
|
1427
|
-
"level": "advanced",
|
|
1428
|
-
"tags": ["development", "throttle", "tool", "rate", "limiting", "progress"],
|
|
1429
|
-
"features": [
|
|
1430
|
-
"Configuring `rateLimit`, `concurrency`, and `timeout` for throttling protection",
|
|
1431
|
-
"Sending progress updates to the client with `this.progress(progress, total, message?)`",
|
|
1432
|
-
"Using `this.mark(stage)` for execution stage tracking and debugging",
|
|
1433
|
-
"Sending log-level notifications with `this.notify(message, level)`",
|
|
1434
|
-
"Setting tool `annotations` to communicate behavioral hints to clients",
|
|
1435
|
-
"Deriving `execute()` types from the schemas via `ToolInputOf<>` / `ToolOutputOf<>`"
|
|
1436
|
-
]
|
|
1437
|
-
}
|
|
1438
|
-
]
|
|
1439
|
-
},
|
|
1440
1944
|
{
|
|
1441
1945
|
"name": "create-workflow",
|
|
1442
1946
|
"description": "Connect multiple jobs into managed DAG pipelines with dependencies, conditions, and triggers",
|
|
@@ -1657,7 +2161,7 @@
|
|
|
1657
2161
|
{
|
|
1658
2162
|
"name": "frontmcp-extensibility",
|
|
1659
2163
|
"category": "extensibility",
|
|
1660
|
-
"description": "
|
|
2164
|
+
"description": "Use when extending FrontMCP beyond the core SDK by integrating external npm packages, libraries, or third-party services into providers and tools. Covers VectoriaDB for in-memory semantic and vector search (ML-based embeddings or TF-IDF keyword engines, with persistence) and the tamper-evident, hash-chained skill audit log (pluggable signer and store, with chain verification). Triggers: add semantic search, vector search, embeddings, similarity search, recommendations, ML features, audit logging, or integrate an external library, database, or API beyond the built-in SDK.",
|
|
1661
2165
|
"path": "frontmcp-extensibility",
|
|
1662
2166
|
"targets": ["all"],
|
|
1663
2167
|
"hasResources": true,
|
|
@@ -1746,7 +2250,7 @@
|
|
|
1746
2250
|
{
|
|
1747
2251
|
"name": "frontmcp-guides",
|
|
1748
2252
|
"category": "guides",
|
|
1749
|
-
"description": "Tutorials,
|
|
2253
|
+
"description": "Tutorials, end-to-end walkthroughs, and complete reference projects for FrontMCP. Use when you want a getting-started guide, a full worked example, or to learn best practices by following a step-by-step build rather than a single API reference. Includes a beginner weather-API server (tool plus static resource, Zod schemas, E2E tests), an authenticated task manager (CRUD tools, Redis storage, OAuth, Vercel deploy, authenticated E2E tests), and a multi-app knowledge base (vector search, semantic resources, an AI research agent, audit logging). Triggers: tutorial, walkthrough, how do I build, getting started, end-to-end example, sample project, learn FrontMCP, full app example.",
|
|
1750
2254
|
"path": "frontmcp-guides",
|
|
1751
2255
|
"targets": ["all"],
|
|
1752
2256
|
"hasResources": true,
|
|
@@ -1892,7 +2396,7 @@
|
|
|
1892
2396
|
{
|
|
1893
2397
|
"name": "frontmcp-production-readiness",
|
|
1894
2398
|
"category": "production",
|
|
1895
|
-
"description": "Pre-production audit and
|
|
2399
|
+
"description": "Pre-production audit, hardening, and go-live checklists for FrontMCP servers. Use before shipping to verify security hardening, performance, reliability, and observability, and for target-specific production checklists: Node server (Docker, graceful shutdown, Redis session scaling), Vercel and edge (cold-start, stateless design), AWS Lambda (cold start, scaling, monitoring), Cloudflare Workers (KV, Durable Objects, runtime limits), CLI binary and local daemon (stdio and socket transport), browser SDK bundle, and embedded npm SDK. Also configuring /healthz and /readyz health and readiness endpoints with custom probes, and distributed high-availability (multi-pod heartbeat, session takeover, notification relay). Triggers: production ready, security audit, hardening, performance check, production checklist, go live, pre-launch review.",
|
|
1896
2400
|
"path": "frontmcp-production-readiness",
|
|
1897
2401
|
"targets": ["all"],
|
|
1898
2402
|
"hasResources": true,
|
|
@@ -2336,7 +2840,7 @@
|
|
|
2336
2840
|
{
|
|
2337
2841
|
"name": "frontmcp-setup",
|
|
2338
2842
|
"category": "setup",
|
|
2339
|
-
"description": "
|
|
2843
|
+
"description": "Use when starting, scaffolding, or organizing a FrontMCP project. Covers creating a new project (CLI scaffold or manual) for Node, Vercel, and other targets; standalone versus Nx-monorepo layout, naming conventions, generators, and dependency rules; composing multiple @App classes, ESM packages, and remote MCP servers into one server; provisioning session and storage backends (Redis, Vercel KV, SQLite with WAL and optional encryption); generating deployment-target-aware README files; and searching, installing, and managing the FrontMCP skill catalog for AI agents (Claude Code, Codex). Triggers: create a new project, how do I start, scaffold, project layout, folder structure, Nx monorepo, add Redis, set up SQLite or a database, compose apps, create a new app, manage skills.",
|
|
2340
2844
|
"path": "frontmcp-setup",
|
|
2341
2845
|
"targets": ["all"],
|
|
2342
2846
|
"hasResources": true,
|
|
@@ -2707,7 +3211,7 @@
|
|
|
2707
3211
|
{
|
|
2708
3212
|
"name": "frontmcp-testing",
|
|
2709
3213
|
"category": "testing",
|
|
2710
|
-
"description": "Use
|
|
3214
|
+
"description": "Use for anything about testing FrontMCP servers: writing or running unit, integration, and E2E tests and reaching the 95%+ coverage bar. Covers Jest setup and coverage gating; unit-testing a ToolContext execute() with mock context, inputs, and Zod schema validation; testing resources and prompts; in-memory testing via create() and connectOpenAI / connectClaude (no HTTP); full MCP-protocol E2E over HTTP with McpTestClient and TestServer; authenticated tests with TestTokenFactory, MockOAuthServer, and role-based access; browser-bundle validation with Playwright; and CLI-binary / SEA startup tests. Triggers: write tests, run tests, add e2e tests, improve coverage, test a tool / resource / prompt, mock auth, jest config. The skill for ALL testing needs.",
|
|
2711
3215
|
"path": "frontmcp-testing",
|
|
2712
3216
|
"targets": ["all"],
|
|
2713
3217
|
"hasResources": true,
|
|
@@ -2978,7 +3482,7 @@
|
|
|
2978
3482
|
{
|
|
2979
3483
|
"name": "frontmcp-observability",
|
|
2980
3484
|
"category": "observability",
|
|
2981
|
-
"description": "Use when
|
|
3485
|
+
"description": "Use when adding tracing, structured logging, metrics, or monitoring to a FrontMCP server. Covers zero-config OpenTelemetry distributed tracing across all flows; the this.telemetry API for custom spans, events, and attributes in tools, plugins, agents, and skills; structured JSON logging with trace correlation and configurable sinks (Winston, Pino, stdout); the off-by-default /metrics endpoint (process and framework metrics, Prometheus-compatible); vendor integrations (Coralogix, Datadog, Logz.io, Grafana Cloud, or any OTLP backend); and testing spans, log correlation, and instrumentation. Triggers: observability, telemetry, tracing, logging, monitoring, OpenTelemetry, OTel, spans, metrics, Prometheus, Datadog, Coralogix, Logz.io, Grafana, Winston, Pino.",
|
|
2982
3486
|
"path": "frontmcp-observability",
|
|
2983
3487
|
"targets": ["all"],
|
|
2984
3488
|
"hasResources": true,
|
|
@@ -3174,7 +3678,7 @@
|
|
|
3174
3678
|
{
|
|
3175
3679
|
"name": "frontmcp-channels",
|
|
3176
3680
|
"category": "development",
|
|
3177
|
-
"description": "Use when
|
|
3681
|
+
"description": "Use when pushing real-time notifications or events into Claude Code (or another MCP client) sessions, or building two-way chat bridges. Covers channel source types: incoming webhooks (such as GitHub), app error events, agent-completion and job-completion alerts, service connectors, file watchers, and replay buffers; plus two-way conversational bridges connecting WhatsApp, Telegram, Slack, and Discord to a Claude Code session. Triggers: push notifications, real-time alerts, webhook channel, chat bridge, WhatsApp / Telegram / Slack / Discord, agent completion alert, job status notification, error forwarding, server-to-client messaging. The skill for CHANNELS and NOTIFICATIONS.",
|
|
3178
3682
|
"path": "frontmcp-channels",
|
|
3179
3683
|
"targets": ["all"],
|
|
3180
3684
|
"hasResources": true,
|
|
@@ -3302,7 +3806,7 @@
|
|
|
3302
3806
|
{
|
|
3303
3807
|
"name": "frontmcp-authorities",
|
|
3304
3808
|
"category": "development",
|
|
3305
|
-
"description": "Use when implementing authorization
|
|
3809
|
+
"description": "Use when implementing authorization and access control for FrontMCP tools, resources, prompts, or skills, deciding who may invoke what. Covers the RBAC, ABAC, and ReBAC models and when to choose each; JWT claims mapping per identity provider (Auth0, Keycloak, Okta, Cognito, Frontegg); reusable named authority profiles; and custom authority evaluators for domain-specific policy. This is about who-can-do-what (permissions, roles, scopes), distinct from configuring auth modes and login (see frontmcp-config) and custom login UI (see frontmcp-auth-ui). Triggers: authorization, access control, RBAC, ABAC, ReBAC, permissions, roles, scopes, policy enforcement, JWT claims, restrict who can call a tool.",
|
|
3306
3810
|
"path": "frontmcp-authorities",
|
|
3307
3811
|
"targets": ["all"],
|
|
3308
3812
|
"hasResources": true,
|