@frontmcp/skills 1.1.2 → 1.2.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 (176) hide show
  1. package/catalog/TEMPLATE.md +16 -11
  2. package/catalog/frontmcp-authorities/SKILL.md +116 -11
  3. package/catalog/frontmcp-authorities/references/authority-profiles.md +39 -36
  4. package/catalog/frontmcp-authorities/references/claims-mapping.md +7 -0
  5. package/catalog/frontmcp-authorities/references/custom-evaluators.md +63 -14
  6. package/catalog/frontmcp-channels/SKILL.md +36 -0
  7. package/catalog/frontmcp-channels/examples/channel-sources/file-watcher.md +8 -2
  8. package/catalog/frontmcp-channels/examples/channel-sources/replay-buffer.md +111 -30
  9. package/catalog/frontmcp-channels/examples/channel-two-way/whatsapp-bridge.md +45 -3
  10. package/catalog/frontmcp-channels/references/channel-sources.md +11 -3
  11. package/catalog/frontmcp-channels/references/channel-two-way.md +60 -89
  12. package/catalog/frontmcp-config/SKILL.md +111 -8
  13. package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +4 -4
  14. package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +7 -1
  15. package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +1 -1
  16. package/catalog/frontmcp-config/examples/configure-deployment-targets/json-schema-ide-support.md +1 -1
  17. package/catalog/frontmcp-config/examples/configure-deployment-targets/multi-target-with-security.md +12 -9
  18. package/catalog/frontmcp-config/examples/configure-http/cors-restricted-origins.md +2 -2
  19. package/catalog/frontmcp-config/examples/configure-http/entry-path-reverse-proxy.md +1 -1
  20. package/catalog/frontmcp-config/examples/configure-security-headers/csp-report-only.md +1 -1
  21. package/catalog/frontmcp-config/examples/configure-security-headers/full-production-headers.md +1 -1
  22. package/catalog/frontmcp-config/examples/configure-skills-http/audit-log-basic.md +76 -0
  23. package/catalog/frontmcp-config/examples/configure-skills-http/audit-log-redis.md +116 -0
  24. package/catalog/frontmcp-config/examples/configure-skills-http/inject-instructions.md +59 -0
  25. package/catalog/frontmcp-config/references/configure-auth-modes.md +5 -5
  26. package/catalog/frontmcp-config/references/configure-deployment-targets.md +27 -24
  27. package/catalog/frontmcp-config/references/configure-http.md +14 -10
  28. package/catalog/frontmcp-config/references/configure-security-headers.md +2 -2
  29. package/catalog/frontmcp-config/references/configure-session.md +25 -25
  30. package/catalog/frontmcp-config/references/configure-skills-http.md +157 -0
  31. package/catalog/frontmcp-config/references/configure-throttle.md +1 -1
  32. package/catalog/frontmcp-config/references/configure-transport.md +2 -2
  33. package/catalog/frontmcp-deployment/SKILL.md +112 -9
  34. package/catalog/frontmcp-deployment/examples/build-for-browser/browser-build-with-custom-entry.md +23 -11
  35. package/catalog/frontmcp-deployment/examples/build-for-browser/browser-crypto-and-storage.md +44 -17
  36. package/catalog/frontmcp-deployment/examples/build-for-browser/react-provider-setup.md +53 -21
  37. package/catalog/frontmcp-deployment/examples/build-for-cli/cli-binary-build.md +1 -1
  38. package/catalog/frontmcp-deployment/examples/build-for-cli/unix-socket-daemon.md +1 -1
  39. package/catalog/frontmcp-deployment/examples/build-for-mcpb/mcpb-bundle-build.md +1 -1
  40. package/catalog/frontmcp-deployment/examples/build-for-sdk/connect-openai.md +1 -1
  41. package/catalog/frontmcp-deployment/examples/build-for-sdk/multi-platform-connect.md +1 -1
  42. package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/basic-worker-deploy.md +7 -8
  43. package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-custom-domain.md +8 -6
  44. package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-with-kv-storage.md +5 -4
  45. package/catalog/frontmcp-deployment/examples/deploy-to-lambda/cdk-deployment.md +8 -5
  46. package/catalog/frontmcp-deployment/examples/deploy-to-lambda/lambda-handler-with-cors.md +20 -18
  47. package/catalog/frontmcp-deployment/examples/deploy-to-lambda/sam-template-basic.md +8 -5
  48. package/catalog/frontmcp-deployment/examples/deploy-to-node/docker-compose-with-redis.md +3 -3
  49. package/catalog/frontmcp-deployment/examples/deploy-to-node/pm2-with-nginx.md +1 -1
  50. package/catalog/frontmcp-deployment/examples/deploy-to-node/resource-limits.md +2 -2
  51. package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/basic-multistage-dockerfile.md +2 -2
  52. package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/secure-nonroot-dockerfile.md +1 -1
  53. package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-mcp-endpoint-test.md +23 -21
  54. package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +25 -22
  55. package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-skills-cache.md +23 -30
  56. package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/minimal-vercel-config.md +52 -28
  57. package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/vercel-config-with-security-headers.md +32 -55
  58. package/catalog/frontmcp-deployment/examples/mcp-client-integration/http-remote.md +9 -0
  59. package/catalog/frontmcp-deployment/references/build-for-browser.md +40 -17
  60. package/catalog/frontmcp-deployment/references/build-for-cli.md +8 -8
  61. package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +43 -24
  62. package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +36 -25
  63. package/catalog/frontmcp-deployment/references/deploy-to-node-dockerfile.md +56 -14
  64. package/catalog/frontmcp-deployment/references/deploy-to-node.md +9 -6
  65. package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +57 -58
  66. package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +49 -59
  67. package/catalog/frontmcp-deployment/references/mcp-client-integration.md +2 -0
  68. package/catalog/frontmcp-development/SKILL.md +186 -11
  69. package/catalog/frontmcp-development/examples/create-agent/custom-multi-pass-agent.md +1 -1
  70. package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +30 -27
  71. package/catalog/frontmcp-development/examples/create-job/job-with-permissions.md +13 -8
  72. package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +33 -23
  73. package/catalog/frontmcp-development/examples/create-provider/config-and-api-providers.md +19 -10
  74. package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +3 -3
  75. package/catalog/frontmcp-development/examples/create-workflow/webhook-triggered-workflow.md +6 -4
  76. package/catalog/frontmcp-development/examples/decorators-guide/agent-skill-job-workflow.md +1 -1
  77. package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md +13 -8
  78. package/catalog/frontmcp-development/examples/decorators-guide/multi-app-with-plugins-and-providers.md +50 -23
  79. package/catalog/frontmcp-development/references/create-agent.md +47 -30
  80. package/catalog/frontmcp-development/references/create-job.md +69 -54
  81. package/catalog/frontmcp-development/references/create-plugin-hooks.md +45 -28
  82. package/catalog/frontmcp-development/references/create-plugin.md +10 -8
  83. package/catalog/frontmcp-development/references/create-prompt.md +3 -3
  84. package/catalog/frontmcp-development/references/create-provider.md +91 -51
  85. package/catalog/frontmcp-development/references/create-resource.md +3 -3
  86. package/catalog/frontmcp-development/references/create-skill.md +2 -2
  87. package/catalog/frontmcp-development/references/create-tool.md +7 -7
  88. package/catalog/frontmcp-development/references/create-workflow.md +8 -10
  89. package/catalog/frontmcp-development/references/decorators-guide.md +92 -56
  90. package/catalog/frontmcp-development/references/official-plugins.md +4 -3
  91. package/catalog/frontmcp-development/references/openapi-adapter.md +1 -1
  92. package/catalog/frontmcp-extensibility/SKILL.md +70 -10
  93. package/catalog/frontmcp-extensibility/examples/skill-audit-log/custom-store.md +197 -0
  94. package/catalog/frontmcp-extensibility/examples/skill-audit-log/verify-chain.md +68 -0
  95. package/catalog/frontmcp-extensibility/examples/vectoriadb/product-catalog-search.md +3 -5
  96. package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md +4 -11
  97. package/catalog/frontmcp-extensibility/examples/vectoriadb/tfidf-keyword-search.md +41 -30
  98. package/catalog/frontmcp-extensibility/references/skill-audit-log.md +233 -0
  99. package/catalog/frontmcp-extensibility/references/vectoriadb.md +73 -63
  100. package/catalog/frontmcp-guides/SKILL.md +84 -27
  101. package/catalog/frontmcp-guides/examples/example-knowledge-base/agent-and-plugin.md +72 -62
  102. package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md +32 -43
  103. package/catalog/frontmcp-guides/examples/example-task-manager/auth-and-crud-tools.md +24 -17
  104. package/catalog/frontmcp-guides/examples/example-task-manager/authenticated-e2e-tests.md +23 -21
  105. package/catalog/frontmcp-guides/examples/example-task-manager/redis-provider-with-di.md +47 -39
  106. package/catalog/frontmcp-guides/examples/example-weather-api/server-and-app-setup.md +16 -6
  107. package/catalog/frontmcp-guides/examples/example-weather-api/unit-and-e2e-tests.md +9 -8
  108. package/catalog/frontmcp-guides/references/example-knowledge-base.md +192 -265
  109. package/catalog/frontmcp-guides/references/example-task-manager.md +60 -54
  110. package/catalog/frontmcp-guides/references/example-weather-api.md +22 -24
  111. package/catalog/frontmcp-observability/SKILL.md +66 -2
  112. package/catalog/frontmcp-observability/examples/telemetry-api/skill-counters.md +100 -0
  113. package/catalog/frontmcp-observability/examples/tracing-setup/production-tracing.md +7 -2
  114. package/catalog/frontmcp-observability/examples/vendor-integrations/coralogix-setup.md +6 -2
  115. package/catalog/frontmcp-observability/references/telemetry-api.md +72 -8
  116. package/catalog/frontmcp-observability/references/testing-observability.md +33 -49
  117. package/catalog/frontmcp-observability/references/tracing-setup.md +12 -5
  118. package/catalog/frontmcp-observability/references/vendor-integrations.md +46 -1
  119. package/catalog/frontmcp-production-readiness/SKILL.md +134 -3
  120. package/catalog/frontmcp-production-readiness/examples/common-checklist/caching-and-performance.md +57 -36
  121. package/catalog/frontmcp-production-readiness/examples/common-checklist/observability-setup.md +1 -1
  122. package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +102 -6
  123. package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/daemon-socket-config.md +2 -1
  124. package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/graceful-shutdown-cleanup.md +66 -58
  125. package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/security-and-permissions.md +5 -3
  126. package/catalog/frontmcp-production-readiness/examples/production-cloudflare/durable-objects-state.md +2 -1
  127. package/catalog/frontmcp-production-readiness/examples/production-cloudflare/wrangler-config.md +55 -76
  128. package/catalog/frontmcp-production-readiness/examples/production-lambda/cold-start-connection-reuse.md +43 -40
  129. package/catalog/frontmcp-production-readiness/examples/production-lambda/sam-template.md +63 -94
  130. package/catalog/frontmcp-production-readiness/examples/production-lambda/scaling-and-monitoring.md +28 -18
  131. package/catalog/frontmcp-production-readiness/examples/production-node-sdk/multi-instance-cleanup.md +29 -14
  132. package/catalog/frontmcp-production-readiness/examples/production-node-server/graceful-shutdown.md +58 -42
  133. package/catalog/frontmcp-production-readiness/examples/production-node-server/redis-session-scaling.md +5 -2
  134. package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md +41 -24
  135. package/catalog/frontmcp-production-readiness/examples/production-vercel/vercel-edge-config.md +56 -65
  136. package/catalog/frontmcp-production-readiness/references/common-checklist.md +17 -5
  137. package/catalog/frontmcp-production-readiness/references/production-cli-daemon.md +5 -5
  138. package/catalog/frontmcp-production-readiness/references/production-cloudflare.md +5 -5
  139. package/catalog/frontmcp-production-readiness/references/production-lambda.md +5 -5
  140. package/catalog/frontmcp-production-readiness/references/production-node-sdk.md +5 -5
  141. package/catalog/frontmcp-production-readiness/references/production-node-server.md +1 -1
  142. package/catalog/frontmcp-production-readiness/references/production-vercel.md +5 -5
  143. package/catalog/frontmcp-setup/SKILL.md +88 -0
  144. package/catalog/frontmcp-setup/examples/project-structure-nx/nx-workspace-with-apps.md +10 -4
  145. package/catalog/frontmcp-setup/examples/project-structure-standalone/dev-workflow-commands.md +21 -8
  146. package/catalog/frontmcp-setup/examples/readme-guide/node-server-readme.md +3 -3
  147. package/catalog/frontmcp-setup/references/multi-app-composition.md +4 -3
  148. package/catalog/frontmcp-setup/references/project-structure-nx.md +15 -6
  149. package/catalog/frontmcp-setup/references/project-structure-standalone.md +18 -15
  150. package/catalog/frontmcp-setup/references/readme-guide.md +1 -1
  151. package/catalog/frontmcp-setup/references/setup-project.md +19 -5
  152. package/catalog/frontmcp-setup/references/setup-redis.md +27 -39
  153. package/catalog/frontmcp-setup/references/setup-sqlite.md +25 -18
  154. package/catalog/frontmcp-testing/SKILL.md +102 -15
  155. package/catalog/frontmcp-testing/examples/setup-testing/unit-test-tool-resource-prompt.md +3 -3
  156. package/catalog/frontmcp-testing/examples/test-auth/oauth-flow-test.md +50 -39
  157. package/catalog/frontmcp-testing/examples/test-auth/role-based-access-test.md +52 -29
  158. package/catalog/frontmcp-testing/examples/test-auth/token-factory-test.md +37 -20
  159. package/catalog/frontmcp-testing/examples/test-direct-client/basic-create-test.md +25 -15
  160. package/catalog/frontmcp-testing/examples/test-direct-client/openai-claude-format-test.md +27 -21
  161. package/catalog/frontmcp-testing/examples/test-e2e-handler/basic-e2e-test.md +29 -20
  162. package/catalog/frontmcp-testing/examples/test-e2e-handler/manual-client-with-transport.md +5 -3
  163. package/catalog/frontmcp-testing/examples/test-e2e-handler/tool-call-and-error-e2e.md +35 -26
  164. package/catalog/frontmcp-testing/examples/test-tool-unit/basic-tool-test.md +8 -3
  165. package/catalog/frontmcp-testing/examples/test-tool-unit/schema-validation-test.md +4 -1
  166. package/catalog/frontmcp-testing/examples/test-tool-unit/tool-error-handling-test.md +6 -3
  167. package/catalog/frontmcp-testing/references/setup-testing.md +35 -39
  168. package/catalog/frontmcp-testing/references/test-auth.md +86 -43
  169. package/catalog/frontmcp-testing/references/test-browser-build.md +1 -1
  170. package/catalog/frontmcp-testing/references/test-direct-client.md +29 -19
  171. package/catalog/frontmcp-testing/references/test-e2e-handler.md +31 -19
  172. package/catalog/frontmcp-testing/references/test-tool-unit.md +6 -2
  173. package/catalog/skills-manifest.json +428 -339
  174. package/package.json +1 -1
  175. package/src/manifest.d.ts +13 -0
  176. package/src/manifest.js.map +1 -1
@@ -2,57 +2,82 @@
2
2
  name: caching-and-performance
3
3
  reference: common-checklist
4
4
  level: advanced
5
- description: 'Shows how to configure caching with TTL, optimize responses, and manage memory with proper provider lifecycle cleanup.'
6
- tags: [production, redis, cache, session, performance, checklist]
5
+ description: Shows how to configure caching with the real `CachePlugin.init(...)` API and how to size connection pools so the server does not exhaust downstream resources.
6
+ tags:
7
+ - production
8
+ - redis
9
+ - cache
10
+ - session
11
+ - performance
12
+ - checklist
7
13
  features:
8
- - 'Configuring per-tool cache TTL instead of a single global value'
9
- - 'Using Redis-backed cache for multi-instance consistency'
10
- - 'Setting session TTL to prevent unbounded storage growth'
11
- - 'Implementing `onDestroy()` in providers for proper connection cleanup'
12
- - 'Using connection pool limits and timeouts to prevent resource exhaustion'
14
+ - 'Using the real `CachePlugin.init({ type, defaultTTL, toolPatterns })` shape (NOT `new CachePlugin({ ttl: { ... } })`)'
15
+ - 'Setting per-tool TTL via `@Tool({ cache: { ttl } })` metadata in seconds'
16
+ - Using Redis-backed cache for multi-instance consistency
17
+ - Configuring connection pool limits and timeouts to prevent resource exhaustion
18
+ - Providers do not implement `onInit` / `onDestroy` — initialize in the constructor and let framework shutdown handle cleanup
13
19
  ---
14
20
 
15
21
  # Caching and Performance Configuration
16
22
 
17
- Shows how to configure caching with TTL, optimize responses, and manage memory with proper provider lifecycle cleanup.
23
+ Shows how to configure caching with the real `CachePlugin.init(...)` API and how to size connection pools so the server does not exhaust downstream resources.
24
+
25
+ > Note: `@Provider`-decorated classes do **not** have `onInit` / `onDestroy` lifecycle hooks. Provider construction is the init step. Shutdown cleanup happens via the framework-managed `scope.shutdown()` path on SIGTERM/SIGINT (see `front-mcp.ts`); you do not need to wire your own shutdown hooks.
18
26
 
19
27
  ## Code
20
28
 
21
29
  ```typescript
22
30
  // src/main.ts
31
+ import CachePlugin from '@frontmcp/plugin-cache';
23
32
  import { FrontMcp } from '@frontmcp/sdk';
24
- import { CachePlugin } from '@frontmcp/plugins';
33
+
25
34
  import { MyApp } from './my.app';
26
35
 
27
36
  @FrontMcp({
28
37
  info: { name: 'perf-server', version: '1.0.0' },
29
38
  apps: [MyApp],
30
39
  plugins: [
31
- new CachePlugin({
32
- // Per-tool TTL tuning (not one-size-fits-all)
33
- ttl: {
34
- get_weather: 300_000, // 5 minutes — data changes slowly
35
- list_tasks: 10_000, // 10 seconds — data changes frequently
40
+ // Real CachePlugin shape — see plugins/plugin-cache/src/cache.types.ts
41
+ CachePlugin.init({
42
+ type: 'redis', // 'memory' | 'redis' | 'redis-client' | 'global-store'
43
+ config: {
44
+ host: process.env.REDIS_HOST ?? 'localhost',
45
+ port: 6379,
36
46
  },
37
- defaultTtl: 60_000, // 1 minute default
47
+ defaultTTL: 60, // seconds — defaults to 1 day if omitted
48
+ // Tool name patterns to auto-cache (supports wildcards)
49
+ toolPatterns: ['get-weather', 'list-tasks', 'mintlify:*'],
38
50
  }),
39
51
  ],
40
52
 
41
- // Redis for multi-instance cache consistency
53
+ // Redis for multi-instance shared state (sessions, jobs, global-store)
42
54
  redis: {
43
55
  provider: 'redis',
44
56
  host: process.env.REDIS_HOST ?? 'localhost',
45
57
  port: 6379,
46
58
  },
47
-
48
- // Session TTL to prevent unbounded growth
49
- session: {
50
- ttl: 3600_000, // 1 hour
51
- },
52
59
  })
53
60
  export default class PerfServer {}
54
61
  ```
55
62
 
63
+ ```typescript
64
+ // src/tools/get-weather.tool.ts — per-tool TTL via metadata
65
+ import { Tool, ToolContext, z } from '@frontmcp/sdk';
66
+
67
+ @Tool({
68
+ name: 'get-weather',
69
+ description: 'Fetch weather (slow-changing data — cache 5 minutes)',
70
+ inputSchema: { city: z.string() },
71
+ outputSchema: { temp: z.number() },
72
+ cache: { ttl: 300, slideWindow: false }, // seconds — overrides plugin default
73
+ })
74
+ export class GetWeatherTool extends ToolContext {
75
+ async execute(input: { city: string }) {
76
+ return { temp: 21 };
77
+ }
78
+ }
79
+ ```
80
+
56
81
  ```typescript
57
82
  // src/providers/db-connection.provider.ts
58
83
  import { Provider, ProviderScope } from '@frontmcp/sdk';
@@ -61,13 +86,13 @@ export const DB_POOL = Symbol('DbPool');
61
86
 
62
87
  @Provider({ token: DB_POOL, scope: ProviderScope.GLOBAL })
63
88
  export class DbConnectionProvider {
64
- private pool!: { query: Function; end: Function };
89
+ // Pool is created in the constructor — providers do not have onInit/onDestroy.
90
+ private readonly pool: { query: Function; end: Function };
65
91
 
66
- async onInit(): Promise<void> {
67
- // Connection pool with limits — prevents resource exhaustion
68
- this.pool = await this.createPool({
92
+ constructor() {
93
+ this.pool = this.createPool({
69
94
  host: process.env.DB_HOST,
70
- max: 20, // Maximum connections
95
+ max: 20, // Maximum connections — prevents resource exhaustion
71
96
  idleTimeoutMs: 30_000, // Close idle connections after 30s
72
97
  connectionTimeoutMs: 5_000, // Don't hang on connection attempts
73
98
  });
@@ -77,12 +102,7 @@ export class DbConnectionProvider {
77
102
  return this.pool.query(sql, params); // Parameterized — no SQL injection
78
103
  }
79
104
 
80
- async onDestroy(): Promise<void> {
81
- // Clean up on shutdown — prevents connection leaks
82
- await this.pool.end();
83
- }
84
-
85
- private async createPool(config: Record<string, unknown>): Promise<{ query: Function; end: Function }> {
105
+ private createPool(config: Record<string, unknown>): { query: Function; end: Function } {
86
106
  // Replace with your database driver (e.g., pg, mysql2)
87
107
  throw new Error('Implement with your database driver');
88
108
  }
@@ -91,12 +111,13 @@ export class DbConnectionProvider {
91
111
 
92
112
  ## What This Demonstrates
93
113
 
94
- - Configuring per-tool cache TTL instead of a single global value
114
+ - Using the real `CachePlugin.init({ type, defaultTTL, toolPatterns })` shape (NOT `new CachePlugin({ ttl: { ... } })`)
115
+ - Setting per-tool TTL via `@Tool({ cache: { ttl } })` metadata in seconds
95
116
  - Using Redis-backed cache for multi-instance consistency
96
- - Setting session TTL to prevent unbounded storage growth
97
- - Implementing `onDestroy()` in providers for proper connection cleanup
98
- - Using connection pool limits and timeouts to prevent resource exhaustion
117
+ - Configuring connection pool limits and timeouts to prevent resource exhaustion
118
+ - Providers do not implement `onInit` / `onDestroy` — initialize in the constructor and let framework shutdown handle cleanup
99
119
 
100
120
  ## Related
101
121
 
102
122
  - See `common-checklist` for the full performance and memory management checklist
123
+ - Plugin source: `plugins/plugin-cache/src/cache.types.ts`
@@ -47,7 +47,7 @@ export class MonitoredOperationTool extends ToolContext {
47
47
  }
48
48
 
49
49
  // Report progress for long-running operations
50
- await this.respondProgress(1, 1);
50
+ this.progress(1, 1);
51
51
 
52
52
  return { status: 'completed', operationId: input.operationId };
53
53
  }
@@ -2,18 +2,21 @@
2
2
  name: security-hardening
3
3
  reference: common-checklist
4
4
  level: basic
5
- description: 'Shows how to configure authentication, CORS, input validation, and rate limiting for a production FrontMCP server.'
6
- tags: [production, redis, session, security, throttle, checklist]
5
+ description: 'Shows how to configure authentication, CORS, input validation, rate limiting, audit logging, and observability counters for a production FrontMCP server.'
6
+ tags: [production, redis, session, security, throttle, audit, observability, checklist]
7
7
  features:
8
8
  - "Restricting CORS origins to known domains instead of using `'*'`"
9
9
  - 'Configuring rate limiting via the `throttle` option'
10
10
  - 'Using Redis for session storage in multi-instance deployments'
11
11
  - 'Defining both `inputSchema` and `outputSchema` on tools to prevent data leaks'
12
+ - 'Enabling the tamper-evident skill audit log with RS256 + a persistent store and a CI verifier'
13
+ - 'Wiring an OTel MeterProvider so framework counters (bundle pulls, signature failures, replay rejects) are exported'
14
+ - 'Keeping the auto-injected skill catalog summary inside the 16 KB initialize ceiling'
12
15
  ---
13
16
 
14
17
  # Security Hardening Configuration
15
18
 
16
- Shows how to configure authentication, CORS, input validation, and rate limiting for a production FrontMCP server.
19
+ Shows how to configure authentication, CORS, input validation, rate limiting, audit logging, and observability counters for a production FrontMCP server.
17
20
 
18
21
  ## Code
19
22
 
@@ -41,10 +44,15 @@ import { MyApp } from './my.app';
41
44
  maxAge: 86400, // Cache preflight for 24 hours
42
45
  },
43
46
 
44
- // Rate limiting: prevent abuse
47
+ // Rate limiting: prevent abuse (GuardConfig — see libs/guard)
45
48
  throttle: {
46
- windowMs: 60_000, // 1 minute window
47
- max: 100, // 100 requests per window per client
49
+ enabled: true,
50
+ global: {
51
+ maxRequests: 100,
52
+ windowMs: 60_000, // 1 minute window
53
+ partitionBy: 'ip', // 'ip' | 'session' | 'global'
54
+ },
55
+ defaultTimeout: { executeMs: 30_000 },
48
56
  },
49
57
 
50
58
  // Session storage: use Redis (not in-memory) for multi-instance
@@ -82,13 +90,101 @@ export class SafeQueryTool extends ToolContext {
82
90
  }
83
91
  ```
84
92
 
93
+ ```typescript
94
+ // src/audit-bootstrap.ts — wire the audit log + meter provider before FrontMcp registers
95
+ import { metrics } from '@opentelemetry/api';
96
+ import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
97
+ import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
98
+
99
+ import {
100
+ Hs256AuditSigner,
101
+ MemoryAuditStore,
102
+ Rs256AuditSigner,
103
+ setSkillAuditFactory,
104
+ SkillAuditWriter,
105
+ SkillAuditWriterToken,
106
+ StorageAdapterAuditStore,
107
+ } from '@frontmcp/adapters/skills';
108
+ import { createStorageAdapter } from '@frontmcp/utils';
109
+
110
+ // 1. Audit subsystem
111
+ //
112
+ // `setSkillAuditFactory` registers the audit module with the SDK; the SDK
113
+ // itself constructs the writer using the positional signature
114
+ // `new SkillAuditWriter(store, signer, logger, metrics?, options?)` and
115
+ // forwards `subjectMode` from `skillsConfig.audit` into the options bag.
116
+ setSkillAuditFactory(() => ({
117
+ SkillAuditWriterToken,
118
+ SkillAuditWriter,
119
+ Hs256AuditSigner,
120
+ MemoryAuditStore,
121
+ }));
122
+
123
+ export const auditSigner = new Rs256AuditSigner(
124
+ // Private key as a JWK. Convert from a PEM if your secret store hands you
125
+ // PEMs (e.g. `crypto.createPrivateKey(pem).export({ format: 'jwk' })`).
126
+ JSON.parse(process.env.BUNDLE_SIGNING_PRIVATE_JWK!),
127
+ 'bundle-signing-2026-01',
128
+ );
129
+
130
+ export const auditStore = new StorageAdapterAuditStore(
131
+ await createStorageAdapter({ provider: 'redis', host: process.env.REDIS_HOST!, port: 6379 }),
132
+ );
133
+
134
+ // 2. Meter provider — exports framework counters (bundle pulls, signature failures, ...)
135
+ metrics.setGlobalMeterProvider(
136
+ new MeterProvider({
137
+ readers: [
138
+ new PeriodicExportingMetricReader({
139
+ exporter: new OTLPMetricExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT! }),
140
+ exportIntervalMillis: 10_000,
141
+ }),
142
+ ],
143
+ }),
144
+ );
145
+ ```
146
+
147
+ ```typescript
148
+ // src/main.ts — wire the audit + meter setup into the FrontMcp config
149
+ import './audit-bootstrap';
150
+
151
+ import { auditSigner, auditStore } from './audit-bootstrap';
152
+
153
+ @FrontMcp({
154
+ // ... auth/cors/throttle/redis as above ...
155
+
156
+ // Keep the user-facing prompt tight so the auto-appended catalog summary
157
+ // stays under the 16 KB initialize ceiling.
158
+ instructions: 'You are a helpful assistant. Use available skills.',
159
+
160
+ skillsConfig: {
161
+ enabled: true,
162
+ auth: 'bearer',
163
+ jwt: { issuer: process.env.JWT_ISSUER!, audience: 'skills-api' },
164
+ injectInstructions: 'append',
165
+ audit: {
166
+ enabled: true,
167
+ signer: auditSigner,
168
+ store: auditStore,
169
+ subjectMode: 'hash',
170
+ },
171
+ },
172
+ })
173
+ export default class HardenedServer {}
174
+ ```
175
+
85
176
  ## What This Demonstrates
86
177
 
87
178
  - Restricting CORS origins to known domains instead of using `'*'`
88
179
  - Configuring rate limiting via the `throttle` option
89
180
  - Using Redis for session storage in multi-instance deployments
90
181
  - Defining both `inputSchema` and `outputSchema` on tools to prevent data leaks
182
+ - Enabling the tamper-evident skill audit log with RS256 + a persistent store and a CI verifier
183
+ - Wiring an OTel MeterProvider so framework counters (bundle pulls, signature failures, replay rejects) are exported
184
+ - Keeping the auto-injected skill catalog summary inside the 16 KB initialize ceiling
91
185
 
92
186
  ## Related
93
187
 
94
188
  - See `common-checklist` for the full security, performance, and reliability checklist
189
+ - See `skill-audit-log` for the audit chain architecture
190
+ - See `configure-skills-http` for the full `skillsConfig` reference
@@ -21,6 +21,7 @@ Shows how to configure a FrontMCP server as a long-running local daemon with Uni
21
21
  ```typescript
22
22
  // src/main.ts
23
23
  import { FrontMcp } from '@frontmcp/sdk';
24
+
24
25
  import { MyApp } from './my.app';
25
26
 
26
27
  @FrontMcp({
@@ -35,7 +36,7 @@ import { MyApp } from './my.app';
35
36
  // SQLite for local persistence (sessions, cache)
36
37
  sqlite: {
37
38
  path: `${process.env.HOME}/.config/my-daemon/data.db`,
38
- wal: true, // WAL mode for concurrent reads
39
+ walMode: true, // WAL mode for concurrent reads — see SqliteOptionsInterface
39
40
  },
40
41
  })
41
42
  export default class MyDaemonServer {}
@@ -2,106 +2,114 @@
2
2
  name: graceful-shutdown-cleanup
3
3
  reference: production-cli-daemon
4
4
  level: intermediate
5
- description: 'Shows how to implement graceful shutdown for a daemon process, including completing in-flight requests, closing database connections, removing the socket file, and cleaning up the PID file.'
6
- tags: [production, unix-socket, cli, database, daemon, graceful]
5
+ description: Shows how to layer daemon-specific cleanup (socket file, PID file) **on top of** the framework's built-in SIGTERM/SIGINT handler.
6
+ tags:
7
+ - production
8
+ - unix-socket
9
+ - cli
10
+ - database
11
+ - daemon
12
+ - graceful
7
13
  features:
8
- - 'SIGTERM handler that completes in-flight requests before exiting'
9
- - 'Removing the Unix socket file to prevent stale `.sock` files on restart'
10
- - 'Cleaning up the PID file on shutdown'
11
- - 'Using `@frontmcp/utils` (`unlink`, `fileExists`, `ensureDir`) for file operations'
12
- - 'Implementing `onDestroy()` to close database connections'
14
+ - The framework already wires SIGTERM/SIGINT daemon cleanup attaches _additional_ listeners and does not call `process.exit()`
15
+ - Using `server.dispose()` (the only real method) instead of fictional `server.close()`
16
+ - Removing the Unix socket file to prevent stale `.sock` files on restart
17
+ - Cleaning up the PID file on shutdown
18
+ - Using `@frontmcp/utils` (`unlink`, `fileExists`, `ensureDir`) for file operations
19
+ - Providers initialize in the constructor — there is no `onInit` / `onDestroy`
13
20
  ---
14
21
 
15
22
  # Daemon Graceful Shutdown with Socket Cleanup
16
23
 
17
- Shows how to implement graceful shutdown for a daemon process, including completing in-flight requests, closing database connections, removing the socket file, and cleaning up the PID file.
24
+ Shows how to layer daemon-specific cleanup (socket file, PID file) **on top of** the framework's built-in SIGTERM/SIGINT handler.
25
+
26
+ > The FrontMCP framework already installs `SIGTERM` / `SIGINT` handlers that call `scope.shutdown()` and `mcpServer.close()` (see `libs/sdk/src/front-mcp/front-mcp.ts`). **Do not install your own** competing shutdown handler — only register _additional_ cleanup hooks (e.g. for socket / PID files) that run before the framework exits.
27
+ >
28
+ > `FrontMcpServerInstance` exposes `dispose()` only — there is **no** `server.close()` method.
18
29
 
19
30
  ## Code
20
31
 
21
32
  ```typescript
22
33
  // src/lifecycle/daemon-shutdown.ts
23
- import { unlink, fileExists } from '@frontmcp/utils';
24
-
25
- export function setupDaemonShutdown(server: { close: () => Promise<void>; dispose: () => Promise<void> }): void {
34
+ import { fileExists, unlink } from '@frontmcp/utils';
35
+
36
+ /**
37
+ * Register daemon-only side-effect cleanup. Run BEFORE the framework's
38
+ * SIGTERM handler tears down the server. Do not call process.exit() here —
39
+ * the framework owns that.
40
+ */
41
+ export function setupDaemonSideEffectCleanup(): void {
26
42
  const socketPath = '/tmp/my-daemon.sock';
27
43
  const pidFile = `${process.env.HOME}/.config/my-daemon/daemon.pid`;
28
44
 
29
- const shutdown = async (signal: string) => {
30
- console.log(`[daemon] Received ${signal}. Shutting down...`);
31
-
32
- // 1. Stop accepting new connections
33
- await server.close();
34
- console.log('[daemon] Server closed.');
35
-
36
- // 2. Dispose all resources (SQLite, providers)
37
- await server.dispose();
38
- console.log('[daemon] Resources disposed.');
39
-
40
- // 3. Remove socket file (prevent stale .sock files)
45
+ const cleanup = async () => {
41
46
  if (await fileExists(socketPath)) {
42
47
  await unlink(socketPath);
43
48
  console.log(`[daemon] Socket removed: ${socketPath}`);
44
49
  }
45
-
46
- // 4. Clean up PID file
47
50
  if (await fileExists(pidFile)) {
48
51
  await unlink(pidFile);
49
52
  console.log(`[daemon] PID file removed: ${pidFile}`);
50
53
  }
51
-
52
- process.exit(0);
53
54
  };
54
55
 
55
- process.on('SIGTERM', () => shutdown('SIGTERM'));
56
- process.on('SIGINT', () => shutdown('SIGINT'));
56
+ // The framework registers its own SIGTERM/SIGINT handlers. Adding ours
57
+ // means BOTH run on signal Node.js fires every registered listener.
58
+ // Keep these idempotent and side-effect-only; framework will exit after.
59
+ process.on('SIGTERM', cleanup);
60
+ process.on('SIGINT', cleanup);
57
61
  }
58
62
  ```
59
63
 
60
64
  ```typescript
61
65
  // src/providers/sqlite-store.provider.ts
62
- import { Provider, ProviderScope } from '@frontmcp/sdk';
66
+ import { dirname } from 'path';
67
+
68
+ import { AsyncProvider, ProviderScope } from '@frontmcp/sdk';
69
+ import { ensureDir } from '@frontmcp/utils';
63
70
 
64
71
  export const LOCAL_STORE = Symbol('LocalStore');
65
72
 
66
- @Provider({ token: LOCAL_STORE, scope: ProviderScope.GLOBAL })
73
+ // Providers do NOT have onInit/onDestroy lifecycle hooks. Anything async
74
+ // at construction time goes through `AsyncProvider({ useFactory })` so the
75
+ // dir is guaranteed to exist before the database is opened.
67
76
  export class SqliteStoreProvider {
68
- private db!: { close: () => void; exec: (sql: string) => void };
69
-
70
- async onInit(): Promise<void> {
71
- // Database path is configurable, not hardcoded
72
- const dbPath = process.env.DB_PATH ?? `${process.env.HOME}/.config/my-daemon/data.db`;
77
+ constructor(private readonly db: { close: () => void; exec: (sql: string) => void }) {}
78
+ }
73
79
 
74
- // Ensure directory exists
75
- const { ensureDir } = await import('@frontmcp/utils');
76
- const path = await import('path');
77
- await ensureDir(path.dirname(dbPath));
78
-
79
- // Initialize with WAL mode for concurrent reads
80
- // Auto-migrate on startup
81
- this.db = await this.openDatabase(dbPath);
82
- this.db.exec('PRAGMA journal_mode=WAL');
83
- }
84
-
85
- async onDestroy(): Promise<void> {
86
- // Close database connection on shutdown
87
- this.db.close();
88
- }
89
-
90
- private async openDatabase(path: string) {
91
- // Replace with your SQLite driver (e.g., better-sqlite3)
92
- throw new Error('Implement with your SQLite driver');
93
- }
80
+ function openDatabase(path: string): { close: () => void; exec: (sql: string) => void } {
81
+ // Replace with your SQLite driver (e.g., better-sqlite3)
82
+ throw new Error('Implement with your SQLite driver');
94
83
  }
84
+
85
+ // Async factory binding — `useFactory` runs once at boot and waits for
86
+ // `ensureDir` before opening the database, eliminating the race that
87
+ // `void ensureDir(...)` in a sync constructor would create.
88
+ export const sqliteStoreProvider = AsyncProvider({
89
+ provide: LOCAL_STORE,
90
+ name: 'SqliteStoreProvider',
91
+ scope: ProviderScope.GLOBAL,
92
+ inject: () => [] as const,
93
+ useFactory: async () => {
94
+ const dbPath = process.env.DB_PATH ?? `${process.env.HOME}/.config/my-daemon/data.db`;
95
+ await ensureDir(dirname(dbPath));
96
+ const db = openDatabase(dbPath);
97
+ db.exec('PRAGMA journal_mode=WAL');
98
+ return new SqliteStoreProvider(db);
99
+ },
100
+ });
95
101
  ```
96
102
 
97
103
  ## What This Demonstrates
98
104
 
99
- - SIGTERM handler that completes in-flight requests before exiting
105
+ - The framework already wires SIGTERM/SIGINT daemon cleanup attaches _additional_ listeners and does not call `process.exit()`
106
+ - Using `server.dispose()` (the only real method) instead of fictional `server.close()`
100
107
  - Removing the Unix socket file to prevent stale `.sock` files on restart
101
108
  - Cleaning up the PID file on shutdown
102
109
  - Using `@frontmcp/utils` (`unlink`, `fileExists`, `ensureDir`) for file operations
103
- - Implementing `onDestroy()` to close database connections
110
+ - Providers initialize in the constructor — there is no `onInit` / `onDestroy`
104
111
 
105
112
  ## Related
106
113
 
107
114
  - See `production-cli-daemon` for the full graceful shutdown and security checklist
115
+ - Framework SIGTERM/SIGINT wiring: `libs/sdk/src/front-mcp/front-mcp.ts`
@@ -20,10 +20,11 @@ Shows how to secure a local daemon with restrictive socket permissions, XDG-comp
20
20
 
21
21
  ```typescript
22
22
  // src/lifecycle/daemon-security.ts
23
- import { stat, writeFile, fileExists, ensureDir, readFile } from '@frontmcp/utils';
24
23
  import { chmod } from 'fs/promises';
25
- import * as path from 'path';
26
24
  import * as os from 'os';
25
+ import * as path from 'path';
26
+
27
+ import { ensureDir, fileExists, readFile, stat, writeFile } from '@frontmcp/utils';
27
28
 
28
29
  // XDG Base Directory compliance
29
30
  function getConfigDir(appName: string): string {
@@ -86,6 +87,7 @@ export async function loadSecrets(configDir: string): Promise<Record<string, str
86
87
  ```typescript
87
88
  // src/main.ts
88
89
  import { FrontMcp } from '@frontmcp/sdk';
90
+
89
91
  import { MyApp } from './my.app';
90
92
 
91
93
  @FrontMcp({
@@ -100,7 +102,7 @@ import { MyApp } from './my.app';
100
102
  // SQLite in the data directory (persistent, writable)
101
103
  sqlite: {
102
104
  path: `${process.env.XDG_DATA_HOME ?? process.env.HOME + '/.local/share'}/secure-daemon/data.db`,
103
- wal: true,
105
+ walMode: true, // SqliteOptionsInterface — see libs/storage-sqlite
104
106
  },
105
107
  })
106
108
  export default class SecureDaemonServer {}
@@ -19,8 +19,9 @@ Shows how to use Cloudflare Durable Objects for stateful coordination alongside
19
19
 
20
20
  ```toml
21
21
  # wrangler.toml — with Durable Objects and R2
22
+ # NOTE: `main` is written by `frontmcp build --target cloudflare`. Do not hand-edit.
22
23
  name = "stateful-mcp-worker"
23
- main = "dist/worker.js"
24
+ main = "dist/cloudflare/index.js"
24
25
  compatibility_date = "2024-01-01"
25
26
 
26
27
  # KV for cache