@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
@@ -13,7 +13,7 @@ Agents are autonomous AI entities that use an LLM to reason, plan, and invoke in
13
13
 
14
14
  - Building an autonomous AI entity that uses LLM reasoning to decide which tools to call
15
15
  - Orchestrating multi-step workflows where the agent plans, acts, and iterates toward a goal
16
- - Creating multi-agent swarms with handoff between specialized agents
16
+ - Creating multi-agent swarms where peers can discover and call each other via the LLM
17
17
 
18
18
  ### Recommended
19
19
 
@@ -87,7 +87,7 @@ class CodeReviewerAgent extends AgentContext {
87
87
  - `this.mark(stage)` -- set the active execution stage for debugging/tracking
88
88
  - `this.fetch(input, init?)` -- HTTP fetch with context propagation
89
89
  - `this.notify(message, level?)` -- send a log-level notification to the client
90
- - `this.respondProgress(value, total?)` -- send a progress notification to the client
90
+ - `this.progress(progress, total?, message?)` -- send a progress notification to the client
91
91
 
92
92
  **Properties:**
93
93
 
@@ -364,41 +364,58 @@ class CodeAuditorAgent extends AgentContext {}
364
364
 
365
365
  ## Swarm Configuration
366
366
 
367
- Swarm mode enables multi-agent handoff, where agents can transfer control to each other during execution. Configure swarms using the `swarm` field.
367
+ Swarm mode lets agents discover and call each other at runtime. The framework registers visible peers as callable tools (`use-agent:<id>`) on the orchestrator's LLM, so the LLM itself decides when to delegate -- there is no declarative routing table.
368
+
369
+ ### SwarmConfig Fields
370
+
371
+ | Field | Type | Default | Description |
372
+ | ------------------- | ---------- | ------- | ------------------------------------------------------------------------------------ |
373
+ | `canSeeOtherAgents` | `boolean` | `false` | If `true`, this agent can discover and call other agents in the same scope |
374
+ | `visibleAgents` | `string[]` | -- | Whitelist of agent IDs this agent is allowed to see (when `canSeeOtherAgents: true`) |
375
+ | `isVisible` | `boolean` | `true` | If `false`, this agent is hidden from peers (cannot be called as `use-agent:<id>`) |
376
+ | `maxCallDepth` | `number` | `3` | Maximum nested agent-to-agent call depth (1-10) |
377
+
378
+ There is no `role`, `handoff`, or `condition` field -- routing is driven by the orchestrator's LLM choosing among the visible `use-agent:*` tools.
368
379
 
369
380
  ```typescript
370
381
  @Agent({
382
+ id: 'triage_agent',
371
383
  name: 'triage_agent',
372
- description: 'Triages incoming requests and hands off to specialists',
384
+ description: 'Triages incoming requests and delegates to specialists',
373
385
  llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
374
386
  inputSchema: {
375
387
  request: z.string().describe('The incoming user request'),
376
388
  },
389
+ // Coordinator sees other agents and can call them.
377
390
  swarm: {
378
- role: 'coordinator',
379
- handoff: [
380
- { agent: 'billing_agent', condition: 'Request is about billing or payments' },
381
- { agent: 'technical_agent', condition: 'Request is about technical issues' },
382
- { agent: 'general_agent', condition: 'Request does not match other categories' },
383
- ],
391
+ canSeeOtherAgents: true,
392
+ visibleAgents: ['billing_agent', 'technical_agent'],
393
+ maxCallDepth: 3,
384
394
  },
385
- systemInstructions: 'Analyze the request and hand off to the appropriate specialist agent.',
395
+ systemInstructions:
396
+ 'Analyze the request and call use-agent:billing_agent or use-agent:technical_agent depending on the topic.',
386
397
  })
387
398
  class TriageAgent extends AgentContext {}
388
399
 
389
400
  @Agent({
401
+ id: 'billing_agent',
390
402
  name: 'billing_agent',
391
403
  description: 'Handles billing and payment inquiries',
392
404
  llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
393
405
  tools: [LookupInvoiceTool, ProcessRefundTool],
394
- swarm: {
395
- role: 'specialist',
396
- handoff: [{ agent: 'triage_agent', condition: 'Request is outside billing scope' }],
397
- },
406
+ // Specialist is visible to peers but does not see others.
407
+ swarm: { isVisible: true },
398
408
  })
399
409
  class BillingAgent extends AgentContext {}
400
410
  ```
401
411
 
412
+ ### How Routing Works
413
+
414
+ - When the orchestrator agent runs its LLM loop, every visible peer is exposed as a tool named `use-agent:<id>`.
415
+ - The orchestrator's `systemInstructions` should describe when to call each peer; the LLM decides at runtime.
416
+ - Peers do not need any swarm config to be callable -- they only need `isVisible: true` (the default).
417
+ - Set `canSeeOtherAgents: false` (the default) on agents that should never be able to delegate.
418
+
402
419
  ## Function-Style Builder
403
420
 
404
421
  For agents that do not need a class, use the `agent()` function builder.
@@ -566,8 +583,8 @@ class DocsAgent extends AgentContext {}
566
583
  | LLM config | `llm: { provider: 'anthropic', model: '...', apiKey: { env: 'KEY' } }` | `llm: { provider: 'anthropic', apiKey: 'sk-hardcoded' }` | Environment variable references prevent leaking secrets in code |
567
584
  | 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 |
568
585
  | Custom execute | Override `execute()` for multi-pass orchestration | Putting all logic in system instructions | Custom `execute()` gives structured control over completion calls and stages |
569
- | Sub-agents | Use `agents: [SubAgent]` for composition | Calling another agent's `execute()` directly | The `agents` array enables proper lifecycle, scope isolation, and handoff |
570
- | 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 |
586
+ | Sub-agents | Use `agents: [SubAgent]` for composition | Calling another agent's `execute()` directly | The `agents` array enables proper lifecycle and scope isolation |
587
+ | Swarm visibility | `swarm: { canSeeOtherAgents: true, visibleAgents: ['peer'] }` | `swarm: { role, handoff }` (those fields do not exist) | Routing is LLM-driven via `use-agent:*` tools; only visibility is configurable |
571
588
 
572
589
  ## Verification Checklist
573
590
 
@@ -585,25 +602,25 @@ class DocsAgent extends AgentContext {}
585
602
  - [ ] LLM adapter connects successfully to the configured provider
586
603
  - [ ] Inner tools are invoked correctly during the agent loop
587
604
  - [ ] `this.completion()` and `this.streamCompletion()` return valid responses
588
- - [ ] Swarm handoff transfers control to the correct specialist agent
605
+ - [ ] Visible peers appear as `use-agent:<id>` tools to the orchestrator agent
589
606
 
590
607
  ## Troubleshooting
591
608
 
592
- | Problem | Cause | Solution |
593
- | ----------------------------------- | ----------------------------------------------------- | --------------------------------------------------------------------------------- |
594
- | Agent not appearing in tool listing | Not registered in `agents` array | Add agent class to `@App` or `@FrontMcp` `agents` array |
595
- | LLM authentication error | API key not set or incorrect env variable | Verify the environment variable name in `apiKey: { env: '...' }` is set |
596
- | Inner tools not being called | Tools not listed in `tools` array of `@Agent` | Add tool classes to the `tools` field in the `@Agent` decorator |
597
- | Agent times out | No timeout or rate limit configured | Add `timeout: { executeMs: 120_000 }` and `rateLimit` to `@Agent` options |
598
- | 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 |
609
+ | Problem | Cause | Solution |
610
+ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
611
+ | Agent not appearing in tool listing | Not registered in `agents` array | Add agent class to `@App` or `@FrontMcp` `agents` array |
612
+ | LLM authentication error | API key not set or incorrect env variable | Verify the environment variable name in `apiKey: { env: '...' }` is set |
613
+ | Inner tools not being called | Tools not listed in `tools` array of `@Agent` | Add tool classes to the `tools` field in the `@Agent` decorator |
614
+ | Agent times out | No timeout or rate limit configured | Add `timeout: { executeMs: 120_000 }` and `rateLimit` to `@Agent` options |
615
+ | Peer agent not callable | Peer has `isVisible: false`, or orchestrator lacks `canSeeOtherAgents: true`, or peer is not in `visibleAgents` whitelist | Set `swarm.isVisible: true` on the peer and `swarm.canSeeOtherAgents: true` (and add the peer to `visibleAgents`) on the orchestrator |
599
616
 
600
617
  ## Examples
601
618
 
602
- | Example | Level | Description |
603
- | ---------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------- |
604
- | [`basic-agent-with-tools`](../examples/create-agent/basic-agent-with-tools.md) | Basic | An autonomous agent that uses inner tools to review GitHub pull requests. |
605
- | [`custom-multi-pass-agent`](../examples/create-agent/custom-multi-pass-agent.md) | Intermediate | An agent that overrides `execute()` to perform multi-pass LLM reasoning with `this.completion()`. |
606
- | [`nested-agents-with-swarm`](../examples/create-agent/nested-agents-with-swarm.md) | Advanced | Composing specialized sub-agents and configuring swarm-based handoff between agents. |
619
+ | Example | Level | Description |
620
+ | ---------------------------------------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
621
+ | [`basic-agent-with-tools`](../examples/create-agent/basic-agent-with-tools.md) | Basic | An autonomous agent that uses inner tools to review GitHub pull requests. |
622
+ | [`custom-multi-pass-agent`](../examples/create-agent/custom-multi-pass-agent.md) | Intermediate | An agent that overrides `execute()` to perform multi-pass LLM reasoning with `this.completion()`. |
623
+ | [`nested-agents-with-swarm`](../examples/create-agent/nested-agents-with-swarm.md) | Advanced | 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. |
607
624
 
608
625
  > See all examples in [`examples/create-agent/`](../examples/create-agent/)
609
626
 
@@ -35,17 +35,17 @@ Create a class extending `JobContext<In, Out>` and implement the `execute(input:
35
35
 
36
36
  ### JobMetadata Fields
37
37
 
38
- | Field | Type | Required | Default | Description |
39
- | -------------- | ------------------------ | -------- | ---------------- | -------------------------------------- |
40
- | `name` | `string` | Yes | -- | Unique job name |
41
- | `inputSchema` | `ZodRawShape` | Yes | -- | Zod raw shape for input validation |
42
- | `outputSchema` | `ZodRawShape \| ZodType` | Yes | -- | Zod schema for output validation |
43
- | `description` | `string` | No | -- | Human-readable description |
44
- | `timeout` | `number` | No | `300000` (5 min) | Maximum execution time in milliseconds |
45
- | `retry` | `RetryPolicy` | No | -- | Retry configuration (see below) |
46
- | `tags` | `string[]` | No | -- | Categorization tags |
47
- | `labels` | `Record<string, string>` | No | -- | Key-value labels for filtering |
48
- | `permissions` | `JobPermissions` | No | -- | Access control configuration |
38
+ | Field | Type | Required | Default | Description |
39
+ | -------------- | ------------------------ | -------- | ---------------- | ------------------------------------------ |
40
+ | `name` | `string` | Yes | -- | Unique job name |
41
+ | `inputSchema` | `ZodRawShape` | Yes | -- | Zod raw shape for input validation |
42
+ | `outputSchema` | `ZodRawShape \| ZodType` | Yes | -- | Zod schema for output validation |
43
+ | `description` | `string` | No | -- | Human-readable description |
44
+ | `timeout` | `number` | No | `300000` (5 min) | Maximum execution time in milliseconds |
45
+ | `retry` | `RetryPolicy` | No | -- | Retry configuration (see below) |
46
+ | `tags` | `string[]` | No | -- | Categorization tags |
47
+ | `labels` | `Record<string, string>` | No | -- | Key-value labels for filtering |
48
+ | `permissions` | `JobPermission[]` | No | -- | Array of permission rules (one per action) |
49
49
 
50
50
  ### Basic Example
51
51
 
@@ -139,10 +139,10 @@ Configure automatic retries with exponential backoff using the `retry` field.
139
139
 
140
140
  | Field | Type | Default | Description |
141
141
  | ------------------- | -------- | ------- | ---------------------------------------------------- |
142
- | `maxAttempts` | `number` | `1` | Total number of attempts (including the initial run) |
142
+ | `maxAttempts` | `number` | `3` | Total number of attempts (including the initial run) |
143
143
  | `backoffMs` | `number` | `1000` | Initial delay before the first retry in milliseconds |
144
144
  | `backoffMultiplier` | `number` | `2` | Multiplier applied to backoff after each retry |
145
- | `maxBackoffMs` | `number` | `30000` | Maximum backoff duration in milliseconds |
145
+ | `maxBackoffMs` | `number` | `60000` | Maximum backoff duration in milliseconds |
146
146
 
147
147
  ### Example with Retry
148
148
 
@@ -201,16 +201,18 @@ class SyncExternalApiJob extends JobContext {
201
201
  }
202
202
  ```
203
203
 
204
- With this configuration, if the job fails:
204
+ With this configuration (`maxAttempts: 5`), if the job fails:
205
205
 
206
206
  - Attempt 1: immediate execution
207
- - Attempt 2: retry after 2000ms
208
- - Attempt 3: retry after 4000ms
209
- - Attempt 4: retry after 8000ms
210
- - Attempt 5: retry after 16000ms
207
+ - Attempt 2: retry after 2000ms (2s)
208
+ - Attempt 3: retry after 4000ms (4s)
209
+ - Attempt 4: retry after 8000ms (8s)
210
+ - Attempt 5: retry after 16000ms (16s)
211
211
 
212
212
  The backoff is capped at `maxBackoffMs` (60000ms), so no delay exceeds 60 seconds.
213
213
 
214
+ > **Default:** when you omit `retry`, the framework uses `maxAttempts: 3`, `backoffMs: 1000`, `backoffMultiplier: 2`, `maxBackoffMs: 60000` -- i.e., the initial run plus two retries (at ~1s and ~2s).
215
+
214
216
  ## Progress Tracking
215
217
 
216
218
  Use `this.progress(pct, total?, msg?)` to report job progress. The framework persists progress and makes it queryable.
@@ -262,7 +264,18 @@ class ImportCsvJob extends JobContext {
262
264
 
263
265
  ## Permissions
264
266
 
265
- Control who can interact with jobs using the `permissions` field. Permissions support action-based access, roles, scopes, and custom predicates.
267
+ Control who can interact with jobs using the `permissions` field. **`permissions` is an array** of rules; each rule grants access to a single `action` and lists the roles, scopes, and/or custom predicate required for that action.
268
+
269
+ ### Permission Rule Shape
270
+
271
+ ```typescript
272
+ interface JobPermission {
273
+ action: 'create' | 'read' | 'update' | 'delete' | 'execute' | 'list'; // singular!
274
+ roles?: string[]; // user must have one of these roles
275
+ scopes?: string[]; // token must include all of these scopes
276
+ custom?: (authInfo: Partial<Record<string, unknown>>) => boolean | Promise<boolean>;
277
+ }
278
+ ```
266
279
 
267
280
  ### Permission Actions
268
281
 
@@ -289,16 +302,20 @@ Control who can interact with jobs using the `permissions` field. Permissions su
289
302
  exportedRows: z.number().int(),
290
303
  location: z.string().url(),
291
304
  },
292
- permissions: {
293
- actions: ['create', 'read', 'execute', 'list'],
294
- roles: ['admin', 'data-engineer'],
295
- scopes: ['jobs:write', 'data:export'],
296
- predicate: (ctx) => ctx.user?.department === 'engineering',
297
- },
305
+ permissions: [
306
+ {
307
+ action: 'execute',
308
+ roles: ['admin', 'data-engineer'],
309
+ scopes: ['jobs:write', 'data:export'],
310
+ custom: (authInfo) => (authInfo as { department?: string }).department === 'engineering',
311
+ },
312
+ { action: 'read', roles: ['admin', 'data-engineer', 'auditor'] },
313
+ { action: 'list', roles: ['admin', 'data-engineer', 'auditor'] },
314
+ ],
298
315
  })
299
316
  class DataExportJob extends JobContext {
300
317
  async execute(input: { dataset: string; destination: string }) {
301
- // Only users with the right roles, scopes, or matching the predicate can run this
318
+ // Only users matching one of the permission rules for this action can run this
302
319
  this.log(`Exporting dataset: ${input.dataset}`);
303
320
  const rows = await this.exportData(input.dataset, input.destination);
304
321
  return { exportedRows: rows, location: input.destination };
@@ -312,25 +329,22 @@ class DataExportJob extends JobContext {
312
329
 
313
330
  ### Combining Permission Strategies
314
331
 
315
- Permissions fields are additive -- all specified conditions must be met:
332
+ Within a single rule, `roles`, `scopes`, and `custom` are additive -- all specified conditions must be met. Add additional entries to grant other actions (or alternative role/scope sets):
316
333
 
317
334
  ```typescript
318
- permissions: {
319
- // Actions this job supports
320
- actions: ['create', 'read', 'execute', 'delete', 'list'],
321
-
322
- // Role-based: user must have one of these roles
323
- roles: ['admin', 'operator'],
324
-
325
- // Scope-based: user token must include these scopes
326
- scopes: ['jobs:manage'],
327
-
328
- // Custom predicate: arbitrary logic
329
- predicate: (ctx) => {
330
- const user = ctx.user;
331
- return user?.isActive && user?.emailVerified;
335
+ permissions: [
336
+ {
337
+ action: 'execute',
338
+ roles: ['admin', 'operator'],
339
+ scopes: ['jobs:manage'],
340
+ custom: (authInfo) => {
341
+ const user = (authInfo as { user?: { isActive?: boolean; emailVerified?: boolean } }).user;
342
+ return Boolean(user?.isActive && user?.emailVerified);
343
+ },
332
344
  },
333
- }
345
+ { action: 'read', roles: ['admin', 'operator', 'viewer'] },
346
+ { action: 'list', roles: ['admin', 'operator', 'viewer'] },
347
+ ];
334
348
  ```
335
349
 
336
350
  ## Function Builder
@@ -475,11 +489,12 @@ import { App, FrontMcp, Job, job, JobContext, z } from '@frontmcp/sdk';
475
489
  },
476
490
  tags: ['etl', 'data-pipeline'],
477
491
  labels: { team: 'data-engineering', priority: 'high' },
478
- permissions: {
479
- actions: ['create', 'read', 'execute', 'list'],
480
- roles: ['admin', 'data-engineer'],
481
- scopes: ['jobs:execute', 'data:write'],
482
- },
492
+ permissions: [
493
+ { action: 'execute', roles: ['admin', 'data-engineer'], scopes: ['jobs:execute', 'data:write'] },
494
+ { action: 'create', roles: ['admin', 'data-engineer'] },
495
+ { action: 'read', roles: ['admin', 'data-engineer'] },
496
+ { action: 'list', roles: ['admin', 'data-engineer'] },
497
+ ],
483
498
  })
484
499
  class EtlPipelineJob extends JobContext {
485
500
  async execute(input: {
@@ -568,13 +583,13 @@ class DataServer {}
568
583
 
569
584
  ## Common Patterns
570
585
 
571
- | Pattern | Correct | Incorrect | Why |
572
- | ----------------- | ------------------------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------------ |
573
- | Progress tracking | `this.progress(50, 100, 'Processing batch 5')` | Not reporting progress | Progress is persisted and queryable; essential for long-running visibility |
574
- | Retry config | `retry: { maxAttempts: 3, backoffMs: 2000, backoffMultiplier: 2 }` | Implementing retry logic manually in `execute()` | Framework handles retry with exponential backoff and attempt tracking |
575
- | 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 |
576
- | Job logging | `this.log('message')` for persistent, queryable logs | Using `console.log()` | `this.log()` persists with job state; `console.log` is ephemeral |
577
- | Permissions | Use `permissions: { roles: [...], scopes: [...] }` declaratively | Checking roles manually inside `execute()` | Declarative permissions are enforced before execution and are self-documenting |
586
+ | Pattern | Correct | Incorrect | Why |
587
+ | ----------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
588
+ | Progress tracking | `this.progress(50, 100, 'Processing batch 5')` | Not reporting progress | Progress is persisted and queryable; essential for long-running visibility |
589
+ | Retry config | `retry: { maxAttempts: 3, backoffMs: 2000, backoffMultiplier: 2 }` | Implementing retry logic manually in `execute()` | Framework handles retry with exponential backoff and attempt tracking |
590
+ | 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 |
591
+ | Job logging | `this.log('message')` for persistent, queryable logs | Using `console.log()` | `this.log()` persists with job state; `console.log` is ephemeral |
592
+ | Permissions | `permissions: [{ action: 'execute', roles: [...] }, ...]` (array, singular `action`) | `permissions: { actions: [...], roles, predicate }` (does not parse) | The schema requires an array of `{ action, roles, scopes, custom }` rules; `actions` plural and top-level `predicate` are not accepted |
578
593
 
579
594
  ## Verification Checklist
580
595
 
@@ -52,52 +52,64 @@ const { Stage, Will, Did, Around } = FlowHooksOf('tools:call-tool');
52
52
 
53
53
  ## Available Flow Names
54
54
 
55
- | Flow Name | Description |
56
- | -------------------------- | ------------------------ |
57
- | `tools:call-tool` | Tool execution |
58
- | `tools:list-tools` | Tool listing / discovery |
59
- | `resources:read-resource` | Resource reading |
60
- | `resources:list-resources` | Resource listing |
61
- | `prompts:get-prompt` | Prompt retrieval |
62
- | `prompts:list-prompts` | Prompt listing |
63
- | `http:request` | HTTP request handling |
64
- | `agents:call-agent` | Agent invocation |
55
+ These are the flow names with pre-built hook decorator exports in `@frontmcp/sdk` (see "Pre-Built Hook Type Exports" below):
56
+
57
+ | Flow Name | Description | Pre-built export |
58
+ | ----------------------------------- | ------------------------- | --------------------------- |
59
+ | `tools:call-tool` | Tool execution | `ToolHook` |
60
+ | `tools:list-tools` | Tool listing / discovery | `ListToolsHook` |
61
+ | `http:request` | HTTP request handling | `HttpHook` |
62
+ | `resources:read-resource` | Resource reading | `ResourceHook` |
63
+ | `resources:list-resources` | Resource listing | `ListResourcesHook` |
64
+ | `resources:list-resource-templates` | Resource template listing | `ListResourceTemplatesHook` |
65
+ | `agents:call-agent` | Agent invocation | `AgentCallHook` |
66
+ | `channels:send-notification` | Channel notification send | `ChannelSendHook` |
67
+ | `channels:list` | Channel listing | `ChannelListHook` |
65
68
 
66
69
  ## Server Lifecycle Hooks
67
70
 
68
- In addition to flow-based hooks, plugins can register callbacks for server lifecycle events. These are not decorator-based they use the `scope.onServerStarted()` API.
71
+ In addition to flow-based hooks, the framework exposes a single `scope.onServerStarted(callback)` API for post-startup work. Callbacks register against the active `ScopeEntry` and run after `server.start()` completes.
69
72
 
70
73
  ### `onServerStarted()`
71
74
 
72
- Runs after the HTTP server is fully initialized and listening. Use for warming caches, starting background indexing, or logging readiness.
75
+ Use for warming caches, starting background indexing, or logging readiness once the server is live.
76
+
77
+ **Signature:** `scope.onServerStarted(callback: () => void | Promise<void>): void`
78
+
79
+ - Callbacks are stored on the active scope and invoked when `emitServerStarted()` runs after startup.
80
+ - Supports both sync and async callbacks; multiple callbacks execute in registration order with `await`.
81
+
82
+ The cleanest place to call it from a plugin is a factory provider whose `useFactory` receives the active scope, or from a class provider's lifecycle. A common pattern is to register the callback from a hook method using the plugin's injected scope (the plugin instance has a `get(token)` accessor available after construction):
73
83
 
74
84
  ```typescript
75
- import { DynamicPlugin, Plugin } from '@frontmcp/sdk';
85
+ import { Plugin, ToolHook } from '@frontmcp/sdk';
86
+
87
+ const { Will } = ToolHook;
76
88
 
77
89
  @Plugin({
78
90
  name: 'cache-warmer',
79
91
  description: 'Warms caches when the server starts',
80
92
  providers: [CacheService],
81
93
  })
82
- class CacheWarmerPlugin extends DynamicPlugin<{}> {
83
- constructor(scope: ScopeEntry) {
84
- super();
85
- // Register lifecycle callback
86
- scope.onServerStarted(async () => {
87
- const cache = this.get(CacheService);
88
- await cache.warmAll();
89
- console.log('Cache warmed successfully');
90
- });
94
+ export class CacheWarmerPlugin {
95
+ private registered = false;
96
+
97
+ // Lazy-register the lifecycle callback the first time any tool is called.
98
+ // For pure post-startup work, prefer registering from a Provider with access
99
+ // to the active scope, or expose the callback registration via a custom Provider.
100
+ @Will('parseInput', { priority: 1000 })
101
+ registerOnce() {
102
+ if (this.registered) return;
103
+ this.registered = true;
104
+ const cache = this.get(CacheService);
105
+ // `this.get` is wired by the plugin registry post-construction; resolve scope similarly
106
+ // via a Provider that exposes onServerStarted, e.g. a `ScopeAccessor` wrapper.
107
+ cache.warmAllInBackground();
91
108
  }
92
109
  }
93
110
  ```
94
111
 
95
- **Signature:** `scope.onServerStarted(callback: () => void | Promise<void>): void`
96
-
97
- - Callbacks are stored and executed after `server.start()` completes
98
- - Supports both sync and async callbacks
99
- - Multiple callbacks are executed in registration order with `await`
100
- - Typically used in plugin constructors or provider `onInit()` methods
112
+ > **Pattern note:** `ScopeEntry` is not directly DI-injectable into a plugin constructor (it is a scope-level entry, not a token-registered provider). For lifecycle work, prefer wiring `onServerStarted(...)` through a Provider that receives the scope via `providers.getActiveScope()`, or use Provider/Adapter `onInit` hooks where appropriate. See `apps/demo` for working patterns.
101
113
 
102
114
  ## Pre-Built Hook Type Exports
103
115
 
@@ -106,8 +118,11 @@ For convenience, FrontMCP exports typed aliases so you do not need to call `Flow
106
118
  ```typescript
107
119
  import {
108
120
  AgentCallHook, // FlowHooksOf('agents:call-agent')
121
+ ChannelListHook, // FlowHooksOf('channels:list')
122
+ ChannelSendHook, // FlowHooksOf('channels:send-notification')
109
123
  HttpHook, // FlowHooksOf('http:request')
110
124
  ListResourcesHook, // FlowHooksOf('resources:list-resources')
125
+ ListResourceTemplatesHook, // FlowHooksOf('resources:list-resource-templates')
111
126
  ListToolsHook, // FlowHooksOf('tools:list-tools')
112
127
  ResourceHook, // FlowHooksOf('resources:read-resource')
113
128
  ToolHook, // FlowHooksOf('tools:call-tool')
@@ -120,6 +135,8 @@ Usage:
120
135
  const { Will, Did, Around, Stage } = ToolHook;
121
136
  ```
122
137
 
138
+ > **Note:** Other internal flows (e.g., `prompts:get-prompt`, `prompts:list-prompts`, `skills:search`, `completion:complete`, transport flows) exist at runtime and can be hooked by passing the flow name to `FlowHooksOf<'flow:name'>('flow:name')`, but they do not currently ship with a pre-built typed export. Prefer the pre-built exports above when one is available.
139
+
123
140
  ## call-tool Flow Stages
124
141
 
125
142
  The `tools:call-tool` flow proceeds through these stages in order:
@@ -96,7 +96,8 @@ export class GreeterService {
96
96
 
97
97
  ```typescript
98
98
  // my-greeter.plugin.ts
99
- import { Plugin, DynamicPlugin, ProviderType } from '@frontmcp/sdk';
99
+ import { DynamicPlugin, Plugin, ProviderType } from '@frontmcp/sdk';
100
+
100
101
  import { GreeterService } from './providers/my-greeter.provider';
101
102
 
102
103
  @Plugin({ name: 'greeter', exports: [GreeterService] })
@@ -110,6 +111,7 @@ export default class GreeterPlugin extends DynamicPlugin<{ prefix: string }> {
110
111
  ```typescript
111
112
  // server.ts
112
113
  import { FrontMcp } from '@frontmcp/sdk';
114
+
113
115
  import GreeterPlugin from './plugins/my-greeter.plugin';
114
116
 
115
117
  @FrontMcp({
@@ -136,7 +138,8 @@ export default class AuditLogPlugin {}
136
138
  Register it in your server:
137
139
 
138
140
  ```typescript
139
- import { FrontMcp, App } from '@frontmcp/sdk';
141
+ import { App, FrontMcp } from '@frontmcp/sdk';
142
+
140
143
  import AuditLogPlugin from './plugins/audit-log.plugin';
141
144
 
142
145
  @App({ name: 'MyApp' })
@@ -158,8 +161,7 @@ class MyServer {}
158
161
  Plugins contribute injectable services via `providers`:
159
162
 
160
163
  ```typescript
161
- import { Plugin, Provider } from '@frontmcp/sdk';
162
- import type { Token } from '@frontmcp/sdk';
164
+ import { Plugin, Provider, type Token } from '@frontmcp/sdk';
163
165
 
164
166
  export const AuditLoggerToken: Token<AuditLogger> = Symbol('AuditLogger');
165
167
 
@@ -202,8 +204,8 @@ declare module '@frontmcp/sdk' {
202
204
  The SDK handles runtime installation when you declare `contextExtensions` in plugin metadata. Do not modify `ExecutionContextBase.prototype` directly.
203
205
 
204
206
  ```typescript
205
- import { Plugin } from '@frontmcp/sdk';
206
- import type { Token } from '@frontmcp/sdk';
207
+ import { Plugin, type Token } from '@frontmcp/sdk';
208
+
207
209
  import './audit-log.context-extension'; // Import for type augmentation side effect
208
210
 
209
211
  export const AuditLoggerToken: Token<AuditLogger> = Symbol('AuditLogger');
@@ -242,8 +244,7 @@ class DeleteRecordTool extends ToolContext {
242
244
  For plugins that accept runtime options, extend `DynamicPlugin`:
243
245
 
244
246
  ```typescript
245
- import { Plugin, DynamicPlugin, ProviderType } from '@frontmcp/sdk';
246
- import type { Token } from '@frontmcp/sdk';
247
+ import { DynamicPlugin, Plugin, ProviderType, type Token } from '@frontmcp/sdk';
247
248
 
248
249
  export interface MyPluginOptions {
249
250
  endpoint: string;
@@ -415,6 +416,7 @@ The TypeScript augmentation file must be imported somewhere in your plugin's bar
415
416
  ```typescript
416
417
  // index.ts
417
418
  import './my-plugin.context-extension'; // side-effect import for type augmentation
419
+
418
420
  export { MyPlugin } from './my-plugin.plugin';
419
421
  export { MyServiceToken } from './my-plugin.symbols';
420
422
  ```
@@ -34,8 +34,8 @@ Prompts define reusable AI interaction patterns in the MCP protocol. They produc
34
34
  Create a class extending `PromptContext` and implement `execute(args)`. The `@Prompt` decorator accepts `name`, optional `description`, and `arguments` (the prompt's input parameters).
35
35
 
36
36
  ```typescript
37
- import { Prompt, PromptContext } from '@frontmcp/sdk';
38
37
  import { GetPromptResult } from '@frontmcp/protocol';
38
+ import { Prompt, PromptContext } from '@frontmcp/sdk';
39
39
 
40
40
  @Prompt({
41
41
  name: 'code-review',
@@ -260,8 +260,8 @@ class AnalyzeConfigPrompt extends PromptContext {
260
260
  For simple prompts that do not need a class, use the `prompt()` function builder:
261
261
 
262
262
  ```typescript
263
- import { prompt } from '@frontmcp/sdk';
264
263
  import { GetPromptResult } from '@frontmcp/protocol';
264
+ import { prompt } from '@frontmcp/sdk';
265
265
 
266
266
  const TranslatePrompt = prompt({
267
267
  name: 'translate',
@@ -375,7 +375,7 @@ class ResearchReportPrompt extends PromptContext {
375
375
  Add prompt classes (or function-style prompts) to the `prompts` array in `@App`.
376
376
 
377
377
  ```typescript
378
- import { FrontMcp, App } from '@frontmcp/sdk';
378
+ import { App, FrontMcp } from '@frontmcp/sdk';
379
379
 
380
380
  @App({
381
381
  name: 'my-app',