@frontmcp/skills 1.1.2-beta.1 → 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.
- 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
|
@@ -2,18 +2,23 @@
|
|
|
2
2
|
name: nested-agents-with-swarm
|
|
3
3
|
reference: create-agent
|
|
4
4
|
level: advanced
|
|
5
|
-
description:
|
|
6
|
-
tags:
|
|
5
|
+
description: Composing specialized agents into a swarm where an orchestrator can discover and call peers at runtime as `use-agent:<id>` tools. Routing is driven by the orchestrator's LLM, not a declarative handoff table.
|
|
6
|
+
tags:
|
|
7
|
+
- development
|
|
8
|
+
- agent
|
|
9
|
+
- nested
|
|
10
|
+
- agents
|
|
11
|
+
- swarm
|
|
7
12
|
features:
|
|
8
|
-
-
|
|
9
|
-
- '
|
|
10
|
-
-
|
|
11
|
-
-
|
|
13
|
+
- 'Setting `swarm: { canSeeOtherAgents: true, visibleAgents: [...] }` on the orchestrator so peers appear as `use-agent:*` tools'
|
|
14
|
+
- 'Setting `swarm: { isVisible: true }` (the default) on specialist peers so they can be called'
|
|
15
|
+
- Routing is driven by the orchestrator LLM choosing among `use-agent:<peer>` tools, not by a declarative handoff table
|
|
16
|
+
- Each agent has its own `llm` config, `tools`, and `systemInstructions` for specialization
|
|
12
17
|
---
|
|
13
18
|
|
|
14
|
-
#
|
|
19
|
+
# Multi-Agent Swarm Visibility
|
|
15
20
|
|
|
16
|
-
Composing specialized
|
|
21
|
+
Composing specialized agents into a swarm where an orchestrator can discover and call peers at runtime as `use-agent:<id>` tools. Routing is driven by the orchestrator's LLM, not a declarative handoff table.
|
|
17
22
|
|
|
18
23
|
## Code
|
|
19
24
|
|
|
@@ -33,14 +38,13 @@ class LookupInvoiceTool extends ToolContext {
|
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
@Agent({
|
|
41
|
+
id: 'billing_agent',
|
|
36
42
|
name: 'billing_agent',
|
|
37
43
|
description: 'Handles billing and payment inquiries',
|
|
38
44
|
llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
|
|
39
45
|
tools: [LookupInvoiceTool],
|
|
40
|
-
swarm
|
|
41
|
-
|
|
42
|
-
handoff: [{ agent: 'triage_agent', condition: 'Request is outside billing scope' }],
|
|
43
|
-
},
|
|
46
|
+
// isVisible defaults to true; specialists do not need swarm config to be callable.
|
|
47
|
+
swarm: { isVisible: true },
|
|
44
48
|
})
|
|
45
49
|
class BillingAgent extends AgentContext {}
|
|
46
50
|
```
|
|
@@ -50,14 +54,12 @@ class BillingAgent extends AgentContext {}
|
|
|
50
54
|
import { Agent, AgentContext } from '@frontmcp/sdk';
|
|
51
55
|
|
|
52
56
|
@Agent({
|
|
57
|
+
id: 'technical_agent',
|
|
53
58
|
name: 'technical_agent',
|
|
54
59
|
description: 'Handles technical support issues',
|
|
55
60
|
llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
|
|
56
61
|
systemInstructions: 'You are a technical support specialist. Diagnose issues and provide solutions.',
|
|
57
|
-
swarm: {
|
|
58
|
-
role: 'specialist',
|
|
59
|
-
handoff: [{ agent: 'triage_agent', condition: 'Request is outside technical scope' }],
|
|
60
|
-
},
|
|
62
|
+
swarm: { isVisible: true },
|
|
61
63
|
})
|
|
62
64
|
class TechnicalAgent extends AgentContext {}
|
|
63
65
|
```
|
|
@@ -67,20 +69,21 @@ class TechnicalAgent extends AgentContext {}
|
|
|
67
69
|
import { Agent, AgentContext, z } from '@frontmcp/sdk';
|
|
68
70
|
|
|
69
71
|
@Agent({
|
|
72
|
+
id: 'triage_agent',
|
|
70
73
|
name: 'triage_agent',
|
|
71
|
-
description: 'Triages incoming requests and
|
|
74
|
+
description: 'Triages incoming requests and delegates to specialists',
|
|
72
75
|
llm: { provider: 'anthropic', model: 'claude-sonnet-4-20250514', apiKey: { env: 'ANTHROPIC_API_KEY' } },
|
|
73
76
|
inputSchema: {
|
|
74
77
|
request: z.string().describe('The incoming user request'),
|
|
75
78
|
},
|
|
79
|
+
// Orchestrator: opts in to seeing peers and (optionally) restricts to a whitelist.
|
|
76
80
|
swarm: {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
{ agent: 'technical_agent', condition: 'Request is about technical issues' },
|
|
81
|
-
],
|
|
81
|
+
canSeeOtherAgents: true,
|
|
82
|
+
visibleAgents: ['billing_agent', 'technical_agent'],
|
|
83
|
+
maxCallDepth: 3,
|
|
82
84
|
},
|
|
83
|
-
systemInstructions:
|
|
85
|
+
systemInstructions:
|
|
86
|
+
'Analyze the request and delegate by calling either use-agent:billing_agent (for billing/payments) or use-agent:technical_agent (for technical issues).',
|
|
84
87
|
})
|
|
85
88
|
class TriageAgent extends AgentContext {}
|
|
86
89
|
```
|
|
@@ -98,12 +101,12 @@ class SupportApp {}
|
|
|
98
101
|
|
|
99
102
|
## What This Demonstrates
|
|
100
103
|
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
+
- Setting `swarm: { canSeeOtherAgents: true, visibleAgents: [...] }` on the orchestrator so peers appear as `use-agent:*` tools
|
|
105
|
+
- Setting `swarm: { isVisible: true }` (the default) on specialist peers so they can be called
|
|
106
|
+
- Routing is driven by the orchestrator LLM choosing among `use-agent:<peer>` tools, not by a declarative handoff table
|
|
104
107
|
- Each agent has its own `llm` config, `tools`, and `systemInstructions` for specialization
|
|
105
108
|
|
|
106
109
|
## Related
|
|
107
110
|
|
|
108
|
-
- See `create-agent` for
|
|
111
|
+
- See `create-agent` for the full swarm field reference and inner-tool composition
|
|
109
112
|
- See `create-agent-llm-config` for using different LLM providers per agent
|
|
@@ -5,7 +5,7 @@ level: advanced
|
|
|
5
5
|
description: 'A data export job with declarative permission controls, plus a function-style job for simple tasks.'
|
|
6
6
|
tags: [development, redis, job, permissions]
|
|
7
7
|
features:
|
|
8
|
-
- 'Declarative `permissions`
|
|
8
|
+
- 'Declarative `permissions` as an array of `{ action, roles, scopes, custom }` rules'
|
|
9
9
|
- 'Using `tags` and `labels` for categorization and filtering'
|
|
10
10
|
- 'The `job()` function builder for simple jobs that need no class'
|
|
11
11
|
- 'Full server registration with `jobs.enabled: true` and a Redis store'
|
|
@@ -34,12 +34,17 @@ import { Job, job, JobContext, z } from '@frontmcp/sdk';
|
|
|
34
34
|
},
|
|
35
35
|
tags: ['export', 'data'],
|
|
36
36
|
labels: { team: 'data-engineering', priority: 'high' },
|
|
37
|
-
permissions:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
permissions: [
|
|
38
|
+
{
|
|
39
|
+
action: 'execute',
|
|
40
|
+
roles: ['admin', 'data-engineer'],
|
|
41
|
+
scopes: ['jobs:write', 'data:export'],
|
|
42
|
+
custom: (authInfo) => (authInfo as { department?: string }).department === 'engineering',
|
|
43
|
+
},
|
|
44
|
+
{ action: 'create', roles: ['admin', 'data-engineer'] },
|
|
45
|
+
{ action: 'read', roles: ['admin', 'data-engineer', 'auditor'] },
|
|
46
|
+
{ action: 'list', roles: ['admin', 'data-engineer', 'auditor'] },
|
|
47
|
+
],
|
|
43
48
|
})
|
|
44
49
|
class DataExportJob extends JobContext {
|
|
45
50
|
async execute(input: { dataset: string; destination: string }) {
|
|
@@ -106,7 +111,7 @@ class DataServer {}
|
|
|
106
111
|
|
|
107
112
|
## What This Demonstrates
|
|
108
113
|
|
|
109
|
-
- Declarative `permissions`
|
|
114
|
+
- Declarative `permissions` as an array of `{ action, roles, scopes, custom }` rules
|
|
110
115
|
- Using `tags` and `labels` for categorization and filtering
|
|
111
116
|
- The `job()` function builder for simple jobs that need no class
|
|
112
117
|
- Full server registration with `jobs.enabled: true` and a Redis store
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
name: basic-database-provider
|
|
3
3
|
reference: create-provider
|
|
4
4
|
level: basic
|
|
5
|
-
description:
|
|
5
|
+
description: A provider that manages a database connection pool, bound through `AsyncProvider({ useFactory })` so the pool is opened before any tool runs.
|
|
6
6
|
tags: [development, database, provider]
|
|
7
7
|
features:
|
|
8
8
|
- 'Defining a typed token with `Token<T>` using a `Symbol` for DI identification'
|
|
9
|
-
- 'Using
|
|
9
|
+
- 'Using `AsyncProvider({ provide, name, scope, useFactory })` so async setup completes before tool execution'
|
|
10
10
|
- 'Consuming the provider in a tool via `this.get(DB_TOKEN)` with full type safety'
|
|
11
|
-
- 'Registering the
|
|
11
|
+
- 'Registering the factory in the `providers` array so tools can resolve it'
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
# Basic Database Provider with
|
|
14
|
+
# Basic Database Provider with Async Setup
|
|
15
15
|
|
|
16
|
-
A provider that manages a database connection pool
|
|
16
|
+
A provider that manages a database connection pool, bound through `AsyncProvider({ useFactory })` so the pool is opened before any tool runs.
|
|
17
17
|
|
|
18
18
|
## Code
|
|
19
19
|
|
|
@@ -31,20 +31,14 @@ export const DB_TOKEN: Token<DatabaseService> = Symbol('DatabaseService');
|
|
|
31
31
|
|
|
32
32
|
```typescript
|
|
33
33
|
// src/apps/main/providers/database.provider.ts
|
|
34
|
-
import { createPool, Pool } from 'your-db-driver';
|
|
34
|
+
import { createPool, type Pool } from 'your-db-driver';
|
|
35
35
|
|
|
36
|
-
import {
|
|
36
|
+
import { AsyncProvider, ProviderScope } from '@frontmcp/sdk';
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
class DatabaseProvider implements DatabaseService {
|
|
40
|
-
private pool!: Pool;
|
|
38
|
+
import { DB_TOKEN, type DatabaseService } from '../tokens';
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
connectionString: process.env.DATABASE_URL,
|
|
45
|
-
max: 20,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
40
|
+
class DatabasePool implements DatabaseService {
|
|
41
|
+
constructor(private readonly pool: Pool) {}
|
|
48
42
|
|
|
49
43
|
async query(sql: string, params?: unknown[]) {
|
|
50
44
|
return this.pool.query(sql, params);
|
|
@@ -53,11 +47,24 @@ class DatabaseProvider implements DatabaseService {
|
|
|
53
47
|
async close() {
|
|
54
48
|
await this.pool.end();
|
|
55
49
|
}
|
|
56
|
-
|
|
57
|
-
async onDestroy() {
|
|
58
|
-
await this.pool.end();
|
|
59
|
-
}
|
|
60
50
|
}
|
|
51
|
+
|
|
52
|
+
// `@Provider` does NOT support `onInit`/`onDestroy` lifecycle hooks. For async
|
|
53
|
+
// setup, register the dependency via `AsyncProvider({ useFactory })` — the
|
|
54
|
+
// framework awaits `useFactory` before any tool can resolve the token.
|
|
55
|
+
export const databaseProvider = AsyncProvider({
|
|
56
|
+
provide: DB_TOKEN,
|
|
57
|
+
name: 'DatabaseProvider',
|
|
58
|
+
scope: ProviderScope.GLOBAL,
|
|
59
|
+
inject: () => [] as const,
|
|
60
|
+
useFactory: async (): Promise<DatabaseService> => {
|
|
61
|
+
const pool = await createPool({
|
|
62
|
+
connectionString: process.env.DATABASE_URL,
|
|
63
|
+
max: 20,
|
|
64
|
+
});
|
|
65
|
+
return new DatabasePool(pool);
|
|
66
|
+
},
|
|
67
|
+
});
|
|
61
68
|
```
|
|
62
69
|
|
|
63
70
|
```typescript
|
|
@@ -93,9 +100,12 @@ class QueryUsersTool extends ToolContext {
|
|
|
93
100
|
// src/apps/main/index.ts
|
|
94
101
|
import { App } from '@frontmcp/sdk';
|
|
95
102
|
|
|
103
|
+
import { databaseProvider } from './providers/database.provider';
|
|
104
|
+
import QueryUsersTool from './tools/query-users.tool';
|
|
105
|
+
|
|
96
106
|
@App({
|
|
97
107
|
name: 'main',
|
|
98
|
-
providers: [
|
|
108
|
+
providers: [databaseProvider],
|
|
99
109
|
tools: [QueryUsersTool],
|
|
100
110
|
})
|
|
101
111
|
class MainApp {}
|
|
@@ -104,9 +114,9 @@ class MainApp {}
|
|
|
104
114
|
## What This Demonstrates
|
|
105
115
|
|
|
106
116
|
- Defining a typed token with `Token<T>` using a `Symbol` for DI identification
|
|
107
|
-
- Using
|
|
117
|
+
- Using `AsyncProvider({ provide, name, scope, useFactory })` so async setup completes before tool execution
|
|
108
118
|
- Consuming the provider in a tool via `this.get(DB_TOKEN)` with full type safety
|
|
109
|
-
- Registering the
|
|
119
|
+
- Registering the factory in the `providers` array so tools can resolve it
|
|
110
120
|
|
|
111
121
|
## Related
|
|
112
122
|
|
|
@@ -5,8 +5,8 @@ level: intermediate
|
|
|
5
5
|
description: 'A configuration provider with readonly environment settings and an HTTP API client provider.'
|
|
6
6
|
tags: [development, provider, config, api, providers]
|
|
7
7
|
features:
|
|
8
|
-
- 'A configuration provider using `readonly` properties from environment variables (
|
|
9
|
-
- 'An API client provider
|
|
8
|
+
- 'A configuration provider using `readonly` properties from environment variables (sync construction)'
|
|
9
|
+
- 'An API client provider that reads credentials in the constructor (no `onInit` — `@Provider` has no lifecycle hooks)'
|
|
10
10
|
- 'Registering providers at `@FrontMcp` level for server-wide sharing across all apps'
|
|
11
11
|
- 'Separating token definitions from provider implementations for clean dependency boundaries'
|
|
12
12
|
---
|
|
@@ -40,6 +40,7 @@ export const API_TOKEN: Token<ApiClient> = Symbol('ApiClient');
|
|
|
40
40
|
```typescript
|
|
41
41
|
// src/apps/main/providers/config.provider.ts
|
|
42
42
|
import { Provider } from '@frontmcp/sdk';
|
|
43
|
+
|
|
43
44
|
import type { AppConfig } from '../tokens';
|
|
44
45
|
|
|
45
46
|
@Provider({ name: 'ConfigProvider' })
|
|
@@ -53,16 +54,24 @@ class ConfigProvider implements AppConfig {
|
|
|
53
54
|
```typescript
|
|
54
55
|
// src/apps/main/providers/api-client.provider.ts
|
|
55
56
|
import { Provider } from '@frontmcp/sdk';
|
|
57
|
+
|
|
56
58
|
import type { ApiClient } from '../tokens';
|
|
57
59
|
|
|
58
60
|
@Provider({ name: 'ApiClientProvider' })
|
|
59
61
|
class ApiClientProvider implements ApiClient {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
// `@Provider` has no `onInit` lifecycle hook — read env in the constructor.
|
|
63
|
+
// First instantiation throws synchronously on missing config (fail fast).
|
|
64
|
+
private readonly baseUrl: string;
|
|
65
|
+
private readonly apiKey: string;
|
|
66
|
+
|
|
67
|
+
constructor() {
|
|
68
|
+
const baseUrl = process.env.API_URL;
|
|
69
|
+
const apiKey = process.env.API_KEY;
|
|
70
|
+
if (!baseUrl || !apiKey) {
|
|
71
|
+
throw new Error('ApiClientProvider: API_URL and API_KEY must be set');
|
|
72
|
+
}
|
|
73
|
+
this.baseUrl = baseUrl;
|
|
74
|
+
this.apiKey = apiKey;
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
async get(path: string) {
|
|
@@ -97,8 +106,8 @@ class MyServer {}
|
|
|
97
106
|
|
|
98
107
|
## What This Demonstrates
|
|
99
108
|
|
|
100
|
-
- A configuration provider using `readonly` properties from environment variables (
|
|
101
|
-
- An API client provider
|
|
109
|
+
- A configuration provider using `readonly` properties from environment variables (sync construction)
|
|
110
|
+
- An API client provider that reads credentials in the constructor (no `onInit` — `@Provider` has no lifecycle hooks)
|
|
102
111
|
- Registering providers at `@FrontMcp` level for server-wide sharing across all apps
|
|
103
112
|
- Separating token definitions from provider implementations for clean dependency boundaries
|
|
104
113
|
|
package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md
CHANGED
|
@@ -6,7 +6,7 @@ description: 'A batch processing tool that uses rate limiting, concurrency contr
|
|
|
6
6
|
tags: [development, throttle, tool, rate, limiting, progress]
|
|
7
7
|
features:
|
|
8
8
|
- 'Configuring `rateLimit`, `concurrency`, and `timeout` for throttling protection'
|
|
9
|
-
- 'Sending progress updates to the client with `this.
|
|
9
|
+
- 'Sending progress updates to the client with `this.progress(progress, total, message?)`'
|
|
10
10
|
- 'Using `this.mark(stage)` for execution stage tracking and debugging'
|
|
11
11
|
- 'Sending log-level notifications with `this.notify(message, level)`'
|
|
12
12
|
- 'Setting tool `annotations` to communicate behavioral hints to clients'
|
|
@@ -52,7 +52,7 @@ class BatchProcessTool extends ToolContext {
|
|
|
52
52
|
this.mark('processing');
|
|
53
53
|
const results: string[] = [];
|
|
54
54
|
for (let i = 0; i < input.items.length; i++) {
|
|
55
|
-
await this.
|
|
55
|
+
await this.progress(i + 1, input.items.length, `Processing item ${i + 1}`);
|
|
56
56
|
const result = await this.processItem(input.items[i]);
|
|
57
57
|
results.push(result);
|
|
58
58
|
}
|
|
@@ -82,7 +82,7 @@ class MainApp {}
|
|
|
82
82
|
## What This Demonstrates
|
|
83
83
|
|
|
84
84
|
- Configuring `rateLimit`, `concurrency`, and `timeout` for throttling protection
|
|
85
|
-
- Sending progress updates to the client with `this.
|
|
85
|
+
- Sending progress updates to the client with `this.progress(progress, total, message?)`
|
|
86
86
|
- Using `this.mark(stage)` for execution stage tracking and debugging
|
|
87
87
|
- Sending log-level notifications with `this.notify(message, level)`
|
|
88
88
|
- Setting tool `annotations` to communicate behavioral hints to clients
|
|
@@ -33,10 +33,12 @@ import { Workflow } from '@frontmcp/sdk';
|
|
|
33
33
|
},
|
|
34
34
|
timeout: 900000, // 15 minutes
|
|
35
35
|
maxConcurrency: 3,
|
|
36
|
-
permissions:
|
|
37
|
-
|
|
38
|
-
roles: ['admin', 'ci-bot'],
|
|
39
|
-
|
|
36
|
+
permissions: [
|
|
37
|
+
{ action: 'execute', roles: ['admin', 'ci-bot'] },
|
|
38
|
+
{ action: 'create', roles: ['admin', 'ci-bot'] },
|
|
39
|
+
{ action: 'read', roles: ['admin', 'ci-bot'] },
|
|
40
|
+
{ action: 'list', roles: ['admin', 'ci-bot'] },
|
|
41
|
+
],
|
|
40
42
|
steps: [
|
|
41
43
|
{
|
|
42
44
|
id: 'build',
|
package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md
CHANGED
|
@@ -7,8 +7,8 @@ tags: [development, decorators, app, tools]
|
|
|
7
7
|
features:
|
|
8
8
|
- 'The `@FrontMcp` -> `@App` -> `@Tool`/`@Resource`/`@Prompt` nesting hierarchy'
|
|
9
9
|
- 'Tool classes extend `ToolContext` and implement `execute()`'
|
|
10
|
-
- 'Resource classes extend `ResourceContext` and implement `
|
|
11
|
-
- 'Prompt classes extend `PromptContext` and implement `execute()`'
|
|
10
|
+
- 'Resource classes extend `ResourceContext` and implement `execute(uri, params)`'
|
|
11
|
+
- 'Prompt classes extend `PromptContext` and implement `execute(args: Record<string, string>)`'
|
|
12
12
|
- 'Apps group related tools, resources, and prompts into logical modules'
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -49,9 +49,9 @@ import { Resource, ResourceContext } from '@frontmcp/sdk';
|
|
|
49
49
|
mimeType: 'application/json',
|
|
50
50
|
})
|
|
51
51
|
class AppConfigResource extends ResourceContext {
|
|
52
|
-
async
|
|
52
|
+
async execute(uri: string, _params: Record<string, string>) {
|
|
53
53
|
const config = await this.get(ConfigService).getAll();
|
|
54
|
-
return { contents: [{ uri
|
|
54
|
+
return { contents: [{ uri, text: JSON.stringify(config) }] };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
```
|
|
@@ -69,14 +69,19 @@ import { Prompt, PromptContext } from '@frontmcp/sdk';
|
|
|
69
69
|
],
|
|
70
70
|
})
|
|
71
71
|
class CodeReviewPrompt extends PromptContext {
|
|
72
|
-
|
|
72
|
+
// Prompt arguments arrive as Record<string, string> — coerce to other types as needed.
|
|
73
|
+
// Required-arg validation is performed before `execute()` is called, so `args.code`
|
|
74
|
+
// is guaranteed present here. The `language` fallback handles the optional arg.
|
|
75
|
+
async execute(args: Record<string, string>) {
|
|
76
|
+
const code = args.code;
|
|
77
|
+
const language = args.language ?? 'unknown';
|
|
73
78
|
return {
|
|
74
79
|
messages: [
|
|
75
80
|
{
|
|
76
81
|
role: 'user' as const,
|
|
77
82
|
content: {
|
|
78
83
|
type: 'text' as const,
|
|
79
|
-
text: `Review this ${
|
|
84
|
+
text: `Review this ${language} code:\n\n${code}`,
|
|
80
85
|
},
|
|
81
86
|
},
|
|
82
87
|
],
|
|
@@ -114,8 +119,8 @@ class MyServer {}
|
|
|
114
119
|
|
|
115
120
|
- The `@FrontMcp` -> `@App` -> `@Tool`/`@Resource`/`@Prompt` nesting hierarchy
|
|
116
121
|
- Tool classes extend `ToolContext` and implement `execute()`
|
|
117
|
-
- Resource classes extend `ResourceContext` and implement `
|
|
118
|
-
- Prompt classes extend `PromptContext` and implement `execute()`
|
|
122
|
+
- Resource classes extend `ResourceContext` and implement `execute(uri, params)`
|
|
123
|
+
- Prompt classes extend `PromptContext` and implement `execute(args: Record<string, string>)`
|
|
119
124
|
- Apps group related tools, resources, and prompts into logical modules
|
|
120
125
|
|
|
121
126
|
## Related
|
|
@@ -2,15 +2,21 @@
|
|
|
2
2
|
name: multi-app-with-plugins-and-providers
|
|
3
3
|
reference: decorators-guide
|
|
4
4
|
level: intermediate
|
|
5
|
-
description:
|
|
6
|
-
tags:
|
|
5
|
+
description: Demonstrates a server with multiple `@App` modules, a `@Provider` for dependency injection, and a `@Plugin` for cross-cutting concerns.
|
|
6
|
+
tags:
|
|
7
|
+
- development
|
|
8
|
+
- database
|
|
9
|
+
- multi-app
|
|
10
|
+
- decorators
|
|
11
|
+
- multi
|
|
12
|
+
- app
|
|
7
13
|
features:
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
+
- Organizing a server into multiple `@App` modules (`analytics` and `admin`)
|
|
15
|
+
- Decorating a service class with `@Provider({ name, scope })` so it acts as its own DI token (the strict schema rejects `useFactory`/`useClass`/`provide` — use `AsyncProvider` for those)
|
|
16
|
+
- Accessing injected dependencies via `this.get(DatabaseClient)` in tools and resources
|
|
17
|
+
- Using `@ResourceTemplate` with URI parameters (`{dashboardId}`) for dynamic resources
|
|
18
|
+
- Registering a `@Plugin` at the server level so it applies across all apps
|
|
19
|
+
- Global plugins go in `@FrontMcp({ plugins })`, app-scoped providers go in `@App({ providers })`
|
|
14
20
|
---
|
|
15
21
|
|
|
16
22
|
# Multi-App Server with Plugins and Providers
|
|
@@ -21,18 +27,39 @@ Demonstrates a server with multiple `@App` modules, a `@Provider` for dependency
|
|
|
21
27
|
|
|
22
28
|
```typescript
|
|
23
29
|
// src/providers/database.provider.ts
|
|
24
|
-
import { Provider } from '@frontmcp/sdk';
|
|
25
|
-
|
|
26
|
-
export const DatabaseToken = Symbol('Database');
|
|
30
|
+
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
27
31
|
|
|
32
|
+
// The @Provider decorator schema is strict: it accepts only `id|name|description|scope`.
|
|
33
|
+
// `provide`/`useClass`/`useValue`/`useFactory` are NOT supported.
|
|
34
|
+
// For simple cases, decorate the class itself — it becomes its own DI token.
|
|
28
35
|
@Provider({
|
|
29
|
-
name: '
|
|
30
|
-
|
|
31
|
-
useFactory: () => new DatabaseClient(process.env.DB_URL),
|
|
36
|
+
name: 'DatabaseClient',
|
|
37
|
+
scope: ProviderScope.GLOBAL,
|
|
32
38
|
})
|
|
33
|
-
class
|
|
39
|
+
export class DatabaseClient {
|
|
40
|
+
constructor(private readonly url = process.env.DB_URL) {}
|
|
41
|
+
|
|
42
|
+
async query(sql: string): Promise<unknown[]> {
|
|
43
|
+
/* ... */
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async getDataset(id: string): Promise<unknown[]> {
|
|
48
|
+
/* ... */
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async getDashboard(id: string): Promise<unknown> {
|
|
53
|
+
/* ... */
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
34
57
|
```
|
|
35
58
|
|
|
59
|
+
> If you need an async factory or want to bind to a separate token, use the
|
|
60
|
+
> `AsyncProvider({ provide, name, scope, inject, useFactory })` helper instead of
|
|
61
|
+
> the `@Provider` decorator.
|
|
62
|
+
|
|
36
63
|
```typescript
|
|
37
64
|
// src/plugins/audit.plugin.ts
|
|
38
65
|
import { Plugin } from '@frontmcp/sdk';
|
|
@@ -58,7 +85,7 @@ import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
|
58
85
|
})
|
|
59
86
|
class QueryTool extends ToolContext {
|
|
60
87
|
async execute(input: { sql: string }) {
|
|
61
|
-
const db = this.get(
|
|
88
|
+
const db = this.get(DatabaseClient);
|
|
62
89
|
const results = await db.query(input.sql);
|
|
63
90
|
return { rows: results };
|
|
64
91
|
}
|
|
@@ -79,7 +106,7 @@ import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
|
79
106
|
})
|
|
80
107
|
class ReportTool extends ToolContext {
|
|
81
108
|
async execute(input: { datasetId: string; format: string }) {
|
|
82
|
-
const db = this.get(
|
|
109
|
+
const db = this.get(DatabaseClient);
|
|
83
110
|
const data = await db.getDataset(input.datasetId);
|
|
84
111
|
return { report: `Report in ${input.format} format`, rows: data.length };
|
|
85
112
|
}
|
|
@@ -96,9 +123,9 @@ import { ResourceContext, ResourceTemplate } from '@frontmcp/sdk';
|
|
|
96
123
|
description: 'Dashboard data by ID',
|
|
97
124
|
mimeType: 'application/json',
|
|
98
125
|
})
|
|
99
|
-
class DashboardResource extends ResourceContext {
|
|
100
|
-
async
|
|
101
|
-
const db = this.get(
|
|
126
|
+
class DashboardResource extends ResourceContext<{ dashboardId: string }> {
|
|
127
|
+
async execute(uri: string, params: { dashboardId: string }) {
|
|
128
|
+
const db = this.get(DatabaseClient);
|
|
102
129
|
const data = await db.getDashboard(params.dashboardId);
|
|
103
130
|
return { contents: [{ uri, text: JSON.stringify(data) }] };
|
|
104
131
|
}
|
|
@@ -113,7 +140,7 @@ import { App, FrontMcp } from '@frontmcp/sdk';
|
|
|
113
140
|
name: 'analytics',
|
|
114
141
|
tools: [QueryTool, ReportTool],
|
|
115
142
|
resources: [DashboardResource],
|
|
116
|
-
providers: [
|
|
143
|
+
providers: [DatabaseClient],
|
|
117
144
|
})
|
|
118
145
|
class AnalyticsApp {}
|
|
119
146
|
|
|
@@ -135,8 +162,8 @@ class MyServer {}
|
|
|
135
162
|
## What This Demonstrates
|
|
136
163
|
|
|
137
164
|
- Organizing a server into multiple `@App` modules (`analytics` and `admin`)
|
|
138
|
-
-
|
|
139
|
-
- Accessing injected dependencies via `this.get(
|
|
165
|
+
- Decorating a service class with `@Provider({ name, scope })` so it acts as its own DI token (the strict schema rejects `useFactory`/`useClass`/`provide` — use `AsyncProvider` for those)
|
|
166
|
+
- Accessing injected dependencies via `this.get(DatabaseClient)` in tools and resources
|
|
140
167
|
- Using `@ResourceTemplate` with URI parameters (`{dashboardId}`) for dynamic resources
|
|
141
168
|
- Registering a `@Plugin` at the server level so it applies across all apps
|
|
142
169
|
- Global plugins go in `@FrontMcp({ plugins })`, app-scoped providers go in `@App({ providers })`
|