@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,598 @@
1
+ ---
2
+ name: decorators-guide
3
+ description: Complete reference for all FrontMCP decorators and when to use each one. Use when choosing between decorators, understanding the architecture, or looking up decorator signatures.
4
+ tags: [decorators, reference, architecture, guide]
5
+ priority: 10
6
+ visibility: both
7
+ license: Apache-2.0
8
+ metadata:
9
+ docs: https://docs.agentfront.dev/frontmcp/sdk-reference/decorators/overview
10
+ ---
11
+
12
+ # FrontMCP Decorators - Complete Reference
13
+
14
+ ## Architecture Overview
15
+
16
+ FrontMCP uses a hierarchical decorator system. The nesting order is:
17
+
18
+ ```
19
+ @FrontMcp (server root)
20
+ +-- @App (application module)
21
+ +-- @Tool (MCP tool)
22
+ +-- @Resource (static MCP resource)
23
+ +-- @ResourceTemplate (parameterized resource)
24
+ +-- @Prompt (MCP prompt)
25
+ +-- @Agent (autonomous AI agent)
26
+ +-- @Skill (knowledge/workflow package)
27
+ +-- @Plugin (lifecycle plugin)
28
+ +-- @Provider (DI provider)
29
+ +-- @Adapter (external source adapter)
30
+ +-- @Job (long-running job)
31
+ +-- @Workflow (multi-step workflow)
32
+ +-- @Flow (custom flow)
33
+ +-- @Hook (@Will, @Did, @Stage, @Around)
34
+ ```
35
+
36
+ ---
37
+
38
+ ## 1. @FrontMcp
39
+
40
+ **Purpose:** Declares the root MCP server and its global configuration.
41
+
42
+ **When to use:** Once per server, on the top-level bootstrap class.
43
+
44
+ **Key fields:**
45
+
46
+ | Field | Description |
47
+ | --------------- | --------------------------------------------------- |
48
+ | `info` | Server name, version, and description |
49
+ | `apps` | Array of `@App` classes to mount |
50
+ | `redis?` | Redis connection options |
51
+ | `plugins?` | Global plugins |
52
+ | `providers?` | Global DI providers |
53
+ | `tools?` | Standalone tools (outside apps) |
54
+ | `resources?` | Standalone resources |
55
+ | `skills?` | Standalone skills |
56
+ | `skillsConfig?` | Skills feature configuration (enabled, cache, auth) |
57
+ | `transport?` | Transport type (stdio, sse, streamable-http) |
58
+ | `http?` | HTTP server options (port, host, cors) |
59
+ | `logging?` | Logging configuration |
60
+ | `elicitation?` | Elicitation store config |
61
+ | `sqlite?` | SQLite storage config |
62
+ | `pubsub?` | Pub/sub configuration |
63
+ | `jobs?` | Job scheduler config |
64
+ | `throttle?` | Rate limiting config |
65
+ | `pagination?` | Pagination defaults |
66
+ | `ui?` | UI configuration |
67
+
68
+ ```typescript
69
+ import { FrontMcp } from '@frontmcp/sdk';
70
+
71
+ @FrontMcp({
72
+ info: { name: 'my-server', version: '1.0.0' },
73
+ apps: [MainApp],
74
+ transport: 'streamable-http',
75
+ http: { port: 3000 },
76
+ plugins: [RememberPlugin],
77
+ skillsConfig: { enabled: true },
78
+ })
79
+ class MyServer {}
80
+ ```
81
+
82
+ ---
83
+
84
+ ## 2. @App
85
+
86
+ **Purpose:** Groups related tools, resources, prompts, agents, and skills into an application module.
87
+
88
+ **When to use:** To organize your server into logical modules. Every server has at least one app.
89
+
90
+ **Key fields:**
91
+
92
+ | Field | Description |
93
+ | ------------- | ----------------------------------------------------- |
94
+ | `name` | Application name |
95
+ | `tools?` | Array of tool classes or function-built tools |
96
+ | `resources?` | Array of resource classes or function-built resources |
97
+ | `prompts?` | Array of prompt classes or function-built prompts |
98
+ | `agents?` | Array of agent classes |
99
+ | `skills?` | Array of skill definitions |
100
+ | `plugins?` | App-scoped plugins |
101
+ | `providers?` | App-scoped DI providers |
102
+ | `adapters?` | External source adapters |
103
+ | `auth?` | Auth configuration |
104
+ | `standalone?` | Whether the app runs independently |
105
+ | `jobs?` | Job definitions |
106
+ | `workflows?` | Workflow definitions |
107
+
108
+ ```typescript
109
+ import { App } from '@frontmcp/sdk';
110
+
111
+ @App({
112
+ name: 'analytics',
113
+ tools: [QueryTool, ReportTool],
114
+ resources: [DashboardResource],
115
+ prompts: [SummaryPrompt],
116
+ providers: [DatabaseProvider],
117
+ })
118
+ class AnalyticsApp {}
119
+ ```
120
+
121
+ ---
122
+
123
+ ## 3. @Tool
124
+
125
+ **Purpose:** Defines an MCP tool that an LLM can invoke to perform actions.
126
+
127
+ **When to use:** When you need the LLM to execute a function, query data, or trigger side effects.
128
+
129
+ **Key fields:**
130
+
131
+ | Field | Description |
132
+ | -------------------- | ---------------------------------------------------------- |
133
+ | `name` | Tool name (used in MCP protocol) |
134
+ | `description` | Human-readable description for the LLM |
135
+ | `inputSchema` | Zod raw shape defining input parameters |
136
+ | `outputSchema?` | Zod schema for output validation |
137
+ | `annotations?` | MCP tool annotations (readOnlyHint, destructiveHint, etc.) |
138
+ | `tags?` | Categorization tags |
139
+ | `hideFromDiscovery?` | Hide from tool listing |
140
+ | `concurrency?` | Max concurrent executions |
141
+ | `rateLimit?` | Rate limiting configuration |
142
+ | `timeout?` | Execution timeout in ms |
143
+ | `ui?` | UI rendering hints |
144
+
145
+ ```typescript
146
+ import { Tool, ToolContext } from '@frontmcp/sdk';
147
+ import { z } from 'zod';
148
+
149
+ @Tool({
150
+ name: 'search_users',
151
+ description: 'Search for users by name or email',
152
+ inputSchema: {
153
+ query: z.string().describe('Search query'),
154
+ limit: z.number().optional().default(10),
155
+ },
156
+ })
157
+ class SearchUsersTool extends ToolContext {
158
+ async execute(input: { query: string; limit: number }) {
159
+ const users = await this.get(UserService).search(input.query, input.limit);
160
+ return { users };
161
+ }
162
+ }
163
+ ```
164
+
165
+ ---
166
+
167
+ ## 4. @Prompt
168
+
169
+ **Purpose:** Defines an MCP prompt template that generates structured messages for the LLM.
170
+
171
+ **When to use:** When you want to expose reusable prompt templates with typed arguments.
172
+
173
+ **Key fields:**
174
+
175
+ | Field | Description |
176
+ | -------------- | ------------------------------------------------------------------- |
177
+ | `name` | Prompt name |
178
+ | `description?` | What this prompt does |
179
+ | `arguments?` | Array of argument definitions (`{ name, description?, required? }`) |
180
+
181
+ ```typescript
182
+ import { Prompt, PromptContext } from '@frontmcp/sdk';
183
+
184
+ @Prompt({
185
+ name: 'code_review',
186
+ description: 'Generate a code review for the given code',
187
+ arguments: [
188
+ { name: 'code', description: 'The code to review', required: true },
189
+ { name: 'language', description: 'Programming language' },
190
+ ],
191
+ })
192
+ class CodeReviewPrompt extends PromptContext {
193
+ async execute(args: { code: string; language?: string }) {
194
+ return {
195
+ messages: [
196
+ {
197
+ role: 'user' as const,
198
+ content: {
199
+ type: 'text' as const,
200
+ text: `Review this ${args.language ?? ''} code:\n\n${args.code}`,
201
+ },
202
+ },
203
+ ],
204
+ };
205
+ }
206
+ }
207
+ ```
208
+
209
+ ---
210
+
211
+ ## 5. @Resource
212
+
213
+ **Purpose:** Exposes a static MCP resource identified by a fixed URI.
214
+
215
+ **When to use:** When you need to expose data at a known, unchanging URI (e.g., config files, system status).
216
+
217
+ **Key fields:**
218
+
219
+ | Field | Description |
220
+ | -------------- | -------------------------------------------- |
221
+ | `name` | Resource name |
222
+ | `uri` | Fixed URI (e.g., `config://app/settings`) |
223
+ | `description?` | What this resource provides |
224
+ | `mimeType?` | Content MIME type (e.g., `application/json`) |
225
+
226
+ ```typescript
227
+ import { Resource, ResourceContext } from '@frontmcp/sdk';
228
+
229
+ @Resource({
230
+ name: 'app_config',
231
+ uri: 'config://app/settings',
232
+ description: 'Current application settings',
233
+ mimeType: 'application/json',
234
+ })
235
+ class AppConfigResource extends ResourceContext {
236
+ async read() {
237
+ const config = await this.get(ConfigService).getAll();
238
+ return { contents: [{ uri: this.uri, text: JSON.stringify(config) }] };
239
+ }
240
+ }
241
+ ```
242
+
243
+ ---
244
+
245
+ ## 6. @ResourceTemplate
246
+
247
+ **Purpose:** Exposes a parameterized MCP resource with URI pattern matching.
248
+
249
+ **When to use:** When resources are identified by dynamic parameters (e.g., user profiles, documents by ID).
250
+
251
+ **Key fields:**
252
+
253
+ | Field | Description |
254
+ | -------------- | --------------------------------------------------------------- |
255
+ | `name` | Resource template name |
256
+ | `uriTemplate` | URI template with parameters (e.g., `users://{userId}/profile`) |
257
+ | `description?` | What this resource provides |
258
+ | `mimeType?` | Content MIME type |
259
+
260
+ ```typescript
261
+ import { ResourceTemplate, ResourceContext } from '@frontmcp/sdk';
262
+
263
+ @ResourceTemplate({
264
+ name: 'user_profile',
265
+ uriTemplate: 'users://{userId}/profile',
266
+ description: 'User profile by ID',
267
+ mimeType: 'application/json',
268
+ })
269
+ class UserProfileResource extends ResourceContext {
270
+ async read(uri: string, params: { userId: string }) {
271
+ const user = await this.get(UserService).findById(params.userId);
272
+ return { contents: [{ uri, text: JSON.stringify(user) }] };
273
+ }
274
+ }
275
+ ```
276
+
277
+ ---
278
+
279
+ ## 7. @Agent
280
+
281
+ **Purpose:** Defines an autonomous AI agent that uses LLMs to accomplish tasks, optionally with tools and sub-agents.
282
+
283
+ **When to use:** When you need an autonomous entity that reasons, plans, and executes multi-step tasks using LLMs.
284
+
285
+ **Key fields:**
286
+
287
+ | Field | Description |
288
+ | --------------- | ------------------------------------------------------ |
289
+ | `name` | Agent name |
290
+ | `description` | What this agent does |
291
+ | `llm` | LLM configuration (model, provider, temperature, etc.) |
292
+ | `inputSchema?` | Zod raw shape for agent input |
293
+ | `outputSchema?` | Zod schema for structured output |
294
+ | `tools?` | Tools available to this agent |
295
+ | `agents?` | Sub-agents for delegation |
296
+ | `exports?` | What capabilities to expose externally |
297
+ | `swarm?` | Multi-agent swarm configuration |
298
+
299
+ ```typescript
300
+ import { Agent, AgentContext } from '@frontmcp/sdk';
301
+ import { z } from 'zod';
302
+
303
+ @Agent({
304
+ name: 'research_agent',
305
+ description: 'Researches topics and produces summaries',
306
+ llm: { model: 'claude-sonnet-4-20250514', provider: 'anthropic' },
307
+ inputSchema: {
308
+ topic: z.string().describe('Topic to research'),
309
+ },
310
+ tools: [WebSearchTool, SummarizeTool],
311
+ })
312
+ class ResearchAgent extends AgentContext {
313
+ async execute(input: { topic: string }) {
314
+ return this.run(`Research and summarize: ${input.topic}`);
315
+ }
316
+ }
317
+ ```
318
+
319
+ ---
320
+
321
+ ## 8. @Skill
322
+
323
+ **Purpose:** Packages knowledge, instructions, and tools into a reusable workflow unit that LLMs can discover and follow.
324
+
325
+ **When to use:** When you want to bundle a set of instructions and tools into a cohesive capability that an LLM can activate.
326
+
327
+ **Key fields:**
328
+
329
+ | Field | Description |
330
+ | ----------------- | ------------------------------------------------------ |
331
+ | `name` | Skill name |
332
+ | `description` | What this skill enables |
333
+ | `instructions` | Detailed instructions the LLM should follow |
334
+ | `tools?` | Tools bundled with this skill |
335
+ | `parameters?` | Configurable parameters |
336
+ | `examples?` | Usage examples |
337
+ | `visibility?` | Where skill is visible: `'mcp'`, `'http'`, or `'both'` |
338
+ | `toolValidation?` | Validation rules for tool usage |
339
+
340
+ ```typescript
341
+ import { Skill } from '@frontmcp/sdk';
342
+
343
+ @Skill({
344
+ name: 'code_migration',
345
+ description: 'Guides migration of code between frameworks',
346
+ instructions: `
347
+ 1. Analyze the source codebase structure
348
+ 2. Identify framework-specific patterns
349
+ 3. Generate migration plan
350
+ 4. Apply transformations using the provided tools
351
+ `,
352
+ tools: [AnalyzeTool, TransformTool, ValidateTool],
353
+ visibility: 'both',
354
+ })
355
+ class CodeMigrationSkill {}
356
+ ```
357
+
358
+ ---
359
+
360
+ ## 9. @Plugin
361
+
362
+ **Purpose:** Adds lifecycle hooks, DI providers, and context extensions to the server.
363
+
364
+ **When to use:** When you need cross-cutting concerns (logging, caching, session memory) that span multiple tools.
365
+
366
+ **Key fields:**
367
+
368
+ | Field | Description |
369
+ | -------------------- | --------------------------------------------------------------- |
370
+ | `name` | Plugin name |
371
+ | `providers?` | DI providers this plugin registers |
372
+ | `contextExtensions?` | Extensions to add to execution contexts (e.g., `this.remember`) |
373
+ | `tools?` | Tools provided by this plugin |
374
+
375
+ ```typescript
376
+ import { Plugin } from '@frontmcp/sdk';
377
+
378
+ @Plugin({
379
+ name: 'audit-log',
380
+ providers: [AuditLogProvider],
381
+ contextExtensions: [installAuditExtension],
382
+ })
383
+ class AuditPlugin {}
384
+ ```
385
+
386
+ ---
387
+
388
+ ## 10. @Adapter
389
+
390
+ **Purpose:** Integrates an external API or data source, converting it into FrontMCP tools and resources.
391
+
392
+ **When to use:** When you want to auto-generate MCP tools/resources from an external OpenAPI spec, GraphQL schema, or other source.
393
+
394
+ **Key fields:**
395
+
396
+ | Field | Description |
397
+ | ------ | ------------ |
398
+ | `name` | Adapter name |
399
+
400
+ ```typescript
401
+ import { Adapter } from '@frontmcp/sdk';
402
+
403
+ @Adapter({ name: 'github-api' })
404
+ class GitHubAdapter {
405
+ async connect() {
406
+ // Load OpenAPI spec and generate tools
407
+ }
408
+ }
409
+ ```
410
+
411
+ ---
412
+
413
+ ## 11. @Provider
414
+
415
+ **Purpose:** Registers a dependency injection provider in the FrontMCP DI container.
416
+
417
+ **When to use:** When you need injectable services, configuration, or factories available via `this.get(Token)`.
418
+
419
+ **Key fields:**
420
+
421
+ | Field | Description |
422
+ | ------------ | --------------------------------------------------------------- |
423
+ | `name` | Provider name |
424
+ | `provide` | Injection token |
425
+ | `useClass` | Class to instantiate (pick one of useClass/useValue/useFactory) |
426
+ | `useValue` | Static value to inject |
427
+ | `useFactory` | Factory function for dynamic creation |
428
+
429
+ ```typescript
430
+ import { Provider } from '@frontmcp/sdk';
431
+
432
+ @Provider({
433
+ name: 'database',
434
+ provide: DatabaseToken,
435
+ useFactory: () => new DatabaseClient(process.env.DB_URL),
436
+ })
437
+ class DatabaseProvider {}
438
+ ```
439
+
440
+ ---
441
+
442
+ ## 12. @Flow
443
+
444
+ **Purpose:** Defines a custom request/response flow with a multi-stage processing plan.
445
+
446
+ **When to use:** When you need complex multi-step request processing beyond simple tool execution (e.g., validation, transformation, approval chains).
447
+
448
+ **Key fields:**
449
+
450
+ | Field | Description |
451
+ | -------------- | ----------------------------------- |
452
+ | `name` | Flow name |
453
+ | `plan` | Array of stages to execute in order |
454
+ | `inputSchema` | Zod schema for flow input |
455
+ | `outputSchema` | Zod schema for flow output |
456
+ | `access` | Access control configuration |
457
+
458
+ ```typescript
459
+ import { Flow } from '@frontmcp/sdk';
460
+ import { z } from 'zod';
461
+
462
+ @Flow({
463
+ name: 'approval-flow',
464
+ plan: [ValidateStage, EnrichStage, ApproveStage, ExecuteStage],
465
+ inputSchema: z.object({ action: z.string(), target: z.string() }),
466
+ outputSchema: z.object({ approved: z.boolean(), result: z.unknown() }),
467
+ access: { roles: ['admin'] },
468
+ })
469
+ class ApprovalFlow {}
470
+ ```
471
+
472
+ ---
473
+
474
+ ## 13. @Job
475
+
476
+ **Purpose:** Declares a long-running or scheduled background job.
477
+
478
+ **When to use:** When you need recurring tasks (cron), background processing, or deferred work.
479
+
480
+ **Key fields:**
481
+
482
+ | Field | Description |
483
+ | ------------- | --------------------------------------------------------- |
484
+ | `name` | Job name |
485
+ | `description` | What the job does |
486
+ | `schedule?` | Cron expression (e.g., `'0 */6 * * *'` for every 6 hours) |
487
+
488
+ ```typescript
489
+ import { Job, JobContext } from '@frontmcp/sdk';
490
+
491
+ @Job({
492
+ name: 'sync_data',
493
+ description: 'Synchronize data from external sources',
494
+ schedule: '0 */6 * * *',
495
+ })
496
+ class SyncDataJob extends JobContext {
497
+ async execute() {
498
+ await this.get(SyncService).runFullSync();
499
+ }
500
+ }
501
+ ```
502
+
503
+ ---
504
+
505
+ ## 14. @Workflow
506
+
507
+ **Purpose:** Orchestrates a multi-step workflow composed of sequential or parallel steps.
508
+
509
+ **When to use:** When you need to coordinate multiple jobs or actions in a defined order with error handling and rollback.
510
+
511
+ **Key fields:**
512
+
513
+ | Field | Description |
514
+ | ------------- | ----------------------------------- |
515
+ | `name` | Workflow name |
516
+ | `description` | What this workflow accomplishes |
517
+ | `steps` | Array of step definitions (ordered) |
518
+
519
+ ```typescript
520
+ import { Workflow } from '@frontmcp/sdk';
521
+
522
+ @Workflow({
523
+ name: 'deploy_pipeline',
524
+ description: 'Full deployment pipeline',
525
+ steps: [
526
+ { name: 'build', job: BuildJob },
527
+ { name: 'test', job: TestJob },
528
+ { name: 'deploy', job: DeployJob },
529
+ ],
530
+ })
531
+ class DeployPipeline {}
532
+ ```
533
+
534
+ ---
535
+
536
+ ## 15. @Hook Decorators (@Will, @Did, @Stage, @Around)
537
+
538
+ **Purpose:** Attach lifecycle hooks to flows, allowing interception at different points.
539
+
540
+ **When to use:** When you need to run logic before, after, at a specific stage of, or wrapping around a flow execution.
541
+
542
+ **Variants:**
543
+
544
+ | Decorator | Timing | Description |
545
+ | --------- | -------- | ----------------------------------------- |
546
+ | `@Will` | Before | Runs before the flow executes |
547
+ | `@Did` | After | Runs after the flow completes |
548
+ | `@Stage` | During | Runs at a specific stage in the flow plan |
549
+ | `@Around` | Wrapping | Wraps the flow, controlling execution |
550
+
551
+ ```typescript
552
+ import { Will, Did, Stage, Around, HookContext } from '@frontmcp/sdk';
553
+
554
+ class AuditHooks {
555
+ @Will('tools:call-tool')
556
+ async beforeToolCall(ctx: HookContext) {
557
+ ctx.state.set('startTime', Date.now());
558
+ }
559
+
560
+ @Did('tools:call-tool')
561
+ async afterToolCall(ctx: HookContext) {
562
+ const duration = Date.now() - ctx.state.get('startTime');
563
+ await this.get(AuditService).log({ tool: ctx.toolName, duration });
564
+ }
565
+
566
+ @Around('resources:read-resource')
567
+ async cacheResource(ctx: HookContext, next: () => Promise<void>) {
568
+ const cached = await this.get(CacheService).get(ctx.uri);
569
+ if (cached) {
570
+ ctx.respond(cached);
571
+ return;
572
+ }
573
+ await next();
574
+ }
575
+ }
576
+ ```
577
+
578
+ ---
579
+
580
+ ## Quick Reference Table
581
+
582
+ | Decorator | Extends | Registered In | Purpose |
583
+ | --------------------------- | ----------------- | ---------------- | ------------------------ |
584
+ | `@FrontMcp` | - | Root | Server configuration |
585
+ | `@App` | - | `@FrontMcp.apps` | Module grouping |
586
+ | `@Tool` | `ToolContext` | `@App.tools` | Executable action |
587
+ | `@Prompt` | `PromptContext` | `@App.prompts` | Prompt template |
588
+ | `@Resource` | `ResourceContext` | `@App.resources` | Static data |
589
+ | `@ResourceTemplate` | `ResourceContext` | `@App.resources` | Parameterized data |
590
+ | `@Agent` | `AgentContext` | `@App.agents` | Autonomous AI agent |
591
+ | `@Skill` | - | `@App.skills` | Knowledge package |
592
+ | `@Plugin` | - | `@App.plugins` | Cross-cutting concern |
593
+ | `@Adapter` | - | `@App.adapters` | External integration |
594
+ | `@Provider` | - | `@App.providers` | DI binding |
595
+ | `@Flow` | - | `@App` | Custom flow |
596
+ | `@Job` | `JobContext` | `@App.jobs` | Background task |
597
+ | `@Workflow` | - | `@App.workflows` | Multi-step orchestration |
598
+ | `@Will/@Did/@Stage/@Around` | - | Entry class | Lifecycle hooks |