@frontmcp/skills 1.1.2 → 1.2.0

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 (176) hide show
  1. package/catalog/TEMPLATE.md +16 -11
  2. package/catalog/frontmcp-authorities/SKILL.md +116 -11
  3. package/catalog/frontmcp-authorities/references/authority-profiles.md +39 -36
  4. package/catalog/frontmcp-authorities/references/claims-mapping.md +7 -0
  5. package/catalog/frontmcp-authorities/references/custom-evaluators.md +63 -14
  6. package/catalog/frontmcp-channels/SKILL.md +36 -0
  7. package/catalog/frontmcp-channels/examples/channel-sources/file-watcher.md +8 -2
  8. package/catalog/frontmcp-channels/examples/channel-sources/replay-buffer.md +111 -30
  9. package/catalog/frontmcp-channels/examples/channel-two-way/whatsapp-bridge.md +45 -3
  10. package/catalog/frontmcp-channels/references/channel-sources.md +11 -3
  11. package/catalog/frontmcp-channels/references/channel-two-way.md +60 -89
  12. package/catalog/frontmcp-config/SKILL.md +111 -8
  13. package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +4 -4
  14. package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +7 -1
  15. package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +1 -1
  16. package/catalog/frontmcp-config/examples/configure-deployment-targets/json-schema-ide-support.md +1 -1
  17. package/catalog/frontmcp-config/examples/configure-deployment-targets/multi-target-with-security.md +12 -9
  18. package/catalog/frontmcp-config/examples/configure-http/cors-restricted-origins.md +2 -2
  19. package/catalog/frontmcp-config/examples/configure-http/entry-path-reverse-proxy.md +1 -1
  20. package/catalog/frontmcp-config/examples/configure-security-headers/csp-report-only.md +1 -1
  21. package/catalog/frontmcp-config/examples/configure-security-headers/full-production-headers.md +1 -1
  22. package/catalog/frontmcp-config/examples/configure-skills-http/audit-log-basic.md +76 -0
  23. package/catalog/frontmcp-config/examples/configure-skills-http/audit-log-redis.md +116 -0
  24. package/catalog/frontmcp-config/examples/configure-skills-http/inject-instructions.md +59 -0
  25. package/catalog/frontmcp-config/references/configure-auth-modes.md +5 -5
  26. package/catalog/frontmcp-config/references/configure-deployment-targets.md +27 -24
  27. package/catalog/frontmcp-config/references/configure-http.md +14 -10
  28. package/catalog/frontmcp-config/references/configure-security-headers.md +2 -2
  29. package/catalog/frontmcp-config/references/configure-session.md +25 -25
  30. package/catalog/frontmcp-config/references/configure-skills-http.md +157 -0
  31. package/catalog/frontmcp-config/references/configure-throttle.md +1 -1
  32. package/catalog/frontmcp-config/references/configure-transport.md +2 -2
  33. package/catalog/frontmcp-deployment/SKILL.md +112 -9
  34. package/catalog/frontmcp-deployment/examples/build-for-browser/browser-build-with-custom-entry.md +23 -11
  35. package/catalog/frontmcp-deployment/examples/build-for-browser/browser-crypto-and-storage.md +44 -17
  36. package/catalog/frontmcp-deployment/examples/build-for-browser/react-provider-setup.md +53 -21
  37. package/catalog/frontmcp-deployment/examples/build-for-cli/cli-binary-build.md +1 -1
  38. package/catalog/frontmcp-deployment/examples/build-for-cli/unix-socket-daemon.md +1 -1
  39. package/catalog/frontmcp-deployment/examples/build-for-mcpb/mcpb-bundle-build.md +1 -1
  40. package/catalog/frontmcp-deployment/examples/build-for-sdk/connect-openai.md +1 -1
  41. package/catalog/frontmcp-deployment/examples/build-for-sdk/multi-platform-connect.md +1 -1
  42. package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/basic-worker-deploy.md +7 -8
  43. package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-custom-domain.md +8 -6
  44. package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-with-kv-storage.md +5 -4
  45. package/catalog/frontmcp-deployment/examples/deploy-to-lambda/cdk-deployment.md +8 -5
  46. package/catalog/frontmcp-deployment/examples/deploy-to-lambda/lambda-handler-with-cors.md +20 -18
  47. package/catalog/frontmcp-deployment/examples/deploy-to-lambda/sam-template-basic.md +8 -5
  48. package/catalog/frontmcp-deployment/examples/deploy-to-node/docker-compose-with-redis.md +3 -3
  49. package/catalog/frontmcp-deployment/examples/deploy-to-node/pm2-with-nginx.md +1 -1
  50. package/catalog/frontmcp-deployment/examples/deploy-to-node/resource-limits.md +2 -2
  51. package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/basic-multistage-dockerfile.md +2 -2
  52. package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/secure-nonroot-dockerfile.md +1 -1
  53. package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-mcp-endpoint-test.md +23 -21
  54. package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +25 -22
  55. package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-skills-cache.md +23 -30
  56. package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/minimal-vercel-config.md +52 -28
  57. package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/vercel-config-with-security-headers.md +32 -55
  58. package/catalog/frontmcp-deployment/examples/mcp-client-integration/http-remote.md +9 -0
  59. package/catalog/frontmcp-deployment/references/build-for-browser.md +40 -17
  60. package/catalog/frontmcp-deployment/references/build-for-cli.md +8 -8
  61. package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +43 -24
  62. package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +36 -25
  63. package/catalog/frontmcp-deployment/references/deploy-to-node-dockerfile.md +56 -14
  64. package/catalog/frontmcp-deployment/references/deploy-to-node.md +9 -6
  65. package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +57 -58
  66. package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +49 -59
  67. package/catalog/frontmcp-deployment/references/mcp-client-integration.md +2 -0
  68. package/catalog/frontmcp-development/SKILL.md +186 -11
  69. package/catalog/frontmcp-development/examples/create-agent/custom-multi-pass-agent.md +1 -1
  70. package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +30 -27
  71. package/catalog/frontmcp-development/examples/create-job/job-with-permissions.md +13 -8
  72. package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +33 -23
  73. package/catalog/frontmcp-development/examples/create-provider/config-and-api-providers.md +19 -10
  74. package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +3 -3
  75. package/catalog/frontmcp-development/examples/create-workflow/webhook-triggered-workflow.md +6 -4
  76. package/catalog/frontmcp-development/examples/decorators-guide/agent-skill-job-workflow.md +1 -1
  77. package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md +13 -8
  78. package/catalog/frontmcp-development/examples/decorators-guide/multi-app-with-plugins-and-providers.md +50 -23
  79. package/catalog/frontmcp-development/references/create-agent.md +47 -30
  80. package/catalog/frontmcp-development/references/create-job.md +69 -54
  81. package/catalog/frontmcp-development/references/create-plugin-hooks.md +45 -28
  82. package/catalog/frontmcp-development/references/create-plugin.md +10 -8
  83. package/catalog/frontmcp-development/references/create-prompt.md +3 -3
  84. package/catalog/frontmcp-development/references/create-provider.md +91 -51
  85. package/catalog/frontmcp-development/references/create-resource.md +3 -3
  86. package/catalog/frontmcp-development/references/create-skill.md +2 -2
  87. package/catalog/frontmcp-development/references/create-tool.md +7 -7
  88. package/catalog/frontmcp-development/references/create-workflow.md +8 -10
  89. package/catalog/frontmcp-development/references/decorators-guide.md +92 -56
  90. package/catalog/frontmcp-development/references/official-plugins.md +4 -3
  91. package/catalog/frontmcp-development/references/openapi-adapter.md +1 -1
  92. package/catalog/frontmcp-extensibility/SKILL.md +70 -10
  93. package/catalog/frontmcp-extensibility/examples/skill-audit-log/custom-store.md +197 -0
  94. package/catalog/frontmcp-extensibility/examples/skill-audit-log/verify-chain.md +68 -0
  95. package/catalog/frontmcp-extensibility/examples/vectoriadb/product-catalog-search.md +3 -5
  96. package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md +4 -11
  97. package/catalog/frontmcp-extensibility/examples/vectoriadb/tfidf-keyword-search.md +41 -30
  98. package/catalog/frontmcp-extensibility/references/skill-audit-log.md +233 -0
  99. package/catalog/frontmcp-extensibility/references/vectoriadb.md +73 -63
  100. package/catalog/frontmcp-guides/SKILL.md +84 -27
  101. package/catalog/frontmcp-guides/examples/example-knowledge-base/agent-and-plugin.md +72 -62
  102. package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md +32 -43
  103. package/catalog/frontmcp-guides/examples/example-task-manager/auth-and-crud-tools.md +24 -17
  104. package/catalog/frontmcp-guides/examples/example-task-manager/authenticated-e2e-tests.md +23 -21
  105. package/catalog/frontmcp-guides/examples/example-task-manager/redis-provider-with-di.md +47 -39
  106. package/catalog/frontmcp-guides/examples/example-weather-api/server-and-app-setup.md +16 -6
  107. package/catalog/frontmcp-guides/examples/example-weather-api/unit-and-e2e-tests.md +9 -8
  108. package/catalog/frontmcp-guides/references/example-knowledge-base.md +192 -265
  109. package/catalog/frontmcp-guides/references/example-task-manager.md +60 -54
  110. package/catalog/frontmcp-guides/references/example-weather-api.md +22 -24
  111. package/catalog/frontmcp-observability/SKILL.md +66 -2
  112. package/catalog/frontmcp-observability/examples/telemetry-api/skill-counters.md +100 -0
  113. package/catalog/frontmcp-observability/examples/tracing-setup/production-tracing.md +7 -2
  114. package/catalog/frontmcp-observability/examples/vendor-integrations/coralogix-setup.md +6 -2
  115. package/catalog/frontmcp-observability/references/telemetry-api.md +72 -8
  116. package/catalog/frontmcp-observability/references/testing-observability.md +33 -49
  117. package/catalog/frontmcp-observability/references/tracing-setup.md +12 -5
  118. package/catalog/frontmcp-observability/references/vendor-integrations.md +46 -1
  119. package/catalog/frontmcp-production-readiness/SKILL.md +134 -3
  120. package/catalog/frontmcp-production-readiness/examples/common-checklist/caching-and-performance.md +57 -36
  121. package/catalog/frontmcp-production-readiness/examples/common-checklist/observability-setup.md +1 -1
  122. package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +102 -6
  123. package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/daemon-socket-config.md +2 -1
  124. package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/graceful-shutdown-cleanup.md +66 -58
  125. package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/security-and-permissions.md +5 -3
  126. package/catalog/frontmcp-production-readiness/examples/production-cloudflare/durable-objects-state.md +2 -1
  127. package/catalog/frontmcp-production-readiness/examples/production-cloudflare/wrangler-config.md +55 -76
  128. package/catalog/frontmcp-production-readiness/examples/production-lambda/cold-start-connection-reuse.md +43 -40
  129. package/catalog/frontmcp-production-readiness/examples/production-lambda/sam-template.md +63 -94
  130. package/catalog/frontmcp-production-readiness/examples/production-lambda/scaling-and-monitoring.md +28 -18
  131. package/catalog/frontmcp-production-readiness/examples/production-node-sdk/multi-instance-cleanup.md +29 -14
  132. package/catalog/frontmcp-production-readiness/examples/production-node-server/graceful-shutdown.md +58 -42
  133. package/catalog/frontmcp-production-readiness/examples/production-node-server/redis-session-scaling.md +5 -2
  134. package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md +41 -24
  135. package/catalog/frontmcp-production-readiness/examples/production-vercel/vercel-edge-config.md +56 -65
  136. package/catalog/frontmcp-production-readiness/references/common-checklist.md +17 -5
  137. package/catalog/frontmcp-production-readiness/references/production-cli-daemon.md +5 -5
  138. package/catalog/frontmcp-production-readiness/references/production-cloudflare.md +5 -5
  139. package/catalog/frontmcp-production-readiness/references/production-lambda.md +5 -5
  140. package/catalog/frontmcp-production-readiness/references/production-node-sdk.md +5 -5
  141. package/catalog/frontmcp-production-readiness/references/production-node-server.md +1 -1
  142. package/catalog/frontmcp-production-readiness/references/production-vercel.md +5 -5
  143. package/catalog/frontmcp-setup/SKILL.md +88 -0
  144. package/catalog/frontmcp-setup/examples/project-structure-nx/nx-workspace-with-apps.md +10 -4
  145. package/catalog/frontmcp-setup/examples/project-structure-standalone/dev-workflow-commands.md +21 -8
  146. package/catalog/frontmcp-setup/examples/readme-guide/node-server-readme.md +3 -3
  147. package/catalog/frontmcp-setup/references/multi-app-composition.md +4 -3
  148. package/catalog/frontmcp-setup/references/project-structure-nx.md +15 -6
  149. package/catalog/frontmcp-setup/references/project-structure-standalone.md +18 -15
  150. package/catalog/frontmcp-setup/references/readme-guide.md +1 -1
  151. package/catalog/frontmcp-setup/references/setup-project.md +19 -5
  152. package/catalog/frontmcp-setup/references/setup-redis.md +27 -39
  153. package/catalog/frontmcp-setup/references/setup-sqlite.md +25 -18
  154. package/catalog/frontmcp-testing/SKILL.md +102 -15
  155. package/catalog/frontmcp-testing/examples/setup-testing/unit-test-tool-resource-prompt.md +3 -3
  156. package/catalog/frontmcp-testing/examples/test-auth/oauth-flow-test.md +50 -39
  157. package/catalog/frontmcp-testing/examples/test-auth/role-based-access-test.md +52 -29
  158. package/catalog/frontmcp-testing/examples/test-auth/token-factory-test.md +37 -20
  159. package/catalog/frontmcp-testing/examples/test-direct-client/basic-create-test.md +25 -15
  160. package/catalog/frontmcp-testing/examples/test-direct-client/openai-claude-format-test.md +27 -21
  161. package/catalog/frontmcp-testing/examples/test-e2e-handler/basic-e2e-test.md +29 -20
  162. package/catalog/frontmcp-testing/examples/test-e2e-handler/manual-client-with-transport.md +5 -3
  163. package/catalog/frontmcp-testing/examples/test-e2e-handler/tool-call-and-error-e2e.md +35 -26
  164. package/catalog/frontmcp-testing/examples/test-tool-unit/basic-tool-test.md +8 -3
  165. package/catalog/frontmcp-testing/examples/test-tool-unit/schema-validation-test.md +4 -1
  166. package/catalog/frontmcp-testing/examples/test-tool-unit/tool-error-handling-test.md +6 -3
  167. package/catalog/frontmcp-testing/references/setup-testing.md +35 -39
  168. package/catalog/frontmcp-testing/references/test-auth.md +86 -43
  169. package/catalog/frontmcp-testing/references/test-browser-build.md +1 -1
  170. package/catalog/frontmcp-testing/references/test-direct-client.md +29 -19
  171. package/catalog/frontmcp-testing/references/test-e2e-handler.md +31 -19
  172. package/catalog/frontmcp-testing/references/test-tool-unit.md +6 -2
  173. package/catalog/skills-manifest.json +428 -339
  174. package/package.json +1 -1
  175. package/src/manifest.d.ts +13 -0
  176. package/src/manifest.js.map +1 -1
@@ -2,18 +2,23 @@
2
2
  name: nested-agents-with-swarm
3
3
  reference: create-agent
4
4
  level: advanced
5
- description: 'Composing specialized sub-agents and configuring swarm-based handoff between agents.'
6
- tags: [development, agent, nested, agents, swarm]
5
+ description: Composing specialized agents into a swarm where an orchestrator can discover and call peers at runtime as `use-agent:<id>` tools. Routing is driven by the orchestrator's LLM, not a declarative handoff table.
6
+ tags:
7
+ - development
8
+ - agent
9
+ - nested
10
+ - agents
11
+ - swarm
7
12
  features:
8
- - "Configuring `swarm` with `role: 'coordinator'` for the triage agent and `role: 'specialist'` for domain agents"
9
- - 'Defining `handoff` rules with `agent` name and `condition` for declarative LLM-driven routing'
10
- - 'Specialist agents can hand back to the triage agent when a request falls outside their scope'
11
- - 'Each agent has its own `llm` config, `tools`, and `systemInstructions` for specialization'
13
+ - 'Setting `swarm: { canSeeOtherAgents: true, visibleAgents: [...] }` on the orchestrator so peers appear as `use-agent:*` tools'
14
+ - 'Setting `swarm: { isVisible: true }` (the default) on specialist peers so they can be called'
15
+ - Routing is driven by the orchestrator LLM choosing among `use-agent:<peer>` tools, not by a declarative handoff table
16
+ - Each agent has its own `llm` config, `tools`, and `systemInstructions` for specialization
12
17
  ---
13
18
 
14
- # Nested Sub-Agents and Swarm Handoff
19
+ # Multi-Agent Swarm Visibility
15
20
 
16
- Composing specialized sub-agents and configuring swarm-based handoff between agents.
21
+ Composing specialized agents into a swarm where an orchestrator can discover and call peers at runtime as `use-agent:<id>` tools. Routing is driven by the orchestrator's LLM, not a declarative handoff table.
17
22
 
18
23
  ## Code
19
24
 
@@ -33,14 +38,13 @@ class LookupInvoiceTool extends ToolContext {
33
38
  }
34
39
 
35
40
  @Agent({
41
+ id: 'billing_agent',
36
42
  name: 'billing_agent',
37
43
  description: 'Handles billing and payment inquiries',
38
44
  llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
39
45
  tools: [LookupInvoiceTool],
40
- swarm: {
41
- role: 'specialist',
42
- handoff: [{ agent: 'triage_agent', condition: 'Request is outside billing scope' }],
43
- },
46
+ // isVisible defaults to true; specialists do not need swarm config to be callable.
47
+ swarm: { isVisible: true },
44
48
  })
45
49
  class BillingAgent extends AgentContext {}
46
50
  ```
@@ -50,14 +54,12 @@ class BillingAgent extends AgentContext {}
50
54
  import { Agent, AgentContext } from '@frontmcp/sdk';
51
55
 
52
56
  @Agent({
57
+ id: 'technical_agent',
53
58
  name: 'technical_agent',
54
59
  description: 'Handles technical support issues',
55
60
  llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
56
61
  systemInstructions: 'You are a technical support specialist. Diagnose issues and provide solutions.',
57
- swarm: {
58
- role: 'specialist',
59
- handoff: [{ agent: 'triage_agent', condition: 'Request is outside technical scope' }],
60
- },
62
+ swarm: { isVisible: true },
61
63
  })
62
64
  class TechnicalAgent extends AgentContext {}
63
65
  ```
@@ -67,20 +69,21 @@ class TechnicalAgent extends AgentContext {}
67
69
  import { Agent, AgentContext, z } from '@frontmcp/sdk';
68
70
 
69
71
  @Agent({
72
+ id: 'triage_agent',
70
73
  name: 'triage_agent',
71
- description: 'Triages incoming requests and hands off to specialists',
74
+ description: 'Triages incoming requests and delegates to specialists',
72
75
  llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
73
76
  inputSchema: {
74
77
  request: z.string().describe('The incoming user request'),
75
78
  },
79
+ // Orchestrator: opts in to seeing peers and (optionally) restricts to a whitelist.
76
80
  swarm: {
77
- role: 'coordinator',
78
- handoff: [
79
- { agent: 'billing_agent', condition: 'Request is about billing or payments' },
80
- { agent: 'technical_agent', condition: 'Request is about technical issues' },
81
- ],
81
+ canSeeOtherAgents: true,
82
+ visibleAgents: ['billing_agent', 'technical_agent'],
83
+ maxCallDepth: 3,
82
84
  },
83
- systemInstructions: 'Analyze the request and hand off to the appropriate specialist agent.',
85
+ systemInstructions:
86
+ 'Analyze the request and delegate by calling either use-agent:billing_agent (for billing/payments) or use-agent:technical_agent (for technical issues).',
84
87
  })
85
88
  class TriageAgent extends AgentContext {}
86
89
  ```
@@ -98,12 +101,12 @@ class SupportApp {}
98
101
 
99
102
  ## What This Demonstrates
100
103
 
101
- - Configuring `swarm` with `role: 'coordinator'` for the triage agent and `role: 'specialist'` for domain agents
102
- - Defining `handoff` rules with `agent` name and `condition` for declarative LLM-driven routing
103
- - Specialist agents can hand back to the triage agent when a request falls outside their scope
104
+ - Setting `swarm: { canSeeOtherAgents: true, visibleAgents: [...] }` on the orchestrator so peers appear as `use-agent:*` tools
105
+ - Setting `swarm: { isVisible: true }` (the default) on specialist peers so they can be called
106
+ - Routing is driven by the orchestrator LLM choosing among `use-agent:<peer>` tools, not by a declarative handoff table
104
107
  - Each agent has its own `llm` config, `tools`, and `systemInstructions` for specialization
105
108
 
106
109
  ## Related
107
110
 
108
- - See `create-agent` for exported tools, function-style builder, providers, and rate limiting
111
+ - See `create-agent` for the full swarm field reference and inner-tool composition
109
112
  - See `create-agent-llm-config` for using different LLM providers per agent
@@ -5,7 +5,7 @@ level: advanced
5
5
  description: 'A data export job with declarative permission controls, plus a function-style job for simple tasks.'
6
6
  tags: [development, redis, job, permissions]
7
7
  features:
8
- - 'Declarative `permissions` with `actions`, `roles`, `scopes`, and a custom `predicate`'
8
+ - 'Declarative `permissions` as an array of `{ action, roles, scopes, custom }` rules'
9
9
  - 'Using `tags` and `labels` for categorization and filtering'
10
10
  - 'The `job()` function builder for simple jobs that need no class'
11
11
  - 'Full server registration with `jobs.enabled: true` and a Redis store'
@@ -34,12 +34,17 @@ import { Job, job, JobContext, z } from '@frontmcp/sdk';
34
34
  },
35
35
  tags: ['export', 'data'],
36
36
  labels: { team: 'data-engineering', priority: 'high' },
37
- permissions: {
38
- actions: ['create', 'read', 'execute', 'list'],
39
- roles: ['admin', 'data-engineer'],
40
- scopes: ['jobs:write', 'data:export'],
41
- predicate: (ctx) => ctx.user?.department === 'engineering',
42
- },
37
+ permissions: [
38
+ {
39
+ action: 'execute',
40
+ roles: ['admin', 'data-engineer'],
41
+ scopes: ['jobs:write', 'data:export'],
42
+ custom: (authInfo) => (authInfo as { department?: string }).department === 'engineering',
43
+ },
44
+ { action: 'create', roles: ['admin', 'data-engineer'] },
45
+ { action: 'read', roles: ['admin', 'data-engineer', 'auditor'] },
46
+ { action: 'list', roles: ['admin', 'data-engineer', 'auditor'] },
47
+ ],
43
48
  })
44
49
  class DataExportJob extends JobContext {
45
50
  async execute(input: { dataset: string; destination: string }) {
@@ -106,7 +111,7 @@ class DataServer {}
106
111
 
107
112
  ## What This Demonstrates
108
113
 
109
- - Declarative `permissions` with `actions`, `roles`, `scopes`, and a custom `predicate`
114
+ - Declarative `permissions` as an array of `{ action, roles, scopes, custom }` rules
110
115
  - Using `tags` and `labels` for categorization and filtering
111
116
  - The `job()` function builder for simple jobs that need no class
112
117
  - Full server registration with `jobs.enabled: true` and a Redis store
@@ -2,18 +2,18 @@
2
2
  name: basic-database-provider
3
3
  reference: create-provider
4
4
  level: basic
5
- description: 'A provider that manages a database connection pool with `onInit()` and `onDestroy()` lifecycle hooks.'
5
+ description: A provider that manages a database connection pool, bound through `AsyncProvider({ useFactory })` so the pool is opened before any tool runs.
6
6
  tags: [development, database, provider]
7
7
  features:
8
8
  - 'Defining a typed token with `Token<T>` using a `Symbol` for DI identification'
9
- - 'Using `@Provider` decorator with `onInit()` for async startup and `onDestroy()` for cleanup'
9
+ - 'Using `AsyncProvider({ provide, name, scope, useFactory })` so async setup completes before tool execution'
10
10
  - 'Consuming the provider in a tool via `this.get(DB_TOKEN)` with full type safety'
11
- - 'Registering the provider in the `providers` array so tools can resolve it'
11
+ - 'Registering the factory in the `providers` array so tools can resolve it'
12
12
  ---
13
13
 
14
- # Basic Database Provider with Lifecycle
14
+ # Basic Database Provider with Async Setup
15
15
 
16
- A provider that manages a database connection pool with `onInit()` and `onDestroy()` lifecycle hooks.
16
+ A provider that manages a database connection pool, bound through `AsyncProvider({ useFactory })` so the pool is opened before any tool runs.
17
17
 
18
18
  ## Code
19
19
 
@@ -31,20 +31,14 @@ export const DB_TOKEN: Token<DatabaseService> = Symbol('DatabaseService');
31
31
 
32
32
  ```typescript
33
33
  // src/apps/main/providers/database.provider.ts
34
- import { createPool, Pool } from 'your-db-driver';
34
+ import { createPool, type Pool } from 'your-db-driver';
35
35
 
36
- import { Provider } from '@frontmcp/sdk';
36
+ import { AsyncProvider, ProviderScope } from '@frontmcp/sdk';
37
37
 
38
- @Provider({ name: 'DatabaseProvider' })
39
- class DatabaseProvider implements DatabaseService {
40
- private pool!: Pool;
38
+ import { DB_TOKEN, type DatabaseService } from '../tokens';
41
39
 
42
- async onInit() {
43
- this.pool = await createPool({
44
- connectionString: process.env.DATABASE_URL,
45
- max: 20,
46
- });
47
- }
40
+ class DatabasePool implements DatabaseService {
41
+ constructor(private readonly pool: Pool) {}
48
42
 
49
43
  async query(sql: string, params?: unknown[]) {
50
44
  return this.pool.query(sql, params);
@@ -53,11 +47,24 @@ class DatabaseProvider implements DatabaseService {
53
47
  async close() {
54
48
  await this.pool.end();
55
49
  }
56
-
57
- async onDestroy() {
58
- await this.pool.end();
59
- }
60
50
  }
51
+
52
+ // `@Provider` does NOT support `onInit`/`onDestroy` lifecycle hooks. For async
53
+ // setup, register the dependency via `AsyncProvider({ useFactory })` — the
54
+ // framework awaits `useFactory` before any tool can resolve the token.
55
+ export const databaseProvider = AsyncProvider({
56
+ provide: DB_TOKEN,
57
+ name: 'DatabaseProvider',
58
+ scope: ProviderScope.GLOBAL,
59
+ inject: () => [] as const,
60
+ useFactory: async (): Promise<DatabaseService> => {
61
+ const pool = await createPool({
62
+ connectionString: process.env.DATABASE_URL,
63
+ max: 20,
64
+ });
65
+ return new DatabasePool(pool);
66
+ },
67
+ });
61
68
  ```
62
69
 
63
70
  ```typescript
@@ -93,9 +100,12 @@ class QueryUsersTool extends ToolContext {
93
100
  // src/apps/main/index.ts
94
101
  import { App } from '@frontmcp/sdk';
95
102
 
103
+ import { databaseProvider } from './providers/database.provider';
104
+ import QueryUsersTool from './tools/query-users.tool';
105
+
96
106
  @App({
97
107
  name: 'main',
98
- providers: [DatabaseProvider],
108
+ providers: [databaseProvider],
99
109
  tools: [QueryUsersTool],
100
110
  })
101
111
  class MainApp {}
@@ -104,9 +114,9 @@ class MainApp {}
104
114
  ## What This Demonstrates
105
115
 
106
116
  - Defining a typed token with `Token<T>` using a `Symbol` for DI identification
107
- - Using `@Provider` decorator with `onInit()` for async startup and `onDestroy()` for cleanup
117
+ - Using `AsyncProvider({ provide, name, scope, useFactory })` so async setup completes before tool execution
108
118
  - Consuming the provider in a tool via `this.get(DB_TOKEN)` with full type safety
109
- - Registering the provider in the `providers` array so tools can resolve it
119
+ - Registering the factory in the `providers` array so tools can resolve it
110
120
 
111
121
  ## Related
112
122
 
@@ -5,8 +5,8 @@ level: intermediate
5
5
  description: 'A configuration provider with readonly environment settings and an HTTP API client provider.'
6
6
  tags: [development, provider, config, api, providers]
7
7
  features:
8
- - 'A configuration provider using `readonly` properties from environment variables (no lifecycle needed)'
9
- - 'An API client provider using `onInit()` for async setup of credentials'
8
+ - 'A configuration provider using `readonly` properties from environment variables (sync construction)'
9
+ - 'An API client provider that reads credentials in the constructor (no `onInit` `@Provider` has no lifecycle hooks)'
10
10
  - 'Registering providers at `@FrontMcp` level for server-wide sharing across all apps'
11
11
  - 'Separating token definitions from provider implementations for clean dependency boundaries'
12
12
  ---
@@ -40,6 +40,7 @@ export const API_TOKEN: Token<ApiClient> = Symbol('ApiClient');
40
40
  ```typescript
41
41
  // src/apps/main/providers/config.provider.ts
42
42
  import { Provider } from '@frontmcp/sdk';
43
+
43
44
  import type { AppConfig } from '../tokens';
44
45
 
45
46
  @Provider({ name: 'ConfigProvider' })
@@ -53,16 +54,24 @@ class ConfigProvider implements AppConfig {
53
54
  ```typescript
54
55
  // src/apps/main/providers/api-client.provider.ts
55
56
  import { Provider } from '@frontmcp/sdk';
57
+
56
58
  import type { ApiClient } from '../tokens';
57
59
 
58
60
  @Provider({ name: 'ApiClientProvider' })
59
61
  class ApiClientProvider implements ApiClient {
60
- private baseUrl!: string;
61
- private apiKey!: string;
62
-
63
- async onInit() {
64
- this.baseUrl = process.env.API_URL!;
65
- this.apiKey = process.env.API_KEY!;
62
+ // `@Provider` has no `onInit` lifecycle hook — read env in the constructor.
63
+ // First instantiation throws synchronously on missing config (fail fast).
64
+ private readonly baseUrl: string;
65
+ private readonly apiKey: string;
66
+
67
+ constructor() {
68
+ const baseUrl = process.env.API_URL;
69
+ const apiKey = process.env.API_KEY;
70
+ if (!baseUrl || !apiKey) {
71
+ throw new Error('ApiClientProvider: API_URL and API_KEY must be set');
72
+ }
73
+ this.baseUrl = baseUrl;
74
+ this.apiKey = apiKey;
66
75
  }
67
76
 
68
77
  async get(path: string) {
@@ -97,8 +106,8 @@ class MyServer {}
97
106
 
98
107
  ## What This Demonstrates
99
108
 
100
- - A configuration provider using `readonly` properties from environment variables (no lifecycle needed)
101
- - An API client provider using `onInit()` for async setup of credentials
109
+ - A configuration provider using `readonly` properties from environment variables (sync construction)
110
+ - An API client provider that reads credentials in the constructor (no `onInit` `@Provider` has no lifecycle hooks)
102
111
  - Registering providers at `@FrontMcp` level for server-wide sharing across all apps
103
112
  - Separating token definitions from provider implementations for clean dependency boundaries
104
113
 
@@ -6,7 +6,7 @@ description: 'A batch processing tool that uses rate limiting, concurrency contr
6
6
  tags: [development, throttle, tool, rate, limiting, progress]
7
7
  features:
8
8
  - 'Configuring `rateLimit`, `concurrency`, and `timeout` for throttling protection'
9
- - 'Sending progress updates to the client with `this.respondProgress(value, total)`'
9
+ - 'Sending progress updates to the client with `this.progress(progress, total, message?)`'
10
10
  - 'Using `this.mark(stage)` for execution stage tracking and debugging'
11
11
  - 'Sending log-level notifications with `this.notify(message, level)`'
12
12
  - 'Setting tool `annotations` to communicate behavioral hints to clients'
@@ -52,7 +52,7 @@ class BatchProcessTool extends ToolContext {
52
52
  this.mark('processing');
53
53
  const results: string[] = [];
54
54
  for (let i = 0; i < input.items.length; i++) {
55
- await this.respondProgress(i + 1, input.items.length);
55
+ await this.progress(i + 1, input.items.length, `Processing item ${i + 1}`);
56
56
  const result = await this.processItem(input.items[i]);
57
57
  results.push(result);
58
58
  }
@@ -82,7 +82,7 @@ class MainApp {}
82
82
  ## What This Demonstrates
83
83
 
84
84
  - Configuring `rateLimit`, `concurrency`, and `timeout` for throttling protection
85
- - Sending progress updates to the client with `this.respondProgress(value, total)`
85
+ - Sending progress updates to the client with `this.progress(progress, total, message?)`
86
86
  - Using `this.mark(stage)` for execution stage tracking and debugging
87
87
  - Sending log-level notifications with `this.notify(message, level)`
88
88
  - Setting tool `annotations` to communicate behavioral hints to clients
@@ -33,10 +33,12 @@ import { Workflow } from '@frontmcp/sdk';
33
33
  },
34
34
  timeout: 900000, // 15 minutes
35
35
  maxConcurrency: 3,
36
- permissions: {
37
- actions: ['create', 'read', 'execute', 'list'],
38
- roles: ['admin', 'ci-bot'],
39
- },
36
+ permissions: [
37
+ { action: 'execute', roles: ['admin', 'ci-bot'] },
38
+ { action: 'create', roles: ['admin', 'ci-bot'] },
39
+ { action: 'read', roles: ['admin', 'ci-bot'] },
40
+ { action: 'list', roles: ['admin', 'ci-bot'] },
41
+ ],
40
42
  steps: [
41
43
  {
42
44
  id: 'build',
@@ -86,7 +86,7 @@ import { Workflow } from '@frontmcp/sdk';
86
86
  name: 'deploy_pipeline',
87
87
  description: 'Full deployment pipeline',
88
88
  trigger: 'webhook',
89
- webhookConfig: {
89
+ webhook: {
90
90
  path: '/hooks/deploy',
91
91
  secret: process.env.WEBHOOK_SECRET!,
92
92
  methods: ['POST'],
@@ -7,8 +7,8 @@ tags: [development, decorators, app, tools]
7
7
  features:
8
8
  - 'The `@FrontMcp` -> `@App` -> `@Tool`/`@Resource`/`@Prompt` nesting hierarchy'
9
9
  - 'Tool classes extend `ToolContext` and implement `execute()`'
10
- - 'Resource classes extend `ResourceContext` and implement `read()`'
11
- - 'Prompt classes extend `PromptContext` and implement `execute()`'
10
+ - 'Resource classes extend `ResourceContext` and implement `execute(uri, params)`'
11
+ - 'Prompt classes extend `PromptContext` and implement `execute(args: Record<string, string>)`'
12
12
  - 'Apps group related tools, resources, and prompts into logical modules'
13
13
  ---
14
14
 
@@ -49,9 +49,9 @@ import { Resource, ResourceContext } from '@frontmcp/sdk';
49
49
  mimeType: 'application/json',
50
50
  })
51
51
  class AppConfigResource extends ResourceContext {
52
- async read() {
52
+ async execute(uri: string, _params: Record<string, string>) {
53
53
  const config = await this.get(ConfigService).getAll();
54
- return { contents: [{ uri: this.uri, text: JSON.stringify(config) }] };
54
+ return { contents: [{ uri, text: JSON.stringify(config) }] };
55
55
  }
56
56
  }
57
57
  ```
@@ -69,14 +69,19 @@ import { Prompt, PromptContext } from '@frontmcp/sdk';
69
69
  ],
70
70
  })
71
71
  class CodeReviewPrompt extends PromptContext {
72
- async execute(args: { code: string; language?: string }) {
72
+ // Prompt arguments arrive as Record<string, string> coerce to other types as needed.
73
+ // Required-arg validation is performed before `execute()` is called, so `args.code`
74
+ // is guaranteed present here. The `language` fallback handles the optional arg.
75
+ async execute(args: Record<string, string>) {
76
+ const code = args.code;
77
+ const language = args.language ?? 'unknown';
73
78
  return {
74
79
  messages: [
75
80
  {
76
81
  role: 'user' as const,
77
82
  content: {
78
83
  type: 'text' as const,
79
- text: `Review this ${args.language ?? ''} code:\n\n${args.code}`,
84
+ text: `Review this ${language} code:\n\n${code}`,
80
85
  },
81
86
  },
82
87
  ],
@@ -114,8 +119,8 @@ class MyServer {}
114
119
 
115
120
  - The `@FrontMcp` -> `@App` -> `@Tool`/`@Resource`/`@Prompt` nesting hierarchy
116
121
  - Tool classes extend `ToolContext` and implement `execute()`
117
- - Resource classes extend `ResourceContext` and implement `read()`
118
- - Prompt classes extend `PromptContext` and implement `execute()`
122
+ - Resource classes extend `ResourceContext` and implement `execute(uri, params)`
123
+ - Prompt classes extend `PromptContext` and implement `execute(args: Record<string, string>)`
119
124
  - Apps group related tools, resources, and prompts into logical modules
120
125
 
121
126
  ## Related
@@ -2,15 +2,21 @@
2
2
  name: multi-app-with-plugins-and-providers
3
3
  reference: decorators-guide
4
4
  level: intermediate
5
- description: 'Demonstrates a server with multiple `@App` modules, a `@Provider` for dependency injection, and a `@Plugin` for cross-cutting concerns.'
6
- tags: [development, database, multi-app, decorators, multi, app]
5
+ description: Demonstrates a server with multiple `@App` modules, a `@Provider` for dependency injection, and a `@Plugin` for cross-cutting concerns.
6
+ tags:
7
+ - development
8
+ - database
9
+ - multi-app
10
+ - decorators
11
+ - multi
12
+ - app
7
13
  features:
8
- - 'Organizing a server into multiple `@App` modules (`analytics` and `admin`)'
9
- - 'Using `@Provider` with `useFactory` to register a database client for dependency injection'
10
- - 'Accessing injected dependencies via `this.get(DatabaseToken)` in tools and resources'
11
- - 'Using `@ResourceTemplate` with URI parameters (`{dashboardId}`) for dynamic resources'
12
- - 'Registering a `@Plugin` at the server level so it applies across all apps'
13
- - 'Global plugins go in `@FrontMcp({ plugins })`, app-scoped providers go in `@App({ providers })`'
14
+ - Organizing a server into multiple `@App` modules (`analytics` and `admin`)
15
+ - Decorating a service class with `@Provider({ name, scope })` so it acts as its own DI token (the strict schema rejects `useFactory`/`useClass`/`provide` use `AsyncProvider` for those)
16
+ - Accessing injected dependencies via `this.get(DatabaseClient)` in tools and resources
17
+ - Using `@ResourceTemplate` with URI parameters (`{dashboardId}`) for dynamic resources
18
+ - Registering a `@Plugin` at the server level so it applies across all apps
19
+ - Global plugins go in `@FrontMcp({ plugins })`, app-scoped providers go in `@App({ providers })`
14
20
  ---
15
21
 
16
22
  # Multi-App Server with Plugins and Providers
@@ -21,18 +27,39 @@ Demonstrates a server with multiple `@App` modules, a `@Provider` for dependency
21
27
 
22
28
  ```typescript
23
29
  // src/providers/database.provider.ts
24
- import { Provider } from '@frontmcp/sdk';
25
-
26
- export const DatabaseToken = Symbol('Database');
30
+ import { Provider, ProviderScope } from '@frontmcp/sdk';
27
31
 
32
+ // The @Provider decorator schema is strict: it accepts only `id|name|description|scope`.
33
+ // `provide`/`useClass`/`useValue`/`useFactory` are NOT supported.
34
+ // For simple cases, decorate the class itself — it becomes its own DI token.
28
35
  @Provider({
29
- name: 'database',
30
- provide: DatabaseToken,
31
- useFactory: () => new DatabaseClient(process.env.DB_URL),
36
+ name: 'DatabaseClient',
37
+ scope: ProviderScope.GLOBAL,
32
38
  })
33
- class DatabaseProvider {}
39
+ export class DatabaseClient {
40
+ constructor(private readonly url = process.env.DB_URL) {}
41
+
42
+ async query(sql: string): Promise<unknown[]> {
43
+ /* ... */
44
+ return [];
45
+ }
46
+
47
+ async getDataset(id: string): Promise<unknown[]> {
48
+ /* ... */
49
+ return [];
50
+ }
51
+
52
+ async getDashboard(id: string): Promise<unknown> {
53
+ /* ... */
54
+ return {};
55
+ }
56
+ }
34
57
  ```
35
58
 
59
+ > If you need an async factory or want to bind to a separate token, use the
60
+ > `AsyncProvider({ provide, name, scope, inject, useFactory })` helper instead of
61
+ > the `@Provider` decorator.
62
+
36
63
  ```typescript
37
64
  // src/plugins/audit.plugin.ts
38
65
  import { Plugin } from '@frontmcp/sdk';
@@ -58,7 +85,7 @@ import { Tool, ToolContext, z } from '@frontmcp/sdk';
58
85
  })
59
86
  class QueryTool extends ToolContext {
60
87
  async execute(input: { sql: string }) {
61
- const db = this.get(DatabaseToken);
88
+ const db = this.get(DatabaseClient);
62
89
  const results = await db.query(input.sql);
63
90
  return { rows: results };
64
91
  }
@@ -79,7 +106,7 @@ import { Tool, ToolContext, z } from '@frontmcp/sdk';
79
106
  })
80
107
  class ReportTool extends ToolContext {
81
108
  async execute(input: { datasetId: string; format: string }) {
82
- const db = this.get(DatabaseToken);
109
+ const db = this.get(DatabaseClient);
83
110
  const data = await db.getDataset(input.datasetId);
84
111
  return { report: `Report in ${input.format} format`, rows: data.length };
85
112
  }
@@ -96,9 +123,9 @@ import { ResourceContext, ResourceTemplate } from '@frontmcp/sdk';
96
123
  description: 'Dashboard data by ID',
97
124
  mimeType: 'application/json',
98
125
  })
99
- class DashboardResource extends ResourceContext {
100
- async read(uri: string, params: { dashboardId: string }) {
101
- const db = this.get(DatabaseToken);
126
+ class DashboardResource extends ResourceContext<{ dashboardId: string }> {
127
+ async execute(uri: string, params: { dashboardId: string }) {
128
+ const db = this.get(DatabaseClient);
102
129
  const data = await db.getDashboard(params.dashboardId);
103
130
  return { contents: [{ uri, text: JSON.stringify(data) }] };
104
131
  }
@@ -113,7 +140,7 @@ import { App, FrontMcp } from '@frontmcp/sdk';
113
140
  name: 'analytics',
114
141
  tools: [QueryTool, ReportTool],
115
142
  resources: [DashboardResource],
116
- providers: [DatabaseProvider],
143
+ providers: [DatabaseClient],
117
144
  })
118
145
  class AnalyticsApp {}
119
146
 
@@ -135,8 +162,8 @@ class MyServer {}
135
162
  ## What This Demonstrates
136
163
 
137
164
  - Organizing a server into multiple `@App` modules (`analytics` and `admin`)
138
- - Using `@Provider` with `useFactory` to register a database client for dependency injection
139
- - Accessing injected dependencies via `this.get(DatabaseToken)` in tools and resources
165
+ - Decorating a service class with `@Provider({ name, scope })` so it acts as its own DI token (the strict schema rejects `useFactory`/`useClass`/`provide` use `AsyncProvider` for those)
166
+ - Accessing injected dependencies via `this.get(DatabaseClient)` in tools and resources
140
167
  - Using `@ResourceTemplate` with URI parameters (`{dashboardId}`) for dynamic resources
141
168
  - Registering a `@Plugin` at the server level so it applies across all apps
142
169
  - Global plugins go in `@FrontMcp({ plugins })`, app-scoped providers go in `@App({ providers })`