@frontmcp/skills 0.0.1 → 1.0.0-beta.10

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 (88) hide show
  1. package/README.md +2 -2
  2. package/catalog/TEMPLATE.md +58 -13
  3. package/catalog/frontmcp-config/SKILL.md +143 -0
  4. package/catalog/frontmcp-config/references/configure-auth.md +238 -0
  5. package/catalog/frontmcp-config/references/configure-elicitation.md +178 -0
  6. package/catalog/frontmcp-config/references/configure-http.md +205 -0
  7. package/catalog/frontmcp-config/references/configure-session.md +205 -0
  8. package/catalog/frontmcp-config/references/configure-throttle.md +229 -0
  9. package/catalog/frontmcp-config/references/configure-transport.md +195 -0
  10. package/catalog/frontmcp-config/references/setup-redis.md +4 -0
  11. package/catalog/frontmcp-config/references/setup-sqlite.md +4 -0
  12. package/catalog/frontmcp-deployment/SKILL.md +127 -0
  13. package/catalog/frontmcp-deployment/references/build-for-browser.md +138 -0
  14. package/catalog/frontmcp-deployment/references/build-for-cli.md +138 -0
  15. package/catalog/{deployment/build-for-sdk/SKILL.md → frontmcp-deployment/references/build-for-sdk.md} +65 -24
  16. package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +213 -0
  17. package/catalog/{deployment/deploy-to-lambda/SKILL.md → frontmcp-deployment/references/deploy-to-lambda.md} +76 -63
  18. package/catalog/{deployment/deploy-to-node/references/Dockerfile.example → frontmcp-deployment/references/deploy-to-node-dockerfile.md} +13 -4
  19. package/catalog/{deployment/deploy-to-node/SKILL.md → frontmcp-deployment/references/deploy-to-node.md} +68 -40
  20. package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +60 -0
  21. package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +224 -0
  22. package/catalog/frontmcp-development/SKILL.md +121 -0
  23. package/catalog/frontmcp-development/references/create-adapter.md +165 -0
  24. package/catalog/{development/create-agent/references/llm-config.md → frontmcp-development/references/create-agent-llm-config.md} +5 -5
  25. package/catalog/{development/create-agent/SKILL.md → frontmcp-development/references/create-agent.md} +82 -44
  26. package/catalog/{development/create-job/SKILL.md → frontmcp-development/references/create-job.md} +61 -19
  27. package/catalog/{plugins/create-plugin-hooks/SKILL.md → frontmcp-development/references/create-plugin-hooks.md} +63 -11
  28. package/catalog/{plugins/create-plugin/SKILL.md → frontmcp-development/references/create-plugin.md} +65 -60
  29. package/catalog/{development/create-prompt/SKILL.md → frontmcp-development/references/create-prompt.md} +62 -26
  30. package/catalog/{development/create-provider/SKILL.md → frontmcp-development/references/create-provider.md} +62 -27
  31. package/catalog/{development/create-resource/SKILL.md → frontmcp-development/references/create-resource.md} +62 -30
  32. package/catalog/{development/create-skill-with-tools/SKILL.md → frontmcp-development/references/create-skill-with-tools.md} +69 -24
  33. package/catalog/{development/create-skill/SKILL.md → frontmcp-development/references/create-skill.md} +96 -22
  34. package/catalog/{development/create-tool/SKILL.md → frontmcp-development/references/create-tool.md} +62 -26
  35. package/catalog/{development/create-workflow/SKILL.md → frontmcp-development/references/create-workflow.md} +60 -18
  36. package/catalog/{development/decorators-guide/SKILL.md → frontmcp-development/references/decorators-guide.md} +123 -34
  37. package/catalog/frontmcp-development/references/official-adapters.md +194 -0
  38. package/catalog/{plugins/official-plugins/SKILL.md → frontmcp-development/references/official-plugins.md} +96 -31
  39. package/catalog/frontmcp-guides/SKILL.md +420 -0
  40. package/catalog/frontmcp-guides/references/example-knowledge-base.md +636 -0
  41. package/catalog/frontmcp-guides/references/example-task-manager.md +512 -0
  42. package/catalog/frontmcp-guides/references/example-weather-api.md +292 -0
  43. package/catalog/frontmcp-production-readiness/SKILL.md +253 -0
  44. package/catalog/frontmcp-setup/SKILL.md +130 -0
  45. package/catalog/frontmcp-setup/references/frontmcp-skills-usage.md +265 -0
  46. package/catalog/{setup/multi-app-composition/SKILL.md → frontmcp-setup/references/multi-app-composition.md} +65 -23
  47. package/catalog/{setup/nx-workflow/SKILL.md → frontmcp-setup/references/nx-workflow.md} +78 -21
  48. package/catalog/frontmcp-setup/references/project-structure-nx.md +246 -0
  49. package/catalog/frontmcp-setup/references/project-structure-standalone.md +212 -0
  50. package/catalog/{setup/setup-project/SKILL.md → frontmcp-setup/references/setup-project.md} +62 -62
  51. package/catalog/{setup/setup-redis/SKILL.md → frontmcp-setup/references/setup-redis.md} +59 -86
  52. package/catalog/{setup/setup-sqlite/SKILL.md → frontmcp-setup/references/setup-sqlite.md} +64 -76
  53. package/catalog/frontmcp-testing/SKILL.md +127 -0
  54. package/catalog/{testing/setup-testing/SKILL.md → frontmcp-testing/references/setup-testing.md} +78 -67
  55. package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-tool-unit.md +1 -0
  56. package/catalog/skills-manifest.json +39 -378
  57. package/package.json +2 -2
  58. package/src/loader.js +0 -1
  59. package/src/loader.js.map +1 -1
  60. package/src/manifest.d.ts +3 -3
  61. package/src/manifest.js +2 -3
  62. package/src/manifest.js.map +1 -1
  63. package/catalog/adapters/create-adapter/SKILL.md +0 -127
  64. package/catalog/adapters/official-adapters/SKILL.md +0 -136
  65. package/catalog/auth/configure-auth/SKILL.md +0 -250
  66. package/catalog/auth/configure-session/SKILL.md +0 -201
  67. package/catalog/config/configure-elicitation/SKILL.md +0 -136
  68. package/catalog/config/configure-http/SKILL.md +0 -167
  69. package/catalog/config/configure-throttle/SKILL.md +0 -189
  70. package/catalog/config/configure-transport/SKILL.md +0 -151
  71. package/catalog/deployment/build-for-browser/SKILL.md +0 -95
  72. package/catalog/deployment/build-for-cli/SKILL.md +0 -100
  73. package/catalog/deployment/deploy-to-cloudflare/SKILL.md +0 -192
  74. package/catalog/deployment/deploy-to-vercel/SKILL.md +0 -196
  75. package/catalog/deployment/deploy-to-vercel/references/vercel.json.example +0 -60
  76. package/catalog/setup/frontmcp-skills-usage/SKILL.md +0 -200
  77. package/catalog/setup/project-structure-nx/SKILL.md +0 -186
  78. package/catalog/setup/project-structure-standalone/SKILL.md +0 -153
  79. /package/catalog/{auth/configure-auth/references/auth-modes.md → frontmcp-config/references/configure-auth-modes.md} +0 -0
  80. /package/catalog/{config/configure-throttle/references/guard-config.md → frontmcp-config/references/configure-throttle-guard-config.md} +0 -0
  81. /package/catalog/{config/configure-transport/references/protocol-presets.md → frontmcp-config/references/configure-transport-protocol-presets.md} +0 -0
  82. /package/catalog/{development/create-tool/references/tool-annotations.md → frontmcp-development/references/create-tool-annotations.md} +0 -0
  83. /package/catalog/{development/create-tool/references/output-schema-types.md → frontmcp-development/references/create-tool-output-schema-types.md} +0 -0
  84. /package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-auth.md +0 -0
  85. /package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-browser-build.md +0 -0
  86. /package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-cli-binary.md +0 -0
  87. /package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-direct-client.md +0 -0
  88. /package/catalog/{testing/setup-testing → frontmcp-testing}/references/test-e2e-handler.md +0 -0
@@ -0,0 +1,165 @@
1
+ # Creating Custom Adapters
2
+
3
+ Build adapters that automatically generate MCP tools, resources, and prompts from external sources — databases, GraphQL schemas, proprietary APIs, or any definition format.
4
+
5
+ ## When to Use This Skill
6
+
7
+ ### Must Use
8
+
9
+ - Integrating a non-OpenAPI source (GraphQL, gRPC, database schema) that should generate MCP tools automatically
10
+ - Building a reusable adapter that converts external definitions into tools, resources, or prompts at startup
11
+ - Creating tools dynamically at runtime based on external state or configuration
12
+
13
+ ### Recommended
14
+
15
+ - Wrapping a proprietary internal API that has its own schema format
16
+ - Auto-generating tools from a database schema or config file on server start
17
+ - Building an adapter that polls an external source and refreshes tool definitions periodically
18
+
19
+ ### Skip When
20
+
21
+ - The external API has an OpenAPI/Swagger spec (see `official-adapters`)
22
+ - You need cross-cutting middleware behavior like logging or caching (see `create-plugin`)
23
+ - You are building a single static tool manually (see `create-tool`)
24
+
25
+ > **Decision:** Use this skill when you need to auto-generate MCP tools, resources, or prompts from a non-OpenAPI external source by extending `DynamicAdapter`.
26
+
27
+ ## Step 1: Extend DynamicAdapter
28
+
29
+ ```typescript
30
+ import { DynamicAdapter, type FrontMcpAdapterResponse } from '@frontmcp/sdk';
31
+
32
+ interface MyAdapterOptions {
33
+ endpoint: string;
34
+ apiKey: string;
35
+ }
36
+
37
+ class MyApiAdapter extends DynamicAdapter<MyAdapterOptions> {
38
+ declare __options_brand: MyAdapterOptions;
39
+
40
+ async fetch(): Promise<FrontMcpAdapterResponse> {
41
+ // Fetch definitions from external source
42
+ const res = await globalThis.fetch(this.options.endpoint, {
43
+ headers: { Authorization: `Bearer ${this.options.apiKey}` },
44
+ });
45
+ const schema = await res.json();
46
+
47
+ // Convert to MCP tool definitions
48
+ return {
49
+ tools: schema.operations.map((op: { name: string; description: string; params: Record<string, unknown> }) => ({
50
+ name: op.name,
51
+ description: op.description,
52
+ inputSchema: this.convertParams(op.params),
53
+ execute: async (input: Record<string, unknown>) => {
54
+ return this.callApi(op.name, input);
55
+ },
56
+ })),
57
+ resources: [],
58
+ prompts: [],
59
+ };
60
+ }
61
+
62
+ private convertParams(params: Record<string, unknown>) {
63
+ // Convert external param definitions to Zod schemas
64
+ // ...
65
+ }
66
+
67
+ private async callApi(operation: string, input: Record<string, unknown>) {
68
+ // Call the external API
69
+ // ...
70
+ }
71
+ }
72
+ ```
73
+
74
+ ## Step 2: Register
75
+
76
+ ```typescript
77
+ @App({
78
+ name: 'MyApp',
79
+ adapters: [
80
+ MyApiAdapter.init({
81
+ name: 'my-api',
82
+ endpoint: 'https://api.example.com/schema',
83
+ apiKey: process.env.API_KEY!,
84
+ }),
85
+ ],
86
+ })
87
+ class MyApp {}
88
+ ```
89
+
90
+ ## FrontMcpAdapterResponse
91
+
92
+ The `fetch()` method returns tools, resources, and prompts to register:
93
+
94
+ ```typescript
95
+ interface FrontMcpAdapterResponse {
96
+ tools?: AdapterToolDefinition[];
97
+ resources?: AdapterResourceDefinition[];
98
+ prompts?: AdapterPromptDefinition[];
99
+ }
100
+ ```
101
+
102
+ ## Static init()
103
+
104
+ `DynamicAdapter` provides a static `init()` method inherited by all subclasses:
105
+
106
+ ```typescript
107
+ // Usage — no manual instantiation needed
108
+ const adapter = MyApiAdapter.init({
109
+ name: 'my-api', // Required: adapter name (used for tool namespacing)
110
+ endpoint: '...',
111
+ apiKey: '...',
112
+ });
113
+
114
+ // Register in @App
115
+ @App({ adapters: [adapter] })
116
+ ```
117
+
118
+ ## Nx Generator
119
+
120
+ ```bash
121
+ nx generate @frontmcp/nx:adapter my-adapter --project=my-app
122
+ ```
123
+
124
+ Creates a `DynamicAdapter` subclass in `src/adapters/my-adapter.adapter.ts`.
125
+
126
+ ## Common Patterns
127
+
128
+ | Pattern | Correct | Incorrect | Why |
129
+ | ----------------------- | ------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------- |
130
+ | Adapter registration | `MyAdapter.init({ name: 'my-api', ... })` in `adapters` array | `new MyAdapter({ ... })` directly | `init()` returns the proper provider entry for DI wiring |
131
+ | Options branding | `declare __options_brand: MyAdapterOptions;` in adapter class | Omitting the brand declaration | Brand ensures TypeScript infers the correct options type for `init()` |
132
+ | Fetch return type | Return `{ tools: [...], resources: [...], prompts: [...] }` | Returning raw API response without conversion | `fetch()` must return `FrontMcpAdapterResponse` with MCP-compatible definitions |
133
+ | Tool naming | Namespace tools: `name: 'my-api:operation-name'` | Flat names without namespace: `name: 'operation-name'` | Namespacing prevents collisions when multiple adapters are registered |
134
+ | Error handling in fetch | Throw descriptive errors with endpoint info | Silently returning empty arrays on failure | Adapter errors should surface at startup so misconfigurations are caught early |
135
+
136
+ ## Verification Checklist
137
+
138
+ ### Configuration
139
+
140
+ - [ ] Adapter class extends `DynamicAdapter<TOptions>`
141
+ - [ ] `__options_brand` is declared with the correct options type
142
+ - [ ] `fetch()` method is implemented and returns `FrontMcpAdapterResponse`
143
+ - [ ] Adapter is registered via `.init()` in the `adapters` array of `@App`
144
+
145
+ ### Runtime
146
+
147
+ - [ ] Generated tools appear in `tools/list` MCP response
148
+ - [ ] Tool names are namespaced with the adapter name (e.g., `my-api:operationId`)
149
+ - [ ] Generated tools accept valid input and return expected output
150
+ - [ ] Adapter fetch errors produce clear startup error messages
151
+
152
+ ## Troubleshooting
153
+
154
+ | Problem | Cause | Solution |
155
+ | ------------------------------------------ | ----------------------------------------------------------- | -------------------------------------------------------------------------------- |
156
+ | No tools appear after adapter registration | `fetch()` returns empty `tools` array | Verify external source is reachable and response is parsed correctly |
157
+ | TypeScript error on `.init()` options | Missing `__options_brand` declaration | Add `declare __options_brand: MyAdapterOptions;` to the adapter class |
158
+ | Tool input validation fails | `inputSchema` conversion does not produce valid Zod schemas | Verify `convertParams` produces `z.object()` shapes matching the external schema |
159
+ | Duplicate tool name error | Multiple adapters produce tools with the same name | Use unique `name` parameter in `init()` to namespace tools |
160
+ | Adapter not found at runtime | Registered in wrong `@App` or not in `adapters` array | Ensure `.init()` result is in the `adapters` array of the correct `@App` |
161
+
162
+ ## Reference
163
+
164
+ - [Adapter Documentation](https://docs.agentfront.dev/frontmcp/adapters/overview)
165
+ - Related skills: `official-adapters`, `create-plugin`, `create-tool`
@@ -1,13 +1,13 @@
1
1
  # Agent LLM Configuration Reference
2
2
 
3
- ## Supported Adapters
3
+ ## Supported Providers
4
4
 
5
5
  ### Anthropic
6
6
 
7
7
  ```typescript
8
8
  llm: {
9
- adapter: 'anthropic',
10
- model: 'claude-sonnet-4-20250514',
9
+ provider: 'anthropic', // Any supported provider — 'anthropic', 'openai', etc.
10
+ model: 'claude-sonnet-4-20250514', // Any supported model for the chosen provider
11
11
  apiKey: { env: 'ANTHROPIC_API_KEY' },
12
12
  maxTokens: 4096,
13
13
  }
@@ -17,8 +17,8 @@ llm: {
17
17
 
18
18
  ```typescript
19
19
  llm: {
20
- adapter: 'openai',
21
- model: 'gpt-4o',
20
+ provider: 'openai',
21
+ model: 'gpt-4o', // Any supported model for the chosen provider
22
22
  apiKey: { env: 'OPENAI_API_KEY' },
23
23
  maxTokens: 4096,
24
24
  }
@@ -1,35 +1,30 @@
1
- ---
2
- name: create-agent
3
- description: Create autonomous AI agents with inner tools, LLM providers, and multi-agent swarms. Use when building agents, configuring LLM adapters, adding inner tools, or setting up agent handoff.
4
- tags: [agent, ai, llm, tools, autonomous]
5
- parameters:
6
- - name: llm-provider
7
- description: LLM provider to use
8
- type: string
9
- default: anthropic
10
- - name: name
11
- description: Agent name
12
- type: string
13
- required: true
14
- examples:
15
- - scenario: Create a code review agent with GitHub tools
16
- expected-outcome: Agent autonomously reviews PRs using inner tools
17
- - scenario: Create a multi-agent swarm for complex workflows
18
- expected-outcome: Agents hand off tasks to each other
19
- priority: 8
20
- visibility: both
21
- license: Apache-2.0
22
- metadata:
23
- docs: https://docs.agentfront.dev/frontmcp/servers/agents
24
- ---
25
-
26
1
  # Creating an Autonomous Agent
27
2
 
28
3
  Agents are autonomous AI entities that use an LLM to reason, plan, and invoke inner tools to accomplish goals. In FrontMCP, agents are TypeScript classes that extend `AgentContext`, decorated with `@Agent`, and registered on a `@FrontMcp` server or inside an `@App`.
29
4
 
30
- ## When to Use @Agent vs @Tool
5
+ ## When to Use This Skill
6
+
7
+ ### Must Use
8
+
9
+ - Building an autonomous AI entity that uses LLM reasoning to decide which tools to call
10
+ - Orchestrating multi-step workflows where the agent plans, acts, and iterates toward a goal
11
+ - Creating multi-agent swarms with handoff between specialized agents
12
+
13
+ ### Recommended
14
+
15
+ - Performing complex tasks that require chaining multiple inner tools with LLM-driven decisions
16
+ - Implementing structured multi-pass review (security pass, quality pass, synthesis)
17
+ - Composing nested sub-agents with different LLM configs for specialized subtasks
31
18
 
32
- Use `@Agent` when the task requires autonomous reasoning, multi-step planning, or LLM-driven decision making. An agent receives a goal, decides which tools to call, interprets results, and iterates until the goal is met. Use `@Tool` when you need a direct, deterministic function that executes a single action without LLM involvement.
19
+ ### Skip When
20
+
21
+ - You need a direct, deterministic function that executes a single action (see `create-tool`)
22
+ - You are building a reusable conversation template without autonomous execution (see `create-prompt`)
23
+ - You only need to expose readable data at a URI (see `create-resource`)
24
+
25
+ > **Decision:** Use this skill when the task requires autonomous LLM-driven reasoning, tool invocation, and iterative planning -- not a single deterministic action.
26
+
27
+ ### @Agent vs @Tool Quick Comparison
33
28
 
34
29
  | Aspect | @Agent | @Tool |
35
30
  | --------------- | ------------------------------- | ---------------------------- |
@@ -50,8 +45,8 @@ import { z } from 'zod';
50
45
  name: 'code_reviewer',
51
46
  description: 'Reviews code changes and provides feedback',
52
47
  llm: {
53
- adapter: 'anthropic',
54
- model: 'claude-sonnet-4-20250514',
48
+ provider: 'anthropic', // Any supported provider — 'anthropic', 'openai', etc.
49
+ model: 'claude-sonnet-4-20250514', // Any supported model for the chosen provider
55
50
  apiKey: { env: 'ANTHROPIC_API_KEY' },
56
51
  },
57
52
  inputSchema: {
@@ -110,7 +105,7 @@ The `llm` field is required and configures which LLM provider and model the agen
110
105
  name: 'my_agent',
111
106
  description: 'An agent with LLM config',
112
107
  llm: {
113
- adapter: 'anthropic', // 'anthropic' or 'openai'
108
+ provider: 'anthropic', // 'anthropic' or 'openai'
114
109
  model: 'claude-sonnet-4-20250514',
115
110
  apiKey: { env: 'ANTHROPIC_API_KEY' }, // read from env var
116
111
  },
@@ -122,7 +117,7 @@ The `apiKey` field accepts either an object `{ env: 'ENV_VAR_NAME' }` to read fr
122
117
  ```typescript
123
118
  // OpenAI example
124
119
  llm: {
125
- adapter: 'openai',
120
+ provider: 'openai',
126
121
  model: 'gpt-4o',
127
122
  apiKey: { env: 'OPENAI_API_KEY' },
128
123
  },
@@ -139,7 +134,7 @@ Override `execute()` when you need custom orchestration logic:
139
134
  name: 'structured_reviewer',
140
135
  description: 'Reviews code with a structured multi-pass approach',
141
136
  llm: {
142
- adapter: 'anthropic',
137
+ provider: 'anthropic',
143
138
  model: 'claude-sonnet-4-20250514',
144
139
  apiKey: { env: 'ANTHROPIC_API_KEY' },
145
140
  },
@@ -193,7 +188,7 @@ Use `completion()` for a single LLM call that returns the full response, and `st
193
188
  name: 'summarizer',
194
189
  description: 'Summarizes text using LLM',
195
190
  llm: {
196
- adapter: 'anthropic',
191
+ provider: 'anthropic',
197
192
  model: 'claude-sonnet-4-20250514',
198
193
  apiKey: { env: 'ANTHROPIC_API_KEY' },
199
194
  },
@@ -287,7 +282,7 @@ class PostReviewCommentTool extends ToolContext {
287
282
  name: 'pr_reviewer',
288
283
  description: 'Autonomously reviews GitHub pull requests',
289
284
  llm: {
290
- adapter: 'anthropic',
285
+ provider: 'anthropic',
291
286
  model: 'claude-sonnet-4-20250514',
292
287
  apiKey: { env: 'ANTHROPIC_API_KEY' },
293
288
  },
@@ -315,7 +310,7 @@ Use `exports: { tools: [] }` to expose specific tools that the agent makes avail
315
310
  name: 'data_pipeline',
316
311
  description: 'Data processing pipeline agent',
317
312
  llm: {
318
- adapter: 'openai',
313
+ provider: 'openai',
319
314
  model: 'gpt-4o',
320
315
  apiKey: { env: 'OPENAI_API_KEY' },
321
316
  },
@@ -333,7 +328,7 @@ Use the `agents` array to compose agents from smaller, specialized sub-agents. E
333
328
  @Agent({
334
329
  name: 'security_auditor',
335
330
  description: 'Audits code for security vulnerabilities',
336
- llm: { adapter: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
331
+ llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
337
332
  systemInstructions: 'Focus on OWASP Top 10 vulnerabilities.',
338
333
  tools: [StaticAnalysisTool],
339
334
  })
@@ -342,7 +337,7 @@ class SecurityAuditorAgent extends AgentContext {}
342
337
  @Agent({
343
338
  name: 'performance_auditor',
344
339
  description: 'Audits code for performance issues',
345
- llm: { adapter: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
340
+ llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
346
341
  systemInstructions: 'Focus on time complexity, memory leaks, and N+1 queries.',
347
342
  tools: [ProfilerTool],
348
343
  })
@@ -351,7 +346,7 @@ class PerformanceAuditorAgent extends AgentContext {}
351
346
  @Agent({
352
347
  name: 'code_auditor',
353
348
  description: 'Comprehensive code auditor that delegates to specialized sub-agents',
354
- llm: { adapter: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
349
+ llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
355
350
  inputSchema: {
356
351
  repository: z.string().describe('Repository URL'),
357
352
  branch: z.string().default('main').describe('Branch to audit'),
@@ -372,7 +367,7 @@ Swarm mode enables multi-agent handoff, where agents can transfer control to eac
372
367
  @Agent({
373
368
  name: 'triage_agent',
374
369
  description: 'Triages incoming requests and hands off to specialists',
375
- llm: { adapter: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
370
+ llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
376
371
  inputSchema: {
377
372
  request: z.string().describe('The incoming user request'),
378
373
  },
@@ -391,7 +386,7 @@ class TriageAgent extends AgentContext {}
391
386
  @Agent({
392
387
  name: 'billing_agent',
393
388
  description: 'Handles billing and payment inquiries',
394
- llm: { adapter: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
389
+ llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
395
390
  tools: [LookupInvoiceTool, ProcessRefundTool],
396
391
  swarm: {
397
392
  role: 'specialist',
@@ -413,7 +408,7 @@ const QuickSummarizer = agent({
413
408
  name: 'quick_summarizer',
414
409
  description: 'Summarizes text quickly',
415
410
  llm: {
416
- adapter: 'anthropic',
411
+ provider: 'anthropic',
417
412
  model: 'claude-sonnet-4-20250514',
418
413
  apiKey: { env: 'ANTHROPIC_API_KEY' },
419
414
  },
@@ -494,7 +489,7 @@ Protect agents with throttling controls:
494
489
  name: 'expensive_agent',
495
490
  description: 'An agent that performs expensive LLM operations',
496
491
  llm: {
497
- adapter: 'anthropic',
492
+ provider: 'anthropic',
498
493
  model: 'claude-sonnet-4-20250514',
499
494
  apiKey: { env: 'ANTHROPIC_API_KEY' },
500
495
  },
@@ -523,7 +518,7 @@ Agents can include their own providers and plugins for self-contained dependency
523
518
  name: 'database_agent',
524
519
  description: 'Agent that interacts with databases',
525
520
  llm: {
526
- adapter: 'anthropic',
521
+ provider: 'anthropic',
527
522
  model: 'claude-sonnet-4-20250514',
528
523
  apiKey: { env: 'ANTHROPIC_API_KEY' },
529
524
  },
@@ -548,7 +543,7 @@ Agents can include resources and prompts that are available within the agent's s
548
543
  name: 'docs_agent',
549
544
  description: 'Agent that manages documentation',
550
545
  llm: {
551
- adapter: 'anthropic',
546
+ provider: 'anthropic',
552
547
  model: 'claude-sonnet-4-20250514',
553
548
  apiKey: { env: 'ANTHROPIC_API_KEY' },
554
549
  },
@@ -561,3 +556,46 @@ Agents can include resources and prompts that are available within the agent's s
561
556
  })
562
557
  class DocsAgent extends AgentContext {}
563
558
  ```
559
+
560
+ ## Common Patterns
561
+
562
+ | Pattern | Correct | Incorrect | Why |
563
+ | ----------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------- |
564
+ | LLM config | `llm: { provider: 'anthropic', model: '...', apiKey: { env: 'KEY' } }` | `llm: { provider: 'anthropic', apiKey: 'sk-hardcoded' }` | Environment variable references prevent leaking secrets in code |
565
+ | Inner tools vs exported | `tools: [...]` for agent-private; `exports: { tools: [...] }` for MCP-visible | Putting all tools in `tools` and expecting clients to see them | Inner tools are private to the agent; only exported tools appear in MCP listing |
566
+ | Custom execute | Override `execute()` for multi-pass orchestration | Putting all logic in system instructions | Custom `execute()` gives structured control over completion calls and stages |
567
+ | Sub-agents | Use `agents: [SubAgent]` for composition | Calling another agent's `execute()` directly | The `agents` array enables proper lifecycle, scope isolation, and handoff |
568
+ | Swarm handoff | Use `swarm.handoff` with `agent` name and `condition` | Manually routing between agents in `execute()` | Swarm config enables declarative, LLM-driven handoff between agents |
569
+
570
+ ## Verification Checklist
571
+
572
+ ### Configuration
573
+
574
+ - [ ] Agent class extends `AgentContext` and has `@Agent` decorator with `name`, `description`, and `llm`
575
+ - [ ] `inputSchema` is defined with Zod raw shape for input validation
576
+ - [ ] Inner tools in `tools` array are valid `@Tool` classes
577
+ - [ ] Agent is registered in `agents` array of `@App` or `@FrontMcp`
578
+ - [ ] API key uses `{ env: 'VAR_NAME' }` pattern, not hardcoded strings
579
+
580
+ ### Runtime
581
+
582
+ - [ ] Agent appears in MCP tool listing (agents surface as callable tools)
583
+ - [ ] LLM adapter connects successfully to the configured provider
584
+ - [ ] Inner tools are invoked correctly during the agent loop
585
+ - [ ] `this.completion()` and `this.streamCompletion()` return valid responses
586
+ - [ ] Swarm handoff transfers control to the correct specialist agent
587
+
588
+ ## Troubleshooting
589
+
590
+ | Problem | Cause | Solution |
591
+ | ----------------------------------- | ----------------------------------------------------- | --------------------------------------------------------------------------------- |
592
+ | Agent not appearing in tool listing | Not registered in `agents` array | Add agent class to `@App` or `@FrontMcp` `agents` array |
593
+ | LLM authentication error | API key not set or incorrect env variable | Verify the environment variable name in `apiKey: { env: '...' }` is set |
594
+ | Inner tools not being called | Tools not listed in `tools` array of `@Agent` | Add tool classes to the `tools` field in the `@Agent` decorator |
595
+ | Agent times out | No timeout or rate limit configured | Add `timeout: { executeMs: 120_000 }` and `rateLimit` to `@Agent` options |
596
+ | Swarm handoff fails | Target agent name does not match any registered agent | Ensure `handoff.agent` matches the `name` of a registered agent in the same scope |
597
+
598
+ ## Reference
599
+
600
+ - [Agents Documentation](https://docs.agentfront.dev/frontmcp/servers/agents)
601
+ - Related skills: `create-tool`, `create-provider`, `create-prompt`, `create-resource`
@@ -1,29 +1,28 @@
1
- ---
2
- name: create-job
3
- description: Create long-running jobs with retry policies, progress tracking, and permission controls. Use when building background tasks, data processing pipelines, or scheduled operations.
4
- tags: [job, background, retry, progress, long-running]
5
- priority: 6
6
- visibility: both
7
- license: Apache-2.0
8
- metadata:
9
- docs: https://docs.agentfront.dev/frontmcp/servers/jobs
10
- ---
11
-
12
1
  # Creating Jobs
13
2
 
14
3
  Jobs are long-running background tasks with built-in retry policies, progress tracking, and permission controls. Unlike tools (which execute synchronously within a request), jobs run asynchronously and persist their state across retries and restarts.
15
4
 
16
- ## When to Use @Job
5
+ ## When to Use This Skill
6
+
7
+ ### Must Use
8
+
9
+ - Running work that takes longer than a request cycle (ETL pipelines, large imports)
10
+ - Tasks that need automatic retry with exponential backoff on failure
11
+ - Background operations that must track and report progress over time
12
+
13
+ ### Recommended
17
14
 
18
- Use `@Job` when you need to run work that may take longer than a request cycle, needs retry guarantees, or should track progress over time. Examples include:
15
+ - Scheduled maintenance tasks or periodic data synchronization
16
+ - Operations requiring permission controls (role-based, scope-based access)
17
+ - Work that must persist state across retries and server restarts
19
18
 
20
- - Data processing and ETL pipelines
21
- - File imports and exports
22
- - Report generation
23
- - Scheduled maintenance tasks
24
- - External API synchronization
19
+ ### Skip When
25
20
 
26
- If the work completes in under a few seconds and does not need retry or progress tracking, use a `@Tool` instead.
21
+ - The work completes in a few seconds and needs no retry or progress tracking (see `create-tool`)
22
+ - You need to expose read-only data at a URI (see `create-resource`)
23
+ - The task requires autonomous LLM reasoning rather than a deterministic pipeline (see `create-agent`)
24
+
25
+ > **Decision:** Use this skill when you need a long-running background task with retry policies, progress tracking, or permission controls.
27
26
 
28
27
  ## Class-Based Pattern
29
28
 
@@ -564,3 +563,46 @@ class DataApp {}
564
563
  })
565
564
  class DataServer {}
566
565
  ```
566
+
567
+ ## Common Patterns
568
+
569
+ | Pattern | Correct | Incorrect | Why |
570
+ | ----------------- | ------------------------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------------ |
571
+ | Progress tracking | `this.progress(50, 100, 'Processing batch 5')` | Not reporting progress | Progress is persisted and queryable; essential for long-running visibility |
572
+ | Retry config | `retry: { maxAttempts: 3, backoffMs: 2000, backoffMultiplier: 2 }` | Implementing retry logic manually in `execute()` | Framework handles retry with exponential backoff and attempt tracking |
573
+ | Attempt awareness | Check `this.attempt` for retry-specific logic | Ignoring attempt number | `this.attempt` is 1-based; use it to log retry context or adjust behavior |
574
+ | Job logging | `this.log('message')` for persistent, queryable logs | Using `console.log()` | `this.log()` persists with job state; `console.log` is ephemeral |
575
+ | Permissions | Use `permissions: { roles: [...], scopes: [...] }` declaratively | Checking roles manually inside `execute()` | Declarative permissions are enforced before execution and are self-documenting |
576
+
577
+ ## Verification Checklist
578
+
579
+ ### Configuration
580
+
581
+ - [ ] Job class extends `JobContext` and implements `execute(input)`
582
+ - [ ] `@Job` decorator has `name`, `inputSchema`, and `outputSchema`
583
+ - [ ] `retry` policy is configured if the job may fail transiently
584
+ - [ ] `timeout` is set appropriately for the expected execution duration
585
+ - [ ] Job is registered in `jobs` array of `@App`
586
+
587
+ ### Runtime
588
+
589
+ - [ ] `jobs.enabled: true` is set in `@FrontMcp` configuration with a store
590
+ - [ ] Job executes and returns output matching `outputSchema`
591
+ - [ ] Progress is reported and queryable during execution
592
+ - [ ] Retry fires with correct backoff delays on transient failures
593
+ - [ ] Permissions block unauthorized users before execution starts
594
+
595
+ ## Troubleshooting
596
+
597
+ | Problem | Cause | Solution |
598
+ | -------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------- |
599
+ | Job not activated | `jobs.enabled` not set to `true` in `@FrontMcp` | Add `jobs: { enabled: true, store: { ... } }` to `@FrontMcp` config |
600
+ | Job fails without retrying | No `retry` policy configured | Add `retry: { maxAttempts: 3, backoffMs: 2000 }` to `@Job` options |
601
+ | Progress not visible | Not calling `this.progress()` during execution | Add `this.progress(pct, total, message)` calls at each stage |
602
+ | Job times out unexpectedly | Default 5-minute timeout too short | Set `timeout` in `@Job` to a higher value (e.g., `600000` for 10 minutes) |
603
+ | Permission denied error | User lacks required roles or scopes | Verify user has one of the `roles` and all `scopes` defined in `permissions` |
604
+
605
+ ## Reference
606
+
607
+ - [Jobs Documentation](https://docs.agentfront.dev/frontmcp/servers/jobs)
608
+ - Related skills: `create-tool`, `create-provider`, `create-agent`, `create-workflow`
@@ -1,18 +1,29 @@
1
- ---
2
- name: create-plugin-hooks
3
- description: Create plugins with flow lifecycle hooks using @Will, @Did, @Stage, and @Around decorators. Use when intercepting tool calls, adding logging, modifying request/response, or implementing cross-cutting middleware.
4
- tags: [plugin, hooks, will, did, stage, around, flow, middleware]
5
- priority: 7
6
- visibility: both
7
- license: Apache-2.0
8
- metadata:
9
- docs: https://docs.agentfront.dev/frontmcp/plugins/creating-plugins
10
- ---
11
-
12
1
  # Creating Plugins with Flow Lifecycle Hooks
13
2
 
14
3
  Plugins intercept and extend FrontMCP flows using lifecycle hook decorators. Every flow (tool calls, resource reads, prompt gets, etc.) is composed of **stages**, and hooks let you run logic before, after, around, or instead of any stage.
15
4
 
5
+ ## When to Use This Skill
6
+
7
+ ### Must Use
8
+
9
+ - Adding before/after logic to tool execution (logging, metrics, input enrichment)
10
+ - Implementing authorization checks that intercept flows before they reach the tool
11
+ - Wrapping stage execution with caching, retry, or timing logic via `@Around`
12
+
13
+ ### Recommended
14
+
15
+ - Replacing a built-in stage entirely with custom logic using `@Stage`
16
+ - Adding hooks directly on a `@Tool` class for tool-specific pre/post processing
17
+ - Filtering hook execution by tool name or context properties using `filter` predicates
18
+
19
+ ### Skip When
20
+
21
+ - You need providers, context extensions, or contributed tools (see `create-plugin`)
22
+ - You want to use an existing official plugin that already provides hooks (see `official-plugins`)
23
+ - You are building a simple tool with no cross-cutting concerns (see `create-tool`)
24
+
25
+ > **Decision:** Use this skill when you need to intercept or wrap flow stages with `@Will`, `@Did`, `@Around`, or `@Stage` decorators.
26
+
16
27
  ## Hook Decorator Types
17
28
 
18
29
  FrontMCP provides four hook decorators obtained via `FlowHooksOf(flowName)`:
@@ -280,3 +291,44 @@ parseInput → findTool → checkToolAuthorization → createToolCallContext
280
291
  ```
281
292
 
282
293
  Any stage can have `@Will`, `@Did`, `@Stage`, or `@Around` hooks.
294
+
295
+ ## Common Patterns
296
+
297
+ | Pattern | Correct | Incorrect | Why |
298
+ | --------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
299
+ | Hook decorator source | `const { Will, Did } = ToolHook;` or `FlowHooksOf('tools:call-tool')` | Importing `Will` directly from `@frontmcp/sdk` | Decorators must be bound to a specific flow via `FlowHooksOf` or pre-built exports |
300
+ | Hook priority | `@Will('execute', { priority: 100 })` for early hooks | Relying on array order without priority | Multiple hooks on the same stage need explicit priority; higher runs first |
301
+ | Around next() | `const result = await next(); return result;` | Forgetting to call `next()` in `@Around` | Omitting `next()` silently skips the wrapped stage and all downstream hooks |
302
+ | Filter predicate | `filter: (ctx) => ctx.toolName !== 'health_check'` | Checking tool name inside the hook body and returning early | Filters skip the hook cleanly; returning early may leave state inconsistent |
303
+ | Tool-level hooks | `@Will('execute')` on a `@Tool` class (scoped to that tool) | `@Will('execute')` on a `@Plugin` class expecting tool-scoped behavior | Plugin hooks fire for all tools; tool-level hooks fire only for that tool |
304
+
305
+ ## Verification Checklist
306
+
307
+ ### Configuration
308
+
309
+ - [ ] Hook decorator is obtained from `FlowHooksOf(flowName)` or a pre-built export (e.g., `ToolHook`)
310
+ - [ ] Stage name matches an actual stage in the targeted flow (e.g., `execute`, `validateInput`)
311
+ - [ ] Plugin with hooks is registered in `plugins` array of `@App` or `@FrontMcp`
312
+
313
+ ### Runtime
314
+
315
+ - [ ] `@Will` hook fires before the targeted stage
316
+ - [ ] `@Did` hook fires after the targeted stage completes
317
+ - [ ] `@Around` hook calls `next()` and the wrapped stage executes
318
+ - [ ] `@Stage` replacement returns a valid response for the flow
319
+ - [ ] Hook `filter` correctly skips invocations for excluded tools
320
+
321
+ ## Troubleshooting
322
+
323
+ | Problem | Cause | Solution |
324
+ | --------------------------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------- |
325
+ | Hook never fires | Plugin not registered in `plugins` array | Add plugin class to `@App` or `@FrontMcp` `plugins` array |
326
+ | Hook fires for wrong flow | Used wrong flow name in `FlowHooksOf` | Verify flow name matches (e.g., `'tools:call-tool'` not `'tool:call'`) |
327
+ | `@Around` skips the stage entirely | `next()` not called inside the around handler | Always `await next()` to execute the wrapped stage |
328
+ | Multiple hooks execute in wrong order | Priorities not set or conflicting | Set explicit `priority` values; higher numbers execute first |
329
+ | `@Stage` replacement causes downstream errors | Return value shape does not match stage contract | Ensure the return matches what the next stage expects (e.g., MCP response format) |
330
+
331
+ ## Reference
332
+
333
+ - [Plugin Hooks Documentation](https://docs.agentfront.dev/frontmcp/plugins/creating-plugins)
334
+ - Related skills: `create-plugin`, `official-plugins`, `create-tool`