@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,754 @@
1
+ ---
2
+ name: decorators-guide
3
+ description: Complete reference for the hierarchical decorator system from @FrontMcp to @Tool
4
+ ---
5
+
6
+ # FrontMCP Decorators - Complete Reference
7
+
8
+ ## Architecture Overview
9
+
10
+ FrontMCP uses a hierarchical decorator system. The nesting order is:
11
+
12
+ ```text
13
+ @FrontMcp (server root)
14
+ +-- @App (application module)
15
+ +-- @Tool (MCP tool)
16
+ +-- @Resource (static MCP resource)
17
+ +-- @ResourceTemplate (parameterized resource)
18
+ +-- @Prompt (MCP prompt)
19
+ +-- @Agent (autonomous AI agent)
20
+ +-- @Skill (knowledge/workflow package)
21
+ +-- @Plugin (lifecycle plugin)
22
+ +-- @Provider (DI provider)
23
+ +-- @Adapter (external source adapter)
24
+ +-- @Job (long-running job)
25
+ +-- @Workflow (multi-step workflow)
26
+ +-- @Flow (custom flow)
27
+ +-- @Hook (@Will, @Did, @Stage, @Around)
28
+ ```
29
+
30
+ ---
31
+
32
+ ## When to Use This Skill
33
+
34
+ ### Must Use
35
+
36
+ - You are building a new FrontMCP server and need to choose the correct decorator for each component
37
+ - You are reviewing or debugging decorator configuration and need to verify field names, types, or nesting hierarchy
38
+ - You are onboarding to the FrontMCP codebase and need a single reference for the full decorator architecture
39
+
40
+ ### Recommended
41
+
42
+ - You are adding a new capability (tool, resource, prompt, agent, skill) to an existing server and want to confirm the correct decorator signature
43
+ - You are designing a plugin or adapter and need to understand how it integrates with the decorator hierarchy
44
+ - You are refactoring an app's module structure and need to verify which decorators belong in `@App` vs `@FrontMcp`
45
+
46
+ ### Skip When
47
+
48
+ - You only need to write business logic inside an existing tool or resource (see `create-tool` reference)
49
+ - You are configuring authentication or session management without changing decorators (see `configure-auth` reference)
50
+ - You are working on CI/CD, deployment, or infrastructure that does not involve decorator choices
51
+
52
+ > **Decision:** Use this skill whenever you need to look up, choose, or validate a FrontMCP decorator -- skip it when the decorator is already chosen and you are only implementing internal logic.
53
+
54
+ ---
55
+
56
+ ## 1. @FrontMcp
57
+
58
+ **Purpose:** Declares the root MCP server and its global configuration.
59
+
60
+ **When to use:** Once per server, on the top-level bootstrap class.
61
+
62
+ **Key fields:**
63
+
64
+ | Field | Description |
65
+ | --------------- | -------------------------------------------------------------------------------- |
66
+ | `info` | Server name, version, and description |
67
+ | `apps` | Array of `@App` classes to mount |
68
+ | `serve?` | Auto-start HTTP server (default: `true`). Set `false` for programmatic usage |
69
+ | `splitByApp?` | If `true`, each app gets its own scope and basePath. Default: `false` |
70
+ | `redis?` | Redis / Vercel KV connection for sessions, transport persistence, auth tokens |
71
+ | `plugins?` | Global plugins (instantiated per scope) |
72
+ | `providers?` | Global DI providers available to all apps |
73
+ | `tools?` | Standalone tools (outside apps, merged with app tools) |
74
+ | `resources?` | Standalone resources (merged with app resources) |
75
+ | `skills?` | Standalone skills (merged with app skills) |
76
+ | `skillsConfig?` | Skills HTTP endpoints (`/llm.txt`, `/skills`) and MCP tool config |
77
+ | `transport?` | Transport preset (`'modern'`, `'legacy'`, `'stateless-api'`, `'full'`) or object |
78
+ | `auth?` | Authentication mode: `'public'`, `'transparent'`, `'local'`, `'remote'` |
79
+ | `http?` | HTTP server options (port, host, cors, socketPath) |
80
+ | `logging?` | Logging configuration (transports and levels) |
81
+ | `elicitation?` | Enable interactive user input during tool execution |
82
+ | `sqlite?` | SQLite storage for local deployments (sessions, events) |
83
+ | `pubsub?` | Redis pub/sub for resource subscriptions (falls back to `redis` config) |
84
+ | `jobs?` | Background jobs/workflows system (`{ enabled, store? }`) |
85
+ | `throttle?` | Server-level guard config (see note below) |
86
+ | `pagination?` | List operation pagination (`tools/list` endpoint) |
87
+ | `ui?` | UI rendering config (CDN overrides for widget imports) |
88
+ | `extApps?` | Widget-to-host MCP Apps communication (host capabilities, session validation) |
89
+ | `loader?` | Default npm/ESM package loader for `App.esm()` / `App.remote()` apps |
90
+
91
+ > **Throttle vs per-tool guards:** Server-level `throttle` is a `GuardConfig` object with `global`, `defaultRateLimit`, `defaultConcurrency`, `defaultTimeout` sub-fields that set server-wide defaults. Tool-level `rateLimit`, `concurrency`, `timeout` fields (on `@Tool`) override these defaults per tool.
92
+
93
+ ```typescript
94
+ import { FrontMcp } from '@frontmcp/sdk';
95
+
96
+ @FrontMcp({
97
+ info: { name: 'my-server', version: '1.0.0' },
98
+ apps: [MainApp],
99
+ transport: 'modern', // Valid presets: 'modern', 'legacy', 'stateless-api', 'full'
100
+ http: { port: 3000 },
101
+ plugins: [RememberPlugin],
102
+ skillsConfig: { enabled: true },
103
+ })
104
+ class MyServer {}
105
+ ```
106
+
107
+ ---
108
+
109
+ ## 2. @App
110
+
111
+ **Purpose:** Groups related tools, resources, prompts, agents, and skills into an application module.
112
+
113
+ **When to use:** To organize your server into logical modules. Every server has at least one app.
114
+
115
+ **Key fields:**
116
+
117
+ | Field | Description |
118
+ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
119
+ | `name` | Application name (unique within server) |
120
+ | `description?` | Human-readable description for docs and UIs |
121
+ | `tools?` | Array of tool classes or function-built tools |
122
+ | `resources?` | Array of resource classes or function-built resources |
123
+ | `prompts?` | Array of prompt classes or function-built prompts |
124
+ | `agents?` | Array of agent classes (each exposed as `use-agent:<name>` tool) |
125
+ | `skills?` | Array of skill definitions |
126
+ | `plugins?` | App-scoped plugins |
127
+ | `providers?` | App-scoped DI providers |
128
+ | `authProviders?` | Named auth providers (e.g., GitHub, Google OAuth) separate from `auth` |
129
+ | `adapters?` | External source adapters (e.g., OpenAPI) |
130
+ | `auth?` | App-level auth config (overrides server default) |
131
+ | `standalone?` | `boolean \| 'includeInParent'` — `true`: isolated scope, excluded. `'includeInParent'`: isolated scope but tools exposed in parent |
132
+ | `jobs?` | Background job definitions |
133
+ | `workflows?` | Multi-step workflow definitions |
134
+
135
+ ```typescript
136
+ import { App } from '@frontmcp/sdk';
137
+
138
+ @App({
139
+ name: 'analytics',
140
+ tools: [QueryTool, ReportTool],
141
+ resources: [DashboardResource],
142
+ prompts: [SummaryPrompt],
143
+ providers: [DatabaseProvider],
144
+ })
145
+ class AnalyticsApp {}
146
+ ```
147
+
148
+ ---
149
+
150
+ ## 3. @Tool
151
+
152
+ **Purpose:** Defines an MCP tool that an LLM can invoke to perform actions.
153
+
154
+ **When to use:** When you need the LLM to execute a function, query data, or trigger side effects.
155
+
156
+ **Key fields:**
157
+
158
+ | Field | Description |
159
+ | -------------------- | -------------------------------------------------------------------- |
160
+ | `name` | Tool name (used in MCP protocol, snake_case) |
161
+ | `description` | Human-readable description for the LLM |
162
+ | `inputSchema` | Zod raw shape defining input parameters |
163
+ | `outputSchema?` | Output type: Zod schema, `'string'`, `'image'`, `'audio'`, etc. |
164
+ | `annotations?` | MCP tool annotations (`readOnlyHint`, `destructiveHint`, etc.) |
165
+ | `tags?` | Categorization tags for filtering |
166
+ | `hideFromDiscovery?` | Hide from `tools/list` (still callable directly) |
167
+ | `examples?` | Usage examples: `[{ description, input, output? }]` |
168
+ | `authProviders?` | Per-tool auth providers: `['GitHub']` or `[{ name, scopes, alias }]` |
169
+ | `rateLimit?` | Rate limiting: `{ maxRequests, windowMs, partitionBy }` |
170
+ | `concurrency?` | Concurrency control: `{ maxConcurrent }` |
171
+ | `timeout?` | Execution timeout: `{ executeMs }` |
172
+ | `ui?` | UI widget configuration for tool rendering |
173
+
174
+ ```typescript
175
+ import { Tool, ToolContext } from '@frontmcp/sdk';
176
+ import { z } from 'zod';
177
+
178
+ @Tool({
179
+ name: 'search_users',
180
+ description: 'Search for users by name or email',
181
+ inputSchema: {
182
+ query: z.string().describe('Search query'),
183
+ limit: z.number().optional().default(10),
184
+ },
185
+ })
186
+ class SearchUsersTool extends ToolContext {
187
+ async execute(input: { query: string; limit: number }) {
188
+ const users = await this.get(UserService).search(input.query, input.limit);
189
+ return { users };
190
+ }
191
+ }
192
+ ```
193
+
194
+ ---
195
+
196
+ ## 4. @Prompt
197
+
198
+ **Purpose:** Defines an MCP prompt template that generates structured messages for the LLM.
199
+
200
+ **When to use:** When you want to expose reusable prompt templates with typed arguments.
201
+
202
+ **Key fields:**
203
+
204
+ | Field | Description |
205
+ | -------------- | ------------------------------------------------------------------- |
206
+ | `name` | Prompt name (used in MCP protocol) |
207
+ | `title?` | Human-readable display title for UIs |
208
+ | `description?` | What this prompt does |
209
+ | `arguments?` | Array of argument definitions (`{ name, description?, required? }`) |
210
+ | `icons?` | Array of Icon objects for UI representation (per MCP spec) |
211
+
212
+ ```typescript
213
+ import { Prompt, PromptContext } from '@frontmcp/sdk';
214
+
215
+ @Prompt({
216
+ name: 'code_review',
217
+ description: 'Generate a code review for the given code',
218
+ arguments: [
219
+ { name: 'code', description: 'The code to review', required: true },
220
+ { name: 'language', description: 'Programming language' },
221
+ ],
222
+ })
223
+ class CodeReviewPrompt extends PromptContext {
224
+ async execute(args: { code: string; language?: string }) {
225
+ return {
226
+ messages: [
227
+ {
228
+ role: 'user' as const,
229
+ content: {
230
+ type: 'text' as const,
231
+ text: `Review this ${args.language ?? ''} code:\n\n${args.code}`,
232
+ },
233
+ },
234
+ ],
235
+ };
236
+ }
237
+ }
238
+ ```
239
+
240
+ ---
241
+
242
+ ## 5. @Resource
243
+
244
+ **Purpose:** Exposes a static MCP resource identified by a fixed URI.
245
+
246
+ **When to use:** When you need to expose data at a known, unchanging URI (e.g., config files, system status).
247
+
248
+ **Key fields:**
249
+
250
+ | Field | Description |
251
+ | -------------- | -------------------------------------------- |
252
+ | `name` | Resource name (used in MCP protocol) |
253
+ | `title?` | Human-readable display title for UIs |
254
+ | `uri` | Fixed URI (e.g., `config://app/settings`) |
255
+ | `description?` | What this resource provides |
256
+ | `mimeType?` | Content MIME type (e.g., `application/json`) |
257
+ | `icons?` | Array of Icon objects for UI representation |
258
+
259
+ ```typescript
260
+ import { Resource, ResourceContext } from '@frontmcp/sdk';
261
+
262
+ @Resource({
263
+ name: 'app_config',
264
+ uri: 'config://app/settings',
265
+ description: 'Current application settings',
266
+ mimeType: 'application/json',
267
+ })
268
+ class AppConfigResource extends ResourceContext {
269
+ async read() {
270
+ const config = await this.get(ConfigService).getAll();
271
+ return { contents: [{ uri: this.uri, text: JSON.stringify(config) }] };
272
+ }
273
+ }
274
+ ```
275
+
276
+ ---
277
+
278
+ ## 6. @ResourceTemplate
279
+
280
+ **Purpose:** Exposes a parameterized MCP resource with URI pattern matching.
281
+
282
+ **When to use:** When resources are identified by dynamic parameters (e.g., user profiles, documents by ID).
283
+
284
+ **Key fields:**
285
+
286
+ | Field | Description |
287
+ | -------------- | --------------------------------------------------------------- |
288
+ | `name` | Resource template name |
289
+ | `title?` | Human-readable display title for UIs |
290
+ | `uriTemplate` | URI template with parameters (e.g., `users://{userId}/profile`) |
291
+ | `description?` | What this resource provides |
292
+ | `mimeType?` | Content MIME type |
293
+ | `icons?` | Array of Icon objects for UI representation |
294
+
295
+ ```typescript
296
+ import { ResourceTemplate, ResourceContext } from '@frontmcp/sdk';
297
+
298
+ @ResourceTemplate({
299
+ name: 'user_profile',
300
+ uriTemplate: 'users://{userId}/profile',
301
+ description: 'User profile by ID',
302
+ mimeType: 'application/json',
303
+ })
304
+ class UserProfileResource extends ResourceContext {
305
+ async read(uri: string, params: { userId: string }) {
306
+ const user = await this.get(UserService).findById(params.userId);
307
+ return { contents: [{ uri, text: JSON.stringify(user) }] };
308
+ }
309
+ }
310
+ ```
311
+
312
+ ---
313
+
314
+ ## 7. @Agent
315
+
316
+ **Purpose:** Defines an autonomous AI agent that uses LLMs to accomplish tasks, optionally with tools and sub-agents.
317
+
318
+ **When to use:** When you need an autonomous entity that reasons, plans, and executes multi-step tasks using LLMs.
319
+
320
+ **Key fields:**
321
+
322
+ | Field | Description |
323
+ | --------------- | ------------------------------------------------------ |
324
+ | `name` | Agent name |
325
+ | `description` | What this agent does |
326
+ | `llm` | LLM configuration (model, provider, temperature, etc.) |
327
+ | `inputSchema?` | Zod raw shape for agent input |
328
+ | `outputSchema?` | Zod schema for structured output |
329
+ | `tools?` | Tools available to this agent |
330
+ | `agents?` | Sub-agents for delegation |
331
+ | `exports?` | What capabilities to expose externally |
332
+ | `swarm?` | Multi-agent swarm configuration |
333
+
334
+ ```typescript
335
+ import { Agent, AgentContext } from '@frontmcp/sdk';
336
+ import { z } from 'zod';
337
+
338
+ @Agent({
339
+ name: 'research_agent',
340
+ description: 'Researches topics and produces summaries',
341
+ llm: { model: 'claude-sonnet-4-20250514', provider: 'anthropic' },
342
+ inputSchema: {
343
+ topic: z.string().describe('Topic to research'),
344
+ },
345
+ tools: [WebSearchTool, SummarizeTool],
346
+ })
347
+ class ResearchAgent extends AgentContext {
348
+ async execute(input: { topic: string }) {
349
+ return this.run(`Research and summarize: ${input.topic}`);
350
+ }
351
+ }
352
+ ```
353
+
354
+ ---
355
+
356
+ ## 8. @Skill
357
+
358
+ **Purpose:** Packages knowledge, instructions, and tools into a reusable workflow unit that LLMs can discover and follow.
359
+
360
+ **When to use:** When you want to bundle a set of instructions and tools into a cohesive capability that an LLM can activate.
361
+
362
+ **Key fields:**
363
+
364
+ | Field | Description |
365
+ | -------------------- | ------------------------------------------------------------------------------ |
366
+ | `name` | Skill name (kebab-case, max 64 chars) |
367
+ | `description` | What this skill enables (max 1024 chars, no HTML/XML) |
368
+ | `instructions` | Inline string, `{ file: '...' }`, or `{ url: '...' }` |
369
+ | `tools?` | Tool classes, names, or `{ tool/name, purpose?, required? }` refs |
370
+ | `parameters?` | Input parameters: `[{ name, description?, type?, default? }]` |
371
+ | `examples?` | Usage examples: `[{ scenario, parameters?, expectedOutcome? }]` |
372
+ | `visibility?` | Discovery scope: `'mcp'`, `'http'`, or `'both'` (default: `'both'`) |
373
+ | `toolValidation?` | `'strict'` \| `'warn'` \| `'ignore'` for missing tool refs (default: `'warn'`) |
374
+ | `priority?` | Search ranking weight (higher = earlier). Default: `0` |
375
+ | `hideFromDiscovery?` | Hide from search results; still loadable by ID |
376
+ | `tags?` | Tags for categorization and search |
377
+ | `license?` | License identifier (per Agent Skills spec, e.g., `'MIT'`) |
378
+ | `compatibility?` | Environment requirements (max 500 chars, e.g., `'Node.js 18+'`) |
379
+ | `specMetadata?` | Arbitrary key-value map (Agent Skills spec `metadata` field) |
380
+ | `allowedTools?` | Space-delimited pre-approved tool names (Agent Skills spec) |
381
+ | `resources?` | Bundled dirs: `{ scripts?, references?, assets? }` (Agent Skills spec) |
382
+
383
+ ```typescript
384
+ import { Skill } from '@frontmcp/sdk';
385
+
386
+ @Skill({
387
+ name: 'code_migration',
388
+ description: 'Guides migration of code between frameworks',
389
+ instructions: `
390
+ 1. Analyze the source codebase structure
391
+ 2. Identify framework-specific patterns
392
+ 3. Generate migration plan
393
+ 4. Apply transformations using the provided tools
394
+ `,
395
+ tools: [AnalyzeTool, TransformTool, ValidateTool],
396
+ visibility: 'both',
397
+ })
398
+ class CodeMigrationSkill {}
399
+ ```
400
+
401
+ ---
402
+
403
+ ## 9. @Plugin
404
+
405
+ **Purpose:** Adds lifecycle hooks, DI providers, and context extensions to the server.
406
+
407
+ **When to use:** When you need cross-cutting concerns (logging, caching, session memory) that span multiple tools.
408
+
409
+ **Key fields:**
410
+
411
+ | Field | Description |
412
+ | -------------------- | --------------------------------------------------------------- |
413
+ | `name` | Plugin name |
414
+ | `providers?` | DI providers this plugin registers |
415
+ | `contextExtensions?` | Extensions to add to execution contexts (e.g., `this.remember`) |
416
+ | `tools?` | Tools provided by this plugin |
417
+
418
+ ```typescript
419
+ import { Plugin } from '@frontmcp/sdk';
420
+
421
+ @Plugin({
422
+ name: 'audit-log',
423
+ providers: [AuditLogProvider],
424
+ contextExtensions: [installAuditExtension],
425
+ })
426
+ class AuditPlugin {}
427
+ ```
428
+
429
+ ---
430
+
431
+ ## 10. @Adapter
432
+
433
+ **Purpose:** Integrates an external API or data source, converting it into FrontMCP tools and resources.
434
+
435
+ **When to use:** When you want to auto-generate MCP tools/resources from an external OpenAPI spec, GraphQL schema, or other source.
436
+
437
+ **Key fields:**
438
+
439
+ | Field | Description |
440
+ | ------ | ------------ |
441
+ | `name` | Adapter name |
442
+
443
+ ```typescript
444
+ import { Adapter } from '@frontmcp/sdk';
445
+
446
+ @Adapter({ name: 'github-api' })
447
+ class GitHubAdapter {
448
+ async connect() {
449
+ // Load OpenAPI spec and generate tools
450
+ }
451
+ }
452
+ ```
453
+
454
+ ---
455
+
456
+ ## 11. @Provider
457
+
458
+ **Purpose:** Registers a dependency injection provider in the FrontMCP DI container.
459
+
460
+ **When to use:** When you need injectable services, configuration, or factories available via `this.get(Token)`.
461
+
462
+ **Key fields:**
463
+
464
+ | Field | Description |
465
+ | ------------ | --------------------------------------------------------------- |
466
+ | `name` | Provider name |
467
+ | `provide` | Injection token |
468
+ | `useClass` | Class to instantiate (pick one of useClass/useValue/useFactory) |
469
+ | `useValue` | Static value to inject |
470
+ | `useFactory` | Factory function for dynamic creation |
471
+
472
+ ```typescript
473
+ import { Provider } from '@frontmcp/sdk';
474
+
475
+ @Provider({
476
+ name: 'database',
477
+ provide: DatabaseToken,
478
+ useFactory: () => new DatabaseClient(process.env.DB_URL),
479
+ })
480
+ class DatabaseProvider {}
481
+ ```
482
+
483
+ ---
484
+
485
+ ## 12. @Flow
486
+
487
+ **Purpose:** Defines a custom request/response flow with a multi-stage processing plan.
488
+
489
+ **When to use:** When you need complex multi-step request processing beyond simple tool execution (e.g., validation, transformation, approval chains).
490
+
491
+ **Key fields:**
492
+
493
+ | Field | Description |
494
+ | -------------- | ----------------------------------- |
495
+ | `name` | Flow name |
496
+ | `plan` | Array of stages to execute in order |
497
+ | `inputSchema` | Zod schema for flow input |
498
+ | `outputSchema` | Zod schema for flow output |
499
+ | `access` | Access control configuration |
500
+
501
+ ```typescript
502
+ import { Flow } from '@frontmcp/sdk';
503
+ import { z } from 'zod';
504
+
505
+ @Flow({
506
+ name: 'approval-flow',
507
+ plan: [ValidateStage, EnrichStage, ApproveStage, ExecuteStage],
508
+ inputSchema: z.object({ action: z.string(), target: z.string() }),
509
+ outputSchema: z.object({ approved: z.boolean(), result: z.unknown() }),
510
+ access: { roles: ['admin'] },
511
+ })
512
+ class ApprovalFlow {}
513
+ ```
514
+
515
+ ---
516
+
517
+ ## 13. @Job
518
+
519
+ **Purpose:** Declares a long-running or scheduled background job.
520
+
521
+ **When to use:** When you need recurring tasks (cron), background processing, or deferred work.
522
+
523
+ **Key fields:**
524
+
525
+ | Field | Description |
526
+ | -------------------- | ------------------------------------------------------------- |
527
+ | `name` | Job name |
528
+ | `description` | What the job does |
529
+ | `inputSchema` | Zod schema for job input parameters |
530
+ | `outputSchema` | Zod schema for job output |
531
+ | `retry?` | `{ maxAttempts, backoffMs, backoffMultiplier, maxBackoffMs }` |
532
+ | `timeout?` | Execution timeout in ms |
533
+ | `tags?` | Categorization tags |
534
+ | `labels?` | Key-value labels (e.g., `{ env: 'prod' }`) |
535
+ | `hideFromDiscovery?` | Hide from job listing |
536
+ | `permissions?` | Access control: `[{ action: 'execute', roles: ['admin'] }]` |
537
+
538
+ ```typescript
539
+ import { Job, JobContext } from '@frontmcp/sdk';
540
+ import { z } from 'zod';
541
+
542
+ @Job({
543
+ name: 'sync_data',
544
+ description: 'Synchronize data from external sources',
545
+ inputSchema: z.object({ source: z.string().describe('Data source to sync') }),
546
+ outputSchema: z.object({ synced: z.number() }),
547
+ retry: { maxAttempts: 3, backoffMs: 1000, backoffMultiplier: 2, maxBackoffMs: 60_000 },
548
+ timeout: 300_000,
549
+ })
550
+ class SyncDataJob extends JobContext {
551
+ async execute(input: { source: string }) {
552
+ const count = await this.get(SyncService).runFullSync(input.source);
553
+ return { synced: count };
554
+ }
555
+ }
556
+ ```
557
+
558
+ ---
559
+
560
+ ## 14. @Workflow
561
+
562
+ **Purpose:** Orchestrates a multi-step workflow composed of sequential or parallel steps.
563
+
564
+ **When to use:** When you need to coordinate multiple jobs or actions in a defined order with error handling and rollback.
565
+
566
+ **Key fields:**
567
+
568
+ | Field | Description |
569
+ | -------------------- | ------------------------------------------------------------------ |
570
+ | `name` | Workflow name |
571
+ | `description` | What this workflow accomplishes |
572
+ | `steps` | Array of step definitions (see step fields below) |
573
+ | `trigger?` | `'manual'` \| `'webhook'` \| `'event'` |
574
+ | `webhook?` | `{ path, secret, methods }` — required when trigger is `'webhook'` |
575
+ | `timeout?` | Overall workflow timeout in ms |
576
+ | `maxConcurrency?` | Maximum parallel step concurrency (default: 5) |
577
+ | `tags?` | Categorization tags |
578
+ | `labels?` | Key-value labels (e.g., `{ env: 'prod' }`) |
579
+ | `hideFromDiscovery?` | Hide from workflow listing |
580
+ | `permissions?` | Access control: `[{ action: 'execute', roles: ['admin'] }]` |
581
+ | `inputSchema?` | Zod schema for workflow input parameters |
582
+ | `outputSchema?` | Zod schema for workflow output |
583
+
584
+ **Step fields:**
585
+
586
+ | Step Field | Description |
587
+ | ------------------ | --------------------------------------------------------------- |
588
+ | `id` | Unique step identifier |
589
+ | `jobName` | Name of the `@Job` to execute |
590
+ | `input?` | Static object or `(steps) => object` function for dynamic input |
591
+ | `dependsOn?` | Array of step IDs that must complete first |
592
+ | `condition?` | `(steps) => boolean` — skip step if returns false |
593
+ | `continueOnError?` | Continue workflow if this step fails (default: `false`) |
594
+ | `timeout?` | Per-step timeout in ms |
595
+ | `retry?` | Per-step retry config (same shape as `@Job.retry`) |
596
+
597
+ ```typescript
598
+ import { Workflow } from '@frontmcp/sdk';
599
+
600
+ @Workflow({
601
+ name: 'deploy_pipeline',
602
+ description: 'Full deployment pipeline',
603
+ trigger: 'webhook',
604
+ webhookConfig: { path: '/hooks/deploy', secret: process.env.WEBHOOK_SECRET!, methods: ['POST'] },
605
+ timeout: 600_000,
606
+ steps: [
607
+ { id: 'build', jobName: 'build_app', input: { env: 'production' } },
608
+ { id: 'test', jobName: 'run_tests', dependsOn: ['build'] },
609
+ { id: 'deploy', jobName: 'deploy_app', dependsOn: ['test'], condition: (steps) => steps.test.success },
610
+ ],
611
+ })
612
+ class DeployPipeline {}
613
+ ```
614
+
615
+ ---
616
+
617
+ ## 15. @Hook Decorators (@Will, @Did, @Stage, @Around)
618
+
619
+ **Purpose:** Attach lifecycle hooks to flows, allowing interception at different points.
620
+
621
+ **When to use:** When you need to run logic before, after, at a specific stage of, or wrapping around a flow execution.
622
+
623
+ **Variants:**
624
+
625
+ | Decorator | Timing | Description |
626
+ | --------- | -------- | ----------------------------------------- |
627
+ | `@Will` | Before | Runs before the flow executes |
628
+ | `@Did` | After | Runs after the flow completes |
629
+ | `@Stage` | During | Runs at a specific stage in the flow plan |
630
+ | `@Around` | Wrapping | Wraps the flow, controlling execution |
631
+
632
+ ```typescript
633
+ import { Will, Did, Stage, Around, HookContext } from '@frontmcp/sdk';
634
+
635
+ class AuditHooks {
636
+ @Will('tools:call-tool')
637
+ async beforeToolCall(ctx: HookContext) {
638
+ ctx.state.set('startTime', Date.now());
639
+ }
640
+
641
+ @Did('tools:call-tool')
642
+ async afterToolCall(ctx: HookContext) {
643
+ const duration = Date.now() - ctx.state.get('startTime');
644
+ await this.get(AuditService).log({ tool: ctx.toolName, duration });
645
+ }
646
+
647
+ @Around('resources:read-resource')
648
+ async cacheResource(ctx: HookContext, next: () => Promise<void>) {
649
+ const cached = await this.get(CacheService).get(ctx.uri);
650
+ if (cached) {
651
+ ctx.respond(cached);
652
+ return;
653
+ }
654
+ await next();
655
+ }
656
+ }
657
+ ```
658
+
659
+ ---
660
+
661
+ ## Quick Reference Table
662
+
663
+ | Decorator | Extends | Registered In | Purpose |
664
+ | --------------------------- | ----------------- | ---------------- | ------------------------ |
665
+ | `@FrontMcp` | - | Root | Server configuration |
666
+ | `@App` | - | `@FrontMcp.apps` | Module grouping |
667
+ | `@Tool` | `ToolContext` | `@App.tools` | Executable action |
668
+ | `@Prompt` | `PromptContext` | `@App.prompts` | Prompt template |
669
+ | `@Resource` | `ResourceContext` | `@App.resources` | Static data |
670
+ | `@ResourceTemplate` | `ResourceContext` | `@App.resources` | Parameterized data |
671
+ | `@Agent` | `AgentContext` | `@App.agents` | Autonomous AI agent |
672
+ | `@Skill` | - | `@App.skills` | Knowledge package |
673
+ | `@Plugin` | - | `@App.plugins` | Cross-cutting concern |
674
+ | `@Adapter` | - | `@App.adapters` | External integration |
675
+ | `@Provider` | - | `@App.providers` | DI binding |
676
+ | `@Flow` | - | `@App` | Custom flow |
677
+ | `@Job` | `JobContext` | `@App.jobs` | Background task |
678
+ | `@Workflow` | - | `@App.workflows` | Multi-step orchestration |
679
+ | `@Will/@Did/@Stage/@Around` | - | Entry class | Lifecycle hooks |
680
+
681
+ ---
682
+
683
+ ## Common Patterns
684
+
685
+ | Pattern | Correct | Incorrect | Why |
686
+ | --------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
687
+ | Grouping tools into modules | Place tools inside `@App({ tools: [...] })` | Register tools directly in `@FrontMcp({ tools: [...] })` for large servers | Apps provide logical grouping, scoped providers, and isolation; standalone tools in `@FrontMcp` are only appropriate for small servers or global utilities |
688
+ | Exposing data to the LLM | Use `@Resource` for fixed URIs, `@ResourceTemplate` for parameterized URIs | Using `@Tool` to return static data that never changes | Resources are the MCP-standard way to expose readable data; tools are for actions with side effects or dynamic computation |
689
+ | Cross-cutting concerns | Create a `@Plugin` with providers and context extensions | Adding logging/caching logic directly inside every tool's `execute()` method | Plugins centralize shared behavior, reduce duplication, and can be reused across servers |
690
+ | Background processing | Use `@Job` with a cron schedule for recurring work | Using `setTimeout` or manual polling inside a tool | Jobs integrate with the scheduler, support persistence, and are visible in server diagnostics |
691
+ | Multi-step orchestration | Use `@Workflow` with ordered steps referencing `@Job` classes | Chaining multiple tool calls manually from the LLM | Workflows provide built-in ordering, error handling, and rollback semantics |
692
+ | Injecting services | Use `@Provider` with `useFactory`/`useClass` and access via `this.get(Token)` | Importing singletons directly or using global state | DI providers support testability, lifecycle management, and per-scope isolation |
693
+
694
+ ---
695
+
696
+ ## Verification Checklist
697
+
698
+ ### Structure
699
+
700
+ - [ ] Server has exactly one `@FrontMcp` decorated class
701
+ - [ ] Every `@App` is listed in the `@FrontMcp({ apps: [...] })` array
702
+ - [ ] Each tool, resource, prompt, agent, and skill is registered in an `@App` (or in `@FrontMcp` for standalone use)
703
+
704
+ ### Decorator Fields
705
+
706
+ - [ ] Every `@Tool` has `name`, `description`, and `inputSchema` defined
707
+ - [ ] Every `@Resource` has `name` and `uri` with a valid scheme (e.g., `config://`, `file://`)
708
+ - [ ] Every `@ResourceTemplate` has `uriTemplate` with `{param}` placeholders matching the `read()` params argument
709
+ - [ ] Every `@Prompt` has `name` and at least one argument when it accepts input
710
+ - [ ] Every `@Agent` has `name`, `description`, and `llm` configuration
711
+
712
+ ### Inheritance
713
+
714
+ - [ ] Tool classes extend `ToolContext` and implement `execute()`
715
+ - [ ] Prompt classes extend `PromptContext` and implement `execute()`
716
+ - [ ] Resource classes extend `ResourceContext` and implement `read()`
717
+ - [ ] Agent classes extend `AgentContext` and implement `execute()`
718
+ - [ ] Job classes extend `JobContext` and implement `execute()`
719
+
720
+ ### Hooks
721
+
722
+ - [ ] Hook flow strings match valid flows (e.g., `tools:call-tool`, `resources:read-resource`)
723
+ - [ ] `@Around` hooks call `await next()` to continue the chain (unless intentionally short-circuiting)
724
+ - [ ] Hooks do not mutate `rawInput` -- use `ctx.state.set()` for flow state
725
+
726
+ ### DI and Plugins
727
+
728
+ - [ ] All `@Provider` entries specify exactly one of `useClass`, `useValue`, or `useFactory`
729
+ - [ ] Plugins are registered in `@App({ plugins: [...] })` or `@FrontMcp({ plugins: [...] })`
730
+ - [ ] Context extensions installed by plugins match the module augmentation declarations
731
+
732
+ ---
733
+
734
+ ## Troubleshooting
735
+
736
+ | Problem | Cause | Solution |
737
+ | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
738
+ | Tool does not appear in `tools/list` MCP response | Tool class is not registered in any `@App({ tools: [...] })` or `@FrontMcp({ tools: [...] })` | Add the tool class to the `tools` array of the appropriate `@App` or `@FrontMcp` decorator |
739
+ | `this.get(Token)` throws `DependencyNotFoundError` | The provider for that token is not registered or is registered in a different app scope | Add a `@Provider` for the token in the same `@App` or in `@FrontMcp({ providers: [...] })` for global access |
740
+ | Resource returns 404 / `ResourceNotFoundError` | The `uri` in `@Resource` does not match the requested URI, or `uriTemplate` parameters are misaligned | Verify the URI string exactly matches what the client requests; for templates, confirm `{param}` names match |
741
+ | Hook never fires | The `flow` string in `@Will`/`@Did`/`@Around`/`@Stage` does not match any registered flow | Check the flow string against valid flows (e.g., `tools:call-tool`, `resources:read-resource`, `resources:list-resources`) |
742
+ | Plugin context extension is `undefined` at runtime | The plugin's `installContextExtension` function was not called, or module augmentation is missing | Ensure the plugin is registered and its context extension function runs at startup; verify the `declare module` augmentation exists |
743
+ | Agent `execute()` returns empty result | LLM configuration is missing or invalid (wrong model name, missing API key) | Verify `llm.model` and `llm.provider` in `@Agent`, and ensure the provider API key is set in environment variables |
744
+
745
+ ---
746
+
747
+ ## Reference
748
+
749
+ - **Official docs:** [FrontMCP Decorators Overview](https://docs.agentfront.dev/frontmcp/sdk-reference/decorators/overview)
750
+ - **Related skills:**
751
+ - `create-tool` -- step-by-step guide for building tools with `@Tool` and `ToolContext`
752
+ - `create-resource` -- patterns for `@Resource` and `@ResourceTemplate` usage
753
+ - `create-plugin` -- creating plugins with `@Plugin`, providers, and context extensions
754
+ - `configure-auth` -- authentication and session configuration (not decorator-focused)