@frontmcp/skills 1.0.0-beta.9 → 1.0.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/README.md +2 -2
- package/catalog/TEMPLATE.md +69 -0
- package/catalog/frontmcp-config/SKILL.md +38 -22
- 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 +15 -0
- package/catalog/frontmcp-config/references/configure-auth.md +15 -0
- package/catalog/frontmcp-config/references/configure-elicitation.md +14 -0
- package/catalog/frontmcp-config/references/configure-http.md +15 -0
- package/catalog/frontmcp-config/references/configure-session.md +15 -0
- package/catalog/frontmcp-config/references/configure-throttle-guard-config.md +14 -0
- package/catalog/frontmcp-config/references/configure-throttle.md +15 -0
- package/catalog/frontmcp-config/references/configure-transport-protocol-presets.md +14 -0
- package/catalog/frontmcp-config/references/configure-transport.md +15 -0
- package/catalog/frontmcp-config/references/setup-redis.md +10 -0
- package/catalog/frontmcp-config/references/setup-sqlite.md +10 -0
- package/catalog/frontmcp-deployment/SKILL.md +40 -12
- 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 +15 -0
- package/catalog/frontmcp-deployment/references/build-for-cli.md +65 -3
- package/catalog/frontmcp-deployment/references/build-for-sdk.md +15 -0
- package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +15 -0
- package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +18 -3
- package/catalog/frontmcp-deployment/references/deploy-to-node-dockerfile.md +16 -2
- package/catalog/frontmcp-deployment/references/deploy-to-node.md +19 -4
- package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +14 -0
- package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +15 -0
- package/catalog/frontmcp-development/SKILL.md +25 -17
- 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 +14 -0
- package/catalog/frontmcp-development/references/create-agent-llm-config.md +14 -0
- package/catalog/frontmcp-development/references/create-agent.md +15 -0
- package/catalog/frontmcp-development/references/create-job.md +15 -0
- package/catalog/frontmcp-development/references/create-plugin-hooks.md +51 -0
- package/catalog/frontmcp-development/references/create-plugin.md +186 -11
- package/catalog/frontmcp-development/references/create-prompt.md +17 -0
- package/catalog/frontmcp-development/references/create-provider.md +14 -0
- package/catalog/frontmcp-development/references/create-resource.md +127 -0
- package/catalog/frontmcp-development/references/create-skill-with-tools.md +126 -7
- package/catalog/frontmcp-development/references/create-skill.md +57 -12
- package/catalog/frontmcp-development/references/create-tool-annotations.md +14 -0
- package/catalog/frontmcp-development/references/create-tool-output-schema-types.md +15 -0
- package/catalog/frontmcp-development/references/create-tool.md +205 -1
- package/catalog/frontmcp-development/references/create-workflow.md +15 -0
- package/catalog/frontmcp-development/references/decorators-guide.md +155 -78
- package/catalog/frontmcp-development/references/official-adapters.md +31 -16
- package/catalog/frontmcp-development/references/official-plugins.md +62 -28
- package/catalog/frontmcp-extensibility/SKILL.md +103 -0
- 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 +299 -0
- package/catalog/frontmcp-guides/SKILL.md +7 -4
- 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 +15 -0
- package/catalog/frontmcp-guides/references/example-task-manager.md +30 -21
- package/catalog/frontmcp-guides/references/example-weather-api.md +18 -6
- package/catalog/frontmcp-observability/SKILL.md +144 -0
- package/catalog/frontmcp-observability/examples/structured-logging/stdout-logging.md +71 -0
- package/catalog/frontmcp-observability/examples/structured-logging/winston-integration.md +70 -0
- package/catalog/frontmcp-observability/examples/telemetry-api/agent-nested-tracing.md +86 -0
- package/catalog/frontmcp-observability/examples/telemetry-api/plugin-telemetry.md +93 -0
- package/catalog/frontmcp-observability/examples/telemetry-api/tool-custom-spans.md +72 -0
- package/catalog/frontmcp-observability/examples/testing-observability/test-custom-spans.md +90 -0
- package/catalog/frontmcp-observability/examples/testing-observability/test-log-correlation.md +104 -0
- package/catalog/frontmcp-observability/examples/tracing-setup/basic-tracing.md +82 -0
- package/catalog/frontmcp-observability/examples/tracing-setup/production-tracing.md +73 -0
- package/catalog/frontmcp-observability/examples/vendor-integrations/coralogix-setup.md +74 -0
- package/catalog/frontmcp-observability/references/structured-logging.md +114 -0
- package/catalog/frontmcp-observability/references/telemetry-api.md +155 -0
- package/catalog/frontmcp-observability/references/testing-observability.md +169 -0
- package/catalog/frontmcp-observability/references/tracing-setup.md +146 -0
- package/catalog/frontmcp-observability/references/vendor-integrations.md +164 -0
- package/catalog/frontmcp-production-readiness/SKILL.md +99 -0
- 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/health-readiness-endpoints/basic-health-setup.md +81 -0
- package/catalog/frontmcp-production-readiness/examples/health-readiness-endpoints/custom-probes.md +136 -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 +175 -0
- package/catalog/frontmcp-production-readiness/references/health-readiness-endpoints.md +198 -0
- package/catalog/frontmcp-production-readiness/references/production-browser.md +56 -0
- package/catalog/frontmcp-production-readiness/references/production-cli-binary.md +71 -0
- package/catalog/frontmcp-production-readiness/references/production-cli-daemon.md +71 -0
- package/catalog/frontmcp-production-readiness/references/production-cloudflare.md +62 -0
- package/catalog/frontmcp-production-readiness/references/production-lambda.md +63 -0
- package/catalog/frontmcp-production-readiness/references/production-node-sdk.md +76 -0
- package/catalog/frontmcp-production-readiness/references/production-node-server.md +71 -0
- package/catalog/frontmcp-production-readiness/references/production-vercel.md +62 -0
- package/catalog/frontmcp-setup/SKILL.md +19 -14
- 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 +33 -9
- package/catalog/frontmcp-setup/references/multi-app-composition.md +15 -0
- package/catalog/frontmcp-setup/references/nx-workflow.md +15 -0
- package/catalog/frontmcp-setup/references/project-structure-nx.md +15 -0
- package/catalog/frontmcp-setup/references/project-structure-standalone.md +15 -0
- package/catalog/frontmcp-setup/references/readme-guide.md +235 -0
- package/catalog/frontmcp-setup/references/setup-project.md +16 -1
- package/catalog/frontmcp-setup/references/setup-redis.md +15 -0
- package/catalog/frontmcp-setup/references/setup-sqlite.md +15 -0
- package/catalog/frontmcp-testing/SKILL.md +41 -27
- 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 +17 -0
- package/catalog/frontmcp-testing/references/test-auth.md +15 -0
- package/catalog/frontmcp-testing/references/test-browser-build.md +14 -0
- package/catalog/frontmcp-testing/references/test-cli-binary.md +14 -0
- package/catalog/frontmcp-testing/references/test-direct-client.md +14 -0
- package/catalog/frontmcp-testing/references/test-e2e-handler.md +15 -0
- package/catalog/frontmcp-testing/references/test-tool-unit.md +15 -0
- package/catalog/skills-manifest.json +2849 -32
- package/package.json +2 -2
- package/src/index.d.ts +1 -1
- package/src/index.js.map +1 -1
- package/src/loader.js +0 -1
- package/src/loader.js.map +1 -1
- package/src/manifest.d.ts +36 -1
- package/src/manifest.js +6 -1
- package/src/manifest.js.map +1 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stdio-transport-error-handling
|
|
3
|
+
reference: production-cli-binary
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Shows how to handle stdin/stdout transport correctly, implement proper exit codes, and handle edge cases like EOF and broken pipes.'
|
|
6
|
+
tags: [production, json-rpc, cli, transport, binary, stdio]
|
|
7
|
+
features:
|
|
8
|
+
- 'Exit code conventions: 0 (success), 1 (user error), 2 (internal error)'
|
|
9
|
+
- 'Using stderr for all logging since stdout is the MCP JSON-RPC channel'
|
|
10
|
+
- 'Handling EOF on stdin and broken pipe on stdout gracefully'
|
|
11
|
+
- 'Showing helpful error messages for unknown flags instead of stack traces'
|
|
12
|
+
- 'Validating file paths to prevent writes to unexpected locations'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Stdio Transport with Error Handling and Exit Codes
|
|
16
|
+
|
|
17
|
+
Shows how to handle stdin/stdout transport correctly, implement proper exit codes, and handle edge cases like EOF and broken pipes.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
#!/usr/bin/env node
|
|
23
|
+
// src/cli.ts
|
|
24
|
+
|
|
25
|
+
// Handle flags early — before any heavy imports
|
|
26
|
+
const args = process.argv.slice(2);
|
|
27
|
+
const unknownFlags = args.filter((a) => a.startsWith('-') && !['--version', '--help'].includes(a));
|
|
28
|
+
|
|
29
|
+
if (unknownFlags.length > 0) {
|
|
30
|
+
// User error: unknown flags — show helpful message, not stack trace
|
|
31
|
+
console.error(`Error: Unknown flag(s): ${unknownFlags.join(', ')}`);
|
|
32
|
+
console.error('Run "my-mcp-cli --help" for usage.');
|
|
33
|
+
process.exit(1); // Exit code 1: user error
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (args.includes('--version')) {
|
|
37
|
+
console.error('my-mcp-cli v1.0.0');
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function main() {
|
|
42
|
+
try {
|
|
43
|
+
// Lazy-load to keep startup fast
|
|
44
|
+
const { FrontMcp } = await import('@frontmcp/sdk');
|
|
45
|
+
const { MyApp } = await import('./my.app');
|
|
46
|
+
|
|
47
|
+
// stderr for all logging — stdout is the MCP JSON-RPC channel
|
|
48
|
+
console.error('[my-mcp-cli] Starting MCP server via stdio...');
|
|
49
|
+
|
|
50
|
+
// Handle EOF on stdin gracefully
|
|
51
|
+
process.stdin.on('end', () => {
|
|
52
|
+
console.error('[my-mcp-cli] stdin closed. Exiting.');
|
|
53
|
+
process.exit(0);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Handle broken pipe on stdout gracefully
|
|
57
|
+
process.stdout.on('error', (err: NodeJS.ErrnoException) => {
|
|
58
|
+
if (err.code === 'EPIPE') {
|
|
59
|
+
console.error('[my-mcp-cli] stdout pipe broken. Exiting.');
|
|
60
|
+
process.exit(0);
|
|
61
|
+
}
|
|
62
|
+
console.error('[my-mcp-cli] stdout error:', err.message);
|
|
63
|
+
process.exit(2); // Exit code 2: internal error
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Start the server (stdio transport)
|
|
67
|
+
@FrontMcp({
|
|
68
|
+
info: { name: 'my-mcp-cli', version: '1.0.0' },
|
|
69
|
+
apps: [MyApp],
|
|
70
|
+
})
|
|
71
|
+
class CliServer {}
|
|
72
|
+
} catch (err) {
|
|
73
|
+
// Internal error: log to stderr, exit with code 2
|
|
74
|
+
console.error('[my-mcp-cli] Fatal error:', err instanceof Error ? err.message : String(err));
|
|
75
|
+
process.exit(2);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
main();
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// src/tools/safe-tool.tool.ts
|
|
84
|
+
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
85
|
+
import { z } from 'zod';
|
|
86
|
+
|
|
87
|
+
@Tool({
|
|
88
|
+
name: 'process_file',
|
|
89
|
+
description: 'Process a file path safely',
|
|
90
|
+
inputSchema: {
|
|
91
|
+
path: z.string().min(1).describe('File path to process'),
|
|
92
|
+
},
|
|
93
|
+
outputSchema: {
|
|
94
|
+
result: z.string(),
|
|
95
|
+
path: z.string(),
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
export class SafeFileTool extends ToolContext {
|
|
99
|
+
async execute(input: { path: string }) {
|
|
100
|
+
// Use os.homedir() and os.tmpdir() — no hardcoded paths
|
|
101
|
+
const os = await import('os');
|
|
102
|
+
const pathMod = await import('path');
|
|
103
|
+
|
|
104
|
+
// Ensure we only read from safe locations
|
|
105
|
+
const resolved = pathMod.resolve(input.path);
|
|
106
|
+
const home = os.homedir();
|
|
107
|
+
const tmp = os.tmpdir();
|
|
108
|
+
|
|
109
|
+
const relToHome = pathMod.relative(home, resolved);
|
|
110
|
+
const relToTmp = pathMod.relative(tmp, resolved);
|
|
111
|
+
const isInHome = !relToHome.startsWith('..') && !pathMod.isAbsolute(relToHome);
|
|
112
|
+
const isInTmp = !relToTmp.startsWith('..') && !pathMod.isAbsolute(relToTmp);
|
|
113
|
+
if (!isInHome && !isInTmp) {
|
|
114
|
+
this.fail(new Error('Path must be within home directory or temp directory'));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return { result: 'processed', path: resolved };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## What This Demonstrates
|
|
123
|
+
|
|
124
|
+
- Exit code conventions: 0 (success), 1 (user error), 2 (internal error)
|
|
125
|
+
- Using stderr for all logging since stdout is the MCP JSON-RPC channel
|
|
126
|
+
- Handling EOF on stdin and broken pipe on stdout gracefully
|
|
127
|
+
- Showing helpful error messages for unknown flags instead of stack traces
|
|
128
|
+
- Validating file paths to prevent writes to unexpected locations
|
|
129
|
+
|
|
130
|
+
## Related
|
|
131
|
+
|
|
132
|
+
- See `production-cli-binary` for the full stdin/stdout transport and exit behavior checklist
|
package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/daemon-socket-config.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: daemon-socket-config
|
|
3
|
+
reference: production-cli-daemon
|
|
4
|
+
level: basic
|
|
5
|
+
description: 'Shows how to configure a FrontMCP server as a long-running local daemon with Unix socket transport, process management, and SQLite storage.'
|
|
6
|
+
tags: [production, unix-socket, sqlite, cli, transport, performance]
|
|
7
|
+
features:
|
|
8
|
+
- 'Configuring Unix socket transport for local-only communication'
|
|
9
|
+
- 'Using SQLite with WAL mode for concurrent read/write performance'
|
|
10
|
+
- 'Storing data in user-specific config directory (`~/.config/`)'
|
|
11
|
+
- 'Process management with `frontmcp start/stop/restart/status/logs`'
|
|
12
|
+
- 'System service registration for auto-start on boot'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Daemon Process with Unix Socket Transport
|
|
16
|
+
|
|
17
|
+
Shows how to configure a FrontMCP server as a long-running local daemon with Unix socket transport, process management, and SQLite storage.
|
|
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: 'my-daemon', version: '1.0.0' },
|
|
28
|
+
apps: [MyApp],
|
|
29
|
+
|
|
30
|
+
// Unix socket transport — no network exposure
|
|
31
|
+
http: {
|
|
32
|
+
socketPath: '/tmp/my-daemon.sock',
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
// SQLite for local persistence (sessions, cache)
|
|
36
|
+
sqlite: {
|
|
37
|
+
path: `${process.env.HOME}/.config/my-daemon/data.db`,
|
|
38
|
+
wal: true, // WAL mode for concurrent reads
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
export default class MyDaemonServer {}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Process management commands
|
|
46
|
+
|
|
47
|
+
# Start the daemon
|
|
48
|
+
frontmcp start my-daemon --entry ./src/main.ts
|
|
49
|
+
|
|
50
|
+
# Check status
|
|
51
|
+
frontmcp status
|
|
52
|
+
# Output: my-daemon running pid:12345 socket:/tmp/my-daemon.sock
|
|
53
|
+
|
|
54
|
+
# View logs
|
|
55
|
+
frontmcp logs my-daemon --follow
|
|
56
|
+
|
|
57
|
+
# Restart without orphaned processes
|
|
58
|
+
frontmcp restart my-daemon
|
|
59
|
+
|
|
60
|
+
# Stop cleanly
|
|
61
|
+
frontmcp stop my-daemon
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Register as a system service (auto-start on boot)
|
|
66
|
+
frontmcp service install my-daemon
|
|
67
|
+
|
|
68
|
+
# Verify system health
|
|
69
|
+
frontmcp doctor
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## What This Demonstrates
|
|
73
|
+
|
|
74
|
+
- Configuring Unix socket transport for local-only communication
|
|
75
|
+
- Using SQLite with WAL mode for concurrent read/write performance
|
|
76
|
+
- Storing data in user-specific config directory (`~/.config/`)
|
|
77
|
+
- Process management with `frontmcp start/stop/restart/status/logs`
|
|
78
|
+
- System service registration for auto-start on boot
|
|
79
|
+
|
|
80
|
+
## Related
|
|
81
|
+
|
|
82
|
+
- See `production-cli-daemon` for the full daemon process management checklist
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: graceful-shutdown-cleanup
|
|
3
|
+
reference: production-cli-daemon
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Shows how to implement graceful shutdown for a daemon process, including completing in-flight requests, closing database connections, removing the socket file, and cleaning up the PID file.'
|
|
6
|
+
tags: [production, unix-socket, cli, database, daemon, graceful]
|
|
7
|
+
features:
|
|
8
|
+
- 'SIGTERM handler that completes in-flight requests before exiting'
|
|
9
|
+
- 'Removing the Unix socket file to prevent stale `.sock` files on restart'
|
|
10
|
+
- 'Cleaning up the PID file on shutdown'
|
|
11
|
+
- 'Using `@frontmcp/utils` (`unlink`, `fileExists`, `ensureDir`) for file operations'
|
|
12
|
+
- 'Implementing `onDestroy()` to close database connections'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Daemon Graceful Shutdown with Socket Cleanup
|
|
16
|
+
|
|
17
|
+
Shows how to implement graceful shutdown for a daemon process, including completing in-flight requests, closing database connections, removing the socket file, and cleaning up the PID file.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// src/lifecycle/daemon-shutdown.ts
|
|
23
|
+
import { unlink, fileExists } from '@frontmcp/utils';
|
|
24
|
+
|
|
25
|
+
export function setupDaemonShutdown(server: { close: () => Promise<void>; dispose: () => Promise<void> }): void {
|
|
26
|
+
const socketPath = '/tmp/my-daemon.sock';
|
|
27
|
+
const pidFile = `${process.env.HOME}/.config/my-daemon/daemon.pid`;
|
|
28
|
+
|
|
29
|
+
const shutdown = async (signal: string) => {
|
|
30
|
+
console.log(`[daemon] Received ${signal}. Shutting down...`);
|
|
31
|
+
|
|
32
|
+
// 1. Stop accepting new connections
|
|
33
|
+
await server.close();
|
|
34
|
+
console.log('[daemon] Server closed.');
|
|
35
|
+
|
|
36
|
+
// 2. Dispose all resources (SQLite, providers)
|
|
37
|
+
await server.dispose();
|
|
38
|
+
console.log('[daemon] Resources disposed.');
|
|
39
|
+
|
|
40
|
+
// 3. Remove socket file (prevent stale .sock files)
|
|
41
|
+
if (await fileExists(socketPath)) {
|
|
42
|
+
await unlink(socketPath);
|
|
43
|
+
console.log(`[daemon] Socket removed: ${socketPath}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 4. Clean up PID file
|
|
47
|
+
if (await fileExists(pidFile)) {
|
|
48
|
+
await unlink(pidFile);
|
|
49
|
+
console.log(`[daemon] PID file removed: ${pidFile}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
process.exit(0);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
56
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// src/providers/sqlite-store.provider.ts
|
|
62
|
+
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
63
|
+
|
|
64
|
+
export const LOCAL_STORE = Symbol('LocalStore');
|
|
65
|
+
|
|
66
|
+
@Provider({ token: LOCAL_STORE, scope: ProviderScope.GLOBAL })
|
|
67
|
+
export class SqliteStoreProvider {
|
|
68
|
+
private db!: { close: () => void; exec: (sql: string) => void };
|
|
69
|
+
|
|
70
|
+
async onInit(): Promise<void> {
|
|
71
|
+
// Database path is configurable, not hardcoded
|
|
72
|
+
const dbPath = process.env.DB_PATH ?? `${process.env.HOME}/.config/my-daemon/data.db`;
|
|
73
|
+
|
|
74
|
+
// Ensure directory exists
|
|
75
|
+
const { ensureDir } = await import('@frontmcp/utils');
|
|
76
|
+
const path = await import('path');
|
|
77
|
+
await ensureDir(path.dirname(dbPath));
|
|
78
|
+
|
|
79
|
+
// Initialize with WAL mode for concurrent reads
|
|
80
|
+
// Auto-migrate on startup
|
|
81
|
+
this.db = await this.openDatabase(dbPath);
|
|
82
|
+
this.db.exec('PRAGMA journal_mode=WAL');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async onDestroy(): Promise<void> {
|
|
86
|
+
// Close database connection on shutdown
|
|
87
|
+
this.db.close();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private async openDatabase(path: string) {
|
|
91
|
+
// Replace with your SQLite driver (e.g., better-sqlite3)
|
|
92
|
+
throw new Error('Implement with your SQLite driver');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## What This Demonstrates
|
|
98
|
+
|
|
99
|
+
- SIGTERM handler that completes in-flight requests before exiting
|
|
100
|
+
- Removing the Unix socket file to prevent stale `.sock` files on restart
|
|
101
|
+
- Cleaning up the PID file on shutdown
|
|
102
|
+
- Using `@frontmcp/utils` (`unlink`, `fileExists`, `ensureDir`) for file operations
|
|
103
|
+
- Implementing `onDestroy()` to close database connections
|
|
104
|
+
|
|
105
|
+
## Related
|
|
106
|
+
|
|
107
|
+
- See `production-cli-daemon` for the full graceful shutdown and security checklist
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-and-permissions
|
|
3
|
+
reference: production-cli-daemon
|
|
4
|
+
level: advanced
|
|
5
|
+
description: 'Shows how to secure a local daemon with restrictive socket permissions, XDG-compliant config storage, and file-based secret management.'
|
|
6
|
+
tags: [production, cli, transport, security, local, node]
|
|
7
|
+
features:
|
|
8
|
+
- 'XDG Base Directory compliance for config and data storage'
|
|
9
|
+
- 'Restrictive file permissions: config at `700`, secrets at `600`'
|
|
10
|
+
- 'Verifying secret file permissions before reading (fail if insecure)'
|
|
11
|
+
- 'Socket-only transport with no TCP network exposure'
|
|
12
|
+
- 'Using `@frontmcp/utils` for file operations instead of `node:fs`'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Daemon Security: Socket Permissions, Config Storage, and Secret Management
|
|
16
|
+
|
|
17
|
+
Shows how to secure a local daemon with restrictive socket permissions, XDG-compliant config storage, and file-based secret management.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// src/lifecycle/daemon-security.ts
|
|
23
|
+
import { stat, writeFile, fileExists, ensureDir, readFile } from '@frontmcp/utils';
|
|
24
|
+
import { chmod } from 'fs/promises';
|
|
25
|
+
import * as path from 'path';
|
|
26
|
+
import * as os from 'os';
|
|
27
|
+
|
|
28
|
+
// XDG Base Directory compliance
|
|
29
|
+
function getConfigDir(appName: string): string {
|
|
30
|
+
return process.env.XDG_CONFIG_HOME
|
|
31
|
+
? path.join(process.env.XDG_CONFIG_HOME, appName)
|
|
32
|
+
: path.join(os.homedir(), '.config', appName);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getDataDir(appName: string): string {
|
|
36
|
+
return process.env.XDG_DATA_HOME
|
|
37
|
+
? path.join(process.env.XDG_DATA_HOME, appName)
|
|
38
|
+
: path.join(os.homedir(), '.local', 'share', appName);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function ensureSecureSetup(appName: string): Promise<{
|
|
42
|
+
configDir: string;
|
|
43
|
+
dataDir: string;
|
|
44
|
+
}> {
|
|
45
|
+
const configDir = getConfigDir(appName);
|
|
46
|
+
const dataDir = getDataDir(appName);
|
|
47
|
+
|
|
48
|
+
// Create directories with restrictive permissions
|
|
49
|
+
await ensureDir(configDir);
|
|
50
|
+
await ensureDir(dataDir);
|
|
51
|
+
|
|
52
|
+
// Config directory: owner-only access (700)
|
|
53
|
+
await chmod(configDir, 0o700);
|
|
54
|
+
|
|
55
|
+
// Secrets file: owner-only read/write (600)
|
|
56
|
+
const secretsFile = path.join(configDir, 'secrets.json');
|
|
57
|
+
if (await fileExists(secretsFile)) {
|
|
58
|
+
await chmod(secretsFile, 0o600);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { configDir, dataDir };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function loadSecrets(configDir: string): Promise<Record<string, string>> {
|
|
65
|
+
const secretsFile = path.join(configDir, 'secrets.json');
|
|
66
|
+
|
|
67
|
+
if (!(await fileExists(secretsFile))) {
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Verify permissions before reading
|
|
72
|
+
const fileStat = await stat(secretsFile);
|
|
73
|
+
const mode = fileStat.mode & 0o777;
|
|
74
|
+
if (mode !== 0o600) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`Secrets file has insecure permissions: ${mode.toString(8)}. Expected 600. ` +
|
|
77
|
+
`Fix with: chmod 600 ${secretsFile}`,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const content = await readFile(secretsFile);
|
|
82
|
+
return JSON.parse(content);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// src/main.ts
|
|
88
|
+
import { FrontMcp } from '@frontmcp/sdk';
|
|
89
|
+
import { MyApp } from './my.app';
|
|
90
|
+
|
|
91
|
+
@FrontMcp({
|
|
92
|
+
info: { name: 'secure-daemon', version: '1.0.0' },
|
|
93
|
+
apps: [MyApp],
|
|
94
|
+
|
|
95
|
+
// Socket-only — no TCP network exposure
|
|
96
|
+
http: {
|
|
97
|
+
socketPath: '/tmp/secure-daemon.sock',
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
// SQLite in the data directory (persistent, writable)
|
|
101
|
+
sqlite: {
|
|
102
|
+
path: `${process.env.XDG_DATA_HOME ?? process.env.HOME + '/.local/share'}/secure-daemon/data.db`,
|
|
103
|
+
wal: true,
|
|
104
|
+
},
|
|
105
|
+
})
|
|
106
|
+
export default class SecureDaemonServer {}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## What This Demonstrates
|
|
110
|
+
|
|
111
|
+
- XDG Base Directory compliance for config and data storage
|
|
112
|
+
- Restrictive file permissions: config at `700`, secrets at `600`
|
|
113
|
+
- Verifying secret file permissions before reading (fail if insecure)
|
|
114
|
+
- Socket-only transport with no TCP network exposure
|
|
115
|
+
- Using `@frontmcp/utils` for file operations instead of `node:fs`
|
|
116
|
+
|
|
117
|
+
## Related
|
|
118
|
+
|
|
119
|
+
- See `production-cli-daemon` for the full security and storage checklist
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: durable-objects-state
|
|
3
|
+
reference: production-cloudflare
|
|
4
|
+
level: advanced
|
|
5
|
+
description: 'Shows how to use Cloudflare Durable Objects for stateful coordination alongside the stateless Workers runtime, with KV for cache and R2 for blob storage.'
|
|
6
|
+
tags: [production, cloudflare, cache, throttle, durable, objects]
|
|
7
|
+
features:
|
|
8
|
+
- 'Using Durable Objects for stateful coordination (rate limiting) in an ephemeral Workers runtime'
|
|
9
|
+
- 'Using R2 for blob/file storage since Workers have no filesystem'
|
|
10
|
+
- 'Combining KV (cache), R2 (files), and Durable Objects (state) in one deployment'
|
|
11
|
+
- 'Wrangler configuration with all three binding types'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Stateful Coordination with Durable Objects
|
|
15
|
+
|
|
16
|
+
Shows how to use Cloudflare Durable Objects for stateful coordination alongside the stateless Workers runtime, with KV for cache and R2 for blob storage.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```toml
|
|
21
|
+
# wrangler.toml — with Durable Objects and R2
|
|
22
|
+
name = "stateful-mcp-worker"
|
|
23
|
+
main = "dist/worker.js"
|
|
24
|
+
compatibility_date = "2024-01-01"
|
|
25
|
+
|
|
26
|
+
# KV for cache
|
|
27
|
+
[[kv_namespaces]]
|
|
28
|
+
binding = "CACHE"
|
|
29
|
+
id = "cache-namespace-id"
|
|
30
|
+
|
|
31
|
+
# R2 for blob/file storage
|
|
32
|
+
[[r2_buckets]]
|
|
33
|
+
binding = "FILES"
|
|
34
|
+
bucket_name = "mcp-files"
|
|
35
|
+
|
|
36
|
+
# Durable Objects for stateful coordination
|
|
37
|
+
[durable_objects]
|
|
38
|
+
bindings = [
|
|
39
|
+
{ name = "RATE_LIMITER", class_name = "RateLimiterDO" }
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[[migrations]]
|
|
43
|
+
tag = "v1"
|
|
44
|
+
new_classes = ["RateLimiterDO"]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// src/tools/rate-limited-action.tool.ts
|
|
49
|
+
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
50
|
+
import { z } from 'zod';
|
|
51
|
+
|
|
52
|
+
@Tool({
|
|
53
|
+
name: 'rate_limited_action',
|
|
54
|
+
description: 'An action that uses Durable Objects for distributed rate limiting',
|
|
55
|
+
inputSchema: {
|
|
56
|
+
userId: z.string().min(1).describe('User identifier'),
|
|
57
|
+
action: z.string().min(1).describe('Action to perform'),
|
|
58
|
+
},
|
|
59
|
+
outputSchema: {
|
|
60
|
+
allowed: z.boolean(),
|
|
61
|
+
remaining: z.number(),
|
|
62
|
+
action: z.string(),
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
export class RateLimitedActionTool extends ToolContext {
|
|
66
|
+
async execute(input: { userId: string; action: string }) {
|
|
67
|
+
// Durable Objects provide stateful rate limiting across Workers instances
|
|
68
|
+
// Each user gets their own Durable Object instance for consistent state
|
|
69
|
+
const result = await this.fetch(`https://internal/rate-check/${input.userId}`, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: { 'Content-Type': 'application/json' },
|
|
72
|
+
body: JSON.stringify({ action: input.action }),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const { allowed, remaining } = await result.json();
|
|
76
|
+
|
|
77
|
+
if (!allowed) {
|
|
78
|
+
this.fail(new Error(`Rate limit exceeded for user ${input.userId}`));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { allowed, remaining, action: input.action };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// src/tools/file-upload.tool.ts
|
|
88
|
+
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
89
|
+
import { z } from 'zod';
|
|
90
|
+
|
|
91
|
+
@Tool({
|
|
92
|
+
name: 'upload_file',
|
|
93
|
+
description: 'Upload a file to R2 object storage',
|
|
94
|
+
inputSchema: {
|
|
95
|
+
filename: z.string().min(1).describe('File name'),
|
|
96
|
+
content: z.string().min(1).describe('File content (base64 encoded)'),
|
|
97
|
+
},
|
|
98
|
+
outputSchema: {
|
|
99
|
+
key: z.string(),
|
|
100
|
+
url: z.string(),
|
|
101
|
+
size: z.number(),
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
export class FileUploadTool extends ToolContext {
|
|
105
|
+
async execute(input: { filename: string; content: string }) {
|
|
106
|
+
// R2 for blob/file storage — no filesystem in Workers
|
|
107
|
+
const key = `uploads/${Date.now()}-${input.filename}`;
|
|
108
|
+
const size = input.content.length;
|
|
109
|
+
|
|
110
|
+
return { key, url: `https://files.example.com/${key}`, size };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## What This Demonstrates
|
|
116
|
+
|
|
117
|
+
- Using Durable Objects for stateful coordination (rate limiting) in an ephemeral Workers runtime
|
|
118
|
+
- Using R2 for blob/file storage since Workers have no filesystem
|
|
119
|
+
- Combining KV (cache), R2 (files), and Durable Objects (state) in one deployment
|
|
120
|
+
- Wrangler configuration with all three binding types
|
|
121
|
+
|
|
122
|
+
## Related
|
|
123
|
+
|
|
124
|
+
- See `production-cloudflare` for the full storage and scaling checklist
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: workers-runtime-constraints
|
|
3
|
+
reference: production-cloudflare
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Shows how to write tools that are compatible with the Cloudflare Workers runtime: no Node.js APIs, no eval, only async I/O, and using Web APIs.'
|
|
6
|
+
tags: [production, cloudflare, node, workers, runtime, constraints]
|
|
7
|
+
features:
|
|
8
|
+
- 'Using `@frontmcp/utils` for crypto instead of `node:crypto` (Workers use V8 isolates, not Node)'
|
|
9
|
+
- 'All I/O is async (no synchronous blocking operations allowed in Workers)'
|
|
10
|
+
- 'No `eval()` or dynamic `Function()` (prohibited in Workers)'
|
|
11
|
+
- 'No filesystem access (Workers have no filesystem)'
|
|
12
|
+
- 'Using Fetch API via `this.fetch()` instead of Node.js `http`/`https`'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Workers Runtime Constraints and Compatibility
|
|
16
|
+
|
|
17
|
+
Shows how to write tools that are compatible with the Cloudflare Workers runtime: no Node.js APIs, no eval, only async I/O, and using Web APIs.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// src/tools/worker-safe.tool.ts
|
|
23
|
+
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
// Use @frontmcp/utils — wraps Web Crypto API, works in Workers
|
|
26
|
+
import { sha256Hex, randomUUID, base64urlEncode } from '@frontmcp/utils';
|
|
27
|
+
|
|
28
|
+
@Tool({
|
|
29
|
+
name: 'transform_data',
|
|
30
|
+
description: 'Transform and hash data in a Workers-compatible way',
|
|
31
|
+
inputSchema: {
|
|
32
|
+
payload: z.string().min(1).describe('Data to transform'),
|
|
33
|
+
},
|
|
34
|
+
outputSchema: {
|
|
35
|
+
id: z.string(),
|
|
36
|
+
hash: z.string(),
|
|
37
|
+
encoded: z.string(),
|
|
38
|
+
timestamp: z.string(),
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
export class TransformDataTool extends ToolContext {
|
|
42
|
+
async execute(input: { payload: string }) {
|
|
43
|
+
// All operations are async — no synchronous blocking
|
|
44
|
+
|
|
45
|
+
// Cross-platform crypto (Web Crypto under the hood)
|
|
46
|
+
const id = randomUUID();
|
|
47
|
+
const hash = sha256Hex(input.payload);
|
|
48
|
+
const encoded = base64urlEncode(input.payload);
|
|
49
|
+
|
|
50
|
+
// Use this.fetch() — standard Fetch API, not node http
|
|
51
|
+
const response = await this.fetch('https://api.example.com/transform', {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: { 'Content-Type': 'application/json' },
|
|
54
|
+
body: JSON.stringify({ id, payload: input.payload }),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
this.fail(new Error(`Transform API error: ${response.status}`));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
id,
|
|
63
|
+
hash,
|
|
64
|
+
encoded,
|
|
65
|
+
timestamp: new Date().toISOString(),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// src/providers/kv-store.provider.ts
|
|
73
|
+
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
74
|
+
|
|
75
|
+
export const KV_STORE = Symbol('KvStore');
|
|
76
|
+
|
|
77
|
+
// Workers KV — no filesystem, no eval, no dynamic Function()
|
|
78
|
+
@Provider({ token: KV_STORE, scope: ProviderScope.GLOBAL })
|
|
79
|
+
export class KvStoreProvider {
|
|
80
|
+
// Workers KV is bound via wrangler.toml, accessed from env
|
|
81
|
+
async get(key: string): Promise<string | null> {
|
|
82
|
+
// In Workers, KV is available via the environment binding
|
|
83
|
+
// This is a pattern — actual binding depends on your worker setup
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async put(key: string, value: string, ttlSeconds?: number): Promise<void> {
|
|
88
|
+
// KV put with optional TTL
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## What This Demonstrates
|
|
94
|
+
|
|
95
|
+
- Using `@frontmcp/utils` for crypto instead of `node:crypto` (Workers use V8 isolates, not Node)
|
|
96
|
+
- All I/O is async (no synchronous blocking operations allowed in Workers)
|
|
97
|
+
- No `eval()` or dynamic `Function()` (prohibited in Workers)
|
|
98
|
+
- No filesystem access (Workers have no filesystem)
|
|
99
|
+
- Using Fetch API via `this.fetch()` instead of Node.js `http`/`https`
|
|
100
|
+
|
|
101
|
+
## Related
|
|
102
|
+
|
|
103
|
+
- See `production-cloudflare` for the full Workers runtime and performance checklist
|