@frontmcp/skills 1.8.7 → 1.9.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.
Files changed (62) hide show
  1. package/README.md +107 -155
  2. package/catalog/create-tool/examples/21-tool-with-availability-constraints.md +1 -1
  3. package/catalog/create-tool/references/availability.md +10 -10
  4. package/catalog/create-tool/references/ui-widgets.md +30 -8
  5. package/catalog/frontmcp-authorities/SKILL.md +5 -0
  6. package/catalog/frontmcp-channels/SKILL.md +17 -16
  7. package/catalog/frontmcp-channels/references/channel-sources.md +4 -4
  8. package/catalog/frontmcp-channels/references/channel-two-way.md +1 -1
  9. package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +2 -0
  10. package/catalog/frontmcp-config/examples/configure-session/vercel-kv-session.md +1 -2
  11. package/catalog/frontmcp-config/examples/configure-transport/custom-protocol-flags.md +0 -1
  12. package/catalog/frontmcp-config/examples/configure-transport/distributed-sessions-redis.md +0 -1
  13. package/catalog/frontmcp-config/examples/configure-transport/stateless-serverless.md +2 -3
  14. package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/stateless-api-serverless.md +2 -3
  15. package/catalog/frontmcp-config/references/configure-auth.md +1 -1
  16. package/catalog/frontmcp-config/references/configure-deployment-targets.md +54 -20
  17. package/catalog/frontmcp-config/references/configure-http.md +5 -2
  18. package/catalog/frontmcp-config/references/configure-throttle-guard-config.md +1 -1
  19. package/catalog/frontmcp-config/references/configure-throttle.md +4 -2
  20. package/catalog/frontmcp-config/references/configure-transport.md +4 -5
  21. package/catalog/frontmcp-deployment/SKILL.md +19 -19
  22. package/catalog/frontmcp-deployment/examples/deploy-to-node/docker-compose-with-redis.md +1 -1
  23. package/catalog/frontmcp-deployment/examples/deploy-to-node/pm2-with-nginx.md +1 -1
  24. package/catalog/frontmcp-deployment/references/build-for-browser.md +38 -9
  25. package/catalog/frontmcp-deployment/references/build-for-mcpb.md +15 -9
  26. package/catalog/frontmcp-deployment/references/build-for-sdk.md +2 -1
  27. package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +3 -1
  28. package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +2 -2
  29. package/catalog/frontmcp-deployment/references/deploy-to-node.md +11 -11
  30. package/catalog/frontmcp-deployment/references/mcp-client-integration.md +12 -7
  31. package/catalog/frontmcp-deployment/references/protocol-versions.md +7 -3
  32. package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +50 -10
  33. package/catalog/frontmcp-development/examples/openapi-adapter/ref-security-and-filtering.md +13 -7
  34. package/catalog/frontmcp-development/references/create-adapter.md +14 -0
  35. package/catalog/frontmcp-development/references/create-agent.md +82 -49
  36. package/catalog/frontmcp-development/references/create-plugin-hooks.md +15 -5
  37. package/catalog/frontmcp-development/references/create-plugin.md +8 -4
  38. package/catalog/frontmcp-development/references/create-skill-with-tools.md +7 -2
  39. package/catalog/frontmcp-development/references/create-skill.md +4 -0
  40. package/catalog/frontmcp-development/references/decorators-guide.md +10 -11
  41. package/catalog/frontmcp-development/references/official-adapters.md +1 -1
  42. package/catalog/frontmcp-development/references/official-plugins.md +127 -24
  43. package/catalog/frontmcp-development/references/openapi-adapter.md +52 -2
  44. package/catalog/frontmcp-observability/references/metrics-endpoint.md +3 -1
  45. package/catalog/frontmcp-production-readiness/examples/distributed-ha/ha-kubernetes-3-replicas.md +12 -1
  46. package/catalog/frontmcp-production-readiness/references/common-checklist.md +2 -1
  47. package/catalog/frontmcp-production-readiness/references/distributed-ha.md +48 -28
  48. package/catalog/frontmcp-setup/examples/nx-workflow/build-test-affected.md +2 -2
  49. package/catalog/frontmcp-setup/examples/nx-workflow/multi-server-deployment.md +9 -5
  50. package/catalog/frontmcp-setup/examples/nx-workflow/scaffold-and-generate.md +1 -1
  51. package/catalog/frontmcp-setup/examples/project-structure-nx/nx-generator-scaffolding.md +1 -1
  52. package/catalog/frontmcp-setup/references/frontmcp-skills-usage.md +28 -15
  53. package/catalog/frontmcp-setup/references/multi-app-composition.md +11 -8
  54. package/catalog/frontmcp-setup/references/nx-workflow.md +53 -21
  55. package/catalog/frontmcp-setup/references/project-structure-nx.md +7 -4
  56. package/catalog/frontmcp-setup/references/setup-project.md +15 -0
  57. package/catalog/frontmcp-setup/references/setup-redis.md +12 -3
  58. package/catalog/frontmcp-setup/references/setup-sqlite.md +12 -8
  59. package/catalog/frontmcp-testing/SKILL.md +16 -12
  60. package/catalog/frontmcp-testing/references/setup-testing.md +14 -1
  61. package/catalog/skills-manifest.json +10 -8
  62. package/package.json +1 -1
@@ -167,8 +167,11 @@ nx g @frontmcp/nx:lib shared-utils
167
167
  ## Build and Test Commands
168
168
 
169
169
  ```bash
170
- # Build a specific server
171
- nx build gateway
170
+ # Build a specific server (server projects are named server-<name>)
171
+ nx build server-gateway
172
+
173
+ # Type-check a project
174
+ nx typecheck billing
172
175
 
173
176
  # Test a specific app
174
177
  nx test billing
@@ -233,8 +236,8 @@ Use `nx graph` to visualize the dependency graph and ensure no circular imports
233
236
 
234
237
  ### Build and Test
235
238
 
236
- - [ ] `nx build gateway` (or server name) succeeds without errors
237
- - [ ] `nx test billing` (or app name) passes all tests
239
+ - [ ] `nx build server-gateway` (or `server-<name>`) succeeds without errors
240
+ - [ ] `nx test billing` (or app name) passes all tests; new apps and libraries start with a spec
238
241
  - [ ] `nx run-many -t test` runs all tests across the workspace
239
242
  - [ ] `nx graph` shows no circular dependencies between apps
240
243
 
@@ -404,6 +404,19 @@ frontmcp dev --show-conflict
404
404
  > `http.port: 4000` in metadata makes the child bind to 4000 regardless of
405
405
  > `--port`/`PORT`, so the pre-flight probe becomes advisory only.
406
406
 
407
+ Ctrl+C, or `SIGINT` / `SIGTERM` sent to the `frontmcp dev` process alone
408
+ (`kill <pid>`), stops the whole tree — tsx, the server it forks and the type
409
+ checker — and the command returns once the port is free.
410
+
411
+ `frontmcp dev` and `frontmcp build` work from any subfolder: they find
412
+ `frontmcp.config.*` by walking up and run from its folder, so `entry`,
413
+ `tsconfig.json` and `.env` resolve from the project root.
414
+
415
+ `frontmcp init` edits `tsconfig.json` in place, keeping comments and trailing
416
+ commas; a file that is not valid JSON(C) is reported (line and column) and left
417
+ untouched, never overwritten. So is one that declares an option `init` must set
418
+ more than once — only the last occurrence takes effect, so remove the duplicate.
419
+
407
420
  Test with curl:
408
421
 
409
422
  ```bash
@@ -468,6 +481,8 @@ nx g @frontmcp/nx:app my-app --directory apps/my-app
468
481
  nx g @frontmcp/nx:server my-server --directory servers/my-server
469
482
  ```
470
483
 
484
+ This works in `create-nx-workspace --preset=ts` workspaces too: the generated project `tsconfig.json` compiles CommonJS JavaScript whatever the TS-solution base inherits (`composite`, `emitDeclarationOnly`, `customConditions`), resolving with `node10` on TypeScript 5 and `bundler` on TypeScript 6+, and library path aliases are written as `./libs/<name>/src/index.ts`, which needs no `baseUrl`.
485
+
471
486
  ### 7c. Nx project.json example
472
487
 
473
488
  If manually configuring, add a `project.json`:
@@ -138,6 +138,15 @@ redis: {
138
138
  },
139
139
  ```
140
140
 
141
+ From a single connection URL (what managed Redis providers hand out). It is read into `host` / `port` / `password` / `db` at parse time; `rediss://` sets `tls: true`; the user part must be empty or `default`; percent-encode reserved password characters (`@` as `%40`, `%` as `%25`), since a malformed escape is a validation error:
142
+
143
+ ```typescript
144
+ redis: {
145
+ url: process.env['REDIS_URL'], // redis://:password@host:6379/0 (or rediss:// for TLS)
146
+ keyPrefix: 'mcp:', // optional, as with the other forms
147
+ },
148
+ ```
149
+
141
150
  ### For Vercel KV
142
151
 
143
152
  ```typescript
@@ -313,13 +322,13 @@ You should see session keys like `mcp:session:<session-id>`.
313
322
 
314
323
  Every instance behind the load balancer needs the **same** values:
315
324
 
316
- - `MCP_SESSION_SECRET` -- session ids are encrypted with it. An id minted under a different secret is answered with HTTP 404 and the client re-initializes (every auth mode, including `public`, where the id is the caller's only credential). An anonymous session minted by one instance is honored by any instance with the same secret.
325
+ - `MCP_SESSION_SECRET` -- session ids are encrypted with it. An id minted under a different secret is answered with HTTP 404 and the client re-initializes (every auth mode, including `public`, where the id is the caller's only credential). An anonymous session minted by one instance is honored by any instance with the same secret: the receiving instance recreates the transport from the stored session (in distributed mode it relays the request to the live node that owns the session, or takes the session over from a node that stopped).
317
326
  - `VAULT_SECRET` (or `JWT_SECRET`) -- signs MCP 2026-07-28 `requestState`. Without either, each instance uses a random per-process key and a multi-round tool (`elicit()` / `sample()`) whose next round lands elsewhere asks its first question again. In production, `redis` or `transport.persistence` without either secret logs a startup warning; each rejected round logs `mcp-20260728: rejected requestState` with `reason: 'bad-signature'` and a `hint` naming `VAULT_SECRET`.
318
327
 
319
328
  ### What happens when Redis is down at startup
320
329
 
321
330
  - `redis` and `transport.persistence` fall back to in-memory storage and log the failure (`[TransportService] Failed to connect to redis - session persistence disabled`); the server starts.
322
- - `throttle.storage` fails closed: startup aborts with `GuardStorageUnavailableError` (`throttle.storage (redis) is unavailable: …`), the default in production. If Redis goes away while the server runs, a rate-limited call is refused with the same error, not `Internal FrontMCP error`. Opt in to per-instance counters explicitly (they also cover a mid-run outage):
331
+ - `throttle.storage` fails closed: startup aborts with `GuardStorageUnavailableError` (`throttle.storage (redis) is unavailable: …`), the default in production. If Redis goes away while the server runs, a rate-limited call is refused with the same error, not `Internal FrontMCP error` (HTTP 503 from the `global` check; an `isError` result with `_meta.code: 'GUARD_STORAGE_UNAVAILABLE'` inside `tools/call`). Opt in to per-instance counters explicitly (they also cover a mid-run outage):
323
332
 
324
333
  ```typescript
325
334
  throttle: {
@@ -332,7 +341,7 @@ throttle: {
332
341
  },
333
342
  ```
334
343
 
335
- `throttle.storage` takes the `@frontmcp/utils` storage shape (`{ type: 'redis', redis: { config } }` or `{ type: 'redis', redis: { url } }`), not the top-level `redis` shape.
344
+ `throttle.storage` takes the `@frontmcp/utils` storage shape (`{ type: 'redis', redis: { config } }` or `{ type: 'redis', redis: { url } }`), not the top-level `redis` shape (which takes `{ host, ... }` or `{ url }`).
336
345
 
337
346
  ## Common Patterns
338
347
 
@@ -77,6 +77,9 @@ interface SqliteOptionsInput {
77
77
 
78
78
  /** Interval in ms for purging expired keys (default: 60000) */
79
79
  ttlCleanupIntervalMs?: number;
80
+
81
+ /** Ms to wait for a lock held by another process before SQLITE_BUSY (default: 5000) */
82
+ busyTimeoutMs?: number;
80
83
  }
81
84
  ```
82
85
 
@@ -406,14 +409,15 @@ The change in `src/main.ts`:
406
409
 
407
410
  ## Troubleshooting
408
411
 
409
- | Problem | Cause | Solution |
410
- | --------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
411
- | `Cannot find module 'better-sqlite3'` | Native module not installed | Run `yarn add @frontmcp/storage-sqlite better-sqlite3` |
412
- | `Could not locate the bindings file` | Native compilation failed | Ensure build tools are installed (Xcode CLI on macOS, `build-essential` on Linux), delete `node_modules` and reinstall |
413
- | `SQLITE_BUSY` errors | Multiple processes accessing the same database file | Enable WAL mode (`walMode: true`) or ensure only one process writes to the database |
414
- | `SQLITE_READONLY` | Insufficient file permissions | Check write permissions on the database file and its parent directory |
415
- | WAL errors on network mount | WAL mode requires a local filesystem with shared-memory support | Move the database to a local disk or set `walMode: false` |
416
- | Encrypted data unreadable after restart | Encryption secret changed or missing | The secret must be identical across restarts; if the original secret is lost, delete the database and let it be recreated |
412
+ | Problem | Cause | Solution |
413
+ | --------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
414
+ | `Cannot find module 'better-sqlite3'` | Native module not installed | Run `yarn add @frontmcp/storage-sqlite better-sqlite3` |
415
+ | `Could not locate the bindings file` | Native compilation failed | Ensure build tools are installed (Xcode CLI on macOS, `build-essential` on Linux), delete `node_modules` and reinstall |
416
+ | `SQLITE_BUSY` errors | Multiple processes accessing the same database file | Enable WAL mode (`walMode: true`), raise `busyTimeoutMs` (default 5000), or ensure only one process writes to the database |
417
+ | `Failed to persist session to SQLite` | A session write waited longer than `busyTimeoutMs` for the lock | Raise `busyTimeoutMs`, or use Redis for many writer processes |
418
+ | `SQLITE_READONLY` | Insufficient file permissions | Check write permissions on the database file and its parent directory |
419
+ | WAL errors on network mount | WAL mode requires a local filesystem with shared-memory support | Move the database to a local disk or set `walMode: false` |
420
+ | Encrypted data unreadable after restart | Encryption secret changed or missing | The secret must be identical across restarts; if the original secret is lost, delete the database and let it be recreated |
417
421
 
418
422
  ## Examples
419
423
 
@@ -146,18 +146,22 @@ This is a router skill. Follow this order to pick a testing approach, then move
146
146
 
147
147
  ## Troubleshooting
148
148
 
149
- | Problem | Cause | Solution |
150
- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
151
- | Jest not finding test files | Wrong file extension (`.test.ts` instead of `.spec.ts`) | Rename to `.spec.ts`; check `testMatch` in jest.config |
152
- | `SyntaxError: Unexpected token 'export'` | An ESM-only dependency is being ignored instead of transpiled | Add it to `test.esmPackages` in `frontmcp.config.ts`. With a hand-written `jest.config.ts`, use the pnpm-safe `transformIgnorePatterns` in [`setup-testing`](./references/setup-testing.md#jest-configuration) AND make sure `transform` matches `.js` (`^.+\.[tj]sx?$` + `allowJs`) — un-ignoring a file does nothing if no transform matches it |
153
- | Coverage below 95% | Untested error paths or conditional branches | Run `frontmcp test --coverage` and inspect uncovered lines in the report |
154
- | E2E test timeout | Server startup too slow or port conflict | Increase Jest timeout; use random port allocation |
155
- | DI resolution fails in tests | Provider not registered in test scope | Register mock providers before creating the test context |
156
- | Istanbul shows 0% on async methods | TypeScript source-map mismatch with Istanbul | Known issue with some TS compilation settings; verify coverage with actual test output |
157
- | Specs see no `.env` values | An older CLI did not load `.env` for `frontmcp test`, only for `dev` | Upgrade the CLI — `frontmcp test` now loads `.env` / `.env.local` with the same precedence as `dev` (real environment wins, so CI secrets still override). Pass `--no-env` for a hermetic run |
158
- | `Invalid first argument, true` at collection time | `test.skip(condition, reason)` reached Jest's `skip(name, fn)` | Upgrade the CLI — the Playwright signature is supported: `test.skip(!hasCredentials, 'credentials not set')` skips every test registered after it in the enclosing block |
159
- | `test.use()` in one `describe` leaks into another, or two files fight over a port | Older `@frontmcp/testing` kept one global config and per-process ports | Upgrade — `test.use()` is scoped per `describe` and ports are locked across Jest workers; use `port: 0` |
160
- | Every spec fails with `HTTP 404` after setting `http.entryPath` | The test client always connected to the server root | Upgrade the CLI — the client now follows the `entryPaths` a 404 reports, and `test.use({ entryPath: '/mcp' })` sets it explicitly |
149
+ | Problem | Cause | Solution |
150
+ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
151
+ | Jest not finding test files | Wrong file extension (`.test.ts` instead of `.spec.ts`) | Rename to `.spec.ts`; check `testMatch` in jest.config |
152
+ | `SyntaxError: Unexpected token 'export'` | An ESM-only dependency is being ignored instead of transpiled | Add it to `test.esmPackages` in `frontmcp.config.ts`. With a hand-written `jest.config.ts`, use the pnpm-safe `transformIgnorePatterns` in [`setup-testing`](./references/setup-testing.md#jest-configuration) AND make sure `transform` matches `.js` (`^.+\.[tj]sx?$` + `allowJs`) — un-ignoring a file does nothing if no transform matches it |
153
+ | Coverage below 95% | Untested error paths or conditional branches | Run `frontmcp test --coverage` and inspect uncovered lines in the report |
154
+ | E2E test timeout | Server startup too slow or port conflict | Increase Jest timeout; use random port allocation |
155
+ | DI resolution fails in tests | Provider not registered in test scope | Register mock providers before creating the test context |
156
+ | Istanbul shows 0% on async methods | TypeScript source-map mismatch with Istanbul | Known issue with some TS compilation settings; verify coverage with actual test output |
157
+ | Specs see no `.env` values | An older CLI did not load `.env` for `frontmcp test`, only for `dev` | Upgrade the CLI — `frontmcp test` now loads `.env` / `.env.local` with the same precedence as `dev` (real environment wins, so CI secrets still override). Pass `--no-env` for a hermetic run |
158
+ | `Invalid first argument, true` at collection time | `test.skip(condition, reason)` reached Jest's `skip(name, fn)` | Upgrade the CLI — the Playwright signature is supported: `test.skip(!hasCredentials, 'credentials not set')` skips every test registered after it in the enclosing block |
159
+ | `test.use()` in one `describe` leaks into another, or two files fight over a port | Older `@frontmcp/testing` kept one global config and per-process ports | Upgrade — `test.use()` is scoped per `describe` and ports are locked across Jest workers; use `port: 0` |
160
+ | Every spec fails with `HTTP 404` after setting `http.entryPath` | The test client always connected to the server root | Upgrade the CLI — the client now follows the `entryPaths` a 404 reports, and `test.use({ entryPath: '/mcp' })` sets it explicitly |
161
+ | `test.beforeEach(async ({ mcp }) => …)` times out waiting for `done` | Older `@frontmcp/testing` handed the hook to Jest, which read the parameter as `done` | Upgrade — hooks that take a parameter now receive the test's fixtures (same `mcp` as the test); `beforeAll` / `afterAll` never get fixtures |
162
+ | `test.use({ transport: 'sse' })` throws "SSE transport not yet implemented" | Older `@frontmcp/testing` had no legacy SSE client | Upgrade — `'sse'` is the legacy HTTP+SSE transport; the server must enable it with `transport: { protocol: { legacy: true } }` |
163
+ | `Module @swc/jest in the transform option was not found` from `frontmcp test` | Older `@frontmcp/testing` did not install the transformer the injected config uses | Upgrade — `@frontmcp/testing` depends on `@swc/jest` / `@swc/core`, and `frontmcp test` resolves the transformer through it |
164
+ | `ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG` from a server started inside a spec | Older SDKs loaded the optional `vectoriadb` with `import()` at boot | Upgrade the SDK — `vectoriadb` loads on the first skill search, through `require` where available; no `--experimental-vm-modules` needed |
161
165
 
162
166
  ## Examples
163
167
 
@@ -399,6 +399,16 @@ You usually do not need to set this: when the client's first request 404s and th
399
399
  ### Scoping config, parameterised tests, ports and restarts
400
400
 
401
401
  - `test.use()` is scoped to the `describe` block it is called in. Nested blocks merge over outer ones (`env` key by key); each distinct configuration gets its own server, stopped by the block that configured it. At file level it applies to the whole file.
402
+ - The `env` object is read when the server starts, so a `beforeAll` may fill in values known only later (e.g. the port of an upstream `TestServer` it started).
403
+ - `test.beforeEach` / `test.afterEach` callbacks that take a parameter get the test's fixtures, Playwright-style — the **same** `mcp` / `server` / `auth` as the test. `beforeEach` runs outer blocks first, `afterEach` inner blocks first, and fixtures are torn down after the last `afterEach`. A callback without parameters is a plain Jest hook; `test.beforeAll` / `test.afterAll` never receive fixtures. Jest's `done` style is not supported on `test.beforeEach` / `test.afterEach`.
404
+
405
+ ```typescript
406
+ test.beforeEach(async ({ mcp }) => {
407
+ await mcp.tools.call('reset_state', {});
408
+ });
409
+ ```
410
+
411
+ - `transport: 'sse'` (in `test.use()` or `server.createClient()`) uses the legacy HTTP+SSE transport: `GET <entryPath>/sse`, messages POSTed to the endpoint the server names, responses read from the stream. The server must enable it (`transport: { protocol: { legacy: true } }`); otherwise connecting fails with the HTTP status.
402
412
  - `port: 0` (or omitting `port`) picks any free port. Ports are reserved with a cross-process lock, so parallel Jest workers do not collide.
403
413
  - `auth: { mode, type }` reaches the server process as `FRONTMCP_TEST_AUTH_MODE` / `FRONTMCP_TEST_AUTH_TYPE`; `mode: 'public'` also keeps the `mcp` client anonymous.
404
414
  - `test.each` / `test.describe.each` pass the row values to the callback (fixtures first for `test.each`):
@@ -518,7 +528,10 @@ In standalone projects driven by `frontmcp test`, prefer `test.esmPackages` in
518
528
  `frontmcp.config.ts` — the injected config already carries the pattern above,
519
529
  and already transpiles `jose`, `@noble/hashes` and `@noble/ciphers` (CodeCall).
520
530
  `frontmcp test` does not set `NODE_OPTIONS=--experimental-vm-modules` (it would make Jest
521
- load ESM natively and bypass these transforms); use Jest 30 (what `frontmcp create` scaffolds):
531
+ load ESM natively and bypass these transforms); use Jest 30 (what `frontmcp create` scaffolds).
532
+ A server created inside the test process (`FrontMcpInstance.createHandler()`, `createDirect()`,
533
+ `create()`) works without the flag too. `@frontmcp/testing` brings `@swc/jest` and `@swc/core`, so a
534
+ bare project needs only `@frontmcp/testing` and `jest` installed:
522
535
 
523
536
  ```typescript
524
537
  // frontmcp.config.ts
@@ -998,7 +998,7 @@
998
998
  "features": [
999
999
  "The `'stateless-api'` preset disables SSE, streaming, and sessions entirely",
1000
1000
  "Each request is standalone with no server-side state",
1001
- "Pair with `sessionMode: 'stateless'` for serverless execution",
1001
+ "No `sessionMode` needed: sessions follow the protocol preset",
1002
1002
  "Required for Vercel, Lambda, Cloudflare Workers where persistent connections are not allowed"
1003
1003
  ]
1004
1004
  }
@@ -1040,7 +1040,7 @@
1040
1040
  "level": "basic",
1041
1041
  "tags": ["config", "vercel", "lambda", "cloudflare", "session", "transport"],
1042
1042
  "features": [
1043
- "Using `sessionMode: 'stateless'` to disable session management",
1043
+ "Serving without sessions: whether the server keeps sessions follows `transport.protocol` (`sessionMode` has no effect)",
1044
1044
  "Using the `'stateless-api'` preset: no SSE, no streaming, pure request/response",
1045
1045
  "Each request is standalone with no server-side state between invocations",
1046
1046
  "Required for serverless targets (Vercel, Lambda, Cloudflare Workers)"
@@ -1619,13 +1619,15 @@
1619
1619
  },
1620
1620
  {
1621
1621
  "name": "nested-agents-with-swarm",
1622
- "description": "Composing specialized agents into a swarm where an orchestrator can discover and call peers at runtime as `use-agent:<id>` tools. Routing is driven by the orchestrator's LLM, not a declarative handoff table.",
1622
+ "description": "Composing specialized agents into a swarm where an orchestrator can discover and call peers at runtime as `invoke_<id>` tools, plus a nested sub-agent and `this.invokeAgent()`. Routing is driven by the orchestrator's LLM, not a declarative handoff table.",
1623
1623
  "level": "advanced",
1624
1624
  "tags": ["development", "agent", "nested", "agents", "swarm"],
1625
1625
  "features": [
1626
- "Setting `swarm: { canSeeOtherAgents: true, visibleAgents: [...] }` on the orchestrator so peers appear as `use-agent:*` tools",
1626
+ "Setting `swarm: { canSeeOtherAgents: true, visibleAgents: [...] }` on the orchestrator so peers are offered to its model as `invoke_*` tools",
1627
1627
  "Setting `swarm: { isVisible: true }` (the default) on specialist peers so they can be called",
1628
- "Routing is driven by the orchestrator LLM choosing among `use-agent:<peer>` tools, not by a declarative handoff table",
1628
+ "Routing is driven by the orchestrator LLM choosing among `invoke_<peer>` tools, not by a declarative handoff table",
1629
+ "A nested sub-agent (`agents: [...]`) private to the orchestrator, called from code with `this.invokeAgent()`",
1630
+ "`swarm.maxCallDepth` bounding how deep agents may call each other",
1629
1631
  "Each agent has its own `llm` config, `tools`, and `systemInstructions` for specialization"
1630
1632
  ]
1631
1633
  }
@@ -2061,7 +2063,7 @@
2061
2063
  },
2062
2064
  {
2063
2065
  "name": "official-plugins",
2064
- "description": "Guide to the 6 official plugins for discovery, memory, auth, caching, flags, and monitoring",
2066
+ "description": "Guide to the 7 official plugins for discovery, memory, auth, caching, flags, monitoring, and WebMCP",
2065
2067
  "examples": [
2066
2068
  {
2067
2069
  "name": "cache-and-feature-flags",
@@ -2173,7 +2175,7 @@
2173
2175
  "Secure defaults: external `$ref` resolution off, spec-URL redirects not followed, internal/private targets blocked (DNS-resolved) \u2014 on `mcp-from-openapi` >= 2.5.0",
2174
2176
  "Opting back into external refs with `allowedProtocols`, and restricting the spec URL + `$ref`s with `allowedHosts`",
2175
2177
  "Using `allowInternalIPs` for trusted internal/local targets (governs the spec URL and `$ref`s)",
2176
- "Filtering operations with `includeOperations`, `excludeOperations`, and `filterFn`",
2178
+ "Filtering operations with `readOnlyOnly`, `includeTags`, `includePaths`, `excludeMethods`, `includeOperations`, `excludeOperations`, and `filterFn`",
2177
2179
  "Combining security hardening with operation filtering for a production-ready setup"
2178
2180
  ]
2179
2181
  }
@@ -2474,7 +2476,7 @@
2474
2476
  },
2475
2477
  {
2476
2478
  "name": "distributed-ha",
2477
- "description": "Deploy FrontMCP across multiple pods with heartbeat, session takeover, and notification relay for zero-downtime failover",
2479
+ "description": "Deploy FrontMCP across multiple pods with heartbeat, cross-pod request relay, session takeover, and notification relay for zero-downtime failover",
2478
2480
  "examples": [
2479
2481
  {
2480
2482
  "name": "ha-kubernetes-3-replicas",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/skills",
3
- "version": "1.8.7",
3
+ "version": "1.9.0",
4
4
  "description": "Curated skills catalog for FrontMCP projects",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "homepage": "https://docs.agentfront.dev",