@frontmcp/skills 1.2.0 → 1.3.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/catalog/frontmcp-config/SKILL.md +5 -5
- package/catalog/frontmcp-config/references/configure-deployment-targets.md +84 -1
- package/catalog/frontmcp-config/references/configure-http.md +57 -2
- package/catalog/frontmcp-config/references/configure-session.md +14 -7
- package/catalog/frontmcp-deployment/SKILL.md +3 -3
- package/catalog/frontmcp-deployment/references/build-for-mcpb.md +1 -1
- package/catalog/frontmcp-deployment/references/mcp-client-integration.md +107 -0
- package/catalog/frontmcp-development/SKILL.md +7 -7
- package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +14 -0
- package/catalog/frontmcp-development/examples/create-provider/config-and-api-providers.md +85 -9
- package/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md +30 -11
- package/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md +62 -14
- package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +30 -12
- package/catalog/frontmcp-development/references/create-job.md +45 -11
- package/catalog/frontmcp-development/references/create-provider.md +80 -8
- package/catalog/frontmcp-development/references/create-skill-with-tools.md +31 -0
- package/catalog/frontmcp-development/references/create-skill.md +45 -0
- package/catalog/frontmcp-development/references/create-tool.md +124 -46
- package/catalog/frontmcp-guides/SKILL.md +7 -7
- package/catalog/frontmcp-observability/SKILL.md +15 -7
- package/catalog/frontmcp-observability/examples/metrics-endpoint/enable-metrics-endpoint.md +77 -0
- package/catalog/frontmcp-observability/references/metrics-endpoint.md +161 -0
- package/catalog/frontmcp-setup/SKILL.md +11 -11
- package/catalog/frontmcp-setup/examples/frontmcp-skills-usage/install-and-search-skills.md +19 -1
- package/catalog/frontmcp-setup/references/frontmcp-skills-usage.md +260 -19
- package/catalog/frontmcp-setup/references/setup-project.md +29 -0
- package/catalog/frontmcp-setup/references/setup-sqlite.md +68 -9
- package/catalog/frontmcp-testing/SKILL.md +17 -17
- package/catalog/skills-manifest.json +32 -6
- package/package.json +1 -1
|
@@ -61,13 +61,33 @@ frontmcp skills install frontmcp-development --provider claude
|
|
|
61
61
|
|
|
62
62
|
# Install a skill for Codex
|
|
63
63
|
frontmcp skills install frontmcp-setup --provider codex
|
|
64
|
+
|
|
65
|
+
# Bulk install — every skill in a category, all at once
|
|
66
|
+
frontmcp skills install --category development --provider claude
|
|
67
|
+
|
|
68
|
+
# Export a skill as a Cursor rule file (for skills-unaware IDEs)
|
|
69
|
+
frontmcp skills export --name frontmcp-development --target cursor
|
|
70
|
+
|
|
71
|
+
# Publish a skill to the Smithery marketplace
|
|
72
|
+
frontmcp skills publish frontmcp-development --target smithery --dry-run
|
|
64
73
|
```
|
|
65
74
|
|
|
66
75
|
## CLI Commands
|
|
67
76
|
|
|
77
|
+
The `frontmcp skills` command tree currently has six subcommands:
|
|
78
|
+
`search`, `list`, `install`, `read`, `export`, `publish`.
|
|
79
|
+
|
|
80
|
+
<!-- AUTOGEN:skills-cli:start -->
|
|
81
|
+
|
|
68
82
|
### `frontmcp skills search <query>`
|
|
69
83
|
|
|
70
|
-
Semantic search through the catalog using weighted text matching (description 3x, tags 2x, name 1x)
|
|
84
|
+
Semantic search through the catalog using weighted text matching (description 3x, tags 2x, name 1x).
|
|
85
|
+
|
|
86
|
+
| Flag | Description | Default |
|
|
87
|
+
| --------------------- | ------------------------- | ------- |
|
|
88
|
+
| `-n, --limit <count>` | Maximum results to return | `10` |
|
|
89
|
+
| `-t, --tag <tag>` | Filter by tag | — |
|
|
90
|
+
| `-c, --category <c>` | Filter by category | — |
|
|
71
91
|
|
|
72
92
|
```bash
|
|
73
93
|
frontmcp skills search "authentication oauth"
|
|
@@ -77,7 +97,13 @@ frontmcp skills search "plugin hooks" --tag middleware --limit 5
|
|
|
77
97
|
|
|
78
98
|
### `frontmcp skills list`
|
|
79
99
|
|
|
80
|
-
List all skills, optionally filtered
|
|
100
|
+
List all skills, optionally filtered.
|
|
101
|
+
|
|
102
|
+
| Flag | Description | Default |
|
|
103
|
+
| --------------------- | ---------------------------------------------------------- | ------- |
|
|
104
|
+
| `-c, --category <c>` | Filter by category | — |
|
|
105
|
+
| `-t, --tag <tag>` | Filter by tag | — |
|
|
106
|
+
| `-b, --bundle <name>` | Filter by bundle preset (`recommended`, `minimal`, `full`) | — |
|
|
81
107
|
|
|
82
108
|
```bash
|
|
83
109
|
frontmcp skills list # All skills
|
|
@@ -86,9 +112,14 @@ frontmcp skills list --tag redis # Skills tagged with redis
|
|
|
86
112
|
frontmcp skills list --bundle recommended # Recommended bundle
|
|
87
113
|
```
|
|
88
114
|
|
|
89
|
-
### `frontmcp skills read <
|
|
115
|
+
### `frontmcp skills read <nameOrPath> [reference]`
|
|
116
|
+
|
|
117
|
+
Read a skill's main SKILL.md, a specific reference, or list available references.
|
|
90
118
|
|
|
91
|
-
|
|
119
|
+
| Flag | Description | Default |
|
|
120
|
+
| ------------------------ | ------------------------------------------------------------------ | ------- |
|
|
121
|
+
| `--refs` | List all available references for the skill | `false` |
|
|
122
|
+
| `--examples [reference]` | List examples for the skill, optionally filtered by reference name | — |
|
|
92
123
|
|
|
93
124
|
```bash
|
|
94
125
|
# Read main skill content
|
|
@@ -97,6 +128,10 @@ frontmcp skills read frontmcp-development
|
|
|
97
128
|
# List all references for a skill
|
|
98
129
|
frontmcp skills read frontmcp-development --refs
|
|
99
130
|
|
|
131
|
+
# List every example bundled with the skill (or filter by reference)
|
|
132
|
+
frontmcp skills read frontmcp-development --examples
|
|
133
|
+
frontmcp skills read frontmcp-development --examples create-tool
|
|
134
|
+
|
|
100
135
|
# Read a specific reference by name
|
|
101
136
|
frontmcp skills read frontmcp-development create-tool
|
|
102
137
|
|
|
@@ -105,19 +140,221 @@ frontmcp skills read frontmcp-development:references/create-tool.md
|
|
|
105
140
|
frontmcp skills read frontmcp-development:scripts/setup.sh
|
|
106
141
|
```
|
|
107
142
|
|
|
108
|
-
### `frontmcp skills install
|
|
143
|
+
### `frontmcp skills install [name]`
|
|
144
|
+
|
|
145
|
+
Install one or many skills to a provider-specific directory. `[name]` is
|
|
146
|
+
optional when one of `--all`, `--tag`, or `--category` is supplied —
|
|
147
|
+
those flags select skills in bulk.
|
|
109
148
|
|
|
110
|
-
|
|
149
|
+
| Flag | Description | Default |
|
|
150
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------ | -------- |
|
|
151
|
+
| `-p, --provider <provider>` | Target provider: `claude` or `codex` | `claude` |
|
|
152
|
+
| `-d, --dir <directory>` | Custom install directory (overrides provider default) | — |
|
|
153
|
+
| `-a, --all` | Install **every** skill in the catalog (or every `@Skill` entry when `--from-*` is set) | `false` |
|
|
154
|
+
| `-t, --tag <tag>` | Install every skill matching a tag (catalog only) | — |
|
|
155
|
+
| `-c, --category <c>` | Install every skill in a category (catalog only) | — |
|
|
156
|
+
| `--from-entry <path>` | Install `@Skill` entries discovered in a **local project entry file** instead of the framework catalog | — |
|
|
157
|
+
| `--from-package <pkg>` | Install `@Skill` entries discovered in a **published package's** main entry | — |
|
|
111
158
|
|
|
112
159
|
```bash
|
|
113
|
-
#
|
|
114
|
-
frontmcp skills install frontmcp-development --provider claude
|
|
160
|
+
# Single-skill install (positional name)
|
|
161
|
+
frontmcp skills install frontmcp-development --provider claude # → .claude/skills/<name>/SKILL.md
|
|
162
|
+
frontmcp skills install frontmcp-setup --provider codex # → .codex/skills/<name>/SKILL.md
|
|
163
|
+
frontmcp skills install frontmcp-guides --dir ./my-skills # custom destination
|
|
164
|
+
|
|
165
|
+
# Bulk install — see "Bulk install patterns" below for the full decision matrix
|
|
166
|
+
frontmcp skills install --all --provider claude
|
|
167
|
+
frontmcp skills install --category development --provider claude
|
|
168
|
+
frontmcp skills install --tag middleware --provider codex
|
|
169
|
+
|
|
170
|
+
# Install a project's own @Skill-decorated entries (see "Installing project-defined skills")
|
|
171
|
+
frontmcp skills install --from-entry src/main.ts --all -p claude
|
|
172
|
+
frontmcp skills install --from-package my-frontmcp-server my-skill -p claude
|
|
173
|
+
```
|
|
115
174
|
|
|
116
|
-
|
|
117
|
-
|
|
175
|
+
### `frontmcp skills export`
|
|
176
|
+
|
|
177
|
+
Convert one or many catalog skills into a rule file for IDEs that
|
|
178
|
+
**don't** speak the skills protocol (Cursor, Windsurf, Copilot). The
|
|
179
|
+
emitted file lives in the current directory by default.
|
|
180
|
+
|
|
181
|
+
| Flag | Description | Default |
|
|
182
|
+
| ----------------------- | ----------------------------------------------------- | -------- |
|
|
183
|
+
| `-t, --target <target>` | Target IDE: `cursor`, `windsurf`, or `copilot` | `cursor` |
|
|
184
|
+
| `-n, --name <name>` | Skill name to export (required unless `--all` is set) | — |
|
|
185
|
+
| `-a, --all` | Export **every** skill in the catalog | `false` |
|
|
186
|
+
| `-d, --out <directory>` | Output directory | `cwd` |
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
frontmcp skills export --name frontmcp-development --target cursor
|
|
190
|
+
frontmcp skills export --name frontmcp-setup --target windsurf
|
|
191
|
+
frontmcp skills export --all --target copilot --out ./.github
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
See **Other AI clients (Cursor / Windsurf / Copilot)** below for the
|
|
195
|
+
output-filename mapping per target.
|
|
196
|
+
|
|
197
|
+
### `frontmcp skills publish <name>`
|
|
198
|
+
|
|
199
|
+
Publish a skill to a public marketplace (Smithery or Glama).
|
|
200
|
+
|
|
201
|
+
| Flag | Description | Default |
|
|
202
|
+
| ----------------------- | ---------------------------------------------------------------- | ---------- |
|
|
203
|
+
| `-t, --target <target>` | Marketplace: `smithery` or `glama` | `smithery` |
|
|
204
|
+
| `--token <token>` | API token (defaults to `SMITHERY_TOKEN` / `GLAMA_TOKEN` env var) | env |
|
|
205
|
+
| `--repository <url>` | Repository URL to advertise on the marketplace | — |
|
|
206
|
+
| `--dry-run` | Print the payload + endpoint without submitting | `false` |
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# Dry run against Smithery (no submission)
|
|
210
|
+
frontmcp skills publish frontmcp-development --dry-run
|
|
211
|
+
|
|
212
|
+
# Real publish to Glama with a custom repo URL + env-var token
|
|
213
|
+
GLAMA_TOKEN=xxx frontmcp skills publish frontmcp-development \
|
|
214
|
+
--target glama --repository https://github.com/me/my-frontmcp-server
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
<!-- AUTOGEN:skills-cli:end -->
|
|
218
|
+
|
|
219
|
+
## Bulk install patterns
|
|
220
|
+
|
|
221
|
+
`frontmcp skills install` accepts a single `[name]` OR one of the bulk
|
|
222
|
+
selectors. They are mutually exclusive — pass exactly one. The decision
|
|
223
|
+
matrix:
|
|
224
|
+
|
|
225
|
+
| Goal | Command |
|
|
226
|
+
| ----------------------------------------------------- | -------------------------------------------------- |
|
|
227
|
+
| Install one specific skill | `frontmcp skills install <name> -p claude` |
|
|
228
|
+
| Install every skill in the catalog | `frontmcp skills install --all -p claude` |
|
|
229
|
+
| Install all skills in a category (e.g. `development`) | `frontmcp skills install -c development -p claude` |
|
|
230
|
+
| Install all skills with a tag (e.g. `middleware`) | `frontmcp skills install -t middleware -p codex` |
|
|
231
|
+
| Install all skills to a non-default directory | `frontmcp skills install --all -d ./custom-skills` |
|
|
232
|
+
|
|
233
|
+
Examples:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Onboard a new repo: install everything for Claude Code
|
|
237
|
+
frontmcp skills install --all -p claude
|
|
238
|
+
|
|
239
|
+
# Scaffold a tools-focused project: only the development category
|
|
240
|
+
frontmcp skills install -c development -p claude
|
|
241
|
+
|
|
242
|
+
# Cross-IDE setup: install middleware skills into a Codex project
|
|
243
|
+
frontmcp skills install -t middleware -p codex
|
|
244
|
+
|
|
245
|
+
# Mono-repo with a shared skills folder
|
|
246
|
+
frontmcp skills install --all -d ./shared/.claude/skills
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
> **Heads up:** `--all` / `--tag` / `--category` make `[name]` optional. Pass
|
|
250
|
+
> exactly one bulk selector OR a `[name]`; combining a positional name with a
|
|
251
|
+
> bulk flag is rejected.
|
|
252
|
+
|
|
253
|
+
## Installing project-defined skills (`@Skill`)
|
|
254
|
+
|
|
255
|
+
The same `frontmcp skills install` command can install **your project's
|
|
256
|
+
own** `@Skill`-decorated entries — not just the framework catalog. Use
|
|
257
|
+
this when you ship a FrontMCP server that registers skills (via the
|
|
258
|
+
`@Skill` decorator or the `skill()` helper — see `create-skill`) and
|
|
259
|
+
want end users to drop those skills onto Claude Code's filesystem.
|
|
260
|
+
|
|
261
|
+
| Flag | When to use it |
|
|
262
|
+
| ---------------------- | --------------------------------------------------------------------------------------------- |
|
|
263
|
+
| `--from-entry <path>` | Resolve `@Skill` entries from a local entry file (`src/main.ts`, etc.) in the current project |
|
|
264
|
+
| `--from-package <pkg>` | Resolve `@Skill` entries from an installed package's main entry (works with `npx` workflows) |
|
|
265
|
+
|
|
266
|
+
The command bundles the entry once via esbuild, boots the SDK with the
|
|
267
|
+
same in-memory client that `frontmcp build` uses, and enumerates every
|
|
268
|
+
`@Skill` entry. Each entry's instructions file (and any `references/` /
|
|
269
|
+
`examples/` / `scripts/` / `assets/` resource directories) is copied
|
|
270
|
+
under `.claude/skills/<skill-name>/`. If the source instructions file
|
|
271
|
+
has no YAML frontmatter, the CLI prepends one synthesized from the
|
|
272
|
+
`@Skill` decorator metadata (`name`, `description`, `tags`, `license`)
|
|
273
|
+
so Claude Code's filesystem loader picks the skill up.
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# From a project checkout: install one named skill
|
|
277
|
+
frontmcp skills install example-project --from-entry src/main.ts -p claude
|
|
278
|
+
|
|
279
|
+
# Install every @Skill the project exposes
|
|
280
|
+
frontmcp skills install --from-entry src/main.ts --all -p claude
|
|
281
|
+
|
|
282
|
+
# From a published package the user has installed:
|
|
283
|
+
frontmcp skills install --from-package my-frontmcp-server --all -p claude
|
|
284
|
+
npx my-frontmcp-server # ... once installed, skills resolve through `my-frontmcp-server`'s main entry
|
|
285
|
+
frontmcp skills install --from-package my-frontmcp-server example-project -p claude
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Selectors and constraints:
|
|
118
289
|
|
|
119
|
-
|
|
120
|
-
|
|
290
|
+
- Pass **either** `<name>` **or** `--all`. `--tag` / `--category` are
|
|
291
|
+
catalog-only and are rejected when `--from-entry` / `--from-package` is
|
|
292
|
+
set — the project's `@Skill` list is the authoritative source.
|
|
293
|
+
- `--from-entry` and `--from-package` are mutually exclusive.
|
|
294
|
+
- The CLAUDE.md auto-generated `<!-- frontmcp:skills -->` block lists
|
|
295
|
+
every installed skill in `.claude/skills/`, catalog **and**
|
|
296
|
+
project-defined together. Re-running install keeps the block coherent.
|
|
297
|
+
|
|
298
|
+
> **Tip:** This is the lightest path for shipping a project's own skills.
|
|
299
|
+
> If you also want to ship slash commands, environment hints, and a
|
|
300
|
+
> `.claude-plugin/plugin.json` manifest in one shot, use the per-bin
|
|
301
|
+
> `<bin> install -p claude` (see `frontmcp-deployment`) — it wraps the
|
|
302
|
+
> same enumeration plus the rest of the plugin surface.
|
|
303
|
+
|
|
304
|
+
## Other AI clients (Cursor / Windsurf / Copilot)
|
|
305
|
+
|
|
306
|
+
For IDEs that don't natively load `SKILL.md` files, `frontmcp skills
|
|
307
|
+
export` converts a skill into the target IDE's native rule format and
|
|
308
|
+
writes it into the current directory (or `--out <dir>`).
|
|
309
|
+
|
|
310
|
+
| Target | Output path (per skill, relative to `--out` / cwd) | Loaded by |
|
|
311
|
+
| ---------- | -------------------------------------------------- | -------------- |
|
|
312
|
+
| `cursor` | `.cursor/rules/<skill>.mdc` | Cursor |
|
|
313
|
+
| `windsurf` | `.windsurfrules` (single file) | Windsurf |
|
|
314
|
+
| `copilot` | `.github/instructions/<skill>.md` | GitHub Copilot |
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Cursor: export one skill → .cursor/rules/frontmcp-development.mdc
|
|
318
|
+
frontmcp skills export --name frontmcp-development --target cursor
|
|
319
|
+
|
|
320
|
+
# Windsurf: export every skill into a single .windsurfrules in the cwd
|
|
321
|
+
frontmcp skills export --all --target windsurf
|
|
322
|
+
|
|
323
|
+
# Copilot: export every skill, one file per skill, under .github/instructions/
|
|
324
|
+
frontmcp skills export --all --target copilot
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
> Today `--provider` on `install` accepts `claude` and `codex` only.
|
|
328
|
+
> Cursor / Windsurf / Copilot integration goes through `export` instead
|
|
329
|
+
> because those clients consume rule files, not skill packages.
|
|
330
|
+
|
|
331
|
+
## Publishing to marketplaces
|
|
332
|
+
|
|
333
|
+
`frontmcp skills publish <name>` ships a skill to a public catalog so
|
|
334
|
+
other developers can discover and install it.
|
|
335
|
+
|
|
336
|
+
| Target | Marketplace | Token env var |
|
|
337
|
+
| ---------- | --------------------- | ---------------- |
|
|
338
|
+
| `smithery` | <https://smithery.ai> | `SMITHERY_TOKEN` |
|
|
339
|
+
| `glama` | <https://glama.ai> | `GLAMA_TOKEN` |
|
|
340
|
+
|
|
341
|
+
The CLI reads the token from the matching env var by default; override
|
|
342
|
+
with `--token <value>`. Use `--dry-run` to inspect the request payload
|
|
343
|
+
before submitting.
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
# Inspect the request without sending it
|
|
347
|
+
frontmcp skills publish frontmcp-development --target smithery --dry-run
|
|
348
|
+
|
|
349
|
+
# Publish to Smithery with a repo link (token from SMITHERY_TOKEN env)
|
|
350
|
+
SMITHERY_TOKEN=sk_xxx frontmcp skills publish frontmcp-development \
|
|
351
|
+
--target smithery \
|
|
352
|
+
--repository https://github.com/me/my-frontmcp-server
|
|
353
|
+
|
|
354
|
+
# Publish to Glama with an explicit token
|
|
355
|
+
frontmcp skills publish frontmcp-development \
|
|
356
|
+
--target glama \
|
|
357
|
+
--token "$GLAMA_TOKEN"
|
|
121
358
|
```
|
|
122
359
|
|
|
123
360
|
## Two Approaches: Static vs Dynamic
|
|
@@ -240,13 +477,17 @@ frontmcp skills list --category guides # End-to-end examples and best prac
|
|
|
240
477
|
|
|
241
478
|
## Common Patterns
|
|
242
479
|
|
|
243
|
-
| Pattern
|
|
244
|
-
|
|
|
245
|
-
| Installing a skill
|
|
246
|
-
|
|
|
247
|
-
|
|
|
248
|
-
|
|
|
249
|
-
|
|
|
480
|
+
| Pattern | Correct | Incorrect | Why |
|
|
481
|
+
| ----------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
482
|
+
| Installing a skill | `frontmcp skills install frontmcp-development --provider claude` | `cp node_modules/.../SKILL.md .claude/skills/` | The CLI handles directory creation, naming, and reference files automatically |
|
|
483
|
+
| Bulk install (entire catalog) | `frontmcp skills install --all --provider claude` | Loop over `frontmcp skills install <name>` per skill name | `--all` resolves the manifest in a single pass and writes consistently into the provider directory |
|
|
484
|
+
| Bulk install (subset) | `frontmcp skills install --category development --provider claude` | `frontmcp skills install --all` followed by manual cleanup | `--category`/`--tag` filter at install time so you only ship the skills you need |
|
|
485
|
+
| Searching skills | `frontmcp skills search "oauth authentication"` | `frontmcp skills list \| grep oauth` | Search uses weighted text matching (description 3x, tags 2x) for better relevance |
|
|
486
|
+
| Choosing delivery mode | Install 2-4 core skills statically; search the rest on demand | Install every skill statically into the project | Static skills consume tokens on every agent invocation; keep the set small |
|
|
487
|
+
| Updating an installed skill | `frontmcp skills install frontmcp-development --provider claude` (re-run) | Manually editing the installed SKILL.md file | Re-installing overwrites with the catalog bundled in the installed CLI version and preserves structure |
|
|
488
|
+
| Filtering by category | `frontmcp skills list --category deployment` | `frontmcp skills search "deployment"` | `--category` uses the manifest taxonomy; search is for free-text queries |
|
|
489
|
+
| Skills-unaware IDE (Cursor) | `frontmcp skills export --name <skill> --target cursor` | `frontmcp skills install <skill> --provider cursor` | Cursor / Windsurf / Copilot consume rule files; `install` only writes `SKILL.md` packages |
|
|
490
|
+
| Publishing | `frontmcp skills publish <name> --dry-run` first, then without `--dry-run` | Submitting directly without inspecting the payload | `--dry-run` prints the exact endpoint + body so you can audit before submitting credentials |
|
|
250
491
|
|
|
251
492
|
## Verification Checklist
|
|
252
493
|
|
|
@@ -375,6 +375,35 @@ Then start the server normally:
|
|
|
375
375
|
frontmcp dev
|
|
376
376
|
```
|
|
377
377
|
|
|
378
|
+
### Port conflict handling
|
|
379
|
+
|
|
380
|
+
`frontmcp dev` performs a pre-flight TCP probe before spawning `tsx --watch`.
|
|
381
|
+
If the port is already in use, the command exits with a one-line message
|
|
382
|
+
listing remediation options — never a raw `EADDRINUSE` stack trace
|
|
383
|
+
(issue #398).
|
|
384
|
+
|
|
385
|
+
| Flag | Behaviour |
|
|
386
|
+
| ----------------- | ----------------------------------------------------------------------------- |
|
|
387
|
+
| `--port <n>` | Bind the dev server to TCP port `<n>` (sets `PORT=<n>` in the child's env). |
|
|
388
|
+
| `--auto-port` | If the requested port is busy, walk forward to the next free port. |
|
|
389
|
+
| `--show-conflict` | On EADDRINUSE, run `lsof` (POSIX) to print which process is holding the port. |
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
# Pick a different port for this run
|
|
393
|
+
frontmcp dev --port 3100
|
|
394
|
+
|
|
395
|
+
# Let the CLI pick the next free port automatically
|
|
396
|
+
frontmcp dev --auto-port
|
|
397
|
+
|
|
398
|
+
# Show what's holding the port
|
|
399
|
+
frontmcp dev --show-conflict
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
> The `PORT` env var (or `--port`) only takes effect when your `@FrontMcp`
|
|
403
|
+
> metadata reads it via `Number(process.env.PORT) || 3000`. Hard-coding
|
|
404
|
+
> `http.port: 4000` in metadata makes the child bind to 4000 regardless of
|
|
405
|
+
> `--port`/`PORT`, so the pre-flight probe becomes advisory only.
|
|
406
|
+
|
|
378
407
|
Test with curl:
|
|
379
408
|
|
|
380
409
|
```bash
|
|
@@ -57,8 +57,14 @@ The `sqlite` field in the `@FrontMcp` decorator accepts a `SqliteOptionsInput` o
|
|
|
57
57
|
|
|
58
58
|
```typescript
|
|
59
59
|
interface SqliteOptionsInput {
|
|
60
|
-
/**
|
|
61
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Path to the .sqlite database file. **Optional** — when omitted the SDK
|
|
62
|
+
* picks a sensible default at startup:
|
|
63
|
+
* - dev + node + non-CLI → `<projectRoot>/dist/sessions.sqlite`
|
|
64
|
+
* - prod OR CLI mode → `~/.{info.name}/sessions.sqlite`
|
|
65
|
+
* Set this to override either default (e.g. `./.data/sessions.sqlite`).
|
|
66
|
+
*/
|
|
67
|
+
path?: string;
|
|
62
68
|
|
|
63
69
|
/** Enable WAL mode for better read concurrency (default: true) */
|
|
64
70
|
walMode?: boolean;
|
|
@@ -74,6 +80,29 @@ interface SqliteOptionsInput {
|
|
|
74
80
|
}
|
|
75
81
|
```
|
|
76
82
|
|
|
83
|
+
### Default-path policy (issue #401)
|
|
84
|
+
|
|
85
|
+
If you set `sqlite: {}` without a `path`, the SDK resolves it as follows:
|
|
86
|
+
|
|
87
|
+
| Environment | Resolved path |
|
|
88
|
+
| -------------------------------------------------------- | ------------------------------------ |
|
|
89
|
+
| `frontmcp dev` (NODE_ENV=development, node, no CLI mode) | `<projectRoot>/dist/sessions.sqlite` |
|
|
90
|
+
| Built CLI binary (`cliMode`) | `~/.{info.name}/sessions.sqlite` |
|
|
91
|
+
| Production node server (`NODE_ENV=production`) | `~/.{info.name}/sessions.sqlite` |
|
|
92
|
+
|
|
93
|
+
The home-directory namespace is **derived from your `info.name`**, so two
|
|
94
|
+
frontmcp apps from different projects never share the same database
|
|
95
|
+
(e.g. `my-server` → `~/.my-server/sessions.sqlite`,
|
|
96
|
+
`other-app` → `~/.other-app/sessions.sqlite`). If `info.name` is unset or
|
|
97
|
+
sanitization strips it to empty, the fallback is `~/.frontmcp/`.
|
|
98
|
+
|
|
99
|
+
The SDK also `mkdir -p`'s the parent directory at startup, so you don't
|
|
100
|
+
need to pre-create it. The resolved path is logged at INFO level:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
[FrontMcp] No `sqlite.path` set — using default { path: '/Users/you/.my-server/sessions.sqlite' }
|
|
104
|
+
```
|
|
105
|
+
|
|
77
106
|
### Basic SQLite setup
|
|
78
107
|
|
|
79
108
|
Update the `@FrontMcp` decorator in `src/main.ts`:
|
|
@@ -98,12 +127,12 @@ export default class Server {}
|
|
|
98
127
|
|
|
99
128
|
Configuration reference:
|
|
100
129
|
|
|
101
|
-
| Option | Type | Default | Description
|
|
102
|
-
| ---------------------- | -------------------- | ----------- |
|
|
103
|
-
| `path` | `string` | (
|
|
104
|
-
| `walMode` | `boolean` | `true` | Enable WAL mode for better read concurrency
|
|
105
|
-
| `encryption` | `{ secret: string }` | `undefined` | AES-256-GCM encryption for values at rest
|
|
106
|
-
| `ttlCleanupIntervalMs` | `number` | `60000` | Interval for purging expired keys (milliseconds)
|
|
130
|
+
| Option | Type | Default | Description |
|
|
131
|
+
| ---------------------- | -------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
132
|
+
| `path` | `string` | (optional) | Absolute or `~`-prefixed path to the `.sqlite` file. Auto-resolved when omitted — see the default-path policy below. |
|
|
133
|
+
| `walMode` | `boolean` | `true` | Enable WAL mode for better read concurrency |
|
|
134
|
+
| `encryption` | `{ secret: string }` | `undefined` | AES-256-GCM encryption for values at rest |
|
|
135
|
+
| `ttlCleanupIntervalMs` | `number` | `60000` | Interval for purging expired keys (milliseconds) |
|
|
107
136
|
|
|
108
137
|
### With at-rest encryption
|
|
109
138
|
|
|
@@ -198,7 +227,37 @@ You do not call any factory yourself. The SDK constructs the SQLite session stor
|
|
|
198
227
|
- TTL cleanup interval setup for automatic key expiration
|
|
199
228
|
- Creating the database file and parent directories if they do not exist
|
|
200
229
|
|
|
201
|
-
|
|
230
|
+
### How the wiring works (issue #401)
|
|
231
|
+
|
|
232
|
+
Top-level `sqlite` is treated by the SDK as the **default SQLite backend** for
|
|
233
|
+
three subsystems:
|
|
234
|
+
|
|
235
|
+
| Subsystem | Default source | Override |
|
|
236
|
+
| ----------------------------- | ------------------ | ------------------------------ |
|
|
237
|
+
| Transport session persistence | top-level `sqlite` | `transport.persistence.sqlite` |
|
|
238
|
+
| Background task store | top-level `sqlite` | `tasks.sqlite` |
|
|
239
|
+
| Elicitation store | top-level `sqlite` | `elicitation.sqlite` |
|
|
240
|
+
|
|
241
|
+
If you want different files per subsystem, set the subsystem's own `sqlite`
|
|
242
|
+
block — it takes precedence over the top-level one. To disable a single
|
|
243
|
+
subsystem, set its `enabled: false` (or set `transport.persistence: false` for
|
|
244
|
+
transports).
|
|
245
|
+
|
|
246
|
+
If you set the top-level `sqlite` block but disable every consuming subsystem,
|
|
247
|
+
the SDK emits a WARN at startup so the no-op doesn't go silent:
|
|
248
|
+
|
|
249
|
+
```text
|
|
250
|
+
[FrontMcp] Top-level `sqlite` config was provided but no subsystem consumes it ...
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
`createSqliteSessionStore` lives in
|
|
254
|
+
`libs/sdk/src/auth/session/index.ts` for the framework's own wiring, but
|
|
255
|
+
it is **not** re-exported from `@frontmcp/sdk`'s public entrypoint and
|
|
256
|
+
there is no `@frontmcp/sdk/auth/session` subpath export. End-user code
|
|
257
|
+
should rely on the decorator path (top-level `sqlite: {...}` on
|
|
258
|
+
`@FrontMcp`) — same guidance as
|
|
259
|
+
[`configure-session`](../../frontmcp-config/references/configure-session.md):
|
|
260
|
+
the SDK constructs the session store; user code does not.
|
|
202
261
|
|
|
203
262
|
If you need to share the same SQLite config in another part of your code, declare it once and reuse it:
|
|
204
263
|
|
|
@@ -36,7 +36,7 @@ Entry point for testing FrontMCP applications. This skill helps you navigate tes
|
|
|
36
36
|
- You need to build components, not test them (see `frontmcp-development`)
|
|
37
37
|
- You need to deploy, not test (see `frontmcp-deployment`)
|
|
38
38
|
|
|
39
|
-
> **Decision:** Use this skill for testing strategy and routing.
|
|
39
|
+
> **Decision:** Use this skill for testing strategy and routing. Open the `setup-testing` reference under `references/` for hands-on Jest configuration and test writing.
|
|
40
40
|
|
|
41
41
|
## Prerequisites
|
|
42
42
|
|
|
@@ -46,17 +46,17 @@ Entry point for testing FrontMCP applications. This skill helps you navigate tes
|
|
|
46
46
|
|
|
47
47
|
## Steps
|
|
48
48
|
|
|
49
|
-
This is a router skill. Follow this order to pick a testing approach, then move to the target
|
|
49
|
+
This is a router skill. Follow this order to pick a testing approach, then move to the target reference under `references/`.
|
|
50
50
|
|
|
51
51
|
1. **Pick the test layer** — unit (fastest, mock DI), integration (real DI scope), or E2E (real MCP client + server). Use the Testing Strategy table below.
|
|
52
52
|
2. **Pick the component flavour** — tool / resource / prompt / agent / job — each has a distinct recipe.
|
|
53
|
-
3. **Pick the runtime concern** — auth, browser/CLI build, direct vs streamable transport — and add the matching
|
|
54
|
-
4. **Open the target
|
|
55
|
-
5. **Enforce coverage** — confirm the project's 95%+ thresholds are wired into Jest before merging (see `setup-testing`).
|
|
53
|
+
3. **Pick the runtime concern** — auth, browser/CLI build, direct vs streamable transport — and add the matching reference to your reading list.
|
|
54
|
+
4. **Open the target reference** (e.g. `references/test-tool-unit.md`, `references/test-e2e-handler.md`, `references/test-auth.md`) and follow its Steps section.
|
|
55
|
+
5. **Enforce coverage** — confirm the project's 95%+ thresholds are wired into Jest before merging (see `references/setup-testing.md`).
|
|
56
56
|
|
|
57
57
|
## Scenario Routing Table
|
|
58
58
|
|
|
59
|
-
| Scenario |
|
|
59
|
+
| Scenario | Reference / Section | Description |
|
|
60
60
|
| --------------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
61
61
|
| Set up Jest, coverage, and test harness | `setup-testing` | Full Jest config, test utilities, and coverage thresholds |
|
|
62
62
|
| Write unit tests for a tool | `test-tool-unit` | Mock DI, validate input/output, test error paths |
|
|
@@ -87,17 +87,17 @@ This is a router skill. Follow this order to pick a testing approach, then move
|
|
|
87
87
|
|
|
88
88
|
## Cross-Cutting Testing Patterns
|
|
89
89
|
|
|
90
|
-
| Pattern | Rule
|
|
91
|
-
| ------------------ |
|
|
92
|
-
| File naming | Always `.spec.ts` (not `.test.ts`); E2E uses `.e2e.spec.ts`
|
|
93
|
-
| File organization | Split E2E tests by app/feature: `e2e/calc.e2e.spec.ts`, `e2e/ecommerce.e2e.spec.ts`. Never put all tests in a single `server.e2e.spec.ts`
|
|
94
|
-
| Test runner | Standalone projects: use `frontmcp test` (auto-generates Jest/SWC config). Nx monorepos: use `nx test <lib>` (resolves the project's `jest.config.ts`). Never invoke `jest --config ...` directly
|
|
95
|
-
| Coverage threshold | 95%+ across statements, branches, functions, lines
|
|
96
|
-
| Test descriptions | Plain English, no prefixes like "PT-001"; describe behavior not implementation
|
|
97
|
-
| Mocking | Mock providers via DI token replacement, never mock the framework
|
|
98
|
-
| httpMock scope | `httpMock` intercepts HTTP in the **test process** only, NOT in the MCP server subprocess. Do not use httpMock to intercept server-to-API calls — those happen in the child process. Use httpMock for verifying client-to-server request shapes or mocking external APIs called from the test itself
|
|
99
|
-
| Error testing | Assert `instanceof` specific error class AND MCP error code
|
|
100
|
-
| Async | Always `await` async operations; use `expect(...).rejects.toThrow()` for async errors
|
|
90
|
+
| Pattern | Rule |
|
|
91
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
92
|
+
| File naming | Always `.spec.ts` (not `.test.ts`); E2E uses `.e2e.spec.ts` |
|
|
93
|
+
| File organization | Split E2E tests by app/feature: `e2e/calc.e2e.spec.ts`, `e2e/ecommerce.e2e.spec.ts`. Never put all tests in a single `server.e2e.spec.ts` |
|
|
94
|
+
| Test runner | Standalone projects: use `frontmcp test` (auto-generates Jest/SWC config; discovers `src/**/*.spec.ts(x)`, `__tests__/**/*.spec.ts(x)`, and `e2e/**/*.e2e.spec.ts(x)`; transforms both `.ts` and `.tsx` with the automatic JSX runtime; delegates to a user-provided `jest.config.{ts,js,mjs,cjs,json}` if present). Nx monorepos: use `nx test <lib>` (resolves the project's `jest.config.ts`). Never invoke `jest --config ...` directly |
|
|
95
|
+
| Coverage threshold | 95%+ across statements, branches, functions, lines |
|
|
96
|
+
| Test descriptions | Plain English, no prefixes like "PT-001"; describe behavior not implementation |
|
|
97
|
+
| Mocking | Mock providers via DI token replacement, never mock the framework |
|
|
98
|
+
| httpMock scope | `httpMock` intercepts HTTP in the **test process** only, NOT in the MCP server subprocess. Do not use httpMock to intercept server-to-API calls — those happen in the child process. Use httpMock for verifying client-to-server request shapes or mocking external APIs called from the test itself |
|
|
99
|
+
| Error testing | Assert `instanceof` specific error class AND MCP error code |
|
|
100
|
+
| Async | Always `await` async operations; use `expect(...).rejects.toThrow()` for async errors |
|
|
101
101
|
|
|
102
102
|
## Common Patterns
|
|
103
103
|
|