@frontmcp/skills 0.0.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 (65) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +135 -0
  3. package/catalog/TEMPLATE.md +49 -0
  4. package/catalog/adapters/create-adapter/SKILL.md +127 -0
  5. package/catalog/adapters/official-adapters/SKILL.md +136 -0
  6. package/catalog/auth/configure-auth/SKILL.md +250 -0
  7. package/catalog/auth/configure-auth/references/auth-modes.md +77 -0
  8. package/catalog/auth/configure-session/SKILL.md +201 -0
  9. package/catalog/config/configure-elicitation/SKILL.md +136 -0
  10. package/catalog/config/configure-http/SKILL.md +167 -0
  11. package/catalog/config/configure-throttle/SKILL.md +189 -0
  12. package/catalog/config/configure-throttle/references/guard-config.md +68 -0
  13. package/catalog/config/configure-transport/SKILL.md +151 -0
  14. package/catalog/config/configure-transport/references/protocol-presets.md +57 -0
  15. package/catalog/deployment/build-for-browser/SKILL.md +95 -0
  16. package/catalog/deployment/build-for-cli/SKILL.md +100 -0
  17. package/catalog/deployment/build-for-sdk/SKILL.md +218 -0
  18. package/catalog/deployment/deploy-to-cloudflare/SKILL.md +192 -0
  19. package/catalog/deployment/deploy-to-lambda/SKILL.md +304 -0
  20. package/catalog/deployment/deploy-to-node/SKILL.md +229 -0
  21. package/catalog/deployment/deploy-to-node/references/Dockerfile.example +45 -0
  22. package/catalog/deployment/deploy-to-vercel/SKILL.md +196 -0
  23. package/catalog/deployment/deploy-to-vercel/references/vercel.json.example +60 -0
  24. package/catalog/development/create-agent/SKILL.md +563 -0
  25. package/catalog/development/create-agent/references/llm-config.md +46 -0
  26. package/catalog/development/create-job/SKILL.md +566 -0
  27. package/catalog/development/create-prompt/SKILL.md +400 -0
  28. package/catalog/development/create-provider/SKILL.md +233 -0
  29. package/catalog/development/create-resource/SKILL.md +437 -0
  30. package/catalog/development/create-skill/SKILL.md +526 -0
  31. package/catalog/development/create-skill-with-tools/SKILL.md +579 -0
  32. package/catalog/development/create-tool/SKILL.md +418 -0
  33. package/catalog/development/create-tool/references/output-schema-types.md +56 -0
  34. package/catalog/development/create-tool/references/tool-annotations.md +34 -0
  35. package/catalog/development/create-workflow/SKILL.md +709 -0
  36. package/catalog/development/decorators-guide/SKILL.md +598 -0
  37. package/catalog/plugins/create-plugin/SKILL.md +336 -0
  38. package/catalog/plugins/create-plugin-hooks/SKILL.md +282 -0
  39. package/catalog/plugins/official-plugins/SKILL.md +667 -0
  40. package/catalog/setup/frontmcp-skills-usage/SKILL.md +200 -0
  41. package/catalog/setup/multi-app-composition/SKILL.md +358 -0
  42. package/catalog/setup/nx-workflow/SKILL.md +357 -0
  43. package/catalog/setup/project-structure-nx/SKILL.md +186 -0
  44. package/catalog/setup/project-structure-standalone/SKILL.md +153 -0
  45. package/catalog/setup/setup-project/SKILL.md +493 -0
  46. package/catalog/setup/setup-redis/SKILL.md +385 -0
  47. package/catalog/setup/setup-sqlite/SKILL.md +359 -0
  48. package/catalog/skills-manifest.json +414 -0
  49. package/catalog/testing/setup-testing/SKILL.md +539 -0
  50. package/catalog/testing/setup-testing/references/test-auth.md +88 -0
  51. package/catalog/testing/setup-testing/references/test-browser-build.md +57 -0
  52. package/catalog/testing/setup-testing/references/test-cli-binary.md +48 -0
  53. package/catalog/testing/setup-testing/references/test-direct-client.md +62 -0
  54. package/catalog/testing/setup-testing/references/test-e2e-handler.md +51 -0
  55. package/catalog/testing/setup-testing/references/test-tool-unit.md +41 -0
  56. package/package.json +34 -0
  57. package/src/index.d.ts +3 -0
  58. package/src/index.js +16 -0
  59. package/src/index.js.map +1 -0
  60. package/src/loader.d.ts +46 -0
  61. package/src/loader.js +75 -0
  62. package/src/loader.js.map +1 -0
  63. package/src/manifest.d.ts +81 -0
  64. package/src/manifest.js +26 -0
  65. package/src/manifest.js.map +1 -0
@@ -0,0 +1,667 @@
1
+ ---
2
+ name: official-plugins
3
+ description: Install and configure official FrontMCP plugins including CodeCall, Remember, Approval, Cache, Feature Flags, and Dashboard. Use when adding caching, memory, tool approval, feature gating, or CodeCall orchestration.
4
+ tags: [plugins, codecall, remember, approval, cache, feature-flags, dashboard]
5
+ priority: 9
6
+ visibility: both
7
+ license: Apache-2.0
8
+ metadata:
9
+ docs: https://docs.agentfront.dev/frontmcp/plugins/overview
10
+ ---
11
+
12
+ # Official FrontMCP Plugins
13
+
14
+ FrontMCP ships 6 official plugins that extend server behavior with cross-cutting concerns: semantic tool discovery, session memory, authorization workflows, result caching, feature gating, and visual monitoring. Install individually or via `@frontmcp/plugins` (meta-package re-exporting cache, codecall, dashboard, and remember).
15
+
16
+ All plugins follow the `DynamicPlugin` pattern and are registered via `@FrontMcp({ plugins: [...] })`.
17
+
18
+ ```typescript
19
+ import { FrontMcp } from '@frontmcp/sdk';
20
+ import CodeCallPlugin from '@frontmcp/plugin-codecall';
21
+ import RememberPlugin from '@frontmcp/plugin-remember';
22
+ import { ApprovalPlugin } from '@frontmcp/plugin-approval';
23
+ import CachePlugin from '@frontmcp/plugin-cache';
24
+ import FeatureFlagPlugin from '@frontmcp/plugin-feature-flags';
25
+ import DashboardPlugin from '@frontmcp/plugin-dashboard';
26
+
27
+ @App()
28
+ class MyApp {}
29
+
30
+ @FrontMcp({
31
+ info: { name: 'my-server', version: '1.0.0' },
32
+ apps: [MyApp],
33
+ plugins: [
34
+ CodeCallPlugin.init({ mode: 'codecall_only', vm: { preset: 'secure' } }),
35
+ RememberPlugin.init({ type: 'memory' }),
36
+ ApprovalPlugin.init({ mode: 'recheck' }),
37
+ CachePlugin.init({ type: 'memory', defaultTTL: 86400 }),
38
+ FeatureFlagPlugin.init({ adapter: 'static', flags: { 'new-tool': true } }),
39
+ DashboardPlugin.init({ enabled: true }),
40
+ ],
41
+ tools: [
42
+ /* your tools */
43
+ ],
44
+ })
45
+ class MyServer {}
46
+ ```
47
+
48
+ ---
49
+
50
+ ## 1. CodeCall Plugin (`@frontmcp/plugin-codecall`)
51
+
52
+ Meta-tools for semantic search and sandboxed VM execution of tools. The AI discovers, describes, and orchestrates your tools via AgentScript instead of calling them individually.
53
+
54
+ ### Installation
55
+
56
+ ```typescript
57
+ import CodeCallPlugin from '@frontmcp/plugin-codecall';
58
+
59
+ @FrontMcp({
60
+ plugins: [
61
+ CodeCallPlugin.init({
62
+ mode: 'codecall_only', // 'codecall_only' | 'codecall_opt_in' | 'metadata_driven'
63
+ topK: 8, // Number of search results returned
64
+ maxDefinitions: 8, // Max tool definitions per describe call
65
+ vm: {
66
+ preset: 'secure', // 'locked_down' | 'secure' | 'balanced' | 'experimental'
67
+ timeoutMs: 5000,
68
+ allowLoops: false,
69
+ },
70
+ embedding: {
71
+ strategy: 'tfidf', // 'tfidf' | 'ml'
72
+ synonymExpansion: { enabled: true },
73
+ },
74
+ }),
75
+ ],
76
+ })
77
+ class MyServer {}
78
+ ```
79
+
80
+ ### Modes
81
+
82
+ - `codecall_only` -- Hides all tools from `list_tools` except CodeCall meta-tools. All other tools are discovered only via `codecall:search`. Best when the server has a large number of tools and you want the AI to search-then-execute.
83
+ - `codecall_opt_in` -- Shows all tools in `list_tools` normally. Tools opt-in to CodeCall execution via metadata. Useful when only some tools benefit from orchestrated execution.
84
+ - `metadata_driven` -- Per-tool `metadata.codecall` controls visibility and CodeCall availability independently. Most granular control.
85
+
86
+ ### VM Presets
87
+
88
+ The sandboxed VM runs AgentScript (a restricted JavaScript subset). Presets control security boundaries:
89
+
90
+ - `locked_down` -- Most restrictive. No loops, no console, minimal builtins. Suitable for untrusted environments.
91
+ - `secure` -- Default. Reasonable limits for production use. Loops disabled, console available.
92
+ - `balanced` -- Relaxed constraints for development. Loops allowed with iteration limits.
93
+ - `experimental` -- Minimal restrictions. Full loop support, extended builtins. Development only.
94
+
95
+ ### Meta-Tools Exposed
96
+
97
+ CodeCall contributes 4 tools to your server:
98
+
99
+ - `codecall:search` -- Semantic search over all registered tools using TF-IDF scoring with synonym expansion. Returns ranked tool names, descriptions, and relevance scores.
100
+ - `codecall:describe` -- Returns full input/output JSON schemas for one or more tools. Use after search to understand tool interfaces before execution.
101
+ - `codecall:execute` -- Runs an AgentScript program in the sandboxed VM. The script can call multiple tools, branch on results, and compose outputs.
102
+ - `codecall:invoke` -- Direct single-tool invocation (available when `directCalls` is enabled). Bypasses the VM for simple one-shot calls.
103
+
104
+ ### Per-Tool CodeCall Metadata
105
+
106
+ Control how individual tools interact with CodeCall:
107
+
108
+ ```typescript
109
+ @Tool({
110
+ name: 'my_tool',
111
+ codecall: {
112
+ visibleInListTools: false, // Hide from list_tools (only discoverable via codecall:search)
113
+ enabledInCodeCall: true, // Available for execution via codecall:execute
114
+ tags: ['data', 'query'], // Extra indexing hints for semantic search
115
+ },
116
+ })
117
+ class MyTool extends ToolContext {
118
+ /* ... */
119
+ }
120
+ ```
121
+
122
+ ### Power Features
123
+
124
+ - **TF-IDF Search** -- Term frequency-inverse document frequency scoring indexes tool names, descriptions, and tags. No external embedding service required.
125
+ - **Synonym Expansion** -- Automatically expands search queries with synonyms (e.g., "delete" also matches "remove", "erase"). Enable via `embedding.synonymExpansion.enabled`.
126
+ - **Pass-by-Reference via Sidecar** -- Large results are stored in a sidecar map and passed by reference between tool calls in AgentScript, avoiding serialization overhead.
127
+
128
+ ---
129
+
130
+ ## 2. Remember Plugin (`@frontmcp/plugin-remember`)
131
+
132
+ Encrypted session memory with multi-scope persistence. Tools can remember values across invocations and sessions using a human-friendly API.
133
+
134
+ ### Installation
135
+
136
+ ```typescript
137
+ import RememberPlugin from '@frontmcp/plugin-remember';
138
+
139
+ // In-memory (development)
140
+ @FrontMcp({
141
+ plugins: [RememberPlugin.init({ type: 'memory' })],
142
+ })
143
+ class DevServer {}
144
+
145
+ // Redis (production)
146
+ @FrontMcp({
147
+ plugins: [
148
+ RememberPlugin.init({
149
+ type: 'redis',
150
+ config: { host: 'localhost', port: 6379 },
151
+ keyPrefix: 'remember:',
152
+ encryption: { enabled: true },
153
+ tools: { enabled: true }, // Expose LLM tools
154
+ }),
155
+ ],
156
+ })
157
+ class ProdServer {}
158
+
159
+ // Redis client (bring your own ioredis instance)
160
+ @FrontMcp({
161
+ plugins: [
162
+ RememberPlugin.init({
163
+ type: 'redis-client',
164
+ client: existingRedisClient,
165
+ }),
166
+ ],
167
+ })
168
+ class ClientServer {}
169
+
170
+ // Vercel KV
171
+ @FrontMcp({
172
+ plugins: [RememberPlugin.init({ type: 'vercel-kv' })],
173
+ })
174
+ class VercelServer {}
175
+
176
+ // Global store (uses @FrontMcp redis config)
177
+ @FrontMcp({
178
+ redis: { host: 'localhost', port: 6379 },
179
+ plugins: [RememberPlugin.init({ type: 'global-store' })],
180
+ })
181
+ class GlobalStoreServer {}
182
+ ```
183
+
184
+ ### Storage Types
185
+
186
+ - `memory` -- In-process Map. Fastest, no persistence. Good for development.
187
+ - `redis` -- Dedicated Redis connection. Plugin manages the client lifecycle.
188
+ - `redis-client` -- Bring your own ioredis client instance.
189
+ - `vercel-kv` -- Vercel KV (Redis-compatible). Uses `@vercel/kv` package.
190
+ - `global-store` -- Reuses the Redis connection from `@FrontMcp({ redis: {...} })`.
191
+
192
+ ### Using `this.remember` in Tools
193
+
194
+ ```typescript
195
+ @Tool({ name: 'my_tool' })
196
+ class MyTool extends ToolContext {
197
+ async execute(input: { query: string }) {
198
+ // Store values (default scope: 'session')
199
+ await this.remember.set('theme', 'dark');
200
+ await this.remember.set('language', 'en', { scope: 'user' });
201
+ await this.remember.set('temp_token', 'xyz', { ttl: 300 });
202
+
203
+ // Retrieve values
204
+ const theme = await this.remember.get('theme', { defaultValue: 'light' });
205
+
206
+ // Check existence
207
+ if (await this.remember.knows('onboarding_complete')) {
208
+ // Skip onboarding
209
+ }
210
+
211
+ // Remove values
212
+ await this.remember.forget('temp_token');
213
+
214
+ // List keys matching pattern
215
+ const keys = await this.remember.list({ pattern: 'user:*' });
216
+
217
+ return { content: [{ type: 'text', text: `Theme: ${theme}` }] };
218
+ }
219
+ }
220
+ ```
221
+
222
+ ### Memory Scopes
223
+
224
+ - `session` -- Valid only for the current session. Default scope. Cleared when the session ends.
225
+ - `user` -- Persists for the user across sessions. Tied to user identity.
226
+ - `tool` -- Scoped to a specific tool + session combination. Isolated per tool.
227
+ - `global` -- Shared across all sessions and users. Use carefully.
228
+
229
+ ### Tools Exposed (when `tools.enabled: true`)
230
+
231
+ - `remember_this` -- Store a key-value pair in memory
232
+ - `recall` -- Retrieve a previously stored value by key
233
+ - `forget` -- Remove a stored value by key
234
+ - `list_memories` -- List all stored keys, optionally filtered by pattern
235
+
236
+ ---
237
+
238
+ ## 3. Approval Plugin (`@frontmcp/plugin-approval`)
239
+
240
+ Tool authorization workflow with PKCE webhook security. Require explicit user or system approval before sensitive tools execute.
241
+
242
+ ### Installation
243
+
244
+ ```typescript
245
+ import { ApprovalPlugin } from '@frontmcp/plugin-approval';
246
+
247
+ // Recheck mode (default) -- re-evaluates approval on each call
248
+ @FrontMcp({
249
+ plugins: [ApprovalPlugin.init()],
250
+ })
251
+ class BasicServer {}
252
+
253
+ // Recheck mode with explicit config
254
+ @FrontMcp({
255
+ plugins: [
256
+ ApprovalPlugin.init({
257
+ mode: 'recheck',
258
+ enableAudit: true,
259
+ }),
260
+ ],
261
+ })
262
+ class AuditedServer {}
263
+
264
+ // Webhook mode -- PKCE-secured external approval flow
265
+ @FrontMcp({
266
+ plugins: [
267
+ ApprovalPlugin.init({
268
+ mode: 'webhook',
269
+ webhook: {
270
+ url: 'https://approval.example.com/webhook',
271
+ challengeTtl: 300,
272
+ callbackPath: '/approval/callback',
273
+ },
274
+ enableAudit: true,
275
+ maxDelegationDepth: 3,
276
+ }),
277
+ ],
278
+ })
279
+ class WebhookServer {}
280
+ ```
281
+
282
+ ### Modes
283
+
284
+ - `recheck` -- Re-evaluates approval status on every tool call. Approval can be granted programmatically via `this.approval.grantSessionApproval()`. Good for interactive approval flows where the user confirms in-band.
285
+ - `webhook` -- Sends a PKCE-secured webhook to an external approval service. The external service calls back to confirm or deny. Suitable for compliance workflows requiring out-of-band approval.
286
+
287
+ ### Using `this.approval` in Tools
288
+
289
+ ```typescript
290
+ @Tool({ name: 'dangerous_action' })
291
+ class DangerousActionTool extends ToolContext {
292
+ async execute(input: { target: string }) {
293
+ // Check if tool is currently approved
294
+ const isApproved = await this.approval.isApproved('dangerous_action');
295
+
296
+ if (!isApproved) {
297
+ // Grant session-scoped approval programmatically
298
+ await this.approval.grantSessionApproval('dangerous_action', {
299
+ reason: 'User confirmed via prompt',
300
+ });
301
+ }
302
+
303
+ // Additional approval API methods:
304
+ // await this.approval.getApproval('tool-id') -- Get approval record
305
+ // await this.approval.getSessionApprovals() -- List session approvals
306
+ // await this.approval.getUserApprovals() -- List user approvals
307
+ // await this.approval.grantUserApproval('tool-id') -- Persist across sessions
308
+ // await this.approval.grantTimeLimitedApproval('tool-id', 60000) -- Auto-expire
309
+ // await this.approval.revokeApproval('tool-id') -- Revoke any approval
310
+
311
+ return { content: [{ type: 'text', text: 'Action completed' }] };
312
+ }
313
+ }
314
+ ```
315
+
316
+ ### Per-Tool Approval Metadata
317
+
318
+ ```typescript
319
+ @Tool({
320
+ name: 'file_write',
321
+ approval: {
322
+ required: true,
323
+ defaultScope: 'session', // 'session' | 'user' | 'time-limited'
324
+ category: 'write',
325
+ riskLevel: 'medium', // 'low' | 'medium' | 'high' | 'critical'
326
+ approvalMessage: 'Allow file writing for this session?',
327
+ },
328
+ })
329
+ class FileWriteTool extends ToolContext {
330
+ /* ... */
331
+ }
332
+ ```
333
+
334
+ When `approval.required` is `true`, the plugin automatically intercepts tool execution and checks approval status before allowing the tool to run.
335
+
336
+ ---
337
+
338
+ ## 4. Cache Plugin (`@frontmcp/plugin-cache`)
339
+
340
+ Automatic tool result caching. Cache responses by tool name patterns or per-tool metadata. Supports sliding window TTL and cache bypass headers.
341
+
342
+ ### Installation
343
+
344
+ ```typescript
345
+ import CachePlugin from '@frontmcp/plugin-cache';
346
+
347
+ // In-memory cache
348
+ @FrontMcp({
349
+ plugins: [
350
+ CachePlugin.init({
351
+ type: 'memory',
352
+ defaultTTL: 3600, // 1 hour in seconds
353
+ toolPatterns: ['api:get-*', 'search:*'], // Cache tools matching glob patterns
354
+ bypassHeader: 'x-frontmcp-disable-cache', // Header to skip cache
355
+ }),
356
+ ],
357
+ })
358
+ class CachedServer {}
359
+
360
+ // Redis cache
361
+ @FrontMcp({
362
+ plugins: [
363
+ CachePlugin.init({
364
+ type: 'redis',
365
+ config: { host: 'localhost', port: 6379 },
366
+ defaultTTL: 86400, // 1 day in seconds
367
+ }),
368
+ ],
369
+ })
370
+ class RedisCachedServer {}
371
+
372
+ // Global store (uses @FrontMcp redis config)
373
+ @FrontMcp({
374
+ redis: { host: 'localhost', port: 6379 },
375
+ plugins: [CachePlugin.init({ type: 'global-store' })],
376
+ })
377
+ class GlobalCacheServer {}
378
+ ```
379
+
380
+ ### Storage Types
381
+
382
+ - `memory` -- In-process Map with automatic eviction. No external dependencies.
383
+ - `redis` -- Dedicated Redis connection with native TTL support. Plugin manages the client.
384
+ - `redis-client` -- Bring your own ioredis client instance.
385
+ - `global-store` -- Reuses the Redis connection from `@FrontMcp({ redis: {...} })`.
386
+
387
+ ### Per-Tool Cache Metadata
388
+
389
+ Enable caching on individual tools via the `cache` metadata field:
390
+
391
+ ```typescript
392
+ // Enable caching with default TTL
393
+ @Tool({ name: 'get_weather', cache: true })
394
+ class GetWeatherTool extends ToolContext {
395
+ /* ... */
396
+ }
397
+
398
+ // Custom TTL and sliding window
399
+ @Tool({
400
+ name: 'get_user_profile',
401
+ cache: {
402
+ ttl: 3600, // Override default TTL (seconds)
403
+ slideWindow: true, // Refresh TTL on cache hit
404
+ },
405
+ })
406
+ class GetUserProfileTool extends ToolContext {
407
+ /* ... */
408
+ }
409
+ ```
410
+
411
+ ### Tool Patterns
412
+
413
+ Use glob patterns to cache groups of tools without modifying each tool:
414
+
415
+ ```typescript
416
+ CachePlugin.init({
417
+ type: 'memory',
418
+ defaultTTL: 3600,
419
+ toolPatterns: [
420
+ 'namespace:*', // All tools in a namespace
421
+ 'api:get-*', // All GET-like API tools
422
+ 'search:*', // All search tools
423
+ ],
424
+ });
425
+ ```
426
+
427
+ A tool is cached if it matches any pattern OR has `cache: true` (or a cache object) in its metadata.
428
+
429
+ ### Cache Bypass
430
+
431
+ Send the bypass header to skip caching for a specific request:
432
+
433
+ ```
434
+ x-frontmcp-disable-cache: true
435
+ ```
436
+
437
+ The header name is configurable via `bypassHeader` in the plugin options. Default: `'x-frontmcp-disable-cache'`.
438
+
439
+ ### Cache Key
440
+
441
+ The cache key is computed from the tool name and the serialized input arguments. Two calls with identical tool name and arguments return the same cached result.
442
+
443
+ ---
444
+
445
+ ## 5. Feature Flags Plugin (`@frontmcp/plugin-feature-flags`)
446
+
447
+ Gate tools, resources, prompts, and skills behind feature flags. Integrates with popular feature flag services or static configuration.
448
+
449
+ ### Installation
450
+
451
+ ```typescript
452
+ import FeatureFlagPlugin from '@frontmcp/plugin-feature-flags';
453
+
454
+ // Static flags (no external dependency)
455
+ @FrontMcp({
456
+ plugins: [
457
+ FeatureFlagPlugin.init({
458
+ adapter: 'static',
459
+ flags: {
460
+ 'beta-tools': true,
461
+ 'experimental-agent': false,
462
+ 'new-search': true,
463
+ },
464
+ }),
465
+ ],
466
+ })
467
+ class StaticFlagServer {}
468
+
469
+ // Split.io
470
+ @FrontMcp({
471
+ plugins: [
472
+ FeatureFlagPlugin.init({
473
+ adapter: 'splitio',
474
+ config: { apiKey: 'sdk-key-xxx' },
475
+ }),
476
+ ],
477
+ })
478
+ class SplitServer {}
479
+
480
+ // LaunchDarkly
481
+ @FrontMcp({
482
+ plugins: [
483
+ FeatureFlagPlugin.init({
484
+ adapter: 'launchdarkly',
485
+ config: { sdkKey: 'sdk-xxx' },
486
+ }),
487
+ ],
488
+ })
489
+ class LDServer {}
490
+
491
+ // Unleash
492
+ @FrontMcp({
493
+ plugins: [
494
+ FeatureFlagPlugin.init({
495
+ adapter: 'unleash',
496
+ config: {
497
+ url: 'https://unleash.example.com/api',
498
+ appName: 'my-mcp-server',
499
+ apiKey: 'xxx',
500
+ },
501
+ }),
502
+ ],
503
+ })
504
+ class UnleashServer {}
505
+
506
+ // Custom adapter
507
+ @FrontMcp({
508
+ plugins: [
509
+ FeatureFlagPlugin.init({
510
+ adapter: 'custom',
511
+ adapterInstance: myCustomAdapter,
512
+ }),
513
+ ],
514
+ })
515
+ class CustomFlagServer {}
516
+ ```
517
+
518
+ ### Adapters
519
+
520
+ - `static` -- Hardcoded flag map. No external service. Good for development and testing.
521
+ - `splitio` -- Split.io integration. Requires `@splitsoftware/splitio` package.
522
+ - `launchdarkly` -- LaunchDarkly integration. Requires `launchdarkly-node-server-sdk` package.
523
+ - `unleash` -- Unleash integration. Requires `unleash-client` package.
524
+ - `custom` -- Provide your own adapter instance implementing the `FeatureFlagAdapter` interface.
525
+
526
+ ### Using `this.featureFlags` in Tools
527
+
528
+ ```typescript
529
+ @Tool({ name: 'beta_feature' })
530
+ class BetaFeatureTool extends ToolContext {
531
+ async execute(input: unknown) {
532
+ // Check if a flag is enabled (returns boolean)
533
+ const enabled = await this.featureFlags.isEnabled('beta-feature-flag');
534
+ if (!enabled) {
535
+ return { content: [{ type: 'text', text: 'Feature not available' }] };
536
+ }
537
+
538
+ // Get variant value (for multivariate flags)
539
+ const variant = await this.featureFlags.getVariant('experiment-flag');
540
+ // variant may be 'control', 'treatment-a', 'treatment-b', etc.
541
+
542
+ return { content: [{ type: 'text', text: `Running variant: ${variant}` }] };
543
+ }
544
+ }
545
+ ```
546
+
547
+ ### Per-Tool Feature Flag Gating
548
+
549
+ Tools gated by a feature flag are automatically hidden from `list_tools` and blocked from execution when the flag is off:
550
+
551
+ ```typescript
552
+ // Simple string key -- flag must be truthy to enable the tool
553
+ @Tool({ name: 'beta_tool', featureFlag: 'enable-beta-tools' })
554
+ class BetaTool extends ToolContext {
555
+ /* ... */
556
+ }
557
+
558
+ // Object with default value -- if flag evaluation fails, use the default
559
+ @Tool({
560
+ name: 'experimental_tool',
561
+ featureFlag: { key: 'experimental-flag', defaultValue: false },
562
+ })
563
+ class ExperimentalTool extends ToolContext {
564
+ /* ... */
565
+ }
566
+ ```
567
+
568
+ The plugin hooks into listing and execution flows for tools, resources, prompts, and skills. When a flag evaluates to `false`, the corresponding entry is filtered from list results and direct invocation returns an error.
569
+
570
+ ---
571
+
572
+ ## 6. Dashboard Plugin (`@frontmcp/plugin-dashboard`)
573
+
574
+ Visual monitoring web UI for your FrontMCP server. View server structure (tools, resources, prompts, apps, plugins) as an interactive graph.
575
+
576
+ ### Installation
577
+
578
+ ```typescript
579
+ import DashboardPlugin from '@frontmcp/plugin-dashboard';
580
+
581
+ // Basic (auto-enabled in dev, disabled in production)
582
+ @FrontMcp({
583
+ plugins: [DashboardPlugin.init({})],
584
+ })
585
+ class DevServer {}
586
+
587
+ // With authentication and custom CDN
588
+ @FrontMcp({
589
+ plugins: [
590
+ DashboardPlugin.init({
591
+ enabled: true,
592
+ basePath: '/dashboard',
593
+ auth: {
594
+ enabled: true,
595
+ token: 'my-secret-token',
596
+ },
597
+ cdn: {
598
+ entrypoint: 'https://cdn.example.com/dashboard-ui@1.0.0/index.js',
599
+ },
600
+ }),
601
+ ],
602
+ })
603
+ class ProdServer {}
604
+ // Access: http://localhost:3000/dashboard?token=my-secret-token
605
+ ```
606
+
607
+ ### Options
608
+
609
+ ```typescript
610
+ interface DashboardPluginOptionsInput {
611
+ enabled?: boolean; // Auto: enabled in dev, disabled in prod
612
+ basePath?: string; // Default: '/dashboard'
613
+ auth?: {
614
+ enabled?: boolean; // Default: false
615
+ token?: string; // Query param auth (?token=xxx)
616
+ };
617
+ cdn?: {
618
+ entrypoint?: string; // Custom UI bundle URL
619
+ react?: string; // React CDN URL override
620
+ reactDom?: string; // React DOM CDN URL override
621
+ xyflow?: string; // XYFlow (React Flow) CDN URL override
622
+ dagre?: string; // Dagre layout CDN URL override
623
+ };
624
+ }
625
+ ```
626
+
627
+ - `enabled` -- When omitted, the dashboard is automatically enabled in development (`NODE_ENV !== 'production'`) and disabled in production.
628
+ - `basePath` -- URL path where the dashboard is served. Default: `'/dashboard'`.
629
+ - `auth.token` -- When set, the dashboard requires `?token=<value>` as a query parameter.
630
+ - `cdn` -- Override default CDN URLs for the dashboard UI bundle and its dependencies. Useful for air-gapped environments.
631
+
632
+ ---
633
+
634
+ ## Registration Pattern
635
+
636
+ All official plugins use the static `init()` pattern inherited from `DynamicPlugin`. Register them in the `plugins` array of your `@FrontMcp` decorator:
637
+
638
+ ```typescript
639
+ @FrontMcp({
640
+ info: { name: 'production-server', version: '1.0.0' },
641
+ apps: [MyApp],
642
+ plugins: [
643
+ CodeCallPlugin.init({ mode: 'codecall_only', vm: { preset: 'secure' } }),
644
+ RememberPlugin.init({ type: 'redis', config: { host: 'redis.internal' } }),
645
+ ApprovalPlugin.init({ mode: 'recheck' }),
646
+ CachePlugin.init({ type: 'redis', config: { host: 'redis.internal' }, defaultTTL: 86400 }),
647
+ FeatureFlagPlugin.init({ adapter: 'launchdarkly', config: { sdkKey: 'sdk-xxx' } }),
648
+ DashboardPlugin.init({ enabled: true, auth: { enabled: true, token: process.env.DASH_TOKEN } }),
649
+ ],
650
+ tools: [
651
+ /* ... */
652
+ ],
653
+ })
654
+ class ProductionServer {}
655
+ ```
656
+
657
+ ## Reference
658
+
659
+ - Plugins docs: [docs.agentfront.dev/frontmcp/plugins/overview](https://docs.agentfront.dev/frontmcp/plugins/overview)
660
+ - `DynamicPlugin` base class: import from `@frontmcp/sdk`
661
+ - CodeCall: `@frontmcp/plugin-codecall` — [source](https://github.com/agentfront/frontmcp/tree/main/plugins/plugin-codecall) | [docs](https://docs.agentfront.dev/frontmcp/plugins/codecall/overview)
662
+ - Remember: `@frontmcp/plugin-remember` — [source](https://github.com/agentfront/frontmcp/tree/main/plugins/plugin-remember) | [docs](https://docs.agentfront.dev/frontmcp/plugins/remember-plugin)
663
+ - Approval: `@frontmcp/plugin-approval` — [source](https://github.com/agentfront/frontmcp/tree/main/plugins/plugin-approval)
664
+ - Cache: `@frontmcp/plugin-cache` — [source](https://github.com/agentfront/frontmcp/tree/main/plugins/plugin-cache) | [docs](https://docs.agentfront.dev/frontmcp/plugins/cache-plugin)
665
+ - Feature Flags: `@frontmcp/plugin-feature-flags` — [source](https://github.com/agentfront/frontmcp/tree/main/plugins/plugin-feature-flags) | [docs](https://docs.agentfront.dev/frontmcp/plugins/feature-flags-plugin)
666
+ - Dashboard: `@frontmcp/plugin-dashboard` — [source](https://github.com/agentfront/frontmcp/tree/main/plugins/plugin-dashboard)
667
+ - Meta-package: `@frontmcp/plugins` (re-exports cache, codecall, dashboard, remember)