@frontmcp/skills 0.0.1 → 1.0.0-beta.11

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 (104) hide show
  1. package/README.md +2 -2
  2. package/catalog/TEMPLATE.md +58 -13
  3. package/catalog/frontmcp-config/SKILL.md +156 -0
  4. package/catalog/{auth/configure-auth/references/auth-modes.md → frontmcp-config/references/configure-auth-modes.md} +5 -0
  5. package/catalog/frontmcp-config/references/configure-auth.md +243 -0
  6. package/catalog/frontmcp-config/references/configure-elicitation.md +183 -0
  7. package/catalog/frontmcp-config/references/configure-http.md +210 -0
  8. package/catalog/frontmcp-config/references/configure-session.md +210 -0
  9. package/catalog/{config/configure-throttle/references/guard-config.md → frontmcp-config/references/configure-throttle-guard-config.md} +5 -0
  10. package/catalog/frontmcp-config/references/configure-throttle.md +234 -0
  11. package/catalog/{config/configure-transport/references/protocol-presets.md → frontmcp-config/references/configure-transport-protocol-presets.md} +5 -0
  12. package/catalog/frontmcp-config/references/configure-transport.md +200 -0
  13. package/catalog/frontmcp-config/references/setup-redis.md +9 -0
  14. package/catalog/frontmcp-config/references/setup-sqlite.md +9 -0
  15. package/catalog/frontmcp-deployment/SKILL.md +152 -0
  16. package/catalog/frontmcp-deployment/references/build-for-browser.md +143 -0
  17. package/catalog/frontmcp-deployment/references/build-for-cli.md +191 -0
  18. package/catalog/{deployment/build-for-sdk/SKILL.md → frontmcp-deployment/references/build-for-sdk.md} +66 -20
  19. package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +218 -0
  20. package/catalog/{deployment/deploy-to-lambda/SKILL.md → frontmcp-deployment/references/deploy-to-lambda.md} +77 -59
  21. package/catalog/{deployment/deploy-to-node/references/Dockerfile.example → frontmcp-deployment/references/deploy-to-node-dockerfile.md} +18 -4
  22. package/catalog/{deployment/deploy-to-node/SKILL.md → frontmcp-deployment/references/deploy-to-node.md} +69 -36
  23. package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +65 -0
  24. package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +229 -0
  25. package/catalog/frontmcp-development/SKILL.md +126 -0
  26. package/catalog/frontmcp-development/references/create-adapter.md +170 -0
  27. package/catalog/{development/create-agent/references/llm-config.md → frontmcp-development/references/create-agent-llm-config.md} +10 -5
  28. package/catalog/{development/create-agent/SKILL.md → frontmcp-development/references/create-agent.md} +83 -40
  29. package/catalog/{development/create-job/SKILL.md → frontmcp-development/references/create-job.md} +62 -15
  30. package/catalog/{plugins/create-plugin-hooks/SKILL.md → frontmcp-development/references/create-plugin-hooks.md} +100 -7
  31. package/catalog/frontmcp-development/references/create-plugin.md +506 -0
  32. package/catalog/{development/create-prompt/SKILL.md → frontmcp-development/references/create-prompt.md} +65 -22
  33. package/catalog/{development/create-provider/SKILL.md → frontmcp-development/references/create-provider.md} +63 -23
  34. package/catalog/{development/create-resource/SKILL.md → frontmcp-development/references/create-resource.md} +148 -26
  35. package/catalog/{development/create-skill-with-tools/SKILL.md → frontmcp-development/references/create-skill-with-tools.md} +174 -20
  36. package/catalog/{development/create-skill/SKILL.md → frontmcp-development/references/create-skill.md} +114 -28
  37. package/catalog/{development/create-tool/references/tool-annotations.md → frontmcp-development/references/create-tool-annotations.md} +5 -0
  38. package/catalog/{development/create-tool/references/output-schema-types.md → frontmcp-development/references/create-tool-output-schema-types.md} +5 -0
  39. package/catalog/{development/create-tool/SKILL.md → frontmcp-development/references/create-tool.md} +172 -23
  40. package/catalog/{development/create-workflow/SKILL.md → frontmcp-development/references/create-workflow.md} +61 -14
  41. package/catalog/frontmcp-development/references/decorators-guide.md +754 -0
  42. package/catalog/frontmcp-development/references/official-adapters.md +199 -0
  43. package/catalog/{plugins/official-plugins/SKILL.md → frontmcp-development/references/official-plugins.md} +97 -27
  44. package/catalog/frontmcp-extensibility/SKILL.md +103 -0
  45. package/catalog/frontmcp-extensibility/references/vectoriadb.md +289 -0
  46. package/catalog/frontmcp-guides/SKILL.md +420 -0
  47. package/catalog/frontmcp-guides/references/example-knowledge-base.md +641 -0
  48. package/catalog/frontmcp-guides/references/example-task-manager.md +517 -0
  49. package/catalog/frontmcp-guides/references/example-weather-api.md +297 -0
  50. package/catalog/frontmcp-production-readiness/SKILL.md +98 -0
  51. package/catalog/frontmcp-production-readiness/references/common-checklist.md +156 -0
  52. package/catalog/frontmcp-production-readiness/references/production-browser.md +46 -0
  53. package/catalog/frontmcp-production-readiness/references/production-cli-binary.md +62 -0
  54. package/catalog/frontmcp-production-readiness/references/production-cli-daemon.md +61 -0
  55. package/catalog/frontmcp-production-readiness/references/production-cloudflare.md +52 -0
  56. package/catalog/frontmcp-production-readiness/references/production-lambda.md +53 -0
  57. package/catalog/frontmcp-production-readiness/references/production-node-sdk.md +66 -0
  58. package/catalog/frontmcp-production-readiness/references/production-node-server.md +61 -0
  59. package/catalog/frontmcp-production-readiness/references/production-vercel.md +52 -0
  60. package/catalog/frontmcp-setup/SKILL.md +132 -0
  61. package/catalog/frontmcp-setup/references/frontmcp-skills-usage.md +280 -0
  62. package/catalog/{setup/multi-app-composition/SKILL.md → frontmcp-setup/references/multi-app-composition.md} +66 -19
  63. package/catalog/{setup/nx-workflow/SKILL.md → frontmcp-setup/references/nx-workflow.md} +79 -17
  64. package/catalog/frontmcp-setup/references/project-structure-nx.md +251 -0
  65. package/catalog/frontmcp-setup/references/project-structure-standalone.md +217 -0
  66. package/catalog/frontmcp-setup/references/readme-guide.md +226 -0
  67. package/catalog/{setup/setup-project/SKILL.md → frontmcp-setup/references/setup-project.md} +63 -58
  68. package/catalog/{setup/setup-redis/SKILL.md → frontmcp-setup/references/setup-redis.md} +60 -82
  69. package/catalog/{setup/setup-sqlite/SKILL.md → frontmcp-setup/references/setup-sqlite.md} +65 -72
  70. package/catalog/frontmcp-testing/SKILL.md +135 -0
  71. package/catalog/{testing/setup-testing/SKILL.md → frontmcp-testing/references/setup-testing.md} +79 -63
  72. package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-auth.md +5 -0
  73. package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-browser-build.md +5 -0
  74. package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-cli-binary.md +5 -0
  75. package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-direct-client.md +5 -0
  76. package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-e2e-handler.md +5 -0
  77. package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-tool-unit.md +6 -0
  78. package/catalog/skills-manifest.json +337 -382
  79. package/package.json +2 -2
  80. package/src/index.d.ts +1 -1
  81. package/src/index.js.map +1 -1
  82. package/src/loader.js +0 -1
  83. package/src/loader.js.map +1 -1
  84. package/src/manifest.d.ts +15 -3
  85. package/src/manifest.js +3 -3
  86. package/src/manifest.js.map +1 -1
  87. package/catalog/adapters/create-adapter/SKILL.md +0 -127
  88. package/catalog/adapters/official-adapters/SKILL.md +0 -136
  89. package/catalog/auth/configure-auth/SKILL.md +0 -250
  90. package/catalog/auth/configure-session/SKILL.md +0 -201
  91. package/catalog/config/configure-elicitation/SKILL.md +0 -136
  92. package/catalog/config/configure-http/SKILL.md +0 -167
  93. package/catalog/config/configure-throttle/SKILL.md +0 -189
  94. package/catalog/config/configure-transport/SKILL.md +0 -151
  95. package/catalog/deployment/build-for-browser/SKILL.md +0 -95
  96. package/catalog/deployment/build-for-cli/SKILL.md +0 -100
  97. package/catalog/deployment/deploy-to-cloudflare/SKILL.md +0 -192
  98. package/catalog/deployment/deploy-to-vercel/SKILL.md +0 -196
  99. package/catalog/deployment/deploy-to-vercel/references/vercel.json.example +0 -60
  100. package/catalog/development/decorators-guide/SKILL.md +0 -598
  101. package/catalog/plugins/create-plugin/SKILL.md +0 -336
  102. package/catalog/setup/frontmcp-skills-usage/SKILL.md +0 -200
  103. package/catalog/setup/project-structure-nx/SKILL.md +0 -186
  104. package/catalog/setup/project-structure-standalone/SKILL.md +0 -153
@@ -0,0 +1,506 @@
1
+ ---
2
+ name: create-plugin
3
+ description: Build plugins with providers, context extensions, lifecycle hooks, and contributed tools
4
+ ---
5
+
6
+ # Create a FrontMCP Plugin
7
+
8
+ This skill covers building custom plugins for FrontMCP and using all 6 official plugins. Plugins are modular units that extend server behavior through providers, context extensions, lifecycle hooks, and contributed tools/resources/prompts.
9
+
10
+ ## When to Use This Skill
11
+
12
+ ### Must Use
13
+
14
+ - Adding cross-cutting behavior (logging, caching, auth) that applies across multiple tools
15
+ - Extending `ExecutionContextBase` with new properties accessible via `this.propertyName` in tools
16
+ - Contributing injectable providers that tools or other plugins depend on
17
+
18
+ ### Recommended
19
+
20
+ - Building a configurable module with runtime options using the `DynamicPlugin` pattern
21
+ - Extending the `@Tool` decorator metadata with custom fields (e.g., audit, approval)
22
+ - Composing multiple related providers, hooks, and tools into a single installable unit
23
+
24
+ ### Skip When
25
+
26
+ - You only need lifecycle hooks without providers or context extensions (see `create-plugin-hooks`)
27
+ - You want to use an existing official plugin (see `official-plugins`)
28
+ - You need to generate tools from an external API spec (see `create-adapter`)
29
+
30
+ > **Decision:** Use this skill when you need a reusable module that bundles providers, context extensions, or contributed entries and registers them via `@Plugin`.
31
+
32
+ ## Plugin Decorator Signature
33
+
34
+ ```typescript
35
+ function Plugin(metadata: PluginMetadata): ClassDecorator;
36
+ ```
37
+
38
+ The `PluginMetadata` interface:
39
+
40
+ ```typescript
41
+ interface PluginMetadata {
42
+ name: string;
43
+ id?: string;
44
+ description?: string;
45
+ providers?: ProviderType[];
46
+ exports?: ProviderType[];
47
+ plugins?: PluginType[];
48
+ adapters?: AdapterType[];
49
+ tools?: ToolType[];
50
+ resources?: ResourceType[];
51
+ prompts?: PromptType[];
52
+ skills?: SkillType[];
53
+ scope?: 'app' | 'server'; // default: 'app'
54
+ contextExtensions?: ContextExtension[];
55
+ }
56
+
57
+ interface ContextExtension {
58
+ property: string;
59
+ token: Token<unknown>;
60
+ errorMessage?: string;
61
+ }
62
+ ```
63
+
64
+ ## DynamicPlugin Base Class
65
+
66
+ For plugins that accept runtime configuration, extend `DynamicPlugin<TOptions, TInput>`:
67
+
68
+ ```typescript
69
+ abstract class DynamicPlugin<TOptions extends object, TInput extends object = TOptions> {
70
+ static dynamicProviders?(options: any): readonly ProviderType[];
71
+ static init<TThis>(options: InitOptions<TInput>): PluginReturn<TOptions>;
72
+ get<T>(token: Reference<T>): T;
73
+ }
74
+ ```
75
+
76
+ - `TOptions` -- the resolved options type (after parsing/defaults)
77
+ - `TInput` -- the input type users provide to `init()` (may have optional fields)
78
+ - `init()` creates a provider entry for use in `plugins: [...]` arrays
79
+ - `dynamicProviders()` returns providers computed from the input options
80
+
81
+ ## Quick Start: Minimal DynamicPlugin
82
+
83
+ The simplest working plugin needs three files: a provider, the plugin class, and registration.
84
+
85
+ ```typescript
86
+ // my-greeter.provider.ts
87
+ import { Provider } from '@frontmcp/sdk';
88
+
89
+ @Provider()
90
+ export class GreeterService {
91
+ greet(name: string): string {
92
+ return `Hello, ${name}`;
93
+ }
94
+ }
95
+ ```
96
+
97
+ ```typescript
98
+ // my-greeter.plugin.ts
99
+ import { Plugin, DynamicPlugin, ProviderType } from '@frontmcp/sdk';
100
+ import { GreeterService } from './providers/my-greeter.provider';
101
+
102
+ @Plugin({ name: 'greeter', exports: [GreeterService] })
103
+ export default class GreeterPlugin extends DynamicPlugin<{ prefix: string }> {
104
+ static override dynamicProviders(opts: { prefix: string }): ProviderType[] {
105
+ return [{ provide: GreeterService, useFactory: () => new GreeterService() }];
106
+ }
107
+ }
108
+ ```
109
+
110
+ ```typescript
111
+ // server.ts
112
+ import { FrontMcp } from '@frontmcp/sdk';
113
+ import GreeterPlugin from './plugins/my-greeter.plugin';
114
+
115
+ @FrontMcp({
116
+ info: { name: 'my-server', version: '1.0.0' },
117
+ plugins: [GreeterPlugin.init({ prefix: 'Hi' })],
118
+ })
119
+ class MyServer {}
120
+ ```
121
+
122
+ ## Step 1: Create a Simple Plugin
123
+
124
+ The minimal plugin only needs a name:
125
+
126
+ ```typescript
127
+ import { Plugin } from '@frontmcp/sdk';
128
+
129
+ @Plugin({
130
+ name: 'audit-log',
131
+ description: 'Logs tool executions for audit compliance',
132
+ })
133
+ export default class AuditLogPlugin {}
134
+ ```
135
+
136
+ Register it in your server:
137
+
138
+ ```typescript
139
+ import { FrontMcp, App } from '@frontmcp/sdk';
140
+ import AuditLogPlugin from './plugins/audit-log.plugin';
141
+
142
+ @App({ name: 'MyApp' })
143
+ class MyApp {}
144
+
145
+ @FrontMcp({
146
+ info: { name: 'my-server', version: '1.0.0' },
147
+ apps: [MyApp],
148
+ plugins: [AuditLogPlugin],
149
+ tools: [
150
+ /* your tools */
151
+ ],
152
+ })
153
+ class MyServer {}
154
+ ```
155
+
156
+ ## Step 2: Add Providers
157
+
158
+ Plugins contribute injectable services via `providers`:
159
+
160
+ ```typescript
161
+ import { Plugin, Provider } from '@frontmcp/sdk';
162
+ import type { Token } from '@frontmcp/sdk';
163
+
164
+ export const AuditLoggerToken: Token<AuditLogger> = Symbol('AuditLogger');
165
+
166
+ @Provider()
167
+ class AuditLogger {
168
+ async logToolCall(toolName: string, userId: string, input: unknown): Promise<void> {
169
+ console.log(`[AUDIT] ${userId} called ${toolName}`, input);
170
+ }
171
+ }
172
+
173
+ @Plugin({
174
+ name: 'audit-log',
175
+ description: 'Logs tool executions for audit compliance',
176
+ providers: [{ provide: AuditLoggerToken, useClass: AuditLogger }],
177
+ exports: [AuditLogger],
178
+ })
179
+ export default class AuditLogPlugin {}
180
+ ```
181
+
182
+ ## Step 3: Add Context Extensions
183
+
184
+ Context extensions add properties to `ExecutionContextBase` so tools access plugin services via `this.propertyName`. Two parts are required:
185
+
186
+ ### Part A: TypeScript Type Declaration (Module Augmentation)
187
+
188
+ ```typescript
189
+ // audit-log.context-extension.ts
190
+ import type { AuditLogger } from './audit-logger';
191
+
192
+ declare module '@frontmcp/sdk' {
193
+ interface ExecutionContextBase {
194
+ /** Audit logger provided by AuditLogPlugin */
195
+ readonly auditLog: AuditLogger;
196
+ }
197
+ }
198
+ ```
199
+
200
+ ### Part B: Register via Plugin Metadata
201
+
202
+ The SDK handles runtime installation when you declare `contextExtensions` in plugin metadata. Do not modify `ExecutionContextBase.prototype` directly.
203
+
204
+ ```typescript
205
+ import { Plugin } from '@frontmcp/sdk';
206
+ import type { Token } from '@frontmcp/sdk';
207
+ import './audit-log.context-extension'; // Import for type augmentation side effect
208
+
209
+ export const AuditLoggerToken: Token<AuditLogger> = Symbol('AuditLogger');
210
+
211
+ @Plugin({
212
+ name: 'audit-log',
213
+ description: 'Logs tool executions for audit compliance',
214
+ providers: [{ provide: AuditLoggerToken, useClass: AuditLogger }],
215
+ contextExtensions: [
216
+ {
217
+ property: 'auditLog',
218
+ token: AuditLoggerToken,
219
+ errorMessage: 'AuditLogPlugin is not installed. Add it to your @FrontMcp plugins array.',
220
+ },
221
+ ],
222
+ })
223
+ export default class AuditLogPlugin {}
224
+ ```
225
+
226
+ Now tools can use `this.auditLog`:
227
+
228
+ ```typescript
229
+ import { Tool, ToolContext } from '@frontmcp/sdk';
230
+
231
+ @Tool({ name: 'delete_record' })
232
+ class DeleteRecordTool extends ToolContext {
233
+ async execute(input: { recordId: string }) {
234
+ await this.auditLog.logToolCall('delete_record', this.scope.userId, input);
235
+ return { deleted: true };
236
+ }
237
+ }
238
+ ```
239
+
240
+ ## Step 4: Create a Configurable Plugin with DynamicPlugin
241
+
242
+ For plugins that accept runtime options, extend `DynamicPlugin`:
243
+
244
+ ```typescript
245
+ import { Plugin, DynamicPlugin, ProviderType } from '@frontmcp/sdk';
246
+ import type { Token } from '@frontmcp/sdk';
247
+
248
+ export interface MyPluginOptions {
249
+ endpoint: string;
250
+ refreshIntervalMs: number;
251
+ }
252
+
253
+ export type MyPluginOptionsInput = Omit<MyPluginOptions, 'refreshIntervalMs'> & {
254
+ refreshIntervalMs?: number;
255
+ };
256
+
257
+ export const MyServiceToken: Token<MyService> = Symbol('MyService');
258
+
259
+ @Plugin({
260
+ name: 'my-plugin',
261
+ description: 'A configurable plugin',
262
+ contextExtensions: [
263
+ {
264
+ property: 'myService',
265
+ token: MyServiceToken,
266
+ errorMessage: 'MyPlugin is not installed.',
267
+ },
268
+ ],
269
+ })
270
+ export default class MyPlugin extends DynamicPlugin<MyPluginOptions, MyPluginOptionsInput> {
271
+ options: MyPluginOptions;
272
+
273
+ constructor(options: MyPluginOptionsInput = { endpoint: '' }) {
274
+ super();
275
+ this.options = { refreshIntervalMs: 30_000, ...options };
276
+ }
277
+
278
+ static override dynamicProviders(options: MyPluginOptionsInput): ProviderType[] {
279
+ return [
280
+ {
281
+ provide: MyServiceToken,
282
+ useFactory: () =>
283
+ new MyService({
284
+ refreshIntervalMs: 30_000,
285
+ ...options,
286
+ }),
287
+ },
288
+ ];
289
+ }
290
+ }
291
+ ```
292
+
293
+ Register with `init()`:
294
+
295
+ ```typescript
296
+ @FrontMcp({
297
+ info: { name: 'my-server', version: '1.0.0' },
298
+ apps: [MyApp],
299
+ plugins: [
300
+ MyPlugin.init({
301
+ endpoint: 'https://api.example.com',
302
+ refreshIntervalMs: 60_000,
303
+ }),
304
+ ],
305
+ })
306
+ class MyServer {}
307
+ ```
308
+
309
+ ## Step 5: Extend Metadata and Execution Context
310
+
311
+ FrontMCP provides two extension mechanisms for plugins: **metadata augmentation** (add fields to decorators) and **context extensions** (add properties to `this` in tools/resources/prompts).
312
+
313
+ ### All Extensible Metadata Interfaces
314
+
315
+ Plugins can extend these `declare global` interfaces to add custom fields to any decorator:
316
+
317
+ | Interface | Decorator | Example Field |
318
+ | ---------------------------------------- | -------------------------- | ---------------------------- |
319
+ | `ExtendFrontMcpToolMetadata` | `@Tool({...})` | `audit: { enabled: true }` |
320
+ | `ExtendFrontMcpAgentMetadata` | `@Agent({...})` | Inherits from ToolMetadata |
321
+ | `ExtendFrontMcpResourceMetadata` | `@Resource({...})` | `cache: { ttl: 3600 }` |
322
+ | `ExtendFrontMcpResourceTemplateMetadata` | `@ResourceTemplate({...})` | `rateLimit: { max: 100 }` |
323
+ | `ExtendFrontMcpPromptMetadata` | `@Prompt({...})` | `category: 'onboarding'` |
324
+ | `ExtendFrontMcpJobMetadata` | `@Job({...})` | `priority: 'high'` |
325
+ | `ExtendFrontMcpWorkflowMetadata` | `@Workflow({...})` | `retryPolicy: 'exponential'` |
326
+ | `ExtendFrontMcpSkillMetadata` | `@Skill({...})` | `complexity: 'advanced'` |
327
+ | `ExtendFrontMcpLoggerMetadata` | Logger transports | `destination: 'sentry'` |
328
+
329
+ ### Metadata Extension Pattern
330
+
331
+ Add custom fields to any decorator via `declare global`:
332
+
333
+ ```typescript
334
+ // my-plugin.types.ts
335
+ declare global {
336
+ interface ExtendFrontMcpToolMetadata {
337
+ audit?: {
338
+ enabled: boolean;
339
+ level: 'info' | 'warn' | 'critical';
340
+ };
341
+ }
342
+ }
343
+ ```
344
+
345
+ Tools then use the custom field directly in the decorator:
346
+
347
+ ```typescript
348
+ @Tool({
349
+ name: 'delete_user',
350
+ audit: { enabled: true, level: 'critical' },
351
+ })
352
+ class DeleteUserTool extends ToolContext {
353
+ /* ... */
354
+ }
355
+ ```
356
+
357
+ The same pattern works for any of the 9 interfaces above — replace `ExtendFrontMcpToolMetadata` with the target interface.
358
+
359
+ ### Context Extension Pattern
360
+
361
+ Add properties like `this.myService` to execution contexts. This requires both TypeScript augmentation and runtime registration.
362
+
363
+ **Part A: TypeScript type declaration** (in a separate `.context-extension.ts` file):
364
+
365
+ ```typescript
366
+ // my-plugin.context-extension.ts
367
+ import type { MyService } from './providers/my-service.provider';
368
+
369
+ declare module '@frontmcp/sdk' {
370
+ interface ExecutionContextBase {
371
+ readonly myService: MyService;
372
+ }
373
+ // PromptContext has a separate prototype chain — augment it too
374
+ interface PromptContext {
375
+ readonly myService: MyService;
376
+ }
377
+ }
378
+ ```
379
+
380
+ **Part B: Runtime registration** (in the `@Plugin` metadata):
381
+
382
+ ```typescript
383
+ @Plugin({
384
+ name: 'my-plugin',
385
+ providers: [MyServiceProvider],
386
+ contextExtensions: [
387
+ {
388
+ property: 'myService',
389
+ token: MyServiceToken,
390
+ errorMessage: 'MyPlugin is not installed. Add it to your app plugins.',
391
+ },
392
+ ],
393
+ })
394
+ export class MyPlugin extends DynamicPlugin<MyPluginOptions> {
395
+ /* ... */
396
+ }
397
+ ```
398
+
399
+ The SDK installs lazy getters on both `ExecutionContextBase.prototype` and `PromptContext.prototype` that resolve the DI token on first access.
400
+
401
+ ### ContextExtension Interface
402
+
403
+ Each entry in the `contextExtensions` array has these fields:
404
+
405
+ | Field | Type | Required | Description |
406
+ | -------------- | ---------------- | -------- | --------------------------------------------- |
407
+ | `property` | `string` | Yes | Property name accessible as `this.{property}` |
408
+ | `token` | `Token<unknown>` | Yes | DI token to resolve when property is accessed |
409
+ | `errorMessage` | `string` | No | Custom error when plugin is not installed |
410
+
411
+ ### Side-Effect Import
412
+
413
+ The TypeScript augmentation file must be imported somewhere in your plugin's barrel export so the type declarations take effect:
414
+
415
+ ```typescript
416
+ // index.ts
417
+ import './my-plugin.context-extension'; // side-effect import for type augmentation
418
+ export { MyPlugin } from './my-plugin.plugin';
419
+ export { MyServiceToken } from './my-plugin.symbols';
420
+ ```
421
+
422
+ ---
423
+
424
+ ## Official Plugins
425
+
426
+ For official plugin installation, configuration, and examples, see the **official-plugins** skill. FrontMCP provides 6 official plugins: CodeCall, Remember, Approval, Cache, Feature Flags, and Dashboard. Install individually or via `@frontmcp/plugins` (meta-package).
427
+
428
+ ## Recommended Folder Structure
429
+
430
+ ```text
431
+ plugins/
432
+ my-plugin/
433
+ index.ts # Barrel exports: plugin, tokens, types, side-effect import
434
+ my-plugin.plugin.ts # Plugin class extending DynamicPlugin
435
+ my-plugin.types.ts # Options Zod schema, TypeScript types, interfaces
436
+ my-plugin.symbols.ts # DI tokens: export const MY_TOKEN: Token<T> = Symbol('...')
437
+ my-plugin.context-extension.ts # Module augmentation (declare module '@frontmcp/sdk')
438
+ providers/
439
+ index.ts # Barrel for providers
440
+ my-service.provider.ts # @Provider class with business logic
441
+ my-store-memory.provider.ts # In-memory store implementation
442
+ my-store-redis.provider.ts # Redis store implementation (optional)
443
+ tools/ # Optional — only if plugin provides tools
444
+ index.ts
445
+ my-action.tool.ts # @Tool class registered via @Plugin({ tools: [...] })
446
+ __tests__/
447
+ my-plugin.spec.ts # Plugin tests
448
+ ```
449
+
450
+ **Key files explained:**
451
+
452
+ - `index.ts` — Must import the context extension file as a side effect: `import './my-plugin.context-extension'`
453
+ - `symbols.ts` — All DI tokens in one place. Other files import from here, not from the plugin class
454
+ - `context-extension.ts` — `declare module '@frontmcp/sdk' { interface ExecutionContextBase { readonly myProp: T } }`
455
+ - `plugin.ts` — The `@Plugin()` decorated class. Lists `providers`, `exports`, `contextExtensions`, `tools`
456
+
457
+ ## Common Patterns
458
+
459
+ | Pattern | Correct | Incorrect | Why |
460
+ | ------------------------------ | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
461
+ | Context extension registration | `contextExtensions: [{ property: 'auditLog', token: AuditLoggerToken }]` in metadata | `Object.defineProperty(ExecutionContextBase.prototype, ...)` manually | SDK handles runtime installation; manual modification causes ordering issues |
462
+ | Type augmentation | `declare module '@frontmcp/sdk' { interface ExecutionContextBase { ... } }` in a separate file | Skipping the augmentation and casting `this` in tools | Without augmentation, TypeScript cannot type-check `this.auditLog` |
463
+ | Provider types | `Token<AuditLogger> = Symbol('AuditLogger')` with typed token | `provide: Symbol('AuditLogger')` without type annotation | Typed tokens enable compile-time DI resolution checking |
464
+ | Plugin scope | `scope: 'app'` (default) for app-scoped behavior | `scope: 'server'` when hooks should only apply to one app | Server scope fires hooks for all apps in a gateway; default to app |
465
+ | Dynamic options | Extend `DynamicPlugin<TOptions, TInput>` with `static dynamicProviders()` | Constructing providers in the constructor body | `dynamicProviders` runs before instantiation, enabling proper DI wiring |
466
+
467
+ ## Verification Checklist
468
+
469
+ ### Configuration
470
+
471
+ - [ ] `@Plugin` decorator has `name` and `description`
472
+ - [ ] Providers are listed in `providers` array with typed tokens
473
+ - [ ] Exported providers are listed in `exports` array
474
+ - [ ] Context extensions have `property`, `token`, and `errorMessage` fields
475
+
476
+ ### Type Safety
477
+
478
+ - [ ] Module augmentation file exists with `declare module '@frontmcp/sdk'` block
479
+ - [ ] Augmented properties are `readonly` on `ExecutionContextBase`
480
+ - [ ] `PromptContext` is augmented alongside `ExecutionContextBase` for context extensions
481
+ - [ ] `declare global` block exists for each metadata extension interface used
482
+ - [ ] Augmentation file is imported (side-effect import) in the plugin barrel export
483
+
484
+ ### Runtime
485
+
486
+ - [ ] Plugin is registered in `plugins` array of `@FrontMcp` or `@App`
487
+ - [ ] `this.propertyName` resolves correctly in tool contexts
488
+ - [ ] Missing plugin produces a clear error message (from `errorMessage`)
489
+ - [ ] Dynamic plugin options are validated in `dynamicProviders()`
490
+
491
+ ## Troubleshooting
492
+
493
+ | Problem | Cause | Solution |
494
+ | ---------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
495
+ | `this.auditLog` has type `any` or is unrecognized | Module augmentation file not imported | Add side-effect import: `import './audit-log.context-extension'` in plugin file |
496
+ | Circular dependency error at startup | Calling `installExtension()` at module top level | Remove manual installation; use `contextExtensions` metadata array instead |
497
+ | Provider not found in tool context | Provider not listed in plugin `exports` | Add the provider to both `providers` and `exports` arrays |
498
+ | Hooks fire for unrelated apps in gateway | Plugin `scope` set to `'server'` | Change to `scope: 'app'` (default) unless server-wide behavior is intended |
499
+ | `DynamicPlugin.init()` options ignored | Overriding constructor without calling `super()` | Ensure constructor calls `super()` and merges defaults properly |
500
+ | `ProviderNotRegisteredError` for context extension | Token in `contextExtensions` not in `providers` | Ensure the token used in `contextExtensions[].token` is registered in the plugin's `providers` array. Use `{ provide: MyToken, useClass: MyService }` or list the class directly. If using `dynamicProviders()`, return the provider there |
501
+ | Provider works in tools but not in context extension | Using class reference instead of Symbol token | Create a typed `Token<T> = Symbol('name')` in `symbols.ts`, use it in both `providers` and `contextExtensions`. Direct class references can fail if not constructable without dependencies |
502
+
503
+ ## Reference
504
+
505
+ - [Plugin System Documentation](https://docs.agentfront.dev/frontmcp/plugins/creating-plugins)
506
+ - Related skills: `create-plugin-hooks`, `official-plugins`, `create-adapter`, `create-provider`
@@ -1,34 +1,33 @@
1
1
  ---
2
2
  name: create-prompt
3
- description: Create MCP prompts for reusable AI interaction patterns. Use when building prompts, defining prompt arguments, or creating conversation templates.
4
- tags: [prompts, mcp, templates, messages, decorator]
5
- tools:
6
- - name: create_prompt
7
- purpose: Scaffold a new prompt class
8
- parameters:
9
- - name: name
10
- description: Prompt name in kebab-case
11
- type: string
12
- required: true
13
- examples:
14
- - scenario: Create a code review prompt with language argument
15
- expected-outcome: Prompt registered and callable via MCP
16
- - scenario: Create a multi-turn debugging prompt with assistant priming
17
- expected-outcome: Prompt producing structured message sequences
18
- priority: 10
19
- visibility: both
20
- license: Apache-2.0
21
- metadata:
22
- docs: https://docs.agentfront.dev/frontmcp/servers/prompts
3
+ description: Define reusable AI interaction patterns that produce structured message sequences
23
4
  ---
24
5
 
25
6
  # Creating MCP Prompts
26
7
 
27
8
  Prompts define reusable AI interaction patterns in the MCP protocol. They produce structured message sequences that clients use to guide LLM conversations. In FrontMCP, prompts are classes extending `PromptContext`, decorated with `@Prompt`, that return `GetPromptResult` objects.
28
9
 
29
- ## When to Use @Prompt
10
+ ## When to Use This Skill
30
11
 
31
- Use `@Prompt` when you need to expose a reusable conversation template that an AI client can invoke with arguments. Prompts are ideal for code review patterns, debugging sessions, RAG queries, report generation, translation workflows, and any scenario where you want a standardized message structure.
12
+ ### Must Use
13
+
14
+ - Building a reusable conversation template that AI clients invoke with arguments
15
+ - Defining structured multi-turn message sequences (user/assistant patterns)
16
+ - Creating domain-specific prompt patterns (code review, debugging, RAG queries)
17
+
18
+ ### Recommended
19
+
20
+ - Standardizing message formats across multiple tools or agents
21
+ - Embedding MCP resource content into prompt messages for context
22
+ - Generating dynamic prompts that perform async lookups (knowledge base, APIs)
23
+
24
+ ### Skip When
25
+
26
+ - You need an executable action that performs work and returns results (see `create-tool`)
27
+ - You need to expose read-only data at a URI (see `create-resource`)
28
+ - The task requires autonomous multi-step reasoning with inner tools (see `create-agent`)
29
+
30
+ > **Decision:** Use this skill when you need a reusable, parameterized conversation template that produces structured `GetPromptResult` messages.
32
31
 
33
32
  ## Class-Based Pattern
34
33
 
@@ -70,8 +69,10 @@ class CodeReviewPrompt extends PromptContext {
70
69
  The `@Prompt` decorator accepts:
71
70
 
72
71
  - `name` (required) -- unique prompt name
72
+ - `title` (optional) -- human-readable display title for UIs (if omitted, `name` is used)
73
73
  - `description` (optional) -- human-readable description
74
74
  - `arguments` (optional) -- array of `PromptArgument` objects
75
+ - `icons` (optional) -- array of Icon objects for UI representation (per MCP spec)
75
76
 
76
77
  ### PromptArgument Structure
77
78
 
@@ -398,3 +399,45 @@ nx generate @frontmcp/nx:prompt
398
399
  ```
399
400
 
400
401
  This creates the prompt file, spec file, and updates barrel exports.
402
+
403
+ ## Common Patterns
404
+
405
+ | Pattern | Correct | Incorrect | Why |
406
+ | ------------------- | ----------------------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------- |
407
+ | Return type | `execute()` returns `Promise<GetPromptResult>` | Returning a plain string or array of strings | MCP protocol requires `{ messages: [...] }` structure |
408
+ | Argument validation | Mark arguments as `required: true` in `arguments` array | Manually checking `args.field` inside `execute()` | Framework validates required arguments before `execute()` runs |
409
+ | Multi-turn priming | Use `assistant` role messages to prime expected response patterns | Putting all instructions in a single `user` message | Alternating roles guides the LLM toward structured output |
410
+ | Resource embedding | Use `type: 'resource'` content with a resource URI | Inlining resource data as raw text in the prompt | Resource references let clients resolve content dynamically |
411
+ | Error handling | Use `this.fail(err)` for validation failures in execute | `throw new Error(...)` directly | `this.fail` triggers the error flow with proper MCP error propagation |
412
+
413
+ ## Verification Checklist
414
+
415
+ ### Configuration
416
+
417
+ - [ ] Prompt class extends `PromptContext` and implements `execute(args)`
418
+ - [ ] `@Prompt` decorator has `name` and `arguments` array with correct `required` flags
419
+ - [ ] Prompt is registered in `prompts` array of `@App` or `@FrontMcp`
420
+ - [ ] All required arguments have `required: true`
421
+
422
+ ### Runtime
423
+
424
+ - [ ] Prompt appears in `prompts/list` MCP response
425
+ - [ ] Calling prompt with valid arguments returns well-formed `GetPromptResult`
426
+ - [ ] Missing required arguments trigger `MissingPromptArgumentError`
427
+ - [ ] Multi-turn messages have correct `user`/`assistant` role alternation
428
+ - [ ] DI dependencies resolve correctly via `this.get()`
429
+
430
+ ## Troubleshooting
431
+
432
+ | Problem | Cause | Solution |
433
+ | ------------------------------------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------- |
434
+ | Prompt not appearing in `prompts/list` | Not registered in `prompts` array | Add prompt class to `@App` or `@FrontMcp` `prompts` array |
435
+ | `MissingPromptArgumentError` on optional argument | Argument marked `required: true` incorrectly | Set `required: false` for optional arguments in the `arguments` array |
436
+ | LLM ignores priming messages | Only using `user` role messages | Add `assistant` role messages to prime the conversation pattern |
437
+ | Type error on `execute()` return | Returning plain string instead of `GetPromptResult` | Wrap return in `{ messages: [{ role: 'user', content: { type: 'text', text: '...' } }] }` |
438
+ | `this.get(TOKEN)` throws DependencyNotFoundError | Provider not registered in scope | Register provider in `providers` array of `@App` or `@FrontMcp` |
439
+
440
+ ## Reference
441
+
442
+ - [Prompts Documentation](https://docs.agentfront.dev/frontmcp/servers/prompts)
443
+ - Related skills: `create-tool`, `create-resource`, `create-agent`, `create-provider`