@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.
- package/README.md +107 -155
- package/catalog/create-tool/examples/21-tool-with-availability-constraints.md +1 -1
- package/catalog/create-tool/references/availability.md +10 -10
- package/catalog/create-tool/references/ui-widgets.md +30 -8
- package/catalog/frontmcp-authorities/SKILL.md +5 -0
- package/catalog/frontmcp-channels/SKILL.md +17 -16
- package/catalog/frontmcp-channels/references/channel-sources.md +4 -4
- package/catalog/frontmcp-channels/references/channel-two-way.md +1 -1
- package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +2 -0
- package/catalog/frontmcp-config/examples/configure-session/vercel-kv-session.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport/custom-protocol-flags.md +0 -1
- package/catalog/frontmcp-config/examples/configure-transport/distributed-sessions-redis.md +0 -1
- package/catalog/frontmcp-config/examples/configure-transport/stateless-serverless.md +2 -3
- package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/stateless-api-serverless.md +2 -3
- package/catalog/frontmcp-config/references/configure-auth.md +1 -1
- package/catalog/frontmcp-config/references/configure-deployment-targets.md +54 -20
- package/catalog/frontmcp-config/references/configure-http.md +5 -2
- package/catalog/frontmcp-config/references/configure-throttle-guard-config.md +1 -1
- package/catalog/frontmcp-config/references/configure-throttle.md +4 -2
- package/catalog/frontmcp-config/references/configure-transport.md +4 -5
- package/catalog/frontmcp-deployment/SKILL.md +19 -19
- package/catalog/frontmcp-deployment/examples/deploy-to-node/docker-compose-with-redis.md +1 -1
- package/catalog/frontmcp-deployment/examples/deploy-to-node/pm2-with-nginx.md +1 -1
- package/catalog/frontmcp-deployment/references/build-for-browser.md +38 -9
- package/catalog/frontmcp-deployment/references/build-for-mcpb.md +15 -9
- package/catalog/frontmcp-deployment/references/build-for-sdk.md +2 -1
- package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +3 -1
- package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +2 -2
- package/catalog/frontmcp-deployment/references/deploy-to-node.md +11 -11
- package/catalog/frontmcp-deployment/references/mcp-client-integration.md +12 -7
- package/catalog/frontmcp-deployment/references/protocol-versions.md +7 -3
- package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +50 -10
- package/catalog/frontmcp-development/examples/openapi-adapter/ref-security-and-filtering.md +13 -7
- package/catalog/frontmcp-development/references/create-adapter.md +14 -0
- package/catalog/frontmcp-development/references/create-agent.md +82 -49
- package/catalog/frontmcp-development/references/create-plugin-hooks.md +15 -5
- package/catalog/frontmcp-development/references/create-plugin.md +8 -4
- package/catalog/frontmcp-development/references/create-skill-with-tools.md +7 -2
- package/catalog/frontmcp-development/references/create-skill.md +4 -0
- package/catalog/frontmcp-development/references/decorators-guide.md +10 -11
- package/catalog/frontmcp-development/references/official-adapters.md +1 -1
- package/catalog/frontmcp-development/references/official-plugins.md +127 -24
- package/catalog/frontmcp-development/references/openapi-adapter.md +52 -2
- package/catalog/frontmcp-observability/references/metrics-endpoint.md +3 -1
- package/catalog/frontmcp-production-readiness/examples/distributed-ha/ha-kubernetes-3-replicas.md +12 -1
- package/catalog/frontmcp-production-readiness/references/common-checklist.md +2 -1
- package/catalog/frontmcp-production-readiness/references/distributed-ha.md +48 -28
- package/catalog/frontmcp-setup/examples/nx-workflow/build-test-affected.md +2 -2
- package/catalog/frontmcp-setup/examples/nx-workflow/multi-server-deployment.md +9 -5
- package/catalog/frontmcp-setup/examples/nx-workflow/scaffold-and-generate.md +1 -1
- package/catalog/frontmcp-setup/examples/project-structure-nx/nx-generator-scaffolding.md +1 -1
- package/catalog/frontmcp-setup/references/frontmcp-skills-usage.md +28 -15
- package/catalog/frontmcp-setup/references/multi-app-composition.md +11 -8
- package/catalog/frontmcp-setup/references/nx-workflow.md +53 -21
- package/catalog/frontmcp-setup/references/project-structure-nx.md +7 -4
- package/catalog/frontmcp-setup/references/setup-project.md +15 -0
- package/catalog/frontmcp-setup/references/setup-redis.md +12 -3
- package/catalog/frontmcp-setup/references/setup-sqlite.md +12 -8
- package/catalog/frontmcp-testing/SKILL.md +16 -12
- package/catalog/frontmcp-testing/references/setup-testing.md +14 -1
- package/catalog/skills-manifest.json +10 -8
- 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
|
|
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
|
|
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
|
-
| `
|
|
415
|
-
|
|
|
416
|
-
|
|
|
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
|
|
150
|
-
| --------------------------------------------------------------------------------- |
|
|
151
|
-
| Jest not finding test files | Wrong file extension (`.test.ts` instead of `.spec.ts`)
|
|
152
|
-
| `SyntaxError: Unexpected token 'export'` | An ESM-only dependency is being ignored instead of transpiled
|
|
153
|
-
| Coverage below 95% | Untested error paths or conditional branches
|
|
154
|
-
| E2E test timeout | Server startup too slow or port conflict
|
|
155
|
-
| DI resolution fails in tests | Provider not registered in test scope
|
|
156
|
-
| Istanbul shows 0% on async methods | TypeScript source-map mismatch with Istanbul
|
|
157
|
-
| Specs see no `.env` values | An older CLI did not load `.env` for `frontmcp test`, only for `dev`
|
|
158
|
-
| `Invalid first argument, true` at collection time | `test.skip(condition, reason)` reached Jest's `skip(name, fn)`
|
|
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
|
|
160
|
-
| Every spec fails with `HTTP 404` after setting `http.entryPath` | The test client always connected to the server root
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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 `
|
|
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
|
|
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 `
|
|
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
|
|
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",
|