@frontmcp/skills 1.0.0-beta.13 → 1.0.0-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/catalog/TEMPLATE.md +55 -0
- package/catalog/frontmcp-config/SKILL.md +2 -2
- package/catalog/frontmcp-config/examples/configure-auth/multi-app-auth.md +87 -0
- package/catalog/frontmcp-config/examples/configure-auth/public-mode-setup.md +63 -0
- package/catalog/frontmcp-config/examples/configure-auth/remote-oauth-with-vault.md +76 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +77 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +73 -0
- package/catalog/frontmcp-config/examples/configure-auth-modes/transparent-jwt-validation.md +64 -0
- package/catalog/frontmcp-config/examples/configure-elicitation/basic-confirmation-gate.md +83 -0
- package/catalog/frontmcp-config/examples/configure-elicitation/distributed-elicitation-redis.md +87 -0
- package/catalog/frontmcp-config/examples/configure-http/cors-restricted-origins.md +52 -0
- package/catalog/frontmcp-config/examples/configure-http/entry-path-reverse-proxy.md +72 -0
- package/catalog/frontmcp-config/examples/configure-http/unix-socket-local.md +64 -0
- package/catalog/frontmcp-config/examples/configure-session/multi-server-key-prefix.md +68 -0
- package/catalog/frontmcp-config/examples/configure-session/redis-session-store.md +52 -0
- package/catalog/frontmcp-config/examples/configure-session/vercel-kv-session.md +52 -0
- package/catalog/frontmcp-config/examples/configure-throttle/distributed-redis-throttle.md +94 -0
- package/catalog/frontmcp-config/examples/configure-throttle/per-tool-rate-limit.md +92 -0
- package/catalog/frontmcp-config/examples/configure-throttle/server-level-rate-limit.md +83 -0
- package/catalog/frontmcp-config/examples/configure-throttle-guard-config/full-guard-config.md +99 -0
- package/catalog/frontmcp-config/examples/configure-throttle-guard-config/minimal-guard-config.md +55 -0
- package/catalog/frontmcp-config/examples/configure-transport/custom-protocol-flags.md +74 -0
- package/catalog/frontmcp-config/examples/configure-transport/distributed-sessions-redis.md +86 -0
- package/catalog/frontmcp-config/examples/configure-transport/stateless-serverless.md +69 -0
- package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/legacy-preset-nodejs.md +65 -0
- package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/stateless-api-serverless.md +69 -0
- package/catalog/frontmcp-config/references/configure-auth-modes.md +10 -0
- package/catalog/frontmcp-config/references/configure-auth.md +10 -0
- package/catalog/frontmcp-config/references/configure-elicitation.md +9 -0
- package/catalog/frontmcp-config/references/configure-http.md +10 -0
- package/catalog/frontmcp-config/references/configure-session.md +10 -0
- package/catalog/frontmcp-config/references/configure-throttle-guard-config.md +9 -0
- package/catalog/frontmcp-config/references/configure-throttle.md +10 -0
- package/catalog/frontmcp-config/references/configure-transport-protocol-presets.md +9 -0
- package/catalog/frontmcp-config/references/configure-transport.md +10 -0
- package/catalog/frontmcp-config/references/setup-redis.md +5 -0
- package/catalog/frontmcp-config/references/setup-sqlite.md +5 -0
- package/catalog/frontmcp-deployment/SKILL.md +2 -2
- package/catalog/frontmcp-deployment/examples/build-for-browser/browser-build-with-custom-entry.md +43 -0
- package/catalog/frontmcp-deployment/examples/build-for-browser/browser-crypto-and-storage.md +85 -0
- package/catalog/frontmcp-deployment/examples/build-for-browser/react-provider-setup.md +61 -0
- package/catalog/frontmcp-deployment/examples/build-for-cli/cli-binary-build.md +66 -0
- package/catalog/frontmcp-deployment/examples/build-for-cli/unix-socket-daemon.md +76 -0
- package/catalog/frontmcp-deployment/examples/build-for-sdk/connect-openai.md +78 -0
- package/catalog/frontmcp-deployment/examples/build-for-sdk/create-flat-config.md +85 -0
- package/catalog/frontmcp-deployment/examples/build-for-sdk/multi-platform-connect.md +104 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/basic-worker-deploy.md +82 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-custom-domain.md +97 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-with-kv-storage.md +92 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/cdk-deployment.md +92 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/lambda-handler-with-cors.md +113 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/sam-template-basic.md +100 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node/docker-compose-with-redis.md +101 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node/pm2-with-nginx.md +79 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node/resource-limits.md +92 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/basic-multistage-dockerfile.md +63 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/secure-nonroot-dockerfile.md +89 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-mcp-endpoint-test.md +69 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +82 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-skills-cache.md +90 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/minimal-vercel-config.md +49 -0
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/vercel-config-with-security-headers.md +92 -0
- package/catalog/frontmcp-deployment/references/build-for-browser.md +10 -0
- package/catalog/frontmcp-deployment/references/build-for-cli.md +9 -0
- package/catalog/frontmcp-deployment/references/build-for-sdk.md +10 -0
- package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +10 -0
- package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +10 -0
- package/catalog/frontmcp-deployment/references/deploy-to-node-dockerfile.md +9 -0
- package/catalog/frontmcp-deployment/references/deploy-to-node.md +10 -0
- package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +9 -0
- package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +10 -0
- package/catalog/frontmcp-development/SKILL.md +2 -2
- package/catalog/frontmcp-development/examples/create-adapter/basic-api-adapter.md +92 -0
- package/catalog/frontmcp-development/examples/create-adapter/namespaced-adapter.md +124 -0
- package/catalog/frontmcp-development/examples/create-agent/basic-agent-with-tools.md +121 -0
- package/catalog/frontmcp-development/examples/create-agent/custom-multi-pass-agent.md +95 -0
- package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +111 -0
- package/catalog/frontmcp-development/examples/create-agent-llm-config/anthropic-config.md +81 -0
- package/catalog/frontmcp-development/examples/create-agent-llm-config/openai-config.md +80 -0
- package/catalog/frontmcp-development/examples/create-job/basic-report-job.md +87 -0
- package/catalog/frontmcp-development/examples/create-job/job-with-permissions.md +117 -0
- package/catalog/frontmcp-development/examples/create-job/job-with-retry.md +88 -0
- package/catalog/frontmcp-development/examples/create-plugin/basic-plugin-with-provider.md +69 -0
- package/catalog/frontmcp-development/examples/create-plugin/configurable-dynamic-plugin.md +178 -0
- package/catalog/frontmcp-development/examples/create-plugin/plugin-with-context-extension.md +107 -0
- package/catalog/frontmcp-development/examples/create-plugin-hooks/basic-logging-plugin.md +69 -0
- package/catalog/frontmcp-development/examples/create-plugin-hooks/caching-with-around.md +80 -0
- package/catalog/frontmcp-development/examples/create-plugin-hooks/tool-level-hooks-and-stage-replacement.md +100 -0
- package/catalog/frontmcp-development/examples/create-prompt/basic-prompt.md +72 -0
- package/catalog/frontmcp-development/examples/create-prompt/dynamic-rag-prompt.md +92 -0
- package/catalog/frontmcp-development/examples/create-prompt/multi-turn-debug-session.md +86 -0
- package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +113 -0
- package/catalog/frontmcp-development/examples/create-provider/config-and-api-providers.md +107 -0
- package/catalog/frontmcp-development/examples/create-resource/basic-static-resource.md +72 -0
- package/catalog/frontmcp-development/examples/create-resource/binary-and-multi-content.md +111 -0
- package/catalog/frontmcp-development/examples/create-resource/parameterized-template.md +84 -0
- package/catalog/frontmcp-development/examples/create-skill/basic-inline-skill.md +96 -0
- package/catalog/frontmcp-development/examples/create-skill/directory-based-skill.md +115 -0
- package/catalog/frontmcp-development/examples/create-skill/parameterized-skill.md +96 -0
- package/catalog/frontmcp-development/examples/create-skill-with-tools/basic-tool-orchestration.md +76 -0
- package/catalog/frontmcp-development/examples/create-skill-with-tools/directory-skill-with-tools.md +149 -0
- package/catalog/frontmcp-development/examples/create-skill-with-tools/incident-response-skill.md +92 -0
- package/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md +62 -0
- package/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md +84 -0
- package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +93 -0
- package/catalog/frontmcp-development/examples/create-tool-annotations/destructive-delete-tool.md +94 -0
- package/catalog/frontmcp-development/examples/create-tool-annotations/readonly-query-tool.md +60 -0
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/primitive-and-media-outputs.md +104 -0
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-raw-shape-output.md +63 -0
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-schema-advanced-output.md +103 -0
- package/catalog/frontmcp-development/examples/create-workflow/basic-deploy-pipeline.md +91 -0
- package/catalog/frontmcp-development/examples/create-workflow/parallel-validation-pipeline.md +90 -0
- package/catalog/frontmcp-development/examples/create-workflow/webhook-triggered-workflow.md +136 -0
- package/catalog/frontmcp-development/examples/decorators-guide/agent-skill-job-workflow.md +145 -0
- package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md +124 -0
- package/catalog/frontmcp-development/examples/decorators-guide/multi-app-with-plugins-and-providers.md +149 -0
- package/catalog/frontmcp-development/examples/official-adapters/authenticated-adapter-with-polling.md +84 -0
- package/catalog/frontmcp-development/examples/official-adapters/basic-openapi-adapter.md +54 -0
- package/catalog/frontmcp-development/examples/official-adapters/multi-api-hub-with-inline-spec.md +130 -0
- package/catalog/frontmcp-development/examples/official-plugins/cache-and-feature-flags.md +117 -0
- package/catalog/frontmcp-development/examples/official-plugins/production-multi-plugin-setup.md +147 -0
- package/catalog/frontmcp-development/examples/official-plugins/remember-plugin-session-memory.md +104 -0
- package/catalog/frontmcp-development/references/create-adapter.md +9 -0
- package/catalog/frontmcp-development/references/create-agent-llm-config.md +9 -0
- package/catalog/frontmcp-development/references/create-agent.md +10 -0
- package/catalog/frontmcp-development/references/create-job.md +10 -0
- package/catalog/frontmcp-development/references/create-plugin-hooks.md +10 -0
- package/catalog/frontmcp-development/references/create-plugin.md +10 -0
- package/catalog/frontmcp-development/references/create-prompt.md +10 -0
- package/catalog/frontmcp-development/references/create-provider.md +9 -0
- package/catalog/frontmcp-development/references/create-resource.md +52 -15
- package/catalog/frontmcp-development/references/create-skill-with-tools.md +10 -0
- package/catalog/frontmcp-development/references/create-skill.md +10 -0
- package/catalog/frontmcp-development/references/create-tool-annotations.md +9 -0
- package/catalog/frontmcp-development/references/create-tool-output-schema-types.md +10 -0
- package/catalog/frontmcp-development/references/create-tool.md +10 -0
- package/catalog/frontmcp-development/references/create-workflow.md +10 -0
- package/catalog/frontmcp-development/references/decorators-guide.md +10 -0
- package/catalog/frontmcp-development/references/official-adapters.md +10 -0
- package/catalog/frontmcp-development/references/official-plugins.md +10 -0
- package/catalog/frontmcp-extensibility/SKILL.md +1 -1
- package/catalog/frontmcp-extensibility/examples/vectoriadb/product-catalog-search.md +175 -0
- package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md +138 -0
- package/catalog/frontmcp-extensibility/examples/vectoriadb/tfidf-keyword-search.md +103 -0
- package/catalog/frontmcp-extensibility/references/vectoriadb.md +10 -0
- package/catalog/frontmcp-guides/SKILL.md +2 -2
- package/catalog/frontmcp-guides/examples/example-knowledge-base/agent-and-plugin.md +160 -0
- package/catalog/frontmcp-guides/examples/example-knowledge-base/multi-app-composition.md +92 -0
- package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md +135 -0
- package/catalog/frontmcp-guides/examples/example-task-manager/auth-and-crud-tools.md +135 -0
- package/catalog/frontmcp-guides/examples/example-task-manager/authenticated-e2e-tests.md +148 -0
- package/catalog/frontmcp-guides/examples/example-task-manager/redis-provider-with-di.md +129 -0
- package/catalog/frontmcp-guides/examples/example-weather-api/server-and-app-setup.md +75 -0
- package/catalog/frontmcp-guides/examples/example-weather-api/unit-and-e2e-tests.md +142 -0
- package/catalog/frontmcp-guides/examples/example-weather-api/weather-tool-with-schemas.md +74 -0
- package/catalog/frontmcp-guides/references/example-knowledge-base.md +10 -0
- package/catalog/frontmcp-guides/references/example-task-manager.md +10 -0
- package/catalog/frontmcp-guides/references/example-weather-api.md +10 -0
- package/catalog/frontmcp-production-readiness/SKILL.md +2 -2
- package/catalog/frontmcp-production-readiness/examples/common-checklist/caching-and-performance.md +102 -0
- package/catalog/frontmcp-production-readiness/examples/common-checklist/observability-setup.md +104 -0
- package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +95 -0
- package/catalog/frontmcp-production-readiness/examples/production-browser/browser-bundle-config.md +93 -0
- package/catalog/frontmcp-production-readiness/examples/production-browser/cross-platform-crypto.md +116 -0
- package/catalog/frontmcp-production-readiness/examples/production-browser/security-and-performance.md +128 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-binary/binary-build-config.md +109 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-binary/stdio-transport-error-handling.md +132 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/daemon-socket-config.md +82 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/graceful-shutdown-cleanup.md +107 -0
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/security-and-permissions.md +119 -0
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/durable-objects-state.md +124 -0
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/workers-runtime-constraints.md +103 -0
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/wrangler-config.md +89 -0
- package/catalog/frontmcp-production-readiness/examples/production-lambda/cold-start-connection-reuse.md +122 -0
- package/catalog/frontmcp-production-readiness/examples/production-lambda/sam-template.md +107 -0
- package/catalog/frontmcp-production-readiness/examples/production-lambda/scaling-and-monitoring.md +138 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-sdk/basic-sdk-lifecycle.md +85 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-sdk/multi-instance-cleanup.md +110 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-sdk/package-json-config.md +107 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-server/docker-multi-stage.md +103 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-server/graceful-shutdown.md +87 -0
- package/catalog/frontmcp-production-readiness/examples/production-node-server/redis-session-scaling.md +97 -0
- package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md +104 -0
- package/catalog/frontmcp-production-readiness/examples/production-vercel/stateless-serverless-design.md +91 -0
- package/catalog/frontmcp-production-readiness/examples/production-vercel/vercel-edge-config.md +78 -0
- package/catalog/frontmcp-production-readiness/references/common-checklist.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-browser.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-cli-binary.md +9 -0
- package/catalog/frontmcp-production-readiness/references/production-cli-daemon.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-cloudflare.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-lambda.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-node-sdk.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-node-server.md +10 -0
- package/catalog/frontmcp-production-readiness/references/production-vercel.md +10 -0
- package/catalog/frontmcp-setup/examples/frontmcp-skills-usage/bundle-presets-scaffolding.md +61 -0
- package/catalog/frontmcp-setup/examples/frontmcp-skills-usage/install-and-search-skills.md +83 -0
- package/catalog/frontmcp-setup/examples/multi-app-composition/local-apps-with-shared-tools.md +87 -0
- package/catalog/frontmcp-setup/examples/multi-app-composition/per-app-auth-and-isolation.md +88 -0
- package/catalog/frontmcp-setup/examples/multi-app-composition/remote-and-esm-apps.md +81 -0
- package/catalog/frontmcp-setup/examples/nx-workflow/build-test-affected.md +77 -0
- package/catalog/frontmcp-setup/examples/nx-workflow/multi-server-deployment.md +93 -0
- package/catalog/frontmcp-setup/examples/nx-workflow/scaffold-and-generate.md +62 -0
- package/catalog/frontmcp-setup/examples/project-structure-nx/nx-generator-scaffolding.md +73 -0
- package/catalog/frontmcp-setup/examples/project-structure-nx/nx-workspace-with-apps.md +85 -0
- package/catalog/frontmcp-setup/examples/project-structure-nx/shared-library-usage.md +89 -0
- package/catalog/frontmcp-setup/examples/project-structure-standalone/dev-workflow-commands.md +64 -0
- package/catalog/frontmcp-setup/examples/project-structure-standalone/feature-folder-organization.md +111 -0
- package/catalog/frontmcp-setup/examples/project-structure-standalone/minimal-standalone-layout.md +73 -0
- package/catalog/frontmcp-setup/examples/readme-guide/node-server-readme.md +89 -0
- package/catalog/frontmcp-setup/examples/readme-guide/vercel-deployment-readme.md +90 -0
- package/catalog/frontmcp-setup/examples/setup-project/basic-node-server.md +99 -0
- package/catalog/frontmcp-setup/examples/setup-project/cli-scaffold-with-flags.md +77 -0
- package/catalog/frontmcp-setup/examples/setup-project/vercel-serverless-server.md +89 -0
- package/catalog/frontmcp-setup/examples/setup-redis/docker-redis-local-dev.md +88 -0
- package/catalog/frontmcp-setup/examples/setup-redis/hybrid-vercel-kv-with-pubsub.md +78 -0
- package/catalog/frontmcp-setup/examples/setup-redis/vercel-kv-serverless.md +78 -0
- package/catalog/frontmcp-setup/examples/setup-sqlite/basic-sqlite-setup.md +75 -0
- package/catalog/frontmcp-setup/examples/setup-sqlite/encrypted-sqlite-storage.md +55 -0
- package/catalog/frontmcp-setup/examples/setup-sqlite/unix-socket-daemon.md +70 -0
- package/catalog/frontmcp-setup/references/frontmcp-skills-usage.md +9 -0
- package/catalog/frontmcp-setup/references/multi-app-composition.md +10 -0
- package/catalog/frontmcp-setup/references/nx-workflow.md +10 -0
- package/catalog/frontmcp-setup/references/project-structure-nx.md +10 -0
- package/catalog/frontmcp-setup/references/project-structure-standalone.md +10 -0
- package/catalog/frontmcp-setup/references/readme-guide.md +9 -0
- package/catalog/frontmcp-setup/references/setup-project.md +10 -0
- package/catalog/frontmcp-setup/references/setup-redis.md +10 -0
- package/catalog/frontmcp-setup/references/setup-sqlite.md +10 -0
- package/catalog/frontmcp-testing/examples/setup-testing/fixture-based-e2e-test.md +70 -0
- package/catalog/frontmcp-testing/examples/setup-testing/jest-config-with-coverage.md +59 -0
- package/catalog/frontmcp-testing/examples/setup-testing/unit-test-tool-resource-prompt.md +115 -0
- package/catalog/frontmcp-testing/examples/test-auth/oauth-flow-test.md +78 -0
- package/catalog/frontmcp-testing/examples/test-auth/role-based-access-test.md +88 -0
- package/catalog/frontmcp-testing/examples/test-auth/token-factory-test.md +71 -0
- package/catalog/frontmcp-testing/examples/test-browser-build/browser-bundle-validation.md +58 -0
- package/catalog/frontmcp-testing/examples/test-browser-build/playwright-browser-test.md +69 -0
- package/catalog/frontmcp-testing/examples/test-cli-binary/binary-startup-test.md +77 -0
- package/catalog/frontmcp-testing/examples/test-cli-binary/js-bundle-import-test.md +56 -0
- package/catalog/frontmcp-testing/examples/test-direct-client/basic-create-test.md +74 -0
- package/catalog/frontmcp-testing/examples/test-direct-client/openai-claude-format-test.md +79 -0
- package/catalog/frontmcp-testing/examples/test-e2e-handler/basic-e2e-test.md +67 -0
- package/catalog/frontmcp-testing/examples/test-e2e-handler/manual-client-with-transport.md +72 -0
- package/catalog/frontmcp-testing/examples/test-e2e-handler/tool-call-and-error-e2e.md +73 -0
- package/catalog/frontmcp-testing/examples/test-tool-unit/basic-tool-test.md +69 -0
- package/catalog/frontmcp-testing/examples/test-tool-unit/schema-validation-test.md +82 -0
- package/catalog/frontmcp-testing/examples/test-tool-unit/tool-error-handling-test.md +92 -0
- package/catalog/frontmcp-testing/references/setup-testing.md +10 -0
- package/catalog/frontmcp-testing/references/test-auth.md +10 -0
- package/catalog/frontmcp-testing/references/test-browser-build.md +9 -0
- package/catalog/frontmcp-testing/references/test-cli-binary.md +9 -0
- package/catalog/frontmcp-testing/references/test-direct-client.md +9 -0
- package/catalog/frontmcp-testing/references/test-e2e-handler.md +10 -0
- package/catalog/frontmcp-testing/references/test-tool-unit.md +10 -0
- package/catalog/skills-manifest.json +2383 -67
- package/package.json +1 -1
- package/src/manifest.d.ts +23 -0
- package/src/manifest.js +3 -1
- package/src/manifest.js.map +1 -1
package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: semantic-search-with-persistence
|
|
3
|
+
reference: vectoriadb
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Shows how to use `VectoriaDB` for semantic search with transformer models, filtered search, and `FileStorageAdapter` for persistence across restarts.'
|
|
6
|
+
tags: [extensibility, vectoriadb, semantic-search, semantic, search, persistence]
|
|
7
|
+
features:
|
|
8
|
+
- 'Using `VectoriaDB` with transformer models for true semantic search'
|
|
9
|
+
- 'Configuring HNSW index (`useHNSW: true`) for fast O(log n) search on large datasets'
|
|
10
|
+
- 'Filtered search with a callback: `filter: (m) => m.category === category`'
|
|
11
|
+
- '`FileStorageAdapter` for persisting vectors to disk (restored without re-embedding)'
|
|
12
|
+
- 'Async initialization with `await db.initialize()` (downloads model on first run)'
|
|
13
|
+
- 'Update-or-add pattern with `db.has(id)` check'
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# VectoriaDB: Semantic ML Search with Persistence
|
|
17
|
+
|
|
18
|
+
Shows how to use `VectoriaDB` for semantic search with transformer models, filtered search, and `FileStorageAdapter` for persistence across restarts.
|
|
19
|
+
|
|
20
|
+
## Code
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// src/providers/knowledge-base.provider.ts
|
|
24
|
+
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
25
|
+
import { VectoriaDB, FileStorageAdapter } from 'vectoriadb';
|
|
26
|
+
import type { DocumentMetadata } from 'vectoriadb';
|
|
27
|
+
|
|
28
|
+
export const KnowledgeBase = Symbol('KnowledgeBase');
|
|
29
|
+
|
|
30
|
+
interface Article extends DocumentMetadata {
|
|
31
|
+
title: string;
|
|
32
|
+
category: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Provider({ name: 'knowledge-base', provide: KnowledgeBase, scope: ProviderScope.GLOBAL })
|
|
36
|
+
export class KnowledgeBaseProvider {
|
|
37
|
+
private db: VectoriaDB<Article>;
|
|
38
|
+
private ready: Promise<void>;
|
|
39
|
+
|
|
40
|
+
constructor() {
|
|
41
|
+
this.db = new VectoriaDB<Article>({
|
|
42
|
+
modelName: 'Xenova/all-MiniLM-L6-v2', // Default transformer model
|
|
43
|
+
cacheDir: './.cache/transformers', // Model cache directory
|
|
44
|
+
useHNSW: true, // HNSW index for O(log n) search
|
|
45
|
+
defaultSimilarityThreshold: 0.4,
|
|
46
|
+
defaultTopK: 10,
|
|
47
|
+
storageAdapter: new FileStorageAdapter({ cacheDir: './.cache/kb-vectors' }),
|
|
48
|
+
});
|
|
49
|
+
// Initialize async — downloads model on first run
|
|
50
|
+
this.ready = this.db.initialize();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async search(query: string, options?: { category?: string; limit?: number }) {
|
|
54
|
+
await this.ready;
|
|
55
|
+
return this.db.search(query, {
|
|
56
|
+
topK: options?.limit ?? 10,
|
|
57
|
+
// Filtered search: narrow results by category
|
|
58
|
+
filter: options?.category ? (m) => m.category === options.category : undefined,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async index(id: string, text: string, metadata: Article) {
|
|
63
|
+
await this.ready;
|
|
64
|
+
// Update if exists, add if new
|
|
65
|
+
if (this.db.has(id)) {
|
|
66
|
+
await this.db.update(id, { text, metadata });
|
|
67
|
+
} else {
|
|
68
|
+
await this.db.add(id, text, metadata);
|
|
69
|
+
}
|
|
70
|
+
// Persist to disk — restored without re-embedding on next startup
|
|
71
|
+
await this.db.saveToStorage();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async loadFromDisk() {
|
|
75
|
+
await this.ready;
|
|
76
|
+
await this.db.loadFromStorage();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// src/tools/semantic-search.tool.ts
|
|
83
|
+
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
84
|
+
import { z } from 'zod';
|
|
85
|
+
import { KnowledgeBase } from '../providers/knowledge-base.provider';
|
|
86
|
+
|
|
87
|
+
@Tool({
|
|
88
|
+
name: 'semantic_search',
|
|
89
|
+
description: 'Search the knowledge base using natural language (understands meaning, not just keywords)',
|
|
90
|
+
inputSchema: {
|
|
91
|
+
query: z.string().min(1).describe('Natural language search query'),
|
|
92
|
+
category: z.string().optional().describe('Filter by category'),
|
|
93
|
+
limit: z.number().int().min(1).max(20).default(5).describe('Max results'),
|
|
94
|
+
},
|
|
95
|
+
outputSchema: {
|
|
96
|
+
results: z.array(
|
|
97
|
+
z.object({
|
|
98
|
+
id: z.string(),
|
|
99
|
+
score: z.number(),
|
|
100
|
+
title: z.string(),
|
|
101
|
+
category: z.string(),
|
|
102
|
+
}),
|
|
103
|
+
),
|
|
104
|
+
},
|
|
105
|
+
})
|
|
106
|
+
export class SemanticSearchTool extends ToolContext {
|
|
107
|
+
async execute(input: { query: string; category?: string; limit: number }) {
|
|
108
|
+
const kb = this.get(KnowledgeBase);
|
|
109
|
+
|
|
110
|
+
const results = await kb.search(input.query, {
|
|
111
|
+
category: input.category,
|
|
112
|
+
limit: input.limit,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
results: results.map((r) => ({
|
|
117
|
+
id: r.id,
|
|
118
|
+
score: r.score,
|
|
119
|
+
title: r.metadata.title,
|
|
120
|
+
category: r.metadata.category,
|
|
121
|
+
})),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## What This Demonstrates
|
|
128
|
+
|
|
129
|
+
- Using `VectoriaDB` with transformer models for true semantic search
|
|
130
|
+
- Configuring HNSW index (`useHNSW: true`) for fast O(log n) search on large datasets
|
|
131
|
+
- Filtered search with a callback: `filter: (m) => m.category === category`
|
|
132
|
+
- `FileStorageAdapter` for persisting vectors to disk (restored without re-embedding)
|
|
133
|
+
- Async initialization with `await db.initialize()` (downloads model on first run)
|
|
134
|
+
- Update-or-add pattern with `db.has(id)` check
|
|
135
|
+
|
|
136
|
+
## Related
|
|
137
|
+
|
|
138
|
+
- See `vectoriadb` for the full configuration reference and engine comparison
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tfidf-keyword-search
|
|
3
|
+
reference: vectoriadb
|
|
4
|
+
level: basic
|
|
5
|
+
description: 'Shows how to use `TFIDFVectoria` for zero-dependency keyword search in a FrontMCP provider, with field weights and index building.'
|
|
6
|
+
tags: [extensibility, vectoriadb, keyword-search, tfidf, keyword, search]
|
|
7
|
+
features:
|
|
8
|
+
- 'Using `TFIDFVectoria` for zero-dependency keyword search (no model downloads)'
|
|
9
|
+
- 'Configuring field weights to control scoring influence'
|
|
10
|
+
- 'Calling `buildIndex()` after adding documents (required for TFIDFVectoria)'
|
|
11
|
+
- 'Wrapping the search engine in a FrontMCP provider with `ProviderScope.GLOBAL`'
|
|
12
|
+
- 'Injecting the provider into tools via `this.get(FAQSearch)`'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# TFIDFVectoria: Lightweight Keyword Search Provider
|
|
16
|
+
|
|
17
|
+
Shows how to use `TFIDFVectoria` for zero-dependency keyword search in a FrontMCP provider, with field weights and index building.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// src/providers/faq-search.provider.ts
|
|
23
|
+
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
24
|
+
import { TFIDFVectoria } from 'vectoriadb';
|
|
25
|
+
|
|
26
|
+
export const FAQSearch = Symbol('FAQSearch');
|
|
27
|
+
|
|
28
|
+
@Provider({ name: 'faq-search', provide: FAQSearch, scope: ProviderScope.GLOBAL })
|
|
29
|
+
export class FAQSearchProvider {
|
|
30
|
+
private db = new TFIDFVectoria({
|
|
31
|
+
fields: {
|
|
32
|
+
question: { weight: 3 }, // Question matches are 3x more important
|
|
33
|
+
answer: { weight: 1 }, // Answer matches are baseline
|
|
34
|
+
tags: { weight: 2 }, // Tag matches are 2x
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
async initialize(faqs: Array<{ id: string; question: string; answer: string; tags: string }>) {
|
|
39
|
+
for (const faq of faqs) {
|
|
40
|
+
this.db.addDocument(faq.id, {
|
|
41
|
+
question: faq.question,
|
|
42
|
+
answer: faq.answer,
|
|
43
|
+
tags: faq.tags,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// Required after adding documents — builds the TF-IDF index
|
|
47
|
+
this.db.buildIndex();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
search(query: string, limit = 5) {
|
|
51
|
+
return this.db.search(query, limit);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// src/tools/search-faq.tool.ts
|
|
58
|
+
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
59
|
+
import { z } from 'zod';
|
|
60
|
+
import { FAQSearch } from '../providers/faq-search.provider';
|
|
61
|
+
|
|
62
|
+
@Tool({
|
|
63
|
+
name: 'search_faq',
|
|
64
|
+
description: 'Search the FAQ knowledge base using keyword matching',
|
|
65
|
+
inputSchema: {
|
|
66
|
+
query: z.string().min(1).describe('Search query'),
|
|
67
|
+
limit: z.number().int().min(1).max(20).default(5).describe('Max results'),
|
|
68
|
+
},
|
|
69
|
+
outputSchema: {
|
|
70
|
+
results: z.array(
|
|
71
|
+
z.object({
|
|
72
|
+
id: z.string(),
|
|
73
|
+
score: z.number(),
|
|
74
|
+
}),
|
|
75
|
+
),
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
export class SearchFaqTool extends ToolContext {
|
|
79
|
+
async execute(input: { query: string; limit: number }) {
|
|
80
|
+
const faqSearch = this.get(FAQSearch);
|
|
81
|
+
const results = faqSearch.search(input.query, input.limit);
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
results: results.map((r) => ({
|
|
85
|
+
id: r.id,
|
|
86
|
+
score: r.score,
|
|
87
|
+
})),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## What This Demonstrates
|
|
94
|
+
|
|
95
|
+
- Using `TFIDFVectoria` for zero-dependency keyword search (no model downloads)
|
|
96
|
+
- Configuring field weights to control scoring influence
|
|
97
|
+
- Calling `buildIndex()` after adding documents (required for TFIDFVectoria)
|
|
98
|
+
- Wrapping the search engine in a FrontMCP provider with `ProviderScope.GLOBAL`
|
|
99
|
+
- Injecting the provider into tools via `this.get(FAQSearch)`
|
|
100
|
+
|
|
101
|
+
## Related
|
|
102
|
+
|
|
103
|
+
- See `vectoriadb` for the full API reference and engine comparison
|
|
@@ -282,6 +282,16 @@ export class KnowledgeBaseProvider {
|
|
|
282
282
|
- [ ] Storage adapter configured if persistence is needed
|
|
283
283
|
- [ ] Search tool injects provider via `this.get(TOKEN)`
|
|
284
284
|
|
|
285
|
+
## Examples
|
|
286
|
+
|
|
287
|
+
| Example | Level | Description |
|
|
288
|
+
| ------------------------------------------------------------------------------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
289
|
+
| [`product-catalog-search`](../examples/vectoriadb/product-catalog-search.md) | Advanced | Shows advanced VectoriaDB usage with typed document metadata, batch operations, filtered search by multiple criteria, and batch indexing of a product catalog. |
|
|
290
|
+
| [`semantic-search-with-persistence`](../examples/vectoriadb/semantic-search-with-persistence.md) | Intermediate | Shows how to use `VectoriaDB` for semantic search with transformer models, filtered search, and `FileStorageAdapter` for persistence across restarts. |
|
|
291
|
+
| [`tfidf-keyword-search`](../examples/vectoriadb/tfidf-keyword-search.md) | Basic | Shows how to use `TFIDFVectoria` for zero-dependency keyword search in a FrontMCP provider, with field weights and index building. |
|
|
292
|
+
|
|
293
|
+
> See all examples in [`examples/vectoriadb/`](../examples/vectoriadb/)
|
|
294
|
+
|
|
285
295
|
## Reference
|
|
286
296
|
|
|
287
297
|
- [VectoriaDB Documentation](https://docs.agentfront.dev/vectoriadb/get-started/welcome)
|
|
@@ -9,7 +9,7 @@ priority: 10
|
|
|
9
9
|
visibility: both
|
|
10
10
|
license: Apache-2.0
|
|
11
11
|
metadata:
|
|
12
|
-
docs: https://docs.agentfront.dev/frontmcp/guides/
|
|
12
|
+
docs: https://docs.agentfront.dev/frontmcp/guides/your-first-tool
|
|
13
13
|
examples:
|
|
14
14
|
- scenario: Build a simple weather API MCP server from scratch
|
|
15
15
|
expected-outcome: Working server with tools, resources, and tests deployed to Node
|
|
@@ -415,6 +415,6 @@ export class ResearcherAgent extends AgentContext {
|
|
|
415
415
|
|
|
416
416
|
## Reference
|
|
417
417
|
|
|
418
|
-
- [
|
|
418
|
+
- [Your First Tool](https://docs.agentfront.dev/frontmcp/guides/your-first-tool)
|
|
419
419
|
- Domain routers: `frontmcp-development`, `frontmcp-deployment`, `frontmcp-testing`, `frontmcp-config`
|
|
420
420
|
- Core skills: `setup-project`, `create-tool`, `create-resource`, `create-provider`, `create-agent`, `configure-auth`, `setup-testing`
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-and-plugin
|
|
3
|
+
reference: example-knowledge-base
|
|
4
|
+
level: advanced
|
|
5
|
+
description: 'Shows an autonomous research agent with inner tools and configurable depth, and a plugin that hooks into tool execution for audit logging.'
|
|
6
|
+
tags: [guides, knowledge-base, knowledge, base, agent, plugin]
|
|
7
|
+
features:
|
|
8
|
+
- 'Agent with `@Agent` decorator, LLM config, inner tools, and system instructions'
|
|
9
|
+
- 'Using `this.run(prompt, { maxIterations })` to execute the LLM tool-use loop'
|
|
10
|
+
- "Configurable behavior via input schema (`depth: 'shallow' | 'deep'`)"
|
|
11
|
+
- 'Plugin hooks: `onToolExecuteBefore`, `onToolExecuteAfter`, `onToolExecuteError`'
|
|
12
|
+
- 'Using `ctx.state.set/get()` for flow state instead of mutating `rawInput`'
|
|
13
|
+
- 'Non-blocking audit logging (`.catch()` prevents audit failures from breaking tools)'
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Knowledge Base: Research Agent and Audit Log Plugin
|
|
17
|
+
|
|
18
|
+
Shows an autonomous research agent with inner tools and configurable depth, and a plugin that hooks into tool execution for audit logging.
|
|
19
|
+
|
|
20
|
+
## Code
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// src/research/agents/researcher.agent.ts
|
|
24
|
+
import { Agent, AgentContext } from '@frontmcp/sdk';
|
|
25
|
+
import { z } from 'zod';
|
|
26
|
+
import { SearchDocsTool } from '../../search/tools/search-docs.tool';
|
|
27
|
+
import { IngestDocumentTool } from '../../ingestion/tools/ingest-document.tool';
|
|
28
|
+
|
|
29
|
+
@Agent({
|
|
30
|
+
name: 'research_topic',
|
|
31
|
+
description: 'Research a topic across the knowledge base and synthesize findings into a structured report',
|
|
32
|
+
inputSchema: {
|
|
33
|
+
topic: z.string().min(1).describe('Research topic or question'),
|
|
34
|
+
depth: z.enum(['shallow', 'deep']).default('shallow').describe('Research depth'),
|
|
35
|
+
},
|
|
36
|
+
outputSchema: {
|
|
37
|
+
topic: z.string(),
|
|
38
|
+
summary: z.string(),
|
|
39
|
+
sources: z.array(
|
|
40
|
+
z.object({
|
|
41
|
+
documentId: z.string(),
|
|
42
|
+
title: z.string(),
|
|
43
|
+
relevance: z.string(),
|
|
44
|
+
}),
|
|
45
|
+
),
|
|
46
|
+
confidence: z.enum(['low', 'medium', 'high']),
|
|
47
|
+
},
|
|
48
|
+
llm: {
|
|
49
|
+
provider: 'anthropic',
|
|
50
|
+
model: 'claude-sonnet-4-20250514',
|
|
51
|
+
apiKey: { env: 'ANTHROPIC_API_KEY' },
|
|
52
|
+
maxTokens: 4096,
|
|
53
|
+
},
|
|
54
|
+
// Inner tools: the agent can call these during its execution
|
|
55
|
+
tools: [SearchDocsTool, IngestDocumentTool],
|
|
56
|
+
systemInstructions: `You are a research assistant with access to a knowledge base.
|
|
57
|
+
Your job is to:
|
|
58
|
+
1. Search the knowledge base for relevant documents using the search_docs tool.
|
|
59
|
+
2. Analyze the results and identify key themes.
|
|
60
|
+
3. If depth is "deep", perform multiple searches with refined queries.
|
|
61
|
+
4. Synthesize findings into a structured summary with source attribution.
|
|
62
|
+
Always cite which documents support your findings.`,
|
|
63
|
+
})
|
|
64
|
+
export class ResearcherAgent extends AgentContext {
|
|
65
|
+
async execute(input: { topic: string; depth: 'shallow' | 'deep' }) {
|
|
66
|
+
const maxIterations = input.depth === 'deep' ? 5 : 2;
|
|
67
|
+
const prompt = [
|
|
68
|
+
`Research the following topic: "${input.topic}"`,
|
|
69
|
+
`Depth: ${input.depth} (max ${maxIterations} search iterations)`,
|
|
70
|
+
'Search the knowledge base, analyze results, and produce a structured summary.',
|
|
71
|
+
'Return your findings as JSON matching the output schema.',
|
|
72
|
+
].join('\n');
|
|
73
|
+
|
|
74
|
+
// this.run() executes the LLM loop with inner tools
|
|
75
|
+
return this.run(prompt, { maxIterations });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// src/plugins/audit-log.plugin.ts
|
|
82
|
+
import { Plugin } from '@frontmcp/sdk';
|
|
83
|
+
import type { PluginHookContext } from '@frontmcp/sdk';
|
|
84
|
+
|
|
85
|
+
@Plugin({
|
|
86
|
+
name: 'AuditLog',
|
|
87
|
+
description: 'Logs all tool invocations for audit compliance',
|
|
88
|
+
})
|
|
89
|
+
export class AuditLogPlugin {
|
|
90
|
+
private readonly logs: Array<{
|
|
91
|
+
timestamp: string;
|
|
92
|
+
tool: string;
|
|
93
|
+
userId: string | undefined;
|
|
94
|
+
duration: number;
|
|
95
|
+
success: boolean;
|
|
96
|
+
}> = [];
|
|
97
|
+
|
|
98
|
+
async onToolExecuteBefore(ctx: PluginHookContext): Promise<void> {
|
|
99
|
+
// Store start time in flow state (not in rawInput)
|
|
100
|
+
ctx.state.set('audit:startTime', Date.now());
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async onToolExecuteAfter(ctx: PluginHookContext): Promise<void> {
|
|
104
|
+
const startTime = ctx.state.get('audit:startTime') as number;
|
|
105
|
+
const duration = Date.now() - startTime;
|
|
106
|
+
|
|
107
|
+
const entry = {
|
|
108
|
+
timestamp: new Date().toISOString(),
|
|
109
|
+
tool: ctx.toolName,
|
|
110
|
+
userId: ctx.session?.userId,
|
|
111
|
+
duration,
|
|
112
|
+
success: true,
|
|
113
|
+
};
|
|
114
|
+
this.logs.push(entry);
|
|
115
|
+
|
|
116
|
+
// In production, send to an external logging service
|
|
117
|
+
if (process.env.AUDIT_LOG_ENDPOINT) {
|
|
118
|
+
await ctx
|
|
119
|
+
.fetch(process.env.AUDIT_LOG_ENDPOINT, {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
headers: { 'Content-Type': 'application/json' },
|
|
122
|
+
body: JSON.stringify(entry),
|
|
123
|
+
})
|
|
124
|
+
.catch(() => {
|
|
125
|
+
// Audit logging should not block tool execution
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async onToolExecuteError(ctx: PluginHookContext): Promise<void> {
|
|
131
|
+
const startTime = ctx.state.get('audit:startTime') as number;
|
|
132
|
+
const duration = Date.now() - startTime;
|
|
133
|
+
|
|
134
|
+
this.logs.push({
|
|
135
|
+
timestamp: new Date().toISOString(),
|
|
136
|
+
tool: ctx.toolName,
|
|
137
|
+
userId: ctx.session?.userId,
|
|
138
|
+
duration,
|
|
139
|
+
success: false,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
getLogs(): typeof this.logs {
|
|
144
|
+
return [...this.logs];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## What This Demonstrates
|
|
150
|
+
|
|
151
|
+
- Agent with `@Agent` decorator, LLM config, inner tools, and system instructions
|
|
152
|
+
- Using `this.run(prompt, { maxIterations })` to execute the LLM tool-use loop
|
|
153
|
+
- Configurable behavior via input schema (`depth: 'shallow' | 'deep'`)
|
|
154
|
+
- Plugin hooks: `onToolExecuteBefore`, `onToolExecuteAfter`, `onToolExecuteError`
|
|
155
|
+
- Using `ctx.state.set/get()` for flow state instead of mutating `rawInput`
|
|
156
|
+
- Non-blocking audit logging (`.catch()` prevents audit failures from breaking tools)
|
|
157
|
+
|
|
158
|
+
## Related
|
|
159
|
+
|
|
160
|
+
- See `example-knowledge-base` for the full knowledge base example with vector store and tests
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: multi-app-composition
|
|
3
|
+
reference: example-knowledge-base
|
|
4
|
+
level: basic
|
|
5
|
+
description: 'Shows how to compose multiple apps (Ingestion, Search, Research) into a single server with shared providers, plugins, and agent registration.'
|
|
6
|
+
tags: [guides, multi-app, knowledge-base, knowledge, base, multi]
|
|
7
|
+
features:
|
|
8
|
+
- 'Composing three apps into one server: Ingestion (tools + providers), Search (tools + resources), Research (agents)'
|
|
9
|
+
- 'Sharing providers across apps (VectorStoreProvider used by both Ingestion and Search)'
|
|
10
|
+
- 'Registering plugins at the server level (AuditLogPlugin applies to all tools)'
|
|
11
|
+
- 'Registering agents in a dedicated app for AI-powered features'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Knowledge Base: Multi-App Composition
|
|
15
|
+
|
|
16
|
+
Shows how to compose multiple apps (Ingestion, Search, Research) into a single server with shared providers, plugins, and agent registration.
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// src/main.ts
|
|
22
|
+
import { FrontMcp } from '@frontmcp/sdk';
|
|
23
|
+
import { IngestionApp } from './ingestion/ingestion.app';
|
|
24
|
+
import { SearchApp } from './search/search.app';
|
|
25
|
+
import { ResearchApp } from './research/research.app';
|
|
26
|
+
import { AuditLogPlugin } from './plugins/audit-log.plugin';
|
|
27
|
+
|
|
28
|
+
@FrontMcp({
|
|
29
|
+
info: { name: 'knowledge-base', version: '1.0.0' },
|
|
30
|
+
apps: [IngestionApp, SearchApp, ResearchApp],
|
|
31
|
+
plugins: [AuditLogPlugin],
|
|
32
|
+
auth: { mode: 'remote', provider: 'https://auth.example.com', clientId: 'my-client-id' },
|
|
33
|
+
redis: { provider: 'redis', host: process.env.REDIS_URL ?? 'localhost' },
|
|
34
|
+
})
|
|
35
|
+
export default class KnowledgeBaseServer {}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// src/ingestion/ingestion.app.ts
|
|
40
|
+
import { App } from '@frontmcp/sdk';
|
|
41
|
+
import { VectorStoreProvider } from './providers/vector-store.provider';
|
|
42
|
+
import { IngestDocumentTool } from './tools/ingest-document.tool';
|
|
43
|
+
|
|
44
|
+
@App({
|
|
45
|
+
name: 'Ingestion',
|
|
46
|
+
description: 'Document ingestion and chunking pipeline',
|
|
47
|
+
providers: [VectorStoreProvider],
|
|
48
|
+
tools: [IngestDocumentTool],
|
|
49
|
+
})
|
|
50
|
+
export class IngestionApp {}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// src/search/search.app.ts
|
|
55
|
+
import { App } from '@frontmcp/sdk';
|
|
56
|
+
import { VectorStoreProvider } from '../ingestion/providers/vector-store.provider';
|
|
57
|
+
import { SearchDocsTool } from './tools/search-docs.tool';
|
|
58
|
+
import { DocResource } from './resources/doc.resource';
|
|
59
|
+
|
|
60
|
+
@App({
|
|
61
|
+
name: 'Search',
|
|
62
|
+
description: 'Semantic search and document retrieval',
|
|
63
|
+
providers: [VectorStoreProvider],
|
|
64
|
+
tools: [SearchDocsTool],
|
|
65
|
+
resources: [DocResource],
|
|
66
|
+
})
|
|
67
|
+
export class SearchApp {}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// src/research/research.app.ts
|
|
72
|
+
import { App } from '@frontmcp/sdk';
|
|
73
|
+
import { ResearcherAgent } from './agents/researcher.agent';
|
|
74
|
+
|
|
75
|
+
@App({
|
|
76
|
+
name: 'Research',
|
|
77
|
+
description: 'AI-powered research agent for knowledge synthesis',
|
|
78
|
+
agents: [ResearcherAgent],
|
|
79
|
+
})
|
|
80
|
+
export class ResearchApp {}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## What This Demonstrates
|
|
84
|
+
|
|
85
|
+
- Composing three apps into one server: Ingestion (tools + providers), Search (tools + resources), Research (agents)
|
|
86
|
+
- Sharing providers across apps (VectorStoreProvider used by both Ingestion and Search)
|
|
87
|
+
- Registering plugins at the server level (AuditLogPlugin applies to all tools)
|
|
88
|
+
- Registering agents in a dedicated app for AI-powered features
|
|
89
|
+
|
|
90
|
+
## Related
|
|
91
|
+
|
|
92
|
+
- See `example-knowledge-base` for the full knowledge base example with vector store, search, and agent code
|
package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vector-search-and-resources
|
|
3
|
+
reference: example-knowledge-base
|
|
4
|
+
level: intermediate
|
|
5
|
+
description: 'Shows a semantic search tool with embedding generation and a resource template for retrieving documents by ID using URI parameters.'
|
|
6
|
+
tags: [guides, openai, semantic-search, knowledge-base, knowledge, base]
|
|
7
|
+
features:
|
|
8
|
+
- 'Semantic search tool that generates query embeddings via `this.fetch()` to OpenAI'
|
|
9
|
+
- 'Using `this.mark()` for execution phase tracing'
|
|
10
|
+
- "Resource template with `uriTemplate: 'kb://documents/{documentId}'` for parameterized URIs"
|
|
11
|
+
- 'Typed params via `ResourceContext<{ documentId: string }>` for type-safe URI parameters'
|
|
12
|
+
- 'Returning `ReadResourceResult` with proper MCP protocol structure'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Knowledge Base: Semantic Search Tool and Resource Template
|
|
16
|
+
|
|
17
|
+
Shows a semantic search tool with embedding generation and a resource template for retrieving documents by ID using URI parameters.
|
|
18
|
+
|
|
19
|
+
## Code
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// src/search/tools/search-docs.tool.ts
|
|
23
|
+
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
import { VECTOR_STORE } from '../../ingestion/providers/vector-store.provider';
|
|
26
|
+
|
|
27
|
+
@Tool({
|
|
28
|
+
name: 'search_docs',
|
|
29
|
+
description: 'Semantic search across the knowledge base',
|
|
30
|
+
inputSchema: {
|
|
31
|
+
query: z.string().min(1).describe('Natural language search query'),
|
|
32
|
+
topK: z.number().int().min(1).max(20).default(5).describe('Number of results'),
|
|
33
|
+
},
|
|
34
|
+
outputSchema: {
|
|
35
|
+
results: z.array(
|
|
36
|
+
z.object({
|
|
37
|
+
documentId: z.string(),
|
|
38
|
+
content: z.string(),
|
|
39
|
+
score: z.number(),
|
|
40
|
+
title: z.string(),
|
|
41
|
+
}),
|
|
42
|
+
),
|
|
43
|
+
total: z.number(),
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
export class SearchDocsTool extends ToolContext {
|
|
47
|
+
async execute(input: { query: string; topK: number }) {
|
|
48
|
+
const store = this.get(VECTOR_STORE);
|
|
49
|
+
|
|
50
|
+
// Mark execution phases for observability
|
|
51
|
+
this.mark('embedding-query');
|
|
52
|
+
const queryEmbedding = await this.generateQueryEmbedding(input.query);
|
|
53
|
+
|
|
54
|
+
this.mark('searching');
|
|
55
|
+
const chunks = await store.search(queryEmbedding, input.topK);
|
|
56
|
+
|
|
57
|
+
const results = chunks.map((chunk) => ({
|
|
58
|
+
documentId: chunk.documentId,
|
|
59
|
+
content: chunk.content,
|
|
60
|
+
score: chunk.metadata.score ? parseFloat(chunk.metadata.score) : 0,
|
|
61
|
+
title: chunk.metadata.title ?? 'Untitled',
|
|
62
|
+
}));
|
|
63
|
+
|
|
64
|
+
return { results, total: results.length };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private async generateQueryEmbedding(query: string): Promise<number[]> {
|
|
68
|
+
const response = await this.fetch('https://api.openai.com/v1/embeddings', {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: {
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
|
|
73
|
+
},
|
|
74
|
+
body: JSON.stringify({ input: query, model: 'text-embedding-3-small' }),
|
|
75
|
+
});
|
|
76
|
+
const data = await response.json();
|
|
77
|
+
return data.data[0].embedding;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// src/search/resources/doc.resource.ts
|
|
84
|
+
import { ResourceTemplate, ResourceContext } from '@frontmcp/sdk';
|
|
85
|
+
import type { ReadResourceResult } from '@frontmcp/protocol';
|
|
86
|
+
import { VECTOR_STORE } from '../../ingestion/providers/vector-store.provider';
|
|
87
|
+
|
|
88
|
+
@ResourceTemplate({
|
|
89
|
+
name: 'document',
|
|
90
|
+
uriTemplate: 'kb://documents/{documentId}',
|
|
91
|
+
description: 'Retrieve all chunks of a document by its ID',
|
|
92
|
+
mimeType: 'application/json',
|
|
93
|
+
})
|
|
94
|
+
export class DocResource extends ResourceContext<{ documentId: string }> {
|
|
95
|
+
async execute(uri: string, params: { documentId: string }): Promise<ReadResourceResult> {
|
|
96
|
+
const store = this.get(VECTOR_STORE);
|
|
97
|
+
const chunks = await store.getByDocumentId(params.documentId);
|
|
98
|
+
|
|
99
|
+
if (chunks.length === 0) {
|
|
100
|
+
this.fail(new Error(`Document not found: ${params.documentId}`));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const document = {
|
|
104
|
+
documentId: params.documentId,
|
|
105
|
+
title: chunks[0].metadata.title ?? 'Untitled',
|
|
106
|
+
chunks: chunks.map((c) => ({
|
|
107
|
+
chunkIndex: c.metadata.chunkIndex,
|
|
108
|
+
content: c.content,
|
|
109
|
+
})),
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
contents: [
|
|
114
|
+
{
|
|
115
|
+
uri,
|
|
116
|
+
mimeType: 'application/json',
|
|
117
|
+
text: JSON.stringify(document, null, 2),
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## What This Demonstrates
|
|
126
|
+
|
|
127
|
+
- Semantic search tool that generates query embeddings via `this.fetch()` to OpenAI
|
|
128
|
+
- Using `this.mark()` for execution phase tracing
|
|
129
|
+
- Resource template with `uriTemplate: 'kb://documents/{documentId}'` for parameterized URIs
|
|
130
|
+
- Typed params via `ResourceContext<{ documentId: string }>` for type-safe URI parameters
|
|
131
|
+
- Returning `ReadResourceResult` with proper MCP protocol structure
|
|
132
|
+
|
|
133
|
+
## Related
|
|
134
|
+
|
|
135
|
+
- See `example-knowledge-base` for the full knowledge base example with ingestion, agent, and plugin code
|