@frontmcp/skills 1.0.0-beta.13 → 1.0.0-beta.14
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 +55 -0
- package/catalog/frontmcp-config/SKILL.md +2 -2
- package/catalog/frontmcp-config/examples/configure-auth/multi-app-auth.md +87 -0
- package/catalog/frontmcp-config/examples/configure-auth/public-mode-setup.md +63 -0
- package/catalog/frontmcp-config/examples/configure-auth/remote-oauth-with-vault.md +76 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +77 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +73 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/transparent-jwt-validation.md +64 -0
- package/catalog/frontmcp-config/examples/configure-elicitation/basic-confirmation-gate.md +83 -0
- package/catalog/frontmcp-config/examples/configure-elicitation/distributed-elicitation-redis.md +87 -0
- package/catalog/frontmcp-config/examples/configure-http/cors-restricted-origins.md +52 -0
- package/catalog/frontmcp-config/examples/configure-http/entry-path-reverse-proxy.md +72 -0
- package/catalog/frontmcp-config/examples/configure-http/unix-socket-local.md +64 -0
- package/catalog/frontmcp-config/examples/configure-session/multi-server-key-prefix.md +68 -0
- package/catalog/frontmcp-config/examples/configure-session/redis-session-store.md +52 -0
- package/catalog/frontmcp-config/examples/configure-session/vercel-kv-session.md +52 -0
- package/catalog/frontmcp-config/examples/configure-throttle/distributed-redis-throttle.md +94 -0
- package/catalog/frontmcp-config/examples/configure-throttle/per-tool-rate-limit.md +92 -0
- package/catalog/frontmcp-config/examples/configure-throttle/server-level-rate-limit.md +83 -0
- package/catalog/frontmcp-config/examples/configure-throttle-guard-config/full-guard-config.md +99 -0
- package/catalog/frontmcp-config/examples/configure-throttle-guard-config/minimal-guard-config.md +55 -0
- package/catalog/frontmcp-config/examples/configure-transport/custom-protocol-flags.md +74 -0
- package/catalog/frontmcp-config/examples/configure-transport/distributed-sessions-redis.md +86 -0
- package/catalog/frontmcp-config/examples/configure-transport/stateless-serverless.md +69 -0
- package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/legacy-preset-nodejs.md +65 -0
- package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/stateless-api-serverless.md +69 -0
- package/catalog/frontmcp-config/references/configure-auth-modes.md +10 -0
- package/catalog/frontmcp-config/references/configure-auth.md +10 -0
- package/catalog/frontmcp-config/references/configure-elicitation.md +9 -0
- package/catalog/frontmcp-config/references/configure-http.md +10 -0
- package/catalog/frontmcp-config/references/configure-session.md +10 -0
- package/catalog/frontmcp-config/references/configure-throttle-guard-config.md +9 -0
- package/catalog/frontmcp-config/references/configure-throttle.md +10 -0
- package/catalog/frontmcp-config/references/configure-transport-protocol-presets.md +9 -0
- package/catalog/frontmcp-config/references/configure-transport.md +10 -0
- package/catalog/frontmcp-config/references/setup-redis.md +5 -0
- package/catalog/frontmcp-config/references/setup-sqlite.md +5 -0
- package/catalog/frontmcp-deployment/SKILL.md +2 -2
- package/catalog/frontmcp-deployment/examples/build-for-browser/browser-build-with-custom-entry.md +43 -0
- package/catalog/frontmcp-deployment/examples/build-for-browser/browser-crypto-and-storage.md +85 -0
- package/catalog/frontmcp-deployment/examples/build-for-browser/react-provider-setup.md +61 -0
- package/catalog/frontmcp-deployment/examples/build-for-cli/cli-binary-build.md +66 -0
- package/catalog/frontmcp-deployment/examples/build-for-cli/unix-socket-daemon.md +76 -0
- package/catalog/frontmcp-deployment/examples/build-for-sdk/connect-openai.md +78 -0
- package/catalog/frontmcp-deployment/examples/build-for-sdk/create-flat-config.md +85 -0
- package/catalog/frontmcp-deployment/examples/build-for-sdk/multi-platform-connect.md +104 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/basic-worker-deploy.md +82 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-custom-domain.md +97 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-with-kv-storage.md +92 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/cdk-deployment.md +92 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/lambda-handler-with-cors.md +113 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/sam-template-basic.md +100 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node/docker-compose-with-redis.md +101 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node/pm2-with-nginx.md +79 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node/resource-limits.md +92 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/basic-multistage-dockerfile.md +63 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/secure-nonroot-dockerfile.md +89 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-mcp-endpoint-test.md +69 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +82 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-skills-cache.md +90 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/minimal-vercel-config.md +49 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/vercel-config-with-security-headers.md +92 -0
- package/catalog/frontmcp-deployment/references/build-for-browser.md +10 -0
- package/catalog/frontmcp-deployment/references/build-for-cli.md +9 -0
- package/catalog/frontmcp-deployment/references/build-for-sdk.md +10 -0
- package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +10 -0
- package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +10 -0
- package/catalog/frontmcp-deployment/references/deploy-to-node-dockerfile.md +9 -0
- package/catalog/frontmcp-deployment/references/deploy-to-node.md +10 -0
- package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +9 -0
- package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +10 -0
- package/catalog/frontmcp-development/SKILL.md +2 -2
- package/catalog/frontmcp-development/examples/create-adapter/basic-api-adapter.md +92 -0
- package/catalog/frontmcp-development/examples/create-adapter/namespaced-adapter.md +124 -0
- package/catalog/frontmcp-development/examples/create-agent/basic-agent-with-tools.md +121 -0
- package/catalog/frontmcp-development/examples/create-agent/custom-multi-pass-agent.md +95 -0
- package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +111 -0
- package/catalog/frontmcp-development/examples/create-agent-llm-config/anthropic-config.md +81 -0
- package/catalog/frontmcp-development/examples/create-agent-llm-config/openai-config.md +80 -0
- package/catalog/frontmcp-development/examples/create-job/basic-report-job.md +87 -0
- package/catalog/frontmcp-development/examples/create-job/job-with-permissions.md +117 -0
- package/catalog/frontmcp-development/examples/create-job/job-with-retry.md +88 -0
- package/catalog/frontmcp-development/examples/create-plugin/basic-plugin-with-provider.md +69 -0
- package/catalog/frontmcp-development/examples/create-plugin/configurable-dynamic-plugin.md +178 -0
- package/catalog/frontmcp-development/examples/create-plugin/plugin-with-context-extension.md +107 -0
- package/catalog/frontmcp-development/examples/create-plugin-hooks/basic-logging-plugin.md +69 -0
- package/catalog/frontmcp-development/examples/create-plugin-hooks/caching-with-around.md +80 -0
- package/catalog/frontmcp-development/examples/create-plugin-hooks/tool-level-hooks-and-stage-replacement.md +100 -0
- package/catalog/frontmcp-development/examples/create-prompt/basic-prompt.md +72 -0
- package/catalog/frontmcp-development/examples/create-prompt/dynamic-rag-prompt.md +92 -0
- package/catalog/frontmcp-development/examples/create-prompt/multi-turn-debug-session.md +86 -0
- package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +113 -0
- package/catalog/frontmcp-development/examples/create-provider/config-and-api-providers.md +107 -0
- package/catalog/frontmcp-development/examples/create-resource/basic-static-resource.md +72 -0
- package/catalog/frontmcp-development/examples/create-resource/binary-and-multi-content.md +111 -0
- package/catalog/frontmcp-development/examples/create-resource/parameterized-template.md +84 -0
- package/catalog/frontmcp-development/examples/create-skill/basic-inline-skill.md +96 -0
- package/catalog/frontmcp-development/examples/create-skill/directory-based-skill.md +115 -0
- package/catalog/frontmcp-development/examples/create-skill/parameterized-skill.md +96 -0
- package/catalog/frontmcp-development/examples/create-skill-with-tools/basic-tool-orchestration.md +76 -0
- package/catalog/frontmcp-development/examples/create-skill-with-tools/directory-skill-with-tools.md +149 -0
- package/catalog/frontmcp-development/examples/create-skill-with-tools/incident-response-skill.md +92 -0
- package/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md +62 -0
- package/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md +84 -0
- package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +93 -0
- package/catalog/frontmcp-development/examples/create-tool-annotations/destructive-delete-tool.md +94 -0
- package/catalog/frontmcp-development/examples/create-tool-annotations/readonly-query-tool.md +60 -0
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/primitive-and-media-outputs.md +104 -0
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-raw-shape-output.md +63 -0
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-schema-advanced-output.md +103 -0
- package/catalog/frontmcp-development/examples/create-workflow/basic-deploy-pipeline.md +91 -0
- package/catalog/frontmcp-development/examples/create-workflow/parallel-validation-pipeline.md +90 -0
- package/catalog/frontmcp-development/examples/create-workflow/webhook-triggered-workflow.md +136 -0
- package/catalog/frontmcp-development/examples/decorators-guide/agent-skill-job-workflow.md +145 -0
- package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md +124 -0
- package/catalog/frontmcp-development/examples/decorators-guide/multi-app-with-plugins-and-providers.md +149 -0
- package/catalog/frontmcp-development/examples/official-adapters/authenticated-adapter-with-polling.md +84 -0
- package/catalog/frontmcp-development/examples/official-adapters/basic-openapi-adapter.md +54 -0
- package/catalog/frontmcp-development/examples/official-adapters/multi-api-hub-with-inline-spec.md +130 -0
- package/catalog/frontmcp-development/examples/official-plugins/cache-and-feature-flags.md +117 -0
- package/catalog/frontmcp-development/examples/official-plugins/production-multi-plugin-setup.md +147 -0
- package/catalog/frontmcp-development/examples/official-plugins/remember-plugin-session-memory.md +104 -0
- package/catalog/frontmcp-development/references/create-adapter.md +9 -0
- package/catalog/frontmcp-development/references/create-agent-llm-config.md +9 -0
- package/catalog/frontmcp-development/references/create-agent.md +10 -0
- package/catalog/frontmcp-development/references/create-job.md +10 -0
- package/catalog/frontmcp-development/references/create-plugin-hooks.md +10 -0
- package/catalog/frontmcp-development/references/create-plugin.md +10 -0
- package/catalog/frontmcp-development/references/create-prompt.md +10 -0
- package/catalog/frontmcp-development/references/create-provider.md +9 -0
- package/catalog/frontmcp-development/references/create-resource.md +52 -15
- package/catalog/frontmcp-development/references/create-skill-with-tools.md +10 -0
- package/catalog/frontmcp-development/references/create-skill.md +10 -0
- package/catalog/frontmcp-development/references/create-tool-annotations.md +9 -0
- package/catalog/frontmcp-development/references/create-tool-output-schema-types.md +10 -0
- package/catalog/frontmcp-development/references/create-tool.md +10 -0
- package/catalog/frontmcp-development/references/create-workflow.md +10 -0
- package/catalog/frontmcp-development/references/decorators-guide.md +10 -0
- package/catalog/frontmcp-development/references/official-adapters.md +10 -0
- package/catalog/frontmcp-development/references/official-plugins.md +10 -0
- package/catalog/frontmcp-extensibility/SKILL.md +1 -1
- package/catalog/frontmcp-extensibility/examples/vectoriadb/product-catalog-search.md +175 -0
- package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md +138 -0
- package/catalog/frontmcp-extensibility/examples/vectoriadb/tfidf-keyword-search.md +103 -0
- package/catalog/frontmcp-extensibility/references/vectoriadb.md +10 -0
- package/catalog/frontmcp-guides/SKILL.md +2 -2
- package/catalog/frontmcp-guides/examples/example-knowledge-base/agent-and-plugin.md +160 -0
- package/catalog/frontmcp-guides/examples/example-knowledge-base/multi-app-composition.md +92 -0
- package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md +135 -0
- package/catalog/frontmcp-guides/examples/example-task-manager/auth-and-crud-tools.md +135 -0
- package/catalog/frontmcp-guides/examples/example-task-manager/authenticated-e2e-tests.md +148 -0
- package/catalog/frontmcp-guides/examples/example-task-manager/redis-provider-with-di.md +129 -0
- package/catalog/frontmcp-guides/examples/example-weather-api/server-and-app-setup.md +75 -0
- package/catalog/frontmcp-guides/examples/example-weather-api/unit-and-e2e-tests.md +142 -0
- package/catalog/frontmcp-guides/examples/example-weather-api/weather-tool-with-schemas.md +74 -0
- package/catalog/frontmcp-guides/references/example-knowledge-base.md +10 -0
- package/catalog/frontmcp-guides/references/example-task-manager.md +10 -0
- package/catalog/frontmcp-guides/references/example-weather-api.md +10 -0
- package/catalog/frontmcp-production-readiness/SKILL.md +2 -2
- package/catalog/frontmcp-production-readiness/examples/common-checklist/caching-and-performance.md +102 -0
- package/catalog/frontmcp-production-readiness/examples/common-checklist/observability-setup.md +104 -0
- package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +95 -0
- package/catalog/frontmcp-production-readiness/examples/production-browser/browser-bundle-config.md +93 -0
- package/catalog/frontmcp-production-readiness/examples/production-browser/cross-platform-crypto.md +116 -0
- package/catalog/frontmcp-production-readiness/examples/production-browser/security-and-performance.md +128 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-binary/binary-build-config.md +109 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-binary/stdio-transport-error-handling.md +132 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/daemon-socket-config.md +82 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/graceful-shutdown-cleanup.md +107 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/security-and-permissions.md +119 -0
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/durable-objects-state.md +124 -0
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/workers-runtime-constraints.md +103 -0
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/wrangler-config.md +89 -0
- package/catalog/frontmcp-production-readiness/examples/production-lambda/cold-start-connection-reuse.md +122 -0
- package/catalog/frontmcp-production-readiness/examples/production-lambda/sam-template.md +107 -0
- package/catalog/frontmcp-production-readiness/examples/production-lambda/scaling-and-monitoring.md +138 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-sdk/basic-sdk-lifecycle.md +85 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-sdk/multi-instance-cleanup.md +110 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-sdk/package-json-config.md +107 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-server/docker-multi-stage.md +103 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-server/graceful-shutdown.md +87 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-server/redis-session-scaling.md +97 -0
- package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md +104 -0
- package/catalog/frontmcp-production-readiness/examples/production-vercel/stateless-serverless-design.md +91 -0
- package/catalog/frontmcp-production-readiness/examples/production-vercel/vercel-edge-config.md +78 -0
- package/catalog/frontmcp-production-readiness/references/common-checklist.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-browser.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-cli-binary.md +9 -0
- package/catalog/frontmcp-production-readiness/references/production-cli-daemon.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-cloudflare.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-lambda.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-node-sdk.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-node-server.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-vercel.md +10 -0
- package/catalog/frontmcp-setup/examples/frontmcp-skills-usage/bundle-presets-scaffolding.md +61 -0
- package/catalog/frontmcp-setup/examples/frontmcp-skills-usage/install-and-search-skills.md +83 -0
- package/catalog/frontmcp-setup/examples/multi-app-composition/local-apps-with-shared-tools.md +87 -0
- package/catalog/frontmcp-setup/examples/multi-app-composition/per-app-auth-and-isolation.md +88 -0
- package/catalog/frontmcp-setup/examples/multi-app-composition/remote-and-esm-apps.md +81 -0
- package/catalog/frontmcp-setup/examples/nx-workflow/build-test-affected.md +77 -0
- package/catalog/frontmcp-setup/examples/nx-workflow/multi-server-deployment.md +93 -0
- package/catalog/frontmcp-setup/examples/nx-workflow/scaffold-and-generate.md +62 -0
- package/catalog/frontmcp-setup/examples/project-structure-nx/nx-generator-scaffolding.md +73 -0
- package/catalog/frontmcp-setup/examples/project-structure-nx/nx-workspace-with-apps.md +85 -0
- package/catalog/frontmcp-setup/examples/project-structure-nx/shared-library-usage.md +89 -0
- package/catalog/frontmcp-setup/examples/project-structure-standalone/dev-workflow-commands.md +64 -0
- package/catalog/frontmcp-setup/examples/project-structure-standalone/feature-folder-organization.md +111 -0
- package/catalog/frontmcp-setup/examples/project-structure-standalone/minimal-standalone-layout.md +73 -0
- package/catalog/frontmcp-setup/examples/readme-guide/node-server-readme.md +89 -0
- package/catalog/frontmcp-setup/examples/readme-guide/vercel-deployment-readme.md +90 -0
- package/catalog/frontmcp-setup/examples/setup-project/basic-node-server.md +99 -0
- package/catalog/frontmcp-setup/examples/setup-project/cli-scaffold-with-flags.md +77 -0
- package/catalog/frontmcp-setup/examples/setup-project/vercel-serverless-server.md +89 -0
- package/catalog/frontmcp-setup/examples/setup-redis/docker-redis-local-dev.md +88 -0
- package/catalog/frontmcp-setup/examples/setup-redis/hybrid-vercel-kv-with-pubsub.md +78 -0
- package/catalog/frontmcp-setup/examples/setup-redis/vercel-kv-serverless.md +78 -0
- package/catalog/frontmcp-setup/examples/setup-sqlite/basic-sqlite-setup.md +75 -0
- package/catalog/frontmcp-setup/examples/setup-sqlite/encrypted-sqlite-storage.md +55 -0
- package/catalog/frontmcp-setup/examples/setup-sqlite/unix-socket-daemon.md +70 -0
- package/catalog/frontmcp-setup/references/frontmcp-skills-usage.md +9 -0
- package/catalog/frontmcp-setup/references/multi-app-composition.md +10 -0
- package/catalog/frontmcp-setup/references/nx-workflow.md +10 -0
- package/catalog/frontmcp-setup/references/project-structure-nx.md +10 -0
- package/catalog/frontmcp-setup/references/project-structure-standalone.md +10 -0
- package/catalog/frontmcp-setup/references/readme-guide.md +9 -0
- package/catalog/frontmcp-setup/references/setup-project.md +10 -0
- package/catalog/frontmcp-setup/references/setup-redis.md +10 -0
- package/catalog/frontmcp-setup/references/setup-sqlite.md +10 -0
- package/catalog/frontmcp-testing/examples/setup-testing/fixture-based-e2e-test.md +70 -0
- package/catalog/frontmcp-testing/examples/setup-testing/jest-config-with-coverage.md +59 -0
- package/catalog/frontmcp-testing/examples/setup-testing/unit-test-tool-resource-prompt.md +115 -0
- package/catalog/frontmcp-testing/examples/test-auth/oauth-flow-test.md +78 -0
- package/catalog/frontmcp-testing/examples/test-auth/role-based-access-test.md +88 -0
- package/catalog/frontmcp-testing/examples/test-auth/token-factory-test.md +71 -0
- package/catalog/frontmcp-testing/examples/test-browser-build/browser-bundle-validation.md +58 -0
- package/catalog/frontmcp-testing/examples/test-browser-build/playwright-browser-test.md +69 -0
- package/catalog/frontmcp-testing/examples/test-cli-binary/binary-startup-test.md +77 -0
- package/catalog/frontmcp-testing/examples/test-cli-binary/js-bundle-import-test.md +56 -0
- package/catalog/frontmcp-testing/examples/test-direct-client/basic-create-test.md +74 -0
- package/catalog/frontmcp-testing/examples/test-direct-client/openai-claude-format-test.md +79 -0
- package/catalog/frontmcp-testing/examples/test-e2e-handler/basic-e2e-test.md +67 -0
- package/catalog/frontmcp-testing/examples/test-e2e-handler/manual-client-with-transport.md +72 -0
- package/catalog/frontmcp-testing/examples/test-e2e-handler/tool-call-and-error-e2e.md +73 -0
- package/catalog/frontmcp-testing/examples/test-tool-unit/basic-tool-test.md +69 -0
- package/catalog/frontmcp-testing/examples/test-tool-unit/schema-validation-test.md +82 -0
- package/catalog/frontmcp-testing/examples/test-tool-unit/tool-error-handling-test.md +92 -0
- package/catalog/frontmcp-testing/references/setup-testing.md +10 -0
- package/catalog/frontmcp-testing/references/test-auth.md +10 -0
- package/catalog/frontmcp-testing/references/test-browser-build.md +9 -0
- package/catalog/frontmcp-testing/references/test-cli-binary.md +9 -0
- package/catalog/frontmcp-testing/references/test-direct-client.md +9 -0
- package/catalog/frontmcp-testing/references/test-e2e-handler.md +10 -0
- package/catalog/frontmcp-testing/references/test-tool-unit.md +10 -0
- package/catalog/skills-manifest.json +2383 -67
- package/package.json +1 -1
- package/src/manifest.d.ts +23 -0
- package/src/manifest.js +3 -1
- package/src/manifest.js.map +1 -1
package/catalog/frontmcp-production-readiness/examples/production-node-sdk/basic-sdk-lifecycle.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: basic-sdk-lifecycle
|
|
3
|
+
reference: production-node-sdk
|
|
4
|
+
level: basic
|
|
5
|
+
description: 'Shows the complete lifecycle of a FrontMCP SDK package used as an embedded client: initialization, tool invocation, and proper cleanup.'
|
|
6
|
+
tags: [production, sdk, node, lifecycle]
|
|
7
|
+
features:
|
|
8
|
+
- 'Exporting a `create()` function as the public API surface'
|
|
9
|
+
- 'No port binding in SDK mode (embedded, not standalone server)'
|
|
10
|
+
- 'The full lifecycle: `create()` -> `connect()` -> `callTool()` -> `close()` -> `dispose()`'
|
|
11
|
+
- 'Proper cleanup to prevent memory and connection leaks'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Basic SDK Lifecycle: Create, Connect, Use, Dispose
|
|
15
|
+
|
|
16
|
+
Shows the complete lifecycle of a FrontMCP SDK package used as an embedded client: initialization, tool invocation, and proper cleanup.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/main.ts
|
|
22
|
+
import { FrontMcp } from '@frontmcp/sdk';
|
|
23
|
+
import { MyApp } from './my.app';
|
|
24
|
+
|
|
25
|
+
@FrontMcp({
|
|
26
|
+
info: { name: 'my-mcp-package', version: '1.0.0' },
|
|
27
|
+
apps: [MyApp],
|
|
28
|
+
// SDK mode: no port binding, no HTTP server
|
|
29
|
+
})
|
|
30
|
+
export default class MyMcpServer {}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// src/index.ts — Public API surface
|
|
35
|
+
// Export a clean create() function for consumers
|
|
36
|
+
import MyMcpServer from './main';
|
|
37
|
+
|
|
38
|
+
export async function create() {
|
|
39
|
+
// create() does not bind a port — SDK mode, not server mode
|
|
40
|
+
const server = await MyMcpServer.create();
|
|
41
|
+
return server;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type { MyMcpServer };
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// examples/usage.ts — How consumers use the SDK
|
|
49
|
+
import { create } from 'my-mcp-package';
|
|
50
|
+
|
|
51
|
+
async function main() {
|
|
52
|
+
// 1. Create the server (no port binding)
|
|
53
|
+
const server = await create();
|
|
54
|
+
|
|
55
|
+
// 2. Connect to get a typed client
|
|
56
|
+
const client = await server.connect();
|
|
57
|
+
|
|
58
|
+
// 3. Use the client
|
|
59
|
+
const tools = await client.listTools();
|
|
60
|
+
console.log(
|
|
61
|
+
'Available tools:',
|
|
62
|
+
tools.map((t) => t.name),
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const result = await client.callTool('my_tool', { input: 'value' });
|
|
66
|
+
console.log('Result:', result);
|
|
67
|
+
|
|
68
|
+
// 4. Always clean up — prevents leaks
|
|
69
|
+
await client.close();
|
|
70
|
+
await server.dispose();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
main().catch(console.error);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## What This Demonstrates
|
|
77
|
+
|
|
78
|
+
- Exporting a `create()` function as the public API surface
|
|
79
|
+
- No port binding in SDK mode (embedded, not standalone server)
|
|
80
|
+
- The full lifecycle: `create()` -> `connect()` -> `callTool()` -> `close()` -> `dispose()`
|
|
81
|
+
- Proper cleanup to prevent memory and connection leaks
|
|
82
|
+
|
|
83
|
+
## Related
|
|
84
|
+
|
|
85
|
+
- See `production-node-sdk` for the full SDK publishing checklist
|
package/catalog/frontmcp-production-readiness/examples/production-node-sdk/multi-instance-cleanup.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: multi-instance-cleanup
|
|
3
|
+
reference: production-node-sdk
|
|
4
|
+
level: advanced
|
|
5
|
+
description: 'Shows how multiple SDK instances can coexist without conflicts, and how to implement proper cleanup to prevent memory leaks from event listeners, timers, and provider resources.'
|
|
6
|
+
tags: [production, sdk, node, multi, instance, cleanup]
|
|
7
|
+
features:
|
|
8
|
+
- 'Implementing `onDestroy()` in providers to clean up timers and listeners'
|
|
9
|
+
- 'Ensuring multiple instances coexist without sharing global state'
|
|
10
|
+
- 'Testing that dispose removes all event listeners (no leaks)'
|
|
11
|
+
- 'Verifying one instance still works after another is disposed'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Multi-Instance Coexistence and Cleanup
|
|
15
|
+
|
|
16
|
+
Shows how multiple SDK instances can coexist without conflicts, and how to implement proper cleanup to prevent memory leaks from event listeners, timers, and provider resources.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/providers/polling.provider.ts
|
|
22
|
+
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
23
|
+
|
|
24
|
+
export const POLLER = Symbol('Poller');
|
|
25
|
+
|
|
26
|
+
@Provider({ token: POLLER, scope: ProviderScope.GLOBAL })
|
|
27
|
+
export class PollingProvider {
|
|
28
|
+
private intervalId: ReturnType<typeof setInterval> | undefined;
|
|
29
|
+
private listeners: Array<() => void> = [];
|
|
30
|
+
|
|
31
|
+
async onInit(): Promise<void> {
|
|
32
|
+
// Start a polling interval
|
|
33
|
+
this.intervalId = setInterval(() => {
|
|
34
|
+
this.listeners.forEach((fn) => fn());
|
|
35
|
+
}, 10_000);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
addListener(fn: () => void): void {
|
|
39
|
+
this.listeners.push(fn);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async onDestroy(): Promise<void> {
|
|
43
|
+
// Clean up timer — prevents dangling intervals after dispose
|
|
44
|
+
if (this.intervalId) {
|
|
45
|
+
clearInterval(this.intervalId);
|
|
46
|
+
this.intervalId = undefined;
|
|
47
|
+
}
|
|
48
|
+
// Remove all listener references — prevents memory leaks
|
|
49
|
+
this.listeners.length = 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// test/multi-instance.spec.ts
|
|
56
|
+
import { create } from '../src/index';
|
|
57
|
+
|
|
58
|
+
describe('Multi-instance coexistence', () => {
|
|
59
|
+
it('should run two instances side by side without conflicts', async () => {
|
|
60
|
+
// Create two independent instances
|
|
61
|
+
const server1 = await create();
|
|
62
|
+
const server2 = await create();
|
|
63
|
+
|
|
64
|
+
const client1 = await server1.connect();
|
|
65
|
+
const client2 = await server2.connect();
|
|
66
|
+
|
|
67
|
+
// Both should work independently
|
|
68
|
+
const tools1 = await client1.listTools();
|
|
69
|
+
const tools2 = await client2.listTools();
|
|
70
|
+
|
|
71
|
+
expect(tools1.tools.length).toBeGreaterThan(0);
|
|
72
|
+
expect(tools2.tools.length).toBeGreaterThan(0);
|
|
73
|
+
|
|
74
|
+
// Clean up both — no shared global state
|
|
75
|
+
await client1.close();
|
|
76
|
+
await server1.dispose();
|
|
77
|
+
|
|
78
|
+
// Instance 2 still works after instance 1 is disposed
|
|
79
|
+
const result = await client2.callTool('my_tool', { input: 'still-alive' });
|
|
80
|
+
expect(result).toBeDefined();
|
|
81
|
+
|
|
82
|
+
await client2.close();
|
|
83
|
+
await server2.dispose();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should not leak event listeners after dispose', async () => {
|
|
87
|
+
const initialListeners = process.listenerCount('SIGTERM');
|
|
88
|
+
|
|
89
|
+
const server = await create();
|
|
90
|
+
const client = await server.connect();
|
|
91
|
+
|
|
92
|
+
await client.close();
|
|
93
|
+
await server.dispose();
|
|
94
|
+
|
|
95
|
+
// No dangling SIGTERM listeners after dispose
|
|
96
|
+
expect(process.listenerCount('SIGTERM')).toBe(initialListeners);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## What This Demonstrates
|
|
102
|
+
|
|
103
|
+
- Implementing `onDestroy()` in providers to clean up timers and listeners
|
|
104
|
+
- Ensuring multiple instances coexist without sharing global state
|
|
105
|
+
- Testing that dispose removes all event listeners (no leaks)
|
|
106
|
+
- Verifying one instance still works after another is disposed
|
|
107
|
+
|
|
108
|
+
## Related
|
|
109
|
+
|
|
110
|
+
- See `production-node-sdk` for the full memory and cleanup checklist
|
package/catalog/frontmcp-production-readiness/examples/production-node-sdk/package-json-config.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: package-json-config
|
|
3
|
+
reference: production-node-sdk
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Shows the correct package.json configuration for publishing a FrontMCP SDK package with CJS + ESM entry points, peer dependencies, and proper file inclusions.'
|
|
6
|
+
tags: [production, sdk, readme, node, package, json]
|
|
7
|
+
features:
|
|
8
|
+
- 'Correct `main`, `module`, `types`, and `exports` fields for CJS + ESM'
|
|
9
|
+
- 'Using `files` to include only `dist/`, `README.md`, and `LICENSE` in the published package'
|
|
10
|
+
- 'Declaring `zod` as a `peerDependency` for shared packages'
|
|
11
|
+
- 'The `prepublishOnly` script ensuring build and tests pass before publishing'
|
|
12
|
+
- 'Integration test verifying the full lifecycle with proper cleanup'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# npm Package Configuration for SDK Publishing
|
|
16
|
+
|
|
17
|
+
Shows the correct package.json configuration for publishing a FrontMCP SDK package with CJS + ESM entry points, peer dependencies, and proper file inclusions.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```jsonc
|
|
22
|
+
// package.json
|
|
23
|
+
{
|
|
24
|
+
"name": "my-mcp-sdk",
|
|
25
|
+
"version": "1.0.0",
|
|
26
|
+
"description": "MCP SDK for task management with type-safe tool invocations",
|
|
27
|
+
"keywords": ["mcp", "sdk", "task-management", "frontmcp"],
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
|
|
30
|
+
// CJS + ESM entry points
|
|
31
|
+
"main": "./dist/cjs/index.js",
|
|
32
|
+
"module": "./dist/esm/index.js",
|
|
33
|
+
"types": "./dist/types/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"import": "./dist/esm/index.js",
|
|
37
|
+
"require": "./dist/cjs/index.js",
|
|
38
|
+
"types": "./dist/types/index.d.ts",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
// Only ship what consumers need
|
|
43
|
+
"files": ["dist/", "README.md", "LICENSE"],
|
|
44
|
+
|
|
45
|
+
// Required Node.js version
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=18.0.0",
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
// Shared dependencies as peerDependencies
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"zod": "^4.0.0",
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@frontmcp/sdk": "^1.0.0",
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@frontmcp/testing": "^1.0.0",
|
|
61
|
+
"jest": "^29.0.0",
|
|
62
|
+
"ts-jest": "^29.0.0",
|
|
63
|
+
"typescript": "^5.4.0",
|
|
64
|
+
"zod": "^4.0.0",
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
"scripts": {
|
|
68
|
+
"build": "frontmcp build",
|
|
69
|
+
"test": "jest --coverage",
|
|
70
|
+
"prepublishOnly": "npm run build && npm test",
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// test/lifecycle.spec.ts — Integration test for the full lifecycle
|
|
77
|
+
import { create } from '../src/index';
|
|
78
|
+
|
|
79
|
+
describe('SDK lifecycle', () => {
|
|
80
|
+
it('should complete create -> connect -> callTool -> close -> dispose', async () => {
|
|
81
|
+
const server = await create();
|
|
82
|
+
const client = await server.connect();
|
|
83
|
+
|
|
84
|
+
const { tools } = await client.listTools();
|
|
85
|
+
expect(tools.length).toBeGreaterThan(0);
|
|
86
|
+
|
|
87
|
+
const result = await client.callTool('my_tool', { input: 'test' });
|
|
88
|
+
expect(result).toBeDefined();
|
|
89
|
+
|
|
90
|
+
// Always clean up — tests must not leak resources
|
|
91
|
+
await client.close();
|
|
92
|
+
await server.dispose();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## What This Demonstrates
|
|
98
|
+
|
|
99
|
+
- Correct `main`, `module`, `types`, and `exports` fields for CJS + ESM
|
|
100
|
+
- Using `files` to include only `dist/`, `README.md`, and `LICENSE` in the published package
|
|
101
|
+
- Declaring `zod` as a `peerDependency` for shared packages
|
|
102
|
+
- The `prepublishOnly` script ensuring build and tests pass before publishing
|
|
103
|
+
- Integration test verifying the full lifecycle with proper cleanup
|
|
104
|
+
|
|
105
|
+
## Related
|
|
106
|
+
|
|
107
|
+
- See `production-node-sdk` for the full npm publishing and testing checklist
|
package/catalog/frontmcp-production-readiness/examples/production-node-server/docker-multi-stage.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: docker-multi-stage
|
|
3
|
+
reference: production-node-server
|
|
4
|
+
level: basic
|
|
5
|
+
description: 'Shows a production-ready Dockerfile with multi-stage build, non-root user, and container health check for a FrontMCP Node.js server.'
|
|
6
|
+
tags: [production, dockerfile, docker, security, node, multi]
|
|
7
|
+
features:
|
|
8
|
+
- 'Multi-stage Docker build separating build dependencies from runtime'
|
|
9
|
+
- 'Using `node:24-slim` as a minimal base image'
|
|
10
|
+
- 'Running as non-root user (`USER node`) for security'
|
|
11
|
+
- 'Container health check for orchestrator-aware restarts'
|
|
12
|
+
- 'Resource limits (memory, CPU) in docker-compose'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Multi-Stage Dockerfile with Health Check
|
|
16
|
+
|
|
17
|
+
Shows a production-ready Dockerfile with multi-stage build, non-root user, and container health check for a FrontMCP Node.js server.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```dockerfile
|
|
22
|
+
# Dockerfile
|
|
23
|
+
# Stage 1: Build
|
|
24
|
+
FROM node:24-slim AS builder
|
|
25
|
+
WORKDIR /app
|
|
26
|
+
COPY package.json yarn.lock ./
|
|
27
|
+
RUN yarn install --frozen-lockfile
|
|
28
|
+
COPY tsconfig.json ./
|
|
29
|
+
COPY src ./src
|
|
30
|
+
RUN npx frontmcp build
|
|
31
|
+
|
|
32
|
+
# Stage 2: Runtime (minimal image)
|
|
33
|
+
FROM node:24-slim AS runtime
|
|
34
|
+
WORKDIR /app
|
|
35
|
+
ENV NODE_ENV=production
|
|
36
|
+
COPY package.json yarn.lock ./
|
|
37
|
+
RUN yarn install --frozen-lockfile --production && yarn cache clean
|
|
38
|
+
COPY --from=builder /app/dist ./dist
|
|
39
|
+
|
|
40
|
+
# Non-root user for security
|
|
41
|
+
USER node
|
|
42
|
+
|
|
43
|
+
# Health check for container orchestration
|
|
44
|
+
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
|
45
|
+
CMD node -e "require('http').get('http://localhost:3000/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"
|
|
46
|
+
|
|
47
|
+
EXPOSE 3000
|
|
48
|
+
CMD ["node", "dist/main.js"]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
# .dockerignore
|
|
53
|
+
node_modules
|
|
54
|
+
.git
|
|
55
|
+
.env
|
|
56
|
+
.env.*
|
|
57
|
+
dist
|
|
58
|
+
coverage
|
|
59
|
+
*.md
|
|
60
|
+
.cache
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
# docker-compose.yml
|
|
65
|
+
version: '3.8'
|
|
66
|
+
services:
|
|
67
|
+
mcp-server:
|
|
68
|
+
build: .
|
|
69
|
+
ports:
|
|
70
|
+
- '3000:3000'
|
|
71
|
+
environment:
|
|
72
|
+
- NODE_ENV=production
|
|
73
|
+
- PORT=3000
|
|
74
|
+
- REDIS_HOST=redis
|
|
75
|
+
depends_on:
|
|
76
|
+
- redis
|
|
77
|
+
deploy:
|
|
78
|
+
resources:
|
|
79
|
+
limits:
|
|
80
|
+
memory: 512M
|
|
81
|
+
cpus: '1.0'
|
|
82
|
+
restart: unless-stopped
|
|
83
|
+
|
|
84
|
+
redis:
|
|
85
|
+
image: redis:7-alpine
|
|
86
|
+
volumes:
|
|
87
|
+
- redis-data:/data
|
|
88
|
+
|
|
89
|
+
volumes:
|
|
90
|
+
redis-data:
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## What This Demonstrates
|
|
94
|
+
|
|
95
|
+
- Multi-stage Docker build separating build dependencies from runtime
|
|
96
|
+
- Using `node:24-slim` as a minimal base image
|
|
97
|
+
- Running as non-root user (`USER node`) for security
|
|
98
|
+
- Container health check for orchestrator-aware restarts
|
|
99
|
+
- Resource limits (memory, CPU) in docker-compose
|
|
100
|
+
|
|
101
|
+
## Related
|
|
102
|
+
|
|
103
|
+
- See `production-node-server` for the full Node.js/Docker checklist
|
package/catalog/frontmcp-production-readiness/examples/production-node-server/graceful-shutdown.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: graceful-shutdown
|
|
3
|
+
reference: production-node-server
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Shows how to implement graceful shutdown with SIGTERM handling, in-flight request draining, and health check status transitions.'
|
|
6
|
+
tags: [production, redis, database, node, graceful, shutdown]
|
|
7
|
+
features:
|
|
8
|
+
- 'Handling SIGTERM for graceful shutdown in containerized environments'
|
|
9
|
+
- 'Draining in-flight requests before exiting with a timeout safety net'
|
|
10
|
+
- 'Disposing all resources (Redis, database) via `server.dispose()`'
|
|
11
|
+
- 'Returning unhealthy during shutdown so load balancers redirect traffic'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Graceful Shutdown with SIGTERM Handling
|
|
15
|
+
|
|
16
|
+
Shows how to implement graceful shutdown with SIGTERM handling, in-flight request draining, and health check status transitions.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/main.ts
|
|
22
|
+
import { FrontMcp } from '@frontmcp/sdk';
|
|
23
|
+
import { MyApp } from './my.app';
|
|
24
|
+
|
|
25
|
+
@FrontMcp({
|
|
26
|
+
info: { name: 'resilient-server', version: '1.0.0' },
|
|
27
|
+
apps: [MyApp],
|
|
28
|
+
redis: {
|
|
29
|
+
provider: 'redis',
|
|
30
|
+
host: process.env.REDIS_HOST ?? 'localhost',
|
|
31
|
+
port: 6379,
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
export default class ResilientServer {}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// src/lifecycle/shutdown.ts
|
|
39
|
+
// Graceful shutdown handler — wire this in your entry point
|
|
40
|
+
|
|
41
|
+
let isShuttingDown = false;
|
|
42
|
+
|
|
43
|
+
export function setupGracefulShutdown(server: { close: () => Promise<void>; dispose: () => Promise<void> }): void {
|
|
44
|
+
const shutdown = async (signal: string) => {
|
|
45
|
+
if (isShuttingDown) return;
|
|
46
|
+
isShuttingDown = true;
|
|
47
|
+
|
|
48
|
+
console.log(`Received ${signal}. Starting graceful shutdown...`);
|
|
49
|
+
|
|
50
|
+
// 1. Stop accepting new connections
|
|
51
|
+
await server.close();
|
|
52
|
+
console.log('Server closed — no new connections accepted.');
|
|
53
|
+
|
|
54
|
+
// 2. Wait for in-flight requests to complete (with timeout)
|
|
55
|
+
const drainTimeout = setTimeout(() => {
|
|
56
|
+
console.error('Drain timeout reached. Forcing exit.');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}, 30_000); // 30 second drain period
|
|
59
|
+
|
|
60
|
+
// 3. Dispose all resources (Redis, DB connections, providers)
|
|
61
|
+
await server.dispose();
|
|
62
|
+
clearTimeout(drainTimeout);
|
|
63
|
+
console.log('All resources disposed. Exiting.');
|
|
64
|
+
|
|
65
|
+
process.exit(0);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
69
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function isHealthy(): boolean {
|
|
73
|
+
// Return unhealthy during shutdown drain so load balancers stop sending traffic
|
|
74
|
+
return !isShuttingDown;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## What This Demonstrates
|
|
79
|
+
|
|
80
|
+
- Handling SIGTERM for graceful shutdown in containerized environments
|
|
81
|
+
- Draining in-flight requests before exiting with a timeout safety net
|
|
82
|
+
- Disposing all resources (Redis, database) via `server.dispose()`
|
|
83
|
+
- Returning unhealthy during shutdown so load balancers redirect traffic
|
|
84
|
+
|
|
85
|
+
## Related
|
|
86
|
+
|
|
87
|
+
- See `production-node-server` for the full process management and scaling checklist
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: redis-session-scaling
|
|
3
|
+
reference: production-node-server
|
|
4
|
+
level: advanced
|
|
5
|
+
description: 'Shows how to configure Redis-backed session storage, connection pooling, and stateless server design for horizontal scaling behind a load balancer.'
|
|
6
|
+
tags: [production, redis, session, node, scaling]
|
|
7
|
+
features:
|
|
8
|
+
- 'Configuring Redis for session storage so all instances share state'
|
|
9
|
+
- 'Using key prefixes to namespace Redis keys and avoid collisions'
|
|
10
|
+
- 'Setting session TTL to prevent unbounded storage growth'
|
|
11
|
+
- 'Configuring Redis-backed job store for multi-instance job processing'
|
|
12
|
+
- 'Validating required environment variables at startup (fail fast)'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Redis Session Storage for Multi-Instance Scaling
|
|
16
|
+
|
|
17
|
+
Shows how to configure Redis-backed session storage, connection pooling, and stateless server design for horizontal scaling behind a load balancer.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// src/main.ts
|
|
23
|
+
import { FrontMcp } from '@frontmcp/sdk';
|
|
24
|
+
import { MyApp } from './my.app';
|
|
25
|
+
|
|
26
|
+
@FrontMcp({
|
|
27
|
+
info: { name: 'scalable-server', version: '1.0.0' },
|
|
28
|
+
apps: [MyApp],
|
|
29
|
+
|
|
30
|
+
// Redis for all shared state — sessions, cache, jobs
|
|
31
|
+
redis: {
|
|
32
|
+
provider: 'redis',
|
|
33
|
+
host: process.env.REDIS_HOST ?? 'localhost',
|
|
34
|
+
port: Number(process.env.REDIS_PORT ?? 6379),
|
|
35
|
+
password: process.env.REDIS_PASSWORD,
|
|
36
|
+
keyPrefix: 'mcp:', // Namespace keys to avoid collisions
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
// Session configuration
|
|
40
|
+
session: {
|
|
41
|
+
ttl: 3600_000, // 1 hour session TTL
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
// Jobs use Redis store for multi-instance consistency
|
|
45
|
+
jobs: {
|
|
46
|
+
enabled: true,
|
|
47
|
+
store: {
|
|
48
|
+
redis: {
|
|
49
|
+
provider: 'redis',
|
|
50
|
+
host: process.env.REDIS_HOST ?? 'localhost',
|
|
51
|
+
port: Number(process.env.REDIS_PORT ?? 6379),
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
retry: {
|
|
55
|
+
maxAttempts: 3,
|
|
56
|
+
maxBackoffMs: 30_000,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
export default class ScalableServer {}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// src/providers/env-validation.provider.ts
|
|
65
|
+
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
66
|
+
|
|
67
|
+
export const ENV_VALIDATOR = Symbol('EnvValidator');
|
|
68
|
+
|
|
69
|
+
@Provider({ token: ENV_VALIDATOR, scope: ProviderScope.GLOBAL })
|
|
70
|
+
export class EnvValidationProvider {
|
|
71
|
+
async onInit(): Promise<void> {
|
|
72
|
+
// Fail fast on missing config — don't discover in production at runtime
|
|
73
|
+
const required = ['REDIS_HOST', 'NODE_ENV'];
|
|
74
|
+
const missing = required.filter((key) => !process.env[key]);
|
|
75
|
+
|
|
76
|
+
if (missing.length > 0) {
|
|
77
|
+
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
81
|
+
console.warn('WARNING: NODE_ENV is not set to "production"');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## What This Demonstrates
|
|
88
|
+
|
|
89
|
+
- Configuring Redis for session storage so all instances share state
|
|
90
|
+
- Using key prefixes to namespace Redis keys and avoid collisions
|
|
91
|
+
- Setting session TTL to prevent unbounded storage growth
|
|
92
|
+
- Configuring Redis-backed job store for multi-instance job processing
|
|
93
|
+
- Validating required environment variables at startup (fail fast)
|
|
94
|
+
|
|
95
|
+
## Related
|
|
96
|
+
|
|
97
|
+
- See `production-node-server` for the full storage and scaling checklist
|
package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cold-start-optimization
|
|
3
|
+
reference: production-vercel
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Shows how to minimize cold start time by lazy-loading dependencies, avoiding heavy initialization at module scope, and caching expensive operations.'
|
|
6
|
+
tags: [production, vercel, openapi, performance, cold, start]
|
|
7
|
+
features:
|
|
8
|
+
- 'Lazy-loading heavy dependencies via dynamic `import()` in `onInit()` instead of module scope'
|
|
9
|
+
- 'Caching expensive fetches (e.g., OpenAPI specs) across warm invocations'
|
|
10
|
+
- 'Keeping the module scope lightweight with no side effects'
|
|
11
|
+
- 'No `top-level await`, no global state, no network calls at import time'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Cold Start Optimization for Serverless
|
|
15
|
+
|
|
16
|
+
Shows how to minimize cold start time by lazy-loading dependencies, avoiding heavy initialization at module scope, and caching expensive operations.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/providers/lazy-api-client.provider.ts
|
|
22
|
+
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
23
|
+
|
|
24
|
+
export const API_CLIENT = Symbol('ApiClient');
|
|
25
|
+
|
|
26
|
+
@Provider({ token: API_CLIENT, scope: ProviderScope.GLOBAL })
|
|
27
|
+
export class LazyApiClientProvider {
|
|
28
|
+
// Lazy-loaded — not imported at module scope
|
|
29
|
+
private client: unknown;
|
|
30
|
+
|
|
31
|
+
async onInit(): Promise<void> {
|
|
32
|
+
// Lazy-load heavy dependencies to reduce cold start time
|
|
33
|
+
// The import only happens when the provider is first used
|
|
34
|
+
const { HeavySDK } = await import('heavy-third-party-sdk');
|
|
35
|
+
this.client = new HeavySDK({
|
|
36
|
+
apiKey: process.env.API_KEY,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
getClient() {
|
|
41
|
+
return this.client;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// src/tools/cached-lookup.tool.ts
|
|
48
|
+
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
49
|
+
import { z } from 'zod';
|
|
50
|
+
|
|
51
|
+
// Cache OpenAPI spec in module scope — survives warm invocations
|
|
52
|
+
let cachedSpec: unknown | undefined;
|
|
53
|
+
|
|
54
|
+
@Tool({
|
|
55
|
+
name: 'lookup',
|
|
56
|
+
description: 'Look up data using a cached API spec',
|
|
57
|
+
inputSchema: {
|
|
58
|
+
query: z.string().min(1).describe('Lookup query'),
|
|
59
|
+
},
|
|
60
|
+
outputSchema: {
|
|
61
|
+
result: z.string(),
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
export class CachedLookupTool extends ToolContext {
|
|
65
|
+
async execute(input: { query: string }) {
|
|
66
|
+
// Cache the spec — not fetched on every invocation
|
|
67
|
+
if (!cachedSpec) {
|
|
68
|
+
const response = await this.fetch('https://api.example.com/openapi.json');
|
|
69
|
+
cachedSpec = await response.json();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Use cached spec for the lookup
|
|
73
|
+
return { result: `Found: ${input.query}` };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// src/main.ts
|
|
80
|
+
import { FrontMcp } from '@frontmcp/sdk';
|
|
81
|
+
// Only import lightweight modules at the top level
|
|
82
|
+
import { MyApp } from './my.app';
|
|
83
|
+
|
|
84
|
+
// No heavy initialization here — this runs on every cold start
|
|
85
|
+
// No top-level await, no global state, no network calls
|
|
86
|
+
|
|
87
|
+
@FrontMcp({
|
|
88
|
+
info: { name: 'fast-start', version: '1.0.0' },
|
|
89
|
+
apps: [MyApp],
|
|
90
|
+
redis: { provider: 'vercel-kv' },
|
|
91
|
+
})
|
|
92
|
+
export default class FastStartServer {}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## What This Demonstrates
|
|
96
|
+
|
|
97
|
+
- Lazy-loading heavy dependencies via dynamic `import()` in `onInit()` instead of module scope
|
|
98
|
+
- Caching expensive fetches (e.g., OpenAPI specs) across warm invocations
|
|
99
|
+
- Keeping the module scope lightweight with no side effects
|
|
100
|
+
- No `top-level await`, no global state, no network calls at import time
|
|
101
|
+
|
|
102
|
+
## Related
|
|
103
|
+
|
|
104
|
+
- See `production-vercel` for the full cold start and edge runtime checklist
|