@frontmcp/skills 1.1.2 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/catalog/TEMPLATE.md +16 -11
- package/catalog/frontmcp-authorities/SKILL.md +116 -11
- package/catalog/frontmcp-authorities/references/authority-profiles.md +39 -36
- package/catalog/frontmcp-authorities/references/claims-mapping.md +7 -0
- package/catalog/frontmcp-authorities/references/custom-evaluators.md +63 -14
- package/catalog/frontmcp-channels/SKILL.md +36 -0
- package/catalog/frontmcp-channels/examples/channel-sources/file-watcher.md +8 -2
- package/catalog/frontmcp-channels/examples/channel-sources/replay-buffer.md +111 -30
- package/catalog/frontmcp-channels/examples/channel-two-way/whatsapp-bridge.md +45 -3
- package/catalog/frontmcp-channels/references/channel-sources.md +11 -3
- package/catalog/frontmcp-channels/references/channel-two-way.md +60 -89
- package/catalog/frontmcp-config/SKILL.md +111 -8
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +4 -4
- package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +7 -1
- package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +1 -1
- package/catalog/frontmcp-config/examples/configure-deployment-targets/json-schema-ide-support.md +1 -1
- package/catalog/frontmcp-config/examples/configure-deployment-targets/multi-target-with-security.md +12 -9
- package/catalog/frontmcp-config/examples/configure-http/cors-restricted-origins.md +2 -2
- package/catalog/frontmcp-config/examples/configure-http/entry-path-reverse-proxy.md +1 -1
- package/catalog/frontmcp-config/examples/configure-security-headers/csp-report-only.md +1 -1
- package/catalog/frontmcp-config/examples/configure-security-headers/full-production-headers.md +1 -1
- package/catalog/frontmcp-config/examples/configure-skills-http/audit-log-basic.md +76 -0
- package/catalog/frontmcp-config/examples/configure-skills-http/audit-log-redis.md +116 -0
- package/catalog/frontmcp-config/examples/configure-skills-http/inject-instructions.md +59 -0
- package/catalog/frontmcp-config/references/configure-auth-modes.md +5 -5
- package/catalog/frontmcp-config/references/configure-deployment-targets.md +27 -24
- package/catalog/frontmcp-config/references/configure-http.md +14 -10
- package/catalog/frontmcp-config/references/configure-security-headers.md +2 -2
- package/catalog/frontmcp-config/references/configure-session.md +25 -25
- package/catalog/frontmcp-config/references/configure-skills-http.md +157 -0
- package/catalog/frontmcp-config/references/configure-throttle.md +1 -1
- package/catalog/frontmcp-config/references/configure-transport.md +2 -2
- package/catalog/frontmcp-deployment/SKILL.md +112 -9
- package/catalog/frontmcp-deployment/examples/build-for-browser/browser-build-with-custom-entry.md +23 -11
- package/catalog/frontmcp-deployment/examples/build-for-browser/browser-crypto-and-storage.md +44 -17
- package/catalog/frontmcp-deployment/examples/build-for-browser/react-provider-setup.md +53 -21
- package/catalog/frontmcp-deployment/examples/build-for-cli/cli-binary-build.md +1 -1
- package/catalog/frontmcp-deployment/examples/build-for-cli/unix-socket-daemon.md +1 -1
- package/catalog/frontmcp-deployment/examples/build-for-mcpb/mcpb-bundle-build.md +1 -1
- package/catalog/frontmcp-deployment/examples/build-for-sdk/connect-openai.md +1 -1
- package/catalog/frontmcp-deployment/examples/build-for-sdk/multi-platform-connect.md +1 -1
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/basic-worker-deploy.md +7 -8
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-custom-domain.md +8 -6
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-with-kv-storage.md +5 -4
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/cdk-deployment.md +8 -5
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/lambda-handler-with-cors.md +20 -18
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/sam-template-basic.md +8 -5
- package/catalog/frontmcp-deployment/examples/deploy-to-node/docker-compose-with-redis.md +3 -3
- package/catalog/frontmcp-deployment/examples/deploy-to-node/pm2-with-nginx.md +1 -1
- package/catalog/frontmcp-deployment/examples/deploy-to-node/resource-limits.md +2 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/basic-multistage-dockerfile.md +2 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/secure-nonroot-dockerfile.md +1 -1
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-mcp-endpoint-test.md +23 -21
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +25 -22
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-skills-cache.md +23 -30
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/minimal-vercel-config.md +52 -28
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/vercel-config-with-security-headers.md +32 -55
- package/catalog/frontmcp-deployment/examples/mcp-client-integration/http-remote.md +9 -0
- package/catalog/frontmcp-deployment/references/build-for-browser.md +40 -17
- package/catalog/frontmcp-deployment/references/build-for-cli.md +8 -8
- package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +43 -24
- package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +36 -25
- package/catalog/frontmcp-deployment/references/deploy-to-node-dockerfile.md +56 -14
- package/catalog/frontmcp-deployment/references/deploy-to-node.md +9 -6
- package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +57 -58
- package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +49 -59
- package/catalog/frontmcp-deployment/references/mcp-client-integration.md +2 -0
- package/catalog/frontmcp-development/SKILL.md +186 -11
- package/catalog/frontmcp-development/examples/create-agent/custom-multi-pass-agent.md +1 -1
- package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +30 -27
- package/catalog/frontmcp-development/examples/create-job/job-with-permissions.md +13 -8
- package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +33 -23
- package/catalog/frontmcp-development/examples/create-provider/config-and-api-providers.md +19 -10
- package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +3 -3
- package/catalog/frontmcp-development/examples/create-workflow/webhook-triggered-workflow.md +6 -4
- package/catalog/frontmcp-development/examples/decorators-guide/agent-skill-job-workflow.md +1 -1
- package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md +13 -8
- package/catalog/frontmcp-development/examples/decorators-guide/multi-app-with-plugins-and-providers.md +50 -23
- package/catalog/frontmcp-development/references/create-agent.md +47 -30
- package/catalog/frontmcp-development/references/create-job.md +69 -54
- package/catalog/frontmcp-development/references/create-plugin-hooks.md +45 -28
- package/catalog/frontmcp-development/references/create-plugin.md +10 -8
- package/catalog/frontmcp-development/references/create-prompt.md +3 -3
- package/catalog/frontmcp-development/references/create-provider.md +91 -51
- package/catalog/frontmcp-development/references/create-resource.md +3 -3
- package/catalog/frontmcp-development/references/create-skill.md +2 -2
- package/catalog/frontmcp-development/references/create-tool.md +7 -7
- package/catalog/frontmcp-development/references/create-workflow.md +8 -10
- package/catalog/frontmcp-development/references/decorators-guide.md +92 -56
- package/catalog/frontmcp-development/references/official-plugins.md +4 -3
- package/catalog/frontmcp-development/references/openapi-adapter.md +1 -1
- package/catalog/frontmcp-extensibility/SKILL.md +70 -10
- package/catalog/frontmcp-extensibility/examples/skill-audit-log/custom-store.md +197 -0
- package/catalog/frontmcp-extensibility/examples/skill-audit-log/verify-chain.md +68 -0
- package/catalog/frontmcp-extensibility/examples/vectoriadb/product-catalog-search.md +3 -5
- package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md +4 -11
- package/catalog/frontmcp-extensibility/examples/vectoriadb/tfidf-keyword-search.md +41 -30
- package/catalog/frontmcp-extensibility/references/skill-audit-log.md +233 -0
- package/catalog/frontmcp-extensibility/references/vectoriadb.md +73 -63
- package/catalog/frontmcp-guides/SKILL.md +84 -27
- package/catalog/frontmcp-guides/examples/example-knowledge-base/agent-and-plugin.md +72 -62
- package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md +32 -43
- package/catalog/frontmcp-guides/examples/example-task-manager/auth-and-crud-tools.md +24 -17
- package/catalog/frontmcp-guides/examples/example-task-manager/authenticated-e2e-tests.md +23 -21
- package/catalog/frontmcp-guides/examples/example-task-manager/redis-provider-with-di.md +47 -39
- package/catalog/frontmcp-guides/examples/example-weather-api/server-and-app-setup.md +16 -6
- package/catalog/frontmcp-guides/examples/example-weather-api/unit-and-e2e-tests.md +9 -8
- package/catalog/frontmcp-guides/references/example-knowledge-base.md +192 -265
- package/catalog/frontmcp-guides/references/example-task-manager.md +60 -54
- package/catalog/frontmcp-guides/references/example-weather-api.md +22 -24
- package/catalog/frontmcp-observability/SKILL.md +66 -2
- package/catalog/frontmcp-observability/examples/telemetry-api/skill-counters.md +100 -0
- package/catalog/frontmcp-observability/examples/tracing-setup/production-tracing.md +7 -2
- package/catalog/frontmcp-observability/examples/vendor-integrations/coralogix-setup.md +6 -2
- package/catalog/frontmcp-observability/references/telemetry-api.md +72 -8
- package/catalog/frontmcp-observability/references/testing-observability.md +33 -49
- package/catalog/frontmcp-observability/references/tracing-setup.md +12 -5
- package/catalog/frontmcp-observability/references/vendor-integrations.md +46 -1
- package/catalog/frontmcp-production-readiness/SKILL.md +134 -3
- package/catalog/frontmcp-production-readiness/examples/common-checklist/caching-and-performance.md +57 -36
- package/catalog/frontmcp-production-readiness/examples/common-checklist/observability-setup.md +1 -1
- package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +102 -6
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/daemon-socket-config.md +2 -1
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/graceful-shutdown-cleanup.md +66 -58
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/security-and-permissions.md +5 -3
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/durable-objects-state.md +2 -1
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/wrangler-config.md +55 -76
- package/catalog/frontmcp-production-readiness/examples/production-lambda/cold-start-connection-reuse.md +43 -40
- package/catalog/frontmcp-production-readiness/examples/production-lambda/sam-template.md +63 -94
- package/catalog/frontmcp-production-readiness/examples/production-lambda/scaling-and-monitoring.md +28 -18
- package/catalog/frontmcp-production-readiness/examples/production-node-sdk/multi-instance-cleanup.md +29 -14
- package/catalog/frontmcp-production-readiness/examples/production-node-server/graceful-shutdown.md +58 -42
- package/catalog/frontmcp-production-readiness/examples/production-node-server/redis-session-scaling.md +5 -2
- package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md +41 -24
- package/catalog/frontmcp-production-readiness/examples/production-vercel/vercel-edge-config.md +56 -65
- package/catalog/frontmcp-production-readiness/references/common-checklist.md +17 -5
- package/catalog/frontmcp-production-readiness/references/production-cli-daemon.md +5 -5
- package/catalog/frontmcp-production-readiness/references/production-cloudflare.md +5 -5
- package/catalog/frontmcp-production-readiness/references/production-lambda.md +5 -5
- package/catalog/frontmcp-production-readiness/references/production-node-sdk.md +5 -5
- package/catalog/frontmcp-production-readiness/references/production-node-server.md +1 -1
- package/catalog/frontmcp-production-readiness/references/production-vercel.md +5 -5
- package/catalog/frontmcp-setup/SKILL.md +88 -0
- package/catalog/frontmcp-setup/examples/project-structure-nx/nx-workspace-with-apps.md +10 -4
- package/catalog/frontmcp-setup/examples/project-structure-standalone/dev-workflow-commands.md +21 -8
- package/catalog/frontmcp-setup/examples/readme-guide/node-server-readme.md +3 -3
- package/catalog/frontmcp-setup/references/multi-app-composition.md +4 -3
- package/catalog/frontmcp-setup/references/project-structure-nx.md +15 -6
- package/catalog/frontmcp-setup/references/project-structure-standalone.md +18 -15
- package/catalog/frontmcp-setup/references/readme-guide.md +1 -1
- package/catalog/frontmcp-setup/references/setup-project.md +19 -5
- package/catalog/frontmcp-setup/references/setup-redis.md +27 -39
- package/catalog/frontmcp-setup/references/setup-sqlite.md +25 -18
- package/catalog/frontmcp-testing/SKILL.md +102 -15
- package/catalog/frontmcp-testing/examples/setup-testing/unit-test-tool-resource-prompt.md +3 -3
- package/catalog/frontmcp-testing/examples/test-auth/oauth-flow-test.md +50 -39
- package/catalog/frontmcp-testing/examples/test-auth/role-based-access-test.md +52 -29
- package/catalog/frontmcp-testing/examples/test-auth/token-factory-test.md +37 -20
- package/catalog/frontmcp-testing/examples/test-direct-client/basic-create-test.md +25 -15
- package/catalog/frontmcp-testing/examples/test-direct-client/openai-claude-format-test.md +27 -21
- package/catalog/frontmcp-testing/examples/test-e2e-handler/basic-e2e-test.md +29 -20
- package/catalog/frontmcp-testing/examples/test-e2e-handler/manual-client-with-transport.md +5 -3
- package/catalog/frontmcp-testing/examples/test-e2e-handler/tool-call-and-error-e2e.md +35 -26
- package/catalog/frontmcp-testing/examples/test-tool-unit/basic-tool-test.md +8 -3
- package/catalog/frontmcp-testing/examples/test-tool-unit/schema-validation-test.md +4 -1
- package/catalog/frontmcp-testing/examples/test-tool-unit/tool-error-handling-test.md +6 -3
- package/catalog/frontmcp-testing/references/setup-testing.md +35 -39
- package/catalog/frontmcp-testing/references/test-auth.md +86 -43
- package/catalog/frontmcp-testing/references/test-browser-build.md +1 -1
- package/catalog/frontmcp-testing/references/test-direct-client.md +29 -19
- package/catalog/frontmcp-testing/references/test-e2e-handler.md +31 -19
- package/catalog/frontmcp-testing/references/test-tool-unit.md +6 -2
- package/catalog/skills-manifest.json +428 -339
- package/package.json +1 -1
- package/src/manifest.d.ts +13 -0
- 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
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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:
|
|
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
|
-
|
|
395
|
-
|
|
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
|
|
570
|
-
| Swarm
|
|
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
|
-
- [ ]
|
|
605
|
+
- [ ] Visible peers appear as `use-agent:<id>` tools to the orchestrator agent
|
|
589
606
|
|
|
590
607
|
## Troubleshooting
|
|
591
608
|
|
|
592
|
-
| Problem | Cause
|
|
593
|
-
| ----------------------------------- |
|
|
594
|
-
| Agent not appearing in tool listing | Not registered in `agents` array
|
|
595
|
-
| LLM authentication error | API key not set or incorrect env variable
|
|
596
|
-
| Inner tools not being called | Tools not listed in `tools` array of `@Agent`
|
|
597
|
-
| Agent times out | No timeout or rate limit configured
|
|
598
|
-
|
|
|
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
|
|
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` | `
|
|
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` | `
|
|
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` | `
|
|
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.
|
|
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
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
480
|
-
roles: ['admin', 'data-engineer'],
|
|
481
|
-
|
|
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
|
|
572
|
-
| ----------------- |
|
|
573
|
-
| Progress tracking | `this.progress(50, 100, 'Processing batch 5')`
|
|
574
|
-
| Retry config | `retry: { maxAttempts: 3, backoffMs: 2000, backoffMultiplier: 2 }`
|
|
575
|
-
| Attempt awareness | Check `this.attempt` for retry-specific logic
|
|
576
|
-
| Job logging | `this.log('message')` for persistent, queryable logs
|
|
577
|
-
| Permissions |
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
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,
|
|
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
|
-
|
|
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 {
|
|
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
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
**
|
|
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 {
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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 {
|
|
378
|
+
import { App, FrontMcp } from '@frontmcp/sdk';
|
|
379
379
|
|
|
380
380
|
@App({
|
|
381
381
|
name: 'my-app',
|