@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
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: js-bundle-import-test
|
|
3
|
+
reference: test-cli-binary
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Verify that the compiled JS bundle can be imported and exports the expected modules after a `frontmcp build` step.'
|
|
6
|
+
tags: [testing, cli, binary, js, bundle, import]
|
|
7
|
+
features:
|
|
8
|
+
- 'Using dynamic `import()` to test that the built JS bundle is importable'
|
|
9
|
+
- 'Verifying the bundle has a default export (server class or factory)'
|
|
10
|
+
- 'Testing CommonJS `require()` compatibility to ensure the bundle works in CJS environments'
|
|
11
|
+
- 'Pointing to the `dist/` output directory where `frontmcp build` places artifacts'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Testing JS Bundle Importability
|
|
15
|
+
|
|
16
|
+
Verify that the compiled JS bundle can be imported and exports the expected modules after a `frontmcp build` step.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/__tests__/js-bundle.spec.ts
|
|
22
|
+
import * as path from 'path';
|
|
23
|
+
|
|
24
|
+
const DIST_DIR = path.resolve(__dirname, '../dist');
|
|
25
|
+
|
|
26
|
+
describe('JS Bundle', () => {
|
|
27
|
+
it('should be importable as a CJS module', async () => {
|
|
28
|
+
const mod = await import(path.join(DIST_DIR, 'my-server.cjs.js'));
|
|
29
|
+
expect(mod).toBeDefined();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should export a default server module', async () => {
|
|
33
|
+
const mod = await import(path.join(DIST_DIR, 'my-server.cjs.js'));
|
|
34
|
+
// The default export should be the server class or factory
|
|
35
|
+
expect(mod.default || mod).toBeDefined();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should not throw on require', () => {
|
|
39
|
+
expect(() => {
|
|
40
|
+
require(path.join(DIST_DIR, 'my-server.cjs.js'));
|
|
41
|
+
}).not.toThrow();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## What This Demonstrates
|
|
47
|
+
|
|
48
|
+
- Using dynamic `import()` to test that the built JS bundle is importable
|
|
49
|
+
- Verifying the bundle has a default export (server class or factory)
|
|
50
|
+
- Testing CommonJS `require()` compatibility to ensure the bundle works in CJS environments
|
|
51
|
+
- Pointing to the `dist/` output directory where `frontmcp build` places artifacts
|
|
52
|
+
|
|
53
|
+
## Related
|
|
54
|
+
|
|
55
|
+
- See `test-cli-binary` for the full CLI binary testing reference
|
|
56
|
+
- See `test-browser-build` for browser-specific build testing
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: basic-create-test
|
|
3
|
+
reference: test-direct-client
|
|
4
|
+
level: basic
|
|
5
|
+
description: 'Test tools in-memory without any HTTP overhead using the `create()` function from `@frontmcp/sdk`.'
|
|
6
|
+
tags: [testing, sdk, transport, direct-client, direct, client]
|
|
7
|
+
features:
|
|
8
|
+
- 'Using `create()` to spin up an in-memory server with no HTTP transport'
|
|
9
|
+
- 'Defining tools inline with the functional `tool()` API and Zod schemas'
|
|
10
|
+
- 'Calling tools directly via `server.callTool()` and checking text content'
|
|
11
|
+
- 'Proper cleanup with `server.dispose()` in each test'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Basic In-Memory Testing with create()
|
|
15
|
+
|
|
16
|
+
Test tools in-memory without any HTTP overhead using the `create()` function from `@frontmcp/sdk`.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/__tests__/direct-client.spec.ts
|
|
22
|
+
import { create } from '@frontmcp/sdk';
|
|
23
|
+
import { tool } from '@frontmcp/sdk';
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
|
|
26
|
+
const AddTool = tool({
|
|
27
|
+
name: 'add',
|
|
28
|
+
description: 'Add numbers',
|
|
29
|
+
inputSchema: { a: z.number(), b: z.number() },
|
|
30
|
+
outputSchema: { sum: z.number() },
|
|
31
|
+
})((input) => ({ sum: input.a + input.b }));
|
|
32
|
+
|
|
33
|
+
describe('Direct Client Testing', () => {
|
|
34
|
+
it('should call tools via create()', async () => {
|
|
35
|
+
const server = await create({
|
|
36
|
+
info: { name: 'test', version: '1.0.0' },
|
|
37
|
+
tools: [AddTool],
|
|
38
|
+
cacheKey: 'test-direct',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const result = await server.callTool('add', { a: 2, b: 3 });
|
|
42
|
+
expect(result.content[0].text).toContain('5');
|
|
43
|
+
|
|
44
|
+
await server.dispose();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should handle multiple tool calls', async () => {
|
|
48
|
+
const server = await create({
|
|
49
|
+
info: { name: 'test', version: '1.0.0' },
|
|
50
|
+
tools: [AddTool],
|
|
51
|
+
cacheKey: 'test-direct-multi',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const r1 = await server.callTool('add', { a: 10, b: 20 });
|
|
55
|
+
expect(r1.content[0].text).toContain('30');
|
|
56
|
+
|
|
57
|
+
const r2 = await server.callTool('add', { a: -5, b: 5 });
|
|
58
|
+
expect(r2.content[0].text).toContain('0');
|
|
59
|
+
|
|
60
|
+
await server.dispose();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## What This Demonstrates
|
|
66
|
+
|
|
67
|
+
- Using `create()` to spin up an in-memory server with no HTTP transport
|
|
68
|
+
- Defining tools inline with the functional `tool()` API and Zod schemas
|
|
69
|
+
- Calling tools directly via `server.callTool()` and checking text content
|
|
70
|
+
- Proper cleanup with `server.dispose()` in each test
|
|
71
|
+
|
|
72
|
+
## Related
|
|
73
|
+
|
|
74
|
+
- See `test-direct-client` for the full direct client testing reference
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: openai-claude-format-test
|
|
3
|
+
reference: test-direct-client
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Verify that tools are returned in the correct format for OpenAI and Claude clients using `connectOpenAI` and `connectClaude`.'
|
|
6
|
+
tags: [testing, openai, anthropic, direct-client, direct, client]
|
|
7
|
+
features:
|
|
8
|
+
- 'Using `connectOpenAI()` with `serve: false` to get an in-memory client without starting an HTTP server'
|
|
9
|
+
- "Verifying OpenAI tool format: `{ type: 'function', function: { name, parameters } }`"
|
|
10
|
+
- 'Using dynamic import for `connectClaude` to test Claude tool format: `{ name, description, input_schema }`'
|
|
11
|
+
- 'Proper cleanup with `client.close()` after each test'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Testing OpenAI and Claude Tool Formats
|
|
15
|
+
|
|
16
|
+
Verify that tools are returned in the correct format for OpenAI and Claude clients using `connectOpenAI` and `connectClaude`.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/__tests__/client-formats.spec.ts
|
|
22
|
+
import { connectOpenAI } from '@frontmcp/sdk';
|
|
23
|
+
import { tool } from '@frontmcp/sdk';
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
|
|
26
|
+
const AddTool = tool({
|
|
27
|
+
name: 'add',
|
|
28
|
+
description: 'Add numbers',
|
|
29
|
+
inputSchema: { a: z.number(), b: z.number() },
|
|
30
|
+
outputSchema: { sum: z.number() },
|
|
31
|
+
})((input) => ({ sum: input.a + input.b }));
|
|
32
|
+
|
|
33
|
+
describe('OpenAI format', () => {
|
|
34
|
+
it('should return OpenAI-formatted tools', async () => {
|
|
35
|
+
const client = await connectOpenAI({
|
|
36
|
+
info: { name: 'test', version: '1.0.0' },
|
|
37
|
+
tools: [AddTool],
|
|
38
|
+
serve: false,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const tools = await client.listTools();
|
|
42
|
+
// OpenAI format: [{ type: 'function', function: { name, parameters } }]
|
|
43
|
+
expect(tools[0].type).toBe('function');
|
|
44
|
+
expect(tools[0].function.name).toBe('add');
|
|
45
|
+
expect(tools[0].function.parameters).toBeDefined();
|
|
46
|
+
|
|
47
|
+
await client.close();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('Claude format', () => {
|
|
52
|
+
it('should return Claude-formatted tools', async () => {
|
|
53
|
+
const { connectClaude } = await import('@frontmcp/sdk');
|
|
54
|
+
const client = await connectClaude({
|
|
55
|
+
info: { name: 'test', version: '1.0.0' },
|
|
56
|
+
tools: [AddTool],
|
|
57
|
+
serve: false,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const tools = await client.listTools();
|
|
61
|
+
// Claude format: [{ name, description, input_schema }]
|
|
62
|
+
expect(tools[0].name).toBe('add');
|
|
63
|
+
expect(tools[0].input_schema).toBeDefined();
|
|
64
|
+
|
|
65
|
+
await client.close();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## What This Demonstrates
|
|
71
|
+
|
|
72
|
+
- Using `connectOpenAI()` with `serve: false` to get an in-memory client without starting an HTTP server
|
|
73
|
+
- Verifying OpenAI tool format: `{ type: 'function', function: { name, parameters } }`
|
|
74
|
+
- Using dynamic import for `connectClaude` to test Claude tool format: `{ name, description, input_schema }`
|
|
75
|
+
- Proper cleanup with `client.close()` after each test
|
|
76
|
+
|
|
77
|
+
## Related
|
|
78
|
+
|
|
79
|
+
- See `test-direct-client` for the full direct client testing reference
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: basic-e2e-test
|
|
3
|
+
reference: test-e2e-handler
|
|
4
|
+
level: basic
|
|
5
|
+
description: 'Set up a basic E2E test that starts a server, connects a client, and verifies tools are listed.'
|
|
6
|
+
tags: [testing, e2e, handler]
|
|
7
|
+
features:
|
|
8
|
+
- 'Using `TestServer.create()` to start a server from its module export'
|
|
9
|
+
- 'Connecting a client via `server.connect()` for automatic base URL wiring'
|
|
10
|
+
- 'Proper lifecycle management with `beforeAll` / `afterAll` for setup and teardown'
|
|
11
|
+
- 'Using the `toContainTool` custom matcher from `@frontmcp/testing`'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Basic E2E Test with McpTestClient
|
|
15
|
+
|
|
16
|
+
Set up a basic E2E test that starts a server, connects a client, and verifies tools are listed.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/__tests__/server.e2e.spec.ts
|
|
22
|
+
import { McpTestClient, TestServer } from '@frontmcp/testing';
|
|
23
|
+
import Server from '../src/main';
|
|
24
|
+
|
|
25
|
+
describe('Server E2E', () => {
|
|
26
|
+
let client: McpTestClient;
|
|
27
|
+
let server: TestServer;
|
|
28
|
+
|
|
29
|
+
beforeAll(async () => {
|
|
30
|
+
server = await TestServer.create(Server);
|
|
31
|
+
client = await server.connect();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterAll(async () => {
|
|
35
|
+
await client.close();
|
|
36
|
+
await server.dispose();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should list all tools', async () => {
|
|
40
|
+
const { tools } = await client.listTools();
|
|
41
|
+
expect(tools.length).toBeGreaterThan(0);
|
|
42
|
+
expect(tools).toContainTool('add_numbers');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should list resources', async () => {
|
|
46
|
+
const { resources } = await client.listResources();
|
|
47
|
+
expect(resources.length).toBeGreaterThanOrEqual(0);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should list prompts', async () => {
|
|
51
|
+
const result = await client.getPrompt('summarize', { topic: 'testing' });
|
|
52
|
+
expect(result.messages).toBeDefined();
|
|
53
|
+
expect(result.messages.length).toBeGreaterThan(0);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## What This Demonstrates
|
|
59
|
+
|
|
60
|
+
- Using `TestServer.create()` to start a server from its module export
|
|
61
|
+
- Connecting a client via `server.connect()` for automatic base URL wiring
|
|
62
|
+
- Proper lifecycle management with `beforeAll` / `afterAll` for setup and teardown
|
|
63
|
+
- Using the `toContainTool` custom matcher from `@frontmcp/testing`
|
|
64
|
+
|
|
65
|
+
## Related
|
|
66
|
+
|
|
67
|
+
- See `test-e2e-handler` for the full E2E handler testing reference
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: manual-client-with-transport
|
|
3
|
+
reference: test-e2e-handler
|
|
4
|
+
level: advanced
|
|
5
|
+
description: 'Use `McpTestClient.create()` with explicit transport settings for fine-grained control over E2E tests.'
|
|
6
|
+
tags: [testing, session, transport, e2e, handler, manual]
|
|
7
|
+
features:
|
|
8
|
+
- 'Using `TestServer.start()` with an explicit command and port for process-based server startup'
|
|
9
|
+
- "Building a client with `McpTestClient.create().withTransport('modern').buildAndConnect()` for streamable HTTP + strict sessions"
|
|
10
|
+
- 'Using `server.info.baseUrl` to wire the client to the correct address'
|
|
11
|
+
- 'Separate `disconnect()` / `stop()` calls for client and server teardown'
|
|
12
|
+
- 'The `toBeError()` and `toHaveTextContent()` custom matchers'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Manual McpTestClient with Transport Configuration
|
|
16
|
+
|
|
17
|
+
Use `McpTestClient.create()` with explicit transport settings for fine-grained control over E2E tests.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// src/__tests__/advanced.e2e.spec.ts
|
|
23
|
+
import { McpTestClient, TestServer } from '@frontmcp/testing';
|
|
24
|
+
|
|
25
|
+
describe('Advanced E2E with Transport Config', () => {
|
|
26
|
+
let server: TestServer;
|
|
27
|
+
let client: McpTestClient;
|
|
28
|
+
|
|
29
|
+
beforeAll(async () => {
|
|
30
|
+
server = await TestServer.start({
|
|
31
|
+
command: 'npx tsx src/main.ts',
|
|
32
|
+
port: 3004,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
client = await McpTestClient.create({ baseUrl: server.info.baseUrl }).withTransport('modern').buildAndConnect();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
afterAll(async () => {
|
|
39
|
+
await client.disconnect();
|
|
40
|
+
await server.stop();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should list tools after initialization', async () => {
|
|
44
|
+
const tools = await client.tools.list();
|
|
45
|
+
expect(tools.length).toBeGreaterThan(0);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should handle tool errors gracefully', async () => {
|
|
49
|
+
const result = await client.tools.call('nonexistent_tool', {});
|
|
50
|
+
expect(result).toBeError();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should call tool and verify result shape', async () => {
|
|
54
|
+
const result = await client.tools.call('add_numbers', { a: 1, b: 2 });
|
|
55
|
+
expect(result).toBeSuccessful();
|
|
56
|
+
expect(result).toHaveTextContent('3');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## What This Demonstrates
|
|
62
|
+
|
|
63
|
+
- Using `TestServer.start()` with an explicit command and port for process-based server startup
|
|
64
|
+
- Building a client with `McpTestClient.create().withTransport('modern').buildAndConnect()` for streamable HTTP + strict sessions
|
|
65
|
+
- Using `server.info.baseUrl` to wire the client to the correct address
|
|
66
|
+
- Separate `disconnect()` / `stop()` calls for client and server teardown
|
|
67
|
+
- The `toBeError()` and `toHaveTextContent()` custom matchers
|
|
68
|
+
|
|
69
|
+
## Related
|
|
70
|
+
|
|
71
|
+
- See `test-e2e-handler` for the full E2E handler testing reference
|
|
72
|
+
- See `setup-testing` for fixture-based E2E patterns
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tool-call-and-error-e2e
|
|
3
|
+
reference: test-e2e-handler
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Test successful tool calls and verify that invalid inputs produce proper error responses over the full MCP protocol.'
|
|
6
|
+
tags: [testing, e2e, handler, tool, call, error]
|
|
7
|
+
features:
|
|
8
|
+
- 'Calling tools via `client.callTool()` and asserting success with `toBeSuccessful()`'
|
|
9
|
+
- 'Verifying text content in tool results with `result.content[0].text`'
|
|
10
|
+
- 'Checking `result.isError` for invalid input and nonexistent tool calls'
|
|
11
|
+
- 'Testing edge cases like zero values and missing optional parameters'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# E2E Testing Tool Calls and Error Responses
|
|
15
|
+
|
|
16
|
+
Test successful tool calls and verify that invalid inputs produce proper error responses over the full MCP protocol.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/__tests__/tool-calls.e2e.spec.ts
|
|
22
|
+
import { McpTestClient, TestServer } from '@frontmcp/testing';
|
|
23
|
+
import Server from '../src/main';
|
|
24
|
+
|
|
25
|
+
describe('Tool Call E2E', () => {
|
|
26
|
+
let client: McpTestClient;
|
|
27
|
+
let server: TestServer;
|
|
28
|
+
|
|
29
|
+
beforeAll(async () => {
|
|
30
|
+
server = await TestServer.create(Server);
|
|
31
|
+
client = await server.connect();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterAll(async () => {
|
|
35
|
+
await client.close();
|
|
36
|
+
await server.dispose();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should call a tool and get a successful result', async () => {
|
|
40
|
+
const result = await client.callTool('add_numbers', { a: 5, b: 3 });
|
|
41
|
+
expect(result).toBeSuccessful();
|
|
42
|
+
expect(result.content[0].text).toContain('8');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should return isError for invalid input', async () => {
|
|
46
|
+
const result = await client.callTool('add_numbers', { a: 'bad' });
|
|
47
|
+
expect(result.isError).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should return error for nonexistent tool', async () => {
|
|
51
|
+
const result = await client.callTool('nonexistent_tool', {});
|
|
52
|
+
expect(result.isError).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should handle tool with optional parameters', async () => {
|
|
56
|
+
const result = await client.callTool('add_numbers', { a: 10, b: 0 });
|
|
57
|
+
expect(result).toBeSuccessful();
|
|
58
|
+
expect(result.content[0].text).toContain('10');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## What This Demonstrates
|
|
64
|
+
|
|
65
|
+
- Calling tools via `client.callTool()` and asserting success with `toBeSuccessful()`
|
|
66
|
+
- Verifying text content in tool results with `result.content[0].text`
|
|
67
|
+
- Checking `result.isError` for invalid input and nonexistent tool calls
|
|
68
|
+
- Testing edge cases like zero values and missing optional parameters
|
|
69
|
+
|
|
70
|
+
## Related
|
|
71
|
+
|
|
72
|
+
- See `test-e2e-handler` for the full E2E handler testing reference
|
|
73
|
+
- See `test-tool-unit` for unit-level tool testing
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: basic-tool-test
|
|
3
|
+
reference: test-tool-unit
|
|
4
|
+
level: basic
|
|
5
|
+
description: "Test a simple tool's `execute()` method with mock context and verify the output."
|
|
6
|
+
tags: [testing, tool, unit]
|
|
7
|
+
features:
|
|
8
|
+
- 'Creating a mock `ToolContext` with all required methods (`get`, `tryGet`, `fail`, `mark`, `notify`, `respondProgress`)'
|
|
9
|
+
- 'Assigning the mock context to the tool instance via `Object.assign`'
|
|
10
|
+
- 'Testing multiple input scenarios including edge cases (negatives, zero)'
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Basic Tool Unit Test
|
|
14
|
+
|
|
15
|
+
Test a simple tool's `execute()` method with mock context and verify the output.
|
|
16
|
+
|
|
17
|
+
## Code
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// src/tools/__tests__/add.tool.spec.ts
|
|
21
|
+
import { ToolContext } from '@frontmcp/sdk';
|
|
22
|
+
import { AddTool } from '../add.tool';
|
|
23
|
+
|
|
24
|
+
describe('AddTool', () => {
|
|
25
|
+
let tool: AddTool;
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
tool = new AddTool();
|
|
29
|
+
|
|
30
|
+
const ctx = {
|
|
31
|
+
get: jest.fn(),
|
|
32
|
+
tryGet: jest.fn(),
|
|
33
|
+
fail: jest.fn((err) => {
|
|
34
|
+
throw err;
|
|
35
|
+
}),
|
|
36
|
+
mark: jest.fn(),
|
|
37
|
+
notify: jest.fn(),
|
|
38
|
+
respondProgress: jest.fn(),
|
|
39
|
+
} as unknown as ToolContext;
|
|
40
|
+
|
|
41
|
+
Object.assign(tool, ctx);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should add two numbers', async () => {
|
|
45
|
+
const result = await tool.execute({ a: 2, b: 3 });
|
|
46
|
+
expect(result).toEqual({ sum: 5 });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should handle negative numbers', async () => {
|
|
50
|
+
const result = await tool.execute({ a: -1, b: -2 });
|
|
51
|
+
expect(result).toEqual({ sum: -3 });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should handle zero values', async () => {
|
|
55
|
+
const result = await tool.execute({ a: 0, b: 0 });
|
|
56
|
+
expect(result).toEqual({ sum: 0 });
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## What This Demonstrates
|
|
62
|
+
|
|
63
|
+
- Creating a mock `ToolContext` with all required methods (`get`, `tryGet`, `fail`, `mark`, `notify`, `respondProgress`)
|
|
64
|
+
- Assigning the mock context to the tool instance via `Object.assign`
|
|
65
|
+
- Testing multiple input scenarios including edge cases (negatives, zero)
|
|
66
|
+
|
|
67
|
+
## Related
|
|
68
|
+
|
|
69
|
+
- See `test-tool-unit` for the full tool unit testing reference
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: schema-validation-test
|
|
3
|
+
reference: test-tool-unit
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: "Validate that a tool's Zod input schema rejects invalid data before `execute()` is called."
|
|
6
|
+
tags: [testing, tool, unit, schema, validation]
|
|
7
|
+
features:
|
|
8
|
+
- 'Testing the Zod input schema separately from the `execute()` method'
|
|
9
|
+
- 'Using `safeParse()` to check validation results without throwing'
|
|
10
|
+
- 'Covering rejection of wrong types, missing fields, and empty input'
|
|
11
|
+
- 'Combining schema validation with execution to test the full flow'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Testing Zod Schema Validation for Tool Input
|
|
15
|
+
|
|
16
|
+
Validate that a tool's Zod input schema rejects invalid data before `execute()` is called.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/tools/__tests__/add.tool.schema.spec.ts
|
|
22
|
+
import { z } from 'zod';
|
|
23
|
+
import { ToolContext } from '@frontmcp/sdk';
|
|
24
|
+
import { AddTool } from '../add.tool';
|
|
25
|
+
|
|
26
|
+
describe('AddTool schema validation', () => {
|
|
27
|
+
const schema = z.object({ a: z.number(), b: z.number() });
|
|
28
|
+
|
|
29
|
+
it('should accept valid numeric input', () => {
|
|
30
|
+
const result = schema.safeParse({ a: 5, b: 10 });
|
|
31
|
+
expect(result.success).toBe(true);
|
|
32
|
+
if (result.success) {
|
|
33
|
+
expect(result.data).toEqual({ a: 5, b: 10 });
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should reject string values for numeric fields', () => {
|
|
38
|
+
const result = schema.safeParse({ a: 'not-a-number', b: 3 });
|
|
39
|
+
expect(result.success).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should reject missing required fields', () => {
|
|
43
|
+
const result = schema.safeParse({ a: 5 });
|
|
44
|
+
expect(result.success).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should reject empty input', () => {
|
|
48
|
+
const result = schema.safeParse({});
|
|
49
|
+
expect(result.success).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should coerce valid input and produce correct output', async () => {
|
|
53
|
+
const tool = new AddTool();
|
|
54
|
+
const ctx = {
|
|
55
|
+
get: jest.fn(),
|
|
56
|
+
tryGet: jest.fn(),
|
|
57
|
+
fail: jest.fn((err) => {
|
|
58
|
+
throw err;
|
|
59
|
+
}),
|
|
60
|
+
mark: jest.fn(),
|
|
61
|
+
notify: jest.fn(),
|
|
62
|
+
respondProgress: jest.fn(),
|
|
63
|
+
} as unknown as ToolContext;
|
|
64
|
+
Object.assign(tool, ctx);
|
|
65
|
+
|
|
66
|
+
const parsed = schema.parse({ a: 7, b: 3 });
|
|
67
|
+
const result = await tool.execute(parsed);
|
|
68
|
+
expect(result).toEqual({ sum: 10 });
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## What This Demonstrates
|
|
74
|
+
|
|
75
|
+
- Testing the Zod input schema separately from the `execute()` method
|
|
76
|
+
- Using `safeParse()` to check validation results without throwing
|
|
77
|
+
- Covering rejection of wrong types, missing fields, and empty input
|
|
78
|
+
- Combining schema validation with execution to test the full flow
|
|
79
|
+
|
|
80
|
+
## Related
|
|
81
|
+
|
|
82
|
+
- See `test-tool-unit` for the full tool unit testing reference
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tool-error-handling-test
|
|
3
|
+
reference: test-tool-unit
|
|
4
|
+
level: advanced
|
|
5
|
+
description: 'Test that a tool throws the correct MCP error classes with proper error codes and JSON-RPC error shapes.'
|
|
6
|
+
tags: [testing, json-rpc, tool, unit, error, handling]
|
|
7
|
+
features:
|
|
8
|
+
- 'Verifying specific error classes with `toBeInstanceOf` instead of just checking that something threw'
|
|
9
|
+
- 'Asserting MCP error codes from `MCP_ERROR_CODES` constants'
|
|
10
|
+
- 'Validating the JSON-RPC error shape returned by `toJsonRpcError()`'
|
|
11
|
+
- 'Testing both success and failure paths in the same suite'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Testing Tool Error Handling and Error Classes
|
|
15
|
+
|
|
16
|
+
Test that a tool throws the correct MCP error classes with proper error codes and JSON-RPC error shapes.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/tools/__tests__/lookup.tool.spec.ts
|
|
22
|
+
import { ToolContext } from '@frontmcp/sdk';
|
|
23
|
+
import { ResourceNotFoundError, MCP_ERROR_CODES } from '@frontmcp/sdk';
|
|
24
|
+
import { LookupTool } from '../lookup.tool';
|
|
25
|
+
|
|
26
|
+
describe('LookupTool error handling', () => {
|
|
27
|
+
let tool: LookupTool;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
tool = new LookupTool();
|
|
31
|
+
|
|
32
|
+
const ctx = {
|
|
33
|
+
get: jest.fn(),
|
|
34
|
+
tryGet: jest.fn(),
|
|
35
|
+
fail: jest.fn((err) => {
|
|
36
|
+
throw err;
|
|
37
|
+
}),
|
|
38
|
+
mark: jest.fn(),
|
|
39
|
+
notify: jest.fn(),
|
|
40
|
+
respondProgress: jest.fn(),
|
|
41
|
+
} as unknown as ToolContext;
|
|
42
|
+
|
|
43
|
+
Object.assign(tool, ctx);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should throw ResourceNotFoundError for missing resource', async () => {
|
|
47
|
+
await expect(tool.execute({ id: 'nonexistent' })).rejects.toThrow(ResourceNotFoundError);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should produce correct MCP error code', async () => {
|
|
51
|
+
try {
|
|
52
|
+
await tool.execute({ id: 'nonexistent' });
|
|
53
|
+
fail('Expected an error to be thrown');
|
|
54
|
+
} catch (err) {
|
|
55
|
+
expect(err).toBeInstanceOf(ResourceNotFoundError);
|
|
56
|
+
expect((err as ResourceNotFoundError).mcpErrorCode).toBe(MCP_ERROR_CODES.RESOURCE_NOT_FOUND);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should produce valid JSON-RPC error shape', async () => {
|
|
61
|
+
try {
|
|
62
|
+
await tool.execute({ id: 'nonexistent' });
|
|
63
|
+
fail('Expected an error to be thrown');
|
|
64
|
+
} catch (err) {
|
|
65
|
+
const rpc = (err as ResourceNotFoundError).toJsonRpcError();
|
|
66
|
+
expect(rpc).toEqual({
|
|
67
|
+
code: -32002,
|
|
68
|
+
message: expect.any(String),
|
|
69
|
+
data: expect.objectContaining({ uri: expect.any(String) }),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should succeed for valid resource id', async () => {
|
|
75
|
+
const result = await tool.execute({ id: 'existing-123' });
|
|
76
|
+
expect(result).toBeDefined();
|
|
77
|
+
expect(result.content).toBeDefined();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## What This Demonstrates
|
|
83
|
+
|
|
84
|
+
- Verifying specific error classes with `toBeInstanceOf` instead of just checking that something threw
|
|
85
|
+
- Asserting MCP error codes from `MCP_ERROR_CODES` constants
|
|
86
|
+
- Validating the JSON-RPC error shape returned by `toJsonRpcError()`
|
|
87
|
+
- Testing both success and failure paths in the same suite
|
|
88
|
+
|
|
89
|
+
## Related
|
|
90
|
+
|
|
91
|
+
- See `test-tool-unit` for the full tool unit testing reference
|
|
92
|
+
- See `setup-testing` for error class testing patterns
|
|
@@ -551,6 +551,16 @@ node scripts/fix-unused-imports.mjs feature/my-branch
|
|
|
551
551
|
| Istanbul shows 0% coverage for async methods | TypeScript compilation source-map mismatch | Known issue with `ts-jest` and certain async patterns; check `tsconfig.spec.json` source-map settings |
|
|
552
552
|
| Auth E2E test returns 401 unexpectedly | Token not set or expired | Call `mcp.setAuthToken(token)` before the tool call; use `auth.createToken()` with valid claims |
|
|
553
553
|
|
|
554
|
+
## Examples
|
|
555
|
+
|
|
556
|
+
| Example | Level | Description |
|
|
557
|
+
| ----------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
558
|
+
| [`fixture-based-e2e-test`](../examples/setup-testing/fixture-based-e2e-test.md) | Advanced | Write E2E tests using the fixture API from `@frontmcp/testing` that manages server lifecycle automatically and uses MCP-specific custom matchers. |
|
|
559
|
+
| [`jest-config-with-coverage`](../examples/setup-testing/jest-config-with-coverage.md) | Basic | Set up a Jest configuration file that enforces 95%+ coverage across all metrics for a FrontMCP library. |
|
|
560
|
+
| [`unit-test-tool-resource-prompt`](../examples/setup-testing/unit-test-tool-resource-prompt.md) | Intermediate | Write unit tests for the three core MCP primitives, verifying that outputs match the expected MCP response shapes. |
|
|
561
|
+
|
|
562
|
+
> See all examples in [`examples/setup-testing/`](../examples/setup-testing/)
|
|
563
|
+
|
|
554
564
|
## Reference
|
|
555
565
|
|
|
556
566
|
- [Testing Documentation](https://docs.agentfront.dev/frontmcp/testing/overview)
|