@frontmcp/skills 1.0.3 → 1.1.0-beta.1

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 (141) hide show
  1. package/catalog/frontmcp-authorities/SKILL.md +272 -0
  2. package/catalog/frontmcp-authorities/references/authority-profiles.md +262 -0
  3. package/catalog/frontmcp-authorities/references/claims-mapping.md +266 -0
  4. package/catalog/frontmcp-authorities/references/custom-evaluators.md +420 -0
  5. package/catalog/frontmcp-authorities/references/rbac-abac-rebac.md +391 -0
  6. package/catalog/frontmcp-channels/SKILL.md +122 -0
  7. package/catalog/frontmcp-channels/examples/channel-sources/agent-notify.md +70 -0
  8. package/catalog/frontmcp-channels/examples/channel-sources/app-errors.md +71 -0
  9. package/catalog/frontmcp-channels/examples/channel-sources/file-watcher.md +102 -0
  10. package/catalog/frontmcp-channels/examples/channel-sources/job-completion.md +79 -0
  11. package/catalog/frontmcp-channels/examples/channel-sources/replay-buffer.md +106 -0
  12. package/catalog/frontmcp-channels/examples/channel-sources/service-connector.md +136 -0
  13. package/catalog/frontmcp-channels/examples/channel-sources/webhook-github.md +85 -0
  14. package/catalog/frontmcp-channels/examples/channel-two-way/whatsapp-bridge.md +133 -0
  15. package/catalog/frontmcp-channels/references/channel-sources.md +214 -0
  16. package/catalog/frontmcp-channels/references/channel-two-way.md +195 -0
  17. package/catalog/frontmcp-config/SKILL.md +20 -18
  18. package/catalog/frontmcp-config/examples/configure-auth/multi-app-auth.md +1 -2
  19. package/catalog/frontmcp-config/examples/configure-auth/public-mode-setup.md +1 -2
  20. package/catalog/frontmcp-config/examples/configure-auth/remote-oauth-with-vault.md +1 -2
  21. package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +1 -2
  22. package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +1 -2
  23. package/catalog/frontmcp-config/examples/configure-auth-modes/transparent-jwt-validation.md +1 -2
  24. package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +121 -0
  25. package/catalog/frontmcp-config/examples/configure-deployment-targets/json-schema-ide-support.md +64 -0
  26. package/catalog/frontmcp-config/examples/configure-deployment-targets/multi-target-with-security.md +113 -0
  27. package/catalog/frontmcp-config/examples/configure-elicitation/basic-confirmation-gate.md +1 -2
  28. package/catalog/frontmcp-config/examples/configure-elicitation/distributed-elicitation-redis.md +1 -2
  29. package/catalog/frontmcp-config/examples/configure-http/entry-path-reverse-proxy.md +1 -2
  30. package/catalog/frontmcp-config/examples/configure-http/unix-socket-local.md +1 -2
  31. package/catalog/frontmcp-config/examples/configure-security-headers/csp-report-only.md +69 -0
  32. package/catalog/frontmcp-config/examples/configure-security-headers/full-production-headers.md +91 -0
  33. package/catalog/frontmcp-config/examples/configure-throttle/distributed-redis-throttle.md +1 -2
  34. package/catalog/frontmcp-config/examples/configure-throttle/per-tool-rate-limit.md +1 -2
  35. package/catalog/frontmcp-config/examples/configure-throttle/server-level-rate-limit.md +1 -2
  36. package/catalog/frontmcp-config/examples/configure-transport/custom-protocol-flags.md +1 -2
  37. package/catalog/frontmcp-config/examples/configure-transport/distributed-sessions-redis.md +1 -2
  38. package/catalog/frontmcp-config/examples/configure-transport/stateless-serverless.md +1 -2
  39. package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/legacy-preset-nodejs.md +1 -2
  40. package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/stateless-api-serverless.md +1 -2
  41. package/catalog/frontmcp-config/references/configure-deployment-targets.md +214 -0
  42. package/catalog/frontmcp-config/references/configure-elicitation.md +1 -2
  43. package/catalog/frontmcp-config/references/configure-security-headers.md +198 -0
  44. package/catalog/frontmcp-deployment/SKILL.md +1 -0
  45. package/catalog/frontmcp-deployment/examples/build-for-cli/cli-binary-build.md +1 -2
  46. package/catalog/frontmcp-deployment/examples/build-for-cli/unix-socket-daemon.md +1 -2
  47. package/catalog/frontmcp-deployment/examples/build-for-mcpb/mcpb-bundle-build.md +117 -0
  48. package/catalog/frontmcp-deployment/examples/build-for-sdk/connect-openai.md +1 -3
  49. package/catalog/frontmcp-deployment/examples/build-for-sdk/create-flat-config.md +1 -2
  50. package/catalog/frontmcp-deployment/examples/build-for-sdk/multi-platform-connect.md +3 -3
  51. package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/basic-worker-deploy.md +1 -2
  52. package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-custom-domain.md +1 -2
  53. package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-with-kv-storage.md +1 -2
  54. package/catalog/frontmcp-deployment/examples/deploy-to-lambda/lambda-handler-with-cors.md +1 -2
  55. package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +1 -2
  56. package/catalog/frontmcp-deployment/examples/mcp-client-integration/http-remote.md +106 -0
  57. package/catalog/frontmcp-deployment/examples/mcp-client-integration/stdio-binary-with-env.md +107 -0
  58. package/catalog/frontmcp-deployment/examples/mcp-client-integration/stdio-npx.md +89 -0
  59. package/catalog/frontmcp-deployment/references/build-for-mcpb.md +209 -0
  60. package/catalog/frontmcp-deployment/references/build-for-sdk.md +1 -2
  61. package/catalog/frontmcp-deployment/references/mcp-client-integration.md +225 -0
  62. package/catalog/frontmcp-development/SKILL.md +4 -3
  63. package/catalog/frontmcp-development/examples/create-agent/basic-agent-with-tools.md +3 -6
  64. package/catalog/frontmcp-development/examples/create-agent/custom-multi-pass-agent.md +1 -2
  65. package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +2 -4
  66. package/catalog/frontmcp-development/examples/create-agent-llm-config/anthropic-config.md +1 -2
  67. package/catalog/frontmcp-development/examples/create-agent-llm-config/openai-config.md +1 -2
  68. package/catalog/frontmcp-development/examples/create-job/basic-report-job.md +1 -2
  69. package/catalog/frontmcp-development/examples/create-job/job-with-permissions.md +2 -3
  70. package/catalog/frontmcp-development/examples/create-job/job-with-retry.md +1 -2
  71. package/catalog/frontmcp-development/examples/create-plugin-hooks/tool-level-hooks-and-stage-replacement.md +2 -5
  72. package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +4 -3
  73. package/catalog/frontmcp-development/examples/create-skill-with-tools/directory-skill-with-tools.md +2 -3
  74. package/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md +1 -2
  75. package/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md +2 -2
  76. package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +1 -2
  77. package/catalog/frontmcp-development/examples/create-tool-annotations/destructive-delete-tool.md +2 -4
  78. package/catalog/frontmcp-development/examples/create-tool-annotations/readonly-query-tool.md +1 -2
  79. package/catalog/frontmcp-development/examples/create-tool-output-schema-types/primitive-and-media-outputs.md +3 -6
  80. package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-raw-shape-output.md +1 -2
  81. package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-schema-advanced-output.md +2 -4
  82. package/catalog/frontmcp-development/examples/decorators-guide/agent-skill-job-workflow.md +3 -5
  83. package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md +5 -5
  84. package/catalog/frontmcp-development/examples/decorators-guide/multi-app-with-plugins-and-providers.md +4 -6
  85. package/catalog/frontmcp-development/examples/official-plugins/cache-and-feature-flags.md +3 -5
  86. package/catalog/frontmcp-development/examples/official-plugins/production-multi-plugin-setup.md +4 -5
  87. package/catalog/frontmcp-development/examples/official-plugins/remember-plugin-session-memory.md +3 -5
  88. package/catalog/frontmcp-development/examples/{official-adapters → openapi-adapter}/authenticated-adapter-with-polling.md +2 -2
  89. package/catalog/frontmcp-development/examples/{official-adapters → openapi-adapter}/basic-openapi-adapter.md +2 -2
  90. package/catalog/frontmcp-development/examples/openapi-adapter/format-resolution-and-custom-resolvers.md +108 -0
  91. package/catalog/frontmcp-development/examples/{official-adapters → openapi-adapter}/multi-api-hub-with-inline-spec.md +2 -2
  92. package/catalog/frontmcp-development/examples/openapi-adapter/ref-security-and-filtering.md +111 -0
  93. package/catalog/frontmcp-development/references/create-agent.md +4 -7
  94. package/catalog/frontmcp-development/references/create-job.md +3 -6
  95. package/catalog/frontmcp-development/references/create-plugin-hooks.md +12 -16
  96. package/catalog/frontmcp-development/references/create-skill-with-tools.md +2 -3
  97. package/catalog/frontmcp-development/references/create-tool.md +93 -23
  98. package/catalog/frontmcp-development/references/create-workflow.md +2 -3
  99. package/catalog/frontmcp-development/references/decorators-guide.md +32 -36
  100. package/catalog/frontmcp-development/references/official-adapters.md +24 -153
  101. package/catalog/frontmcp-development/references/openapi-adapter.md +431 -0
  102. package/catalog/frontmcp-extensibility/examples/vectoriadb/product-catalog-search.md +4 -4
  103. package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md +4 -4
  104. package/catalog/frontmcp-extensibility/examples/vectoriadb/tfidf-keyword-search.md +4 -3
  105. package/catalog/frontmcp-guides/SKILL.md +3 -3
  106. package/catalog/frontmcp-guides/examples/example-knowledge-base/agent-and-plugin.md +4 -5
  107. package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md +4 -3
  108. package/catalog/frontmcp-guides/examples/example-task-manager/auth-and-crud-tools.md +4 -4
  109. package/catalog/frontmcp-guides/examples/example-weather-api/weather-tool-with-schemas.md +1 -2
  110. package/catalog/frontmcp-guides/references/example-knowledge-base.md +22 -17
  111. package/catalog/frontmcp-guides/references/example-task-manager.md +16 -11
  112. package/catalog/frontmcp-guides/references/example-weather-api.md +6 -3
  113. package/catalog/frontmcp-observability/examples/telemetry-api/tool-custom-spans.md +2 -3
  114. package/catalog/frontmcp-observability/examples/tracing-setup/basic-tracing.md +4 -3
  115. package/catalog/frontmcp-observability/references/telemetry-api.md +2 -3
  116. package/catalog/frontmcp-production-readiness/examples/common-checklist/observability-setup.md +1 -2
  117. package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +3 -4
  118. package/catalog/frontmcp-production-readiness/examples/distributed-ha/ha-kubernetes-3-replicas.md +229 -0
  119. package/catalog/frontmcp-production-readiness/examples/production-browser/cross-platform-crypto.md +2 -3
  120. package/catalog/frontmcp-production-readiness/examples/production-cli-binary/stdio-transport-error-handling.md +1 -2
  121. package/catalog/frontmcp-production-readiness/examples/production-cloudflare/durable-objects-state.md +2 -4
  122. package/catalog/frontmcp-production-readiness/examples/production-cloudflare/workers-runtime-constraints.md +2 -3
  123. package/catalog/frontmcp-production-readiness/examples/production-lambda/cold-start-connection-reuse.md +3 -2
  124. package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md +2 -2
  125. package/catalog/frontmcp-production-readiness/examples/production-vercel/stateless-serverless-design.md +3 -3
  126. package/catalog/frontmcp-production-readiness/references/distributed-ha.md +194 -0
  127. package/catalog/frontmcp-setup/SKILL.md +11 -11
  128. package/catalog/frontmcp-setup/examples/project-structure-standalone/feature-folder-organization.md +5 -3
  129. package/catalog/frontmcp-setup/examples/project-structure-standalone/minimal-standalone-layout.md +4 -2
  130. package/catalog/frontmcp-setup/examples/setup-project/basic-node-server.md +4 -2
  131. package/catalog/frontmcp-setup/examples/setup-project/vercel-serverless-server.md +4 -2
  132. package/catalog/frontmcp-setup/examples/setup-redis/hybrid-vercel-kv-with-pubsub.md +8 -7
  133. package/catalog/frontmcp-setup/references/setup-project.md +10 -9
  134. package/catalog/frontmcp-setup/references/setup-redis.md +19 -16
  135. package/catalog/frontmcp-testing/examples/test-direct-client/basic-create-test.md +1 -3
  136. package/catalog/frontmcp-testing/examples/test-direct-client/openai-claude-format-test.md +1 -3
  137. package/catalog/frontmcp-testing/examples/test-tool-unit/schema-validation-test.md +2 -2
  138. package/catalog/frontmcp-testing/references/test-direct-client.md +1 -3
  139. package/catalog/frontmcp-testing/references/test-tool-unit.md +2 -2
  140. package/catalog/skills-manifest.json +364 -12
  141. package/package.json +1 -1
@@ -45,8 +45,7 @@ export class LazyApiClientProvider {
45
45
 
46
46
  ```typescript
47
47
  // src/tools/cached-lookup.tool.ts
48
- import { Tool, ToolContext } from '@frontmcp/sdk';
49
- import { z } from 'zod';
48
+ import { Tool, ToolContext, z } from '@frontmcp/sdk';
50
49
 
51
50
  // Cache OpenAPI spec in module scope — survives warm invocations
52
51
  let cachedSpec: unknown | undefined;
@@ -78,6 +77,7 @@ export class CachedLookupTool extends ToolContext {
78
77
  ```typescript
79
78
  // src/main.ts
80
79
  import { FrontMcp } from '@frontmcp/sdk';
80
+
81
81
  // Only import lightweight modules at the top level
82
82
  import { MyApp } from './my.app';
83
83
 
@@ -19,10 +19,9 @@ Shows a fully stateless server design that works on Vercel edge runtime with no
19
19
 
20
20
  ```typescript
21
21
  // src/tools/edge-safe-tool.tool.ts
22
- import { Tool, ToolContext } from '@frontmcp/sdk';
23
- import { z } from 'zod';
22
+ import { Tool, ToolContext, z } from '@frontmcp/sdk';
24
23
  // Use @frontmcp/utils for cross-platform crypto — not node:crypto
25
- import { sha256Hex, randomUUID } from '@frontmcp/utils';
24
+ import { randomUUID, sha256Hex } from '@frontmcp/utils';
26
25
 
27
26
  @Tool({
28
27
  name: 'process_request',
@@ -60,6 +59,7 @@ export class ProcessRequestTool extends ToolContext {
60
59
  ```typescript
61
60
  // src/main.ts
62
61
  import { FrontMcp } from '@frontmcp/sdk';
62
+
63
63
  import { EdgeApp } from './edge.app';
64
64
 
65
65
  @FrontMcp({
@@ -0,0 +1,194 @@
1
+ ---
2
+ name: distributed-ha
3
+ description: Deploy FrontMCP across multiple pods with heartbeat, session takeover, and notification relay for zero-downtime failover
4
+ ---
5
+
6
+ # Distributed High Availability
7
+
8
+ FrontMCP's HA module provides automatic session failover across multiple pods using Redis. Three components work together: HeartbeatService (liveness detection), session takeover (atomic CAS), and NotificationRelay (cross-pod MCP notifications).
9
+
10
+ ## When to Use This Skill
11
+
12
+ ### Must Use
13
+
14
+ - Running 2+ FrontMCP pods behind a load balancer with Redis available
15
+ - Production deployments where pod restarts must not drop active MCP sessions
16
+ - Kubernetes deployments with rolling updates or horizontal pod autoscaling
17
+
18
+ ### Recommended
19
+
20
+ - Any production deployment where zero-downtime upgrades are needed
21
+ - Multi-region setups with Redis replication
22
+
23
+ ### Skip When
24
+
25
+ - Single-pod deployments (use `deploy-to-node` instead)
26
+ - Serverless platforms (Vercel, Lambda, Cloudflare) --- stateless by design
27
+ - Development and testing --- use `direct-client` or standalone mode
28
+
29
+ > **Decision:** Use this skill when you need session continuity across pod restarts. Skip for serverless or single-pod setups.
30
+
31
+ ## Prerequisites
32
+
33
+ - Redis 6+ accessible from all pods
34
+ - `@frontmcp/sdk` and `@frontmcp/cli` installed
35
+ - `FRONTMCP_DEPLOYMENT_MODE=distributed` environment variable
36
+
37
+ ## Step 1: Configure @FrontMcp Decorator
38
+
39
+ ```typescript
40
+ import { FrontMcp } from '@frontmcp/sdk';
41
+
42
+ @FrontMcp({
43
+ info: { name: 'my-server', version: '1.0.0' },
44
+ apps: [MyApp],
45
+ redis: { provider: 'redis', host: 'redis', port: 6379 },
46
+ transport: {
47
+ persistence: {
48
+ redis: { provider: 'redis', host: 'redis', port: 6379 },
49
+ },
50
+ },
51
+ })
52
+ class Server {}
53
+ ```
54
+
55
+ ## Step 2: Create Configuration File
56
+
57
+ ```typescript
58
+ // frontmcp.config.ts
59
+ import { defineConfig } from '@frontmcp/cli';
60
+
61
+ export default defineConfig({
62
+ name: 'my-server',
63
+ version: '1.0.0',
64
+ deployments: [
65
+ {
66
+ target: 'distributed',
67
+ ha: {
68
+ heartbeatIntervalMs: 10000,
69
+ heartbeatTtlMs: 30000,
70
+ takeoverGracePeriodMs: 5000,
71
+ redisKeyPrefix: 'mcp:ha:',
72
+ },
73
+ },
74
+ ],
75
+ });
76
+ ```
77
+
78
+ ## Step 3: Build and Deploy
79
+
80
+ ```bash
81
+ export FRONTMCP_DEPLOYMENT_MODE=distributed
82
+ frontmcp build --target distributed
83
+ ```
84
+
85
+ Deploy with Docker or Kubernetes (see example below).
86
+
87
+ ## Step 4: Verify Heartbeats
88
+
89
+ ```bash
90
+ # Check heartbeat keys exist for each pod
91
+ redis-cli --scan --pattern "mcp:ha:heartbeat:*"
92
+
93
+ # Inspect a heartbeat value
94
+ redis-cli GET "mcp:ha:heartbeat:mcp-server-7b8f9-abc12"
95
+ # Returns: {"nodeId":"mcp-server-7b8f9-abc12","startedAt":1712620800000,"lastBeat":1712620810000,"sessionCount":5}
96
+ ```
97
+
98
+ ## Configuration
99
+
100
+ | Field | Type | Default | Description |
101
+ | ----------------------- | ------ | --------- | ------------------------------------------------ |
102
+ | `heartbeatIntervalMs` | number | 10000 | How often each pod writes its heartbeat to Redis |
103
+ | `heartbeatTtlMs` | number | 30000 | TTL for heartbeat key (should be 2-3x interval) |
104
+ | `takeoverGracePeriodMs` | number | 5000 | Wait time before claiming orphaned sessions |
105
+ | `redisKeyPrefix` | string | `mcp:ha:` | Redis key prefix for all HA keys |
106
+
107
+ ## Architecture
108
+
109
+ ### Heartbeat Service
110
+
111
+ Each pod writes `mcp:ha:heartbeat:{nodeId}` to Redis every `heartbeatIntervalMs` with PX TTL of `heartbeatTtlMs`. The value contains `{ nodeId, startedAt, lastBeat, sessionCount }`. When a pod dies, the key expires.
112
+
113
+ ### Session Takeover
114
+
115
+ When a request arrives for a session owned by a dead pod:
116
+
117
+ 1. The live pod checks if the owner's heartbeat key exists
118
+ 2. If missing, runs an atomic Lua CAS script: verifies `expectedOldNodeId`, updates `nodeId` + `reassignedAt`
119
+ 3. Returns `{ claimed: true }` on success, `{ claimed: false }` if another pod won the race
120
+
121
+ ### Notification Relay
122
+
123
+ Each pod subscribes to `mcp:ha:notify:{nodeId}` via Redis Pub/Sub. Cross-pod MCP notifications (progress updates, resource changes) are published to the target pod's channel for local delivery.
124
+
125
+ ## Load Balancer Affinity
126
+
127
+ FrontMCP sets:
128
+
129
+ - **Cookie**: `__frontmcp_node` on Streamable HTTP initialize
130
+ - **Header**: `X-FrontMCP-Machine-Id` on every distributed response
131
+
132
+ NGINX sticky session example:
133
+
134
+ ```nginx
135
+ upstream mcp_backend {
136
+ hash $cookie___frontmcp_node consistent;
137
+ server pod-1:3000;
138
+ server pod-2:3000;
139
+ server pod-3:3000;
140
+ }
141
+ ```
142
+
143
+ ## Common Patterns
144
+
145
+ | Pattern | Correct | Incorrect | Why |
146
+ | ----------------- | ------------------------------------- | ----------------------------- | ------------------------------------------------- |
147
+ | Heartbeat TTL | `heartbeatTtlMs: 30000` (3x interval) | `heartbeatTtlMs: 10000` (1x) | Too low causes false-positive pod death detection |
148
+ | Redis connections | Dedicated pub/sub + data connections | Shared single connection | Pub/Sub blocks the connection |
149
+ | Machine ID | Let K8s set HOSTNAME | Override HOSTNAME in pod spec | Breaks session ownership mapping |
150
+
151
+ ## Errors
152
+
153
+ | Error | When | Solution |
154
+ | --------------------------- | ------------------------------------------ | ------------------------------------------------------- |
155
+ | `SessionClaimConflictError` | Session claimed by another pod during race | Retry --- the load balancer will route to the new owner |
156
+ | `HaConfigurationError` | Redis not configured for distributed mode | Add `redis` to `@FrontMcp()` config |
157
+
158
+ ## Verification Checklist
159
+
160
+ ### Configuration
161
+
162
+ - [ ] `FRONTMCP_DEPLOYMENT_MODE=distributed` set in deployment
163
+ - [ ] Redis accessible from all pods
164
+ - [ ] `heartbeatTtlMs` >= 2x `heartbeatIntervalMs`
165
+ - [ ] Transport persistence configured with Redis
166
+
167
+ ### Runtime
168
+
169
+ - [ ] `redis-cli --scan --pattern "mcp:ha:heartbeat:*"` shows entries for each pod
170
+ - [ ] Killing a pod results in its heartbeat expiring within TTL
171
+ - [ ] Surviving pods claim orphaned sessions after takeover grace period
172
+ - [ ] `/healthz` and `/readyz` return healthy on all pods
173
+
174
+ ## Troubleshooting
175
+
176
+ | Problem | Cause | Solution |
177
+ | ---------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------ |
178
+ | Sessions not transferred after pod death | `heartbeatTtlMs` too high | Lower TTL while keeping >= 2x interval (e.g., 20-30s for a 10s interval) |
179
+ | `HaConfigurationError` on startup | Missing Redis config | Add `redis` to `@FrontMcp()` decorator |
180
+ | Duplicate notifications | Shared Redis subscriber connection | Use dedicated connections per relay |
181
+ | Session takeover race failures | High pod count + simultaneous restarts | Increase `takeoverGracePeriodMs` |
182
+
183
+ ## Examples
184
+
185
+ | Example | Level | Description |
186
+ | ------------------------------------------------------------------------------------ | ------------ | ------------------------------------------------------------------------------------ |
187
+ | [`ha-kubernetes-3-replicas`](../examples/distributed-ha/ha-kubernetes-3-replicas.md) | Intermediate | Deploy FrontMCP with 3 replicas, Redis, and automatic session failover on Kubernetes |
188
+
189
+ > See all examples in [`examples/distributed-ha/`](../examples/distributed-ha/)
190
+
191
+ ## Reference
192
+
193
+ - [Documentation](https://docs.agentfront.dev/frontmcp/deployment/high-availability)
194
+ - Related skills: `frontmcp-deployment`, `frontmcp-config`, `deploy-to-node`
@@ -52,17 +52,17 @@ Entry point for project setup and scaffolding. This skill helps you find the rig
52
52
 
53
53
  ## Scenario Routing Table
54
54
 
55
- | Scenario | Reference | Description |
56
- | --------------------------------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------- |
57
- | Scaffold a new project with `frontmcp create` | `references/setup-project.md` | CLI scaffolder (flags: `--target`, `--redis`, `--skills <bundle>`, `--cicd`, `--nx`, `--pm`) |
58
- | Organize a standalone (non-Nx) project | `references/project-structure-standalone.md` | File layout, naming conventions (`<name>.<type>.ts`), folder hierarchy |
59
- | Organize an Nx monorepo | `references/project-structure-nx.md` | apps/, libs/, servers/ layout, generators, dependency rules |
60
- | Set up Redis for production storage | `references/setup-redis.md` | Docker Redis, Vercel KV, pub/sub for subscriptions |
61
- | Set up SQLite for local development | `references/setup-sqlite.md` | WAL mode, migration helpers, encryption |
62
- | Compose multiple apps into one server | `references/multi-app-composition.md` | `@FrontMcp` with multiple `@App` classes, cross-app providers |
63
- | Use Nx build, test, and CI commands | `references/nx-workflow.md` | `nx build`, `nx test`, `nx run-many`, caching, affected commands |
64
- | Browse, install, and manage skills | `references/frontmcp-skills-usage.md` | CLI commands, bundles, categories, search |
65
- | Generate or update project README.md | `references/readme-guide.md` | Deployment-target-aware README for npm, CLI, Docker, serverless |
55
+ | Scenario | Reference | Description |
56
+ | --------------------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------- |
57
+ | Scaffold a new project with `frontmcp create` | `references/setup-project.md` | CLI scaffolder (flags: `--target`, `--redis`, `--skills <bundle>`, `--cicd`, `--nx`, `--pm`) |
58
+ | Organize a standalone (non-Nx) project | `references/project-structure-standalone.md` | File layout, naming conventions (`<name>.<type>.ts`), folder hierarchy |
59
+ | Organize an Nx monorepo | `references/project-structure-nx.md` | apps/, libs/, servers/ layout, generators, dependency rules |
60
+ | Set up Redis for production storage | `references/setup-redis.md` | Docker Redis, Vercel KV, pub/sub for distributed subscriptions (single-server uses in-memory) |
61
+ | Set up SQLite for local development | `references/setup-sqlite.md` | WAL mode, migration helpers, encryption |
62
+ | Compose multiple apps into one server | `references/multi-app-composition.md` | `@FrontMcp` with multiple `@App` classes, cross-app providers |
63
+ | Use Nx build, test, and CI commands | `references/nx-workflow.md` | `nx build`, `nx test`, `nx run-many`, caching, affected commands |
64
+ | Browse, install, and manage skills | `references/frontmcp-skills-usage.md` | CLI commands, bundles, categories, search |
65
+ | Generate or update project README.md | `references/readme-guide.md` | Deployment-target-aware README for npm, CLI, Docker, serverless |
66
66
 
67
67
  ## Recommended Reading Order
68
68
 
@@ -19,8 +19,7 @@ Organize a growing standalone project into domain-specific feature folders inste
19
19
 
20
20
  ```typescript
21
21
  // src/billing/create-invoice.tool.ts
22
- import { Tool, ToolContext } from '@frontmcp/sdk';
23
- import { z } from 'zod';
22
+ import { Tool, ToolContext, z } from '@frontmcp/sdk';
24
23
 
25
24
  @Tool({
26
25
  name: 'create_invoice',
@@ -71,9 +70,10 @@ export class BillingProvider {
71
70
  ```typescript
72
71
  // src/my-app.app.ts
73
72
  import { App } from '@frontmcp/sdk';
73
+
74
+ import { BillingProvider } from './billing/billing.provider';
74
75
  import CreateInvoiceTool from './billing/create-invoice.tool';
75
76
  import InvoiceResource from './billing/invoice.resource';
76
- import { BillingProvider } from './billing/billing.provider';
77
77
 
78
78
  @App({
79
79
  name: 'my-app',
@@ -87,7 +87,9 @@ export class MyApp {}
87
87
  ```typescript
88
88
  // src/main.ts
89
89
  import 'reflect-metadata';
90
+
90
91
  import { FrontMcp } from '@frontmcp/sdk';
92
+
91
93
  import { MyApp } from './my-app.app';
92
94
 
93
95
  @FrontMcp({
@@ -19,8 +19,7 @@ Set up the canonical file structure for a standalone FrontMCP project with one a
19
19
 
20
20
  ```typescript
21
21
  // src/tools/fetch-weather.tool.ts
22
- import { Tool, ToolContext } from '@frontmcp/sdk';
23
- import { z } from 'zod';
22
+ import { Tool, ToolContext, z } from '@frontmcp/sdk';
24
23
 
25
24
  @Tool({
26
25
  name: 'fetch_weather',
@@ -37,6 +36,7 @@ export default class FetchWeatherTool extends ToolContext {
37
36
  ```typescript
38
37
  // src/my-app.app.ts
39
38
  import { App } from '@frontmcp/sdk';
39
+
40
40
  import FetchWeatherTool from './tools/fetch-weather.tool';
41
41
 
42
42
  @App({
@@ -49,7 +49,9 @@ export class MyApp {}
49
49
  ```typescript
50
50
  // src/main.ts
51
51
  import 'reflect-metadata';
52
+
52
53
  import { FrontMcp } from '@frontmcp/sdk';
54
+
53
55
  import { MyApp } from './my-app.app';
54
56
 
55
57
  @FrontMcp({
@@ -20,8 +20,7 @@ Scaffold a minimal FrontMCP server with one app and one tool, running on Node.js
20
20
 
21
21
  ```typescript
22
22
  // src/tools/add.tool.ts
23
- import { Tool, ToolContext } from '@frontmcp/sdk';
24
- import { z } from 'zod';
23
+ import { Tool, ToolContext, z } from '@frontmcp/sdk';
25
24
 
26
25
  @Tool({
27
26
  name: 'add',
@@ -41,6 +40,7 @@ export default class AddTool extends ToolContext {
41
40
  ```typescript
42
41
  // src/apps/calc.app.ts
43
42
  import { App } from '@frontmcp/sdk';
43
+
44
44
  import AddTool from '../tools/add.tool';
45
45
 
46
46
  @App({
@@ -53,7 +53,9 @@ export class CalcApp {}
53
53
  ```typescript
54
54
  // src/main.ts
55
55
  import 'reflect-metadata';
56
+
56
57
  import { FrontMcp } from '@frontmcp/sdk';
58
+
57
59
  import { CalcApp } from './apps/calc.app';
58
60
 
59
61
  @FrontMcp({
@@ -19,8 +19,7 @@ Configure a FrontMCP server for Vercel deployment with Vercel KV storage and mod
19
19
 
20
20
  ```typescript
21
21
  // src/tools/lookup-user.tool.ts
22
- import { Tool, ToolContext } from '@frontmcp/sdk';
23
- import { z } from 'zod';
22
+ import { Tool, ToolContext, z } from '@frontmcp/sdk';
24
23
 
25
24
  @Tool({
26
25
  name: 'lookup_user',
@@ -37,6 +36,7 @@ export default class LookupUserTool extends ToolContext {
37
36
  ```typescript
38
37
  // src/apps/users.app.ts
39
38
  import { App } from '@frontmcp/sdk';
39
+
40
40
  import LookupUserTool from '../tools/lookup-user.tool';
41
41
 
42
42
  @App({
@@ -49,7 +49,9 @@ export class UsersApp {}
49
49
  ```typescript
50
50
  // src/main.ts
51
51
  import 'reflect-metadata';
52
+
52
53
  import { FrontMcp } from '@frontmcp/sdk';
54
+
53
55
  import { UsersApp } from './apps/users.app';
54
56
 
55
57
  @FrontMcp({
@@ -2,18 +2,20 @@
2
2
  name: hybrid-vercel-kv-with-pubsub
3
3
  reference: setup-redis
4
4
  level: advanced
5
- description: 'Use Vercel KV for session storage and a separate Redis instance for pub/sub resource subscriptions.'
5
+ description: 'Use Vercel KV for session storage and a separate Redis instance for pub/sub resource subscriptions in distributed multi-instance deployments.'
6
6
  tags: [setup, vercel-kv, redis, vercel, session, hybrid]
7
7
  features:
8
8
  - 'Vercel KV handles sessions (`redis` config) while a real Redis handles pub/sub (`pubsub` config)'
9
- - 'Vercel KV does not support pub/sub operations, so a separate Redis instance is required'
10
- - 'Resources with `subscribe: true` rely on the `pubsub` config for real-time notifications'
9
+ - 'Vercel KV does not support pub/sub operations, so a separate Redis instance is required for distributed setups'
10
+ - 'Resource subscriptions across multiple server instances rely on the `pubsub` config for cross-instance notifications (single-instance servers use in-memory subscriptions automatically)'
11
11
  - "The `pubsub` field accepts `provider: 'redis'` only (no Vercel KV support)"
12
12
  ---
13
13
 
14
14
  # Hybrid Vercel KV with Redis Pub/Sub
15
15
 
16
- Use Vercel KV for session storage and a separate Redis instance for pub/sub resource subscriptions.
16
+ Use Vercel KV for session storage and a separate Redis instance for pub/sub resource subscriptions in distributed multi-instance deployments.
17
+
18
+ > **Note:** Single-server deployments (stdio, binary, or single-instance HTTP) do not need pub/sub — resource subscriptions work in-memory out of the box.
17
19
 
18
20
  ## Code
19
21
 
@@ -50,7 +52,6 @@ import { Resource, ResourceContext } from '@frontmcp/sdk';
50
52
  uri: 'metrics://live',
51
53
  name: 'Live Metrics',
52
54
  mimeType: 'application/json',
53
- subscribe: true,
54
55
  })
55
56
  export default class LiveMetricsResource extends ResourceContext {
56
57
  async read() {
@@ -69,8 +70,8 @@ REDIS_PUBSUB_PASSWORD=secret
69
70
  ## What This Demonstrates
70
71
 
71
72
  - Vercel KV handles sessions (`redis` config) while a real Redis handles pub/sub (`pubsub` config)
72
- - Vercel KV does not support pub/sub operations, so a separate Redis instance is required
73
- - Resources with `subscribe: true` rely on the `pubsub` config for real-time notifications
73
+ - Vercel KV does not support pub/sub operations, so a separate Redis instance is required for distributed setups
74
+ - Resource subscriptions across multiple server instances rely on the `pubsub` config for cross-instance notifications (single-instance servers use in-memory subscriptions automatically)
74
75
  - The `pubsub` field accepts `provider: 'redis'` only (no Vercel KV support)
75
76
 
76
77
  ## Related
@@ -141,6 +141,7 @@ The `@FrontMcp` decorator accepts a `FrontMcpMetadata` object with these fields:
141
141
 
142
142
  ```typescript
143
143
  import 'reflect-metadata';
144
+
144
145
  import { FrontMcp } from '@frontmcp/sdk';
145
146
 
146
147
  @FrontMcp({
@@ -180,6 +181,7 @@ export default class Server {}
180
181
 
181
182
  ```typescript
182
183
  import 'reflect-metadata';
184
+
183
185
  import { FrontMcp } from '@frontmcp/sdk';
184
186
 
185
187
  @FrontMcp({
@@ -225,8 +227,7 @@ export default class Server {}
225
227
  Create `src/tools/add.tool.ts`:
226
228
 
227
229
  ```typescript
228
- import { Tool, ToolContext } from '@frontmcp/sdk';
229
- import { z } from 'zod';
230
+ import { Tool, ToolContext, z } from '@frontmcp/sdk';
230
231
 
231
232
  @Tool({
232
233
  name: 'add',
@@ -249,6 +250,7 @@ Create `src/apps/calc.app.ts`:
249
250
 
250
251
  ```typescript
251
252
  import { App } from '@frontmcp/sdk';
253
+
252
254
  import AddTool from '../tools/add.tool';
253
255
 
254
256
  @App({
@@ -276,7 +278,9 @@ Update `src/main.ts`:
276
278
 
277
279
  ```typescript
278
280
  import 'reflect-metadata';
281
+
279
282
  import { FrontMcp } from '@frontmcp/sdk';
283
+
280
284
  import { CalcApp } from './apps/calc.app';
281
285
 
282
286
  @FrontMcp({
@@ -292,24 +296,21 @@ Resources, Prompts, and Skills follow the same decorator pattern:
292
296
 
293
297
  ```typescript
294
298
  // Resource - returns MCP ReadResourceResult
295
- import { Resource, ResourceContext } from '@frontmcp/sdk';
299
+ // Prompt - returns MCP GetPromptResult
300
+
301
+ // Skill - compound capability with tools + instructions
302
+ import { Prompt, PromptContext, Resource, ResourceContext, Skill, SkillContext } from '@frontmcp/sdk';
296
303
 
297
304
  @Resource({ uri: 'config://app', name: 'App Config', mimeType: 'application/json' })
298
305
  export default class AppConfigResource extends ResourceContext {
299
306
  /* ... */
300
307
  }
301
308
 
302
- // Prompt - returns MCP GetPromptResult
303
- import { Prompt, PromptContext } from '@frontmcp/sdk';
304
-
305
309
  @Prompt({ name: 'summarize', description: 'Summarize a document' })
306
310
  export default class SummarizePrompt extends PromptContext {
307
311
  /* ... */
308
312
  }
309
313
 
310
- // Skill - compound capability with tools + instructions
311
- import { Skill, SkillContext } from '@frontmcp/sdk';
312
-
313
314
  @Skill({ name: 'data-analysis', description: 'Analyze datasets' })
314
315
  export default class DataAnalysisSkill extends SkillContext {
315
316
  /* ... */
@@ -15,15 +15,16 @@ description: Provision and configure Redis or Vercel KV for session storage and
15
15
 
16
16
  ### Recommended
17
17
 
18
- - Resource subscriptions with `subscribe: true` are enabled and need pub/sub
18
+ - Resource subscriptions with `subscribe: true` across **multiple server instances** (distributed pub/sub)
19
19
  - Auth sessions or elicitation state must persist across server restarts
20
20
  - Distributed rate limiting is configured in the throttle guard
21
21
 
22
22
  ### Skip When
23
23
 
24
- - Running a single-instance stdio-only server for local development -- use `setup-sqlite` or in-memory stores
24
+ - Running a single-instance stdio-only server for local development -- use `setup-sqlite` or in-memory stores (resource subscriptions work in-memory without Redis)
25
25
  - Only need to configure session TTL and key prefix on an already-provisioned Redis -- use `configure-session`
26
26
  - Deploying a read-only MCP server with no sessions, subscriptions, or stateful tools
27
+ - Using resource subscriptions on a single server instance -- subscriptions work in-memory out of the box
27
28
 
28
29
  > **Decision:** Use this skill to provision and connect Redis (Docker, existing instance, or Vercel KV); use `configure-session` to tune session-specific options after Redis is available.
29
30
 
@@ -217,9 +218,11 @@ const sessionStore = createSessionStoreSync({
217
218
  });
218
219
  ```
219
220
 
220
- ## Step 4 -- Pub/Sub for Resource Subscriptions
221
+ ## Step 4 -- Pub/Sub for Resource Subscriptions (Multi-Instance Only)
221
222
 
222
- If your server exposes resources with `subscribe: true`, you need pub/sub. Pub/sub requires a real Redis instance -- Vercel KV does not support pub/sub operations.
223
+ > **Single-server note:** If you run a single server instance (stdio, binary, or single-instance HTTP), resource subscriptions work in-memory without any Redis or pub/sub configuration. Skip this step for local development and single-server deployments.
224
+
225
+ For **distributed multi-instance** deployments where subscription state must be shared across server instances, you need pub/sub. Pub/sub requires a real Redis instance -- Vercel KV does not support pub/sub operations.
223
226
 
224
227
  For a hybrid setup (Vercel KV for sessions, Redis for pub/sub):
225
228
 
@@ -318,13 +321,13 @@ You should see session keys like `mcp:session:<session-id>`.
318
321
 
319
322
  ## Common Patterns
320
323
 
321
- | Pattern | Correct | Incorrect | Why |
322
- | ---------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
323
- | Redis provider field | `redis: { provider: 'redis', host: '...', port: 6379 }` | `redis: { host: '...', port: 6379 }` without `provider` | Both forms are type-safe (the SDK's `RedisOptions` union accepts both shapes), but explicit `provider: 'redis'` improves clarity and intent |
324
- | Environment variables | `host: process.env['REDIS_HOST'] ?? 'localhost'` | Hardcoding `host: 'redis.internal'` in source | Hardcoded values break across environments (dev, staging, prod); always read from env with a sensible fallback |
325
- | Vercel KV credentials | Let Vercel auto-inject `KV_REST_API_URL` and `KV_REST_API_TOKEN` | Manually setting KV tokens in the `redis` config object | Auto-injection is safer and ensures tokens rotate correctly; manual values risk stale or committed secrets |
326
- | Docker persistence | `command: redis-server --appendonly yes` in docker-compose | Running Redis without `--appendonly` in development | Without AOF persistence, data is lost on container restart; `--appendonly yes` preserves data across restarts |
327
- | Pub/sub with Vercel KV | Separate `pubsub: { provider: 'redis', ... }` alongside `redis: { provider: 'vercel-kv' }` | Expecting Vercel KV to handle pub/sub | Vercel KV does not support pub/sub; a real Redis instance is required for resource subscriptions |
324
+ | Pattern | Correct | Incorrect | Why |
325
+ | ---------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
326
+ | Redis provider field | `redis: { provider: 'redis', host: '...', port: 6379 }` | `redis: { host: '...', port: 6379 }` without `provider` | Both forms are type-safe (the SDK's `RedisOptions` union accepts both shapes), but explicit `provider: 'redis'` improves clarity and intent |
327
+ | Environment variables | `host: process.env['REDIS_HOST'] ?? 'localhost'` | Hardcoding `host: 'redis.internal'` in source | Hardcoded values break across environments (dev, staging, prod); always read from env with a sensible fallback |
328
+ | Vercel KV credentials | Let Vercel auto-inject `KV_REST_API_URL` and `KV_REST_API_TOKEN` | Manually setting KV tokens in the `redis` config object | Auto-injection is safer and ensures tokens rotate correctly; manual values risk stale or committed secrets |
329
+ | Docker persistence | `command: redis-server --appendonly yes` in docker-compose | Running Redis without `--appendonly` in development | Without AOF persistence, data is lost on container restart; `--appendonly yes` preserves data across restarts |
330
+ | Pub/sub with Vercel KV | Separate `pubsub: { provider: 'redis', ... }` alongside `redis: { provider: 'vercel-kv' }` | Expecting Vercel KV to handle pub/sub | Vercel KV does not support pub/sub; a real Redis instance is required for distributed resource subscriptions (single-instance servers use in-memory subscriptions and do not need pub/sub) |
328
331
 
329
332
  ## Verification Checklist
330
333
 
@@ -359,11 +362,11 @@ You should see session keys like `mcp:session:<session-id>`.
359
362
 
360
363
  ## Examples
361
364
 
362
- | Example | Level | Description |
363
- | ----------------------------------------------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------- |
364
- | [`docker-redis-local-dev`](../examples/setup-redis/docker-redis-local-dev.md) | Basic | Provision Redis with Docker Compose and connect a FrontMCP server for local session storage. |
365
- | [`hybrid-vercel-kv-with-pubsub`](../examples/setup-redis/hybrid-vercel-kv-with-pubsub.md) | Advanced | Use Vercel KV for session storage and a separate Redis instance for pub/sub resource subscriptions. |
366
- | [`vercel-kv-serverless`](../examples/setup-redis/vercel-kv-serverless.md) | Intermediate | Configure a FrontMCP server with Vercel KV as the session store for serverless deployment. |
365
+ | Example | Level | Description |
366
+ | ----------------------------------------------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
367
+ | [`docker-redis-local-dev`](../examples/setup-redis/docker-redis-local-dev.md) | Basic | Provision Redis with Docker Compose and connect a FrontMCP server for local session storage. |
368
+ | [`hybrid-vercel-kv-with-pubsub`](../examples/setup-redis/hybrid-vercel-kv-with-pubsub.md) | Advanced | Use Vercel KV for session storage and a separate Redis instance for pub/sub resource subscriptions in distributed multi-instance deployments. |
369
+ | [`vercel-kv-serverless`](../examples/setup-redis/vercel-kv-serverless.md) | Intermediate | Configure a FrontMCP server with Vercel KV as the session store for serverless deployment. |
367
370
 
368
371
  > See all examples in [`examples/setup-redis/`](../examples/setup-redis/)
369
372
 
@@ -19,9 +19,7 @@ Test tools in-memory without any HTTP overhead using the `create()` function fro
19
19
 
20
20
  ```typescript
21
21
  // src/__tests__/direct-client.spec.ts
22
- import { create } from '@frontmcp/sdk';
23
- import { tool } from '@frontmcp/sdk';
24
- import { z } from 'zod';
22
+ import { create, tool, z } from '@frontmcp/sdk';
25
23
 
26
24
  const AddTool = tool({
27
25
  name: 'add',
@@ -19,9 +19,7 @@ Verify that tools are returned in the correct format for OpenAI and Claude clien
19
19
 
20
20
  ```typescript
21
21
  // src/__tests__/client-formats.spec.ts
22
- import { connectOpenAI } from '@frontmcp/sdk';
23
- import { tool } from '@frontmcp/sdk';
24
- import { z } from 'zod';
22
+ import { connectOpenAI, tool, z } from '@frontmcp/sdk';
25
23
 
26
24
  const AddTool = tool({
27
25
  name: 'add',
@@ -19,8 +19,8 @@ Validate that a tool's Zod input schema rejects invalid data before `execute()`
19
19
 
20
20
  ```typescript
21
21
  // src/tools/__tests__/add.tool.schema.spec.ts
22
- import { z } from 'zod';
23
- import { ToolContext } from '@frontmcp/sdk';
22
+ import { ToolContext, z } from '@frontmcp/sdk';
23
+
24
24
  import { AddTool } from '../add.tool';
25
25
 
26
26
  describe('AddTool schema validation', () => {
@@ -8,9 +8,7 @@ description: In-memory testing with create() and connectOpenAI/connectClaude wit
8
8
  Uses `connect()` or `create()` for in-memory testing without HTTP overhead.
9
9
 
10
10
  ```typescript
11
- import { create, connectOpenAI } from '@frontmcp/sdk';
12
- import { tool } from '@frontmcp/sdk';
13
- import { z } from 'zod';
11
+ import { connectOpenAI, create, tool, z } from '@frontmcp/sdk';
14
12
 
15
13
  const AddTool = tool({
16
14
  name: 'add',
@@ -6,8 +6,8 @@ description: Unit test a ToolContext execute method with mock context, inputs, a
6
6
  # Unit Testing a Tool
7
7
 
8
8
  ```typescript
9
- import { z } from 'zod';
10
- import { ToolContext } from '@frontmcp/sdk';
9
+ import { ToolContext, z } from '@frontmcp/sdk';
10
+
11
11
  import { AddTool } from '../tools/add.tool';
12
12
 
13
13
  describe('AddTool', () => {