@frontmcp/skills 1.0.3 → 1.1.0-beta.1
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/frontmcp-authorities/SKILL.md +272 -0
- package/catalog/frontmcp-authorities/references/authority-profiles.md +262 -0
- package/catalog/frontmcp-authorities/references/claims-mapping.md +266 -0
- package/catalog/frontmcp-authorities/references/custom-evaluators.md +420 -0
- package/catalog/frontmcp-authorities/references/rbac-abac-rebac.md +391 -0
- package/catalog/frontmcp-channels/SKILL.md +122 -0
- package/catalog/frontmcp-channels/examples/channel-sources/agent-notify.md +70 -0
- package/catalog/frontmcp-channels/examples/channel-sources/app-errors.md +71 -0
- package/catalog/frontmcp-channels/examples/channel-sources/file-watcher.md +102 -0
- package/catalog/frontmcp-channels/examples/channel-sources/job-completion.md +79 -0
- package/catalog/frontmcp-channels/examples/channel-sources/replay-buffer.md +106 -0
- package/catalog/frontmcp-channels/examples/channel-sources/service-connector.md +136 -0
- package/catalog/frontmcp-channels/examples/channel-sources/webhook-github.md +85 -0
- package/catalog/frontmcp-channels/examples/channel-two-way/whatsapp-bridge.md +133 -0
- package/catalog/frontmcp-channels/references/channel-sources.md +214 -0
- package/catalog/frontmcp-channels/references/channel-two-way.md +195 -0
- package/catalog/frontmcp-config/SKILL.md +20 -18
- package/catalog/frontmcp-config/examples/configure-auth/multi-app-auth.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth/public-mode-setup.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth/remote-oauth-with-vault.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +1 -2
- package/catalog/frontmcp-config/examples/configure-auth-modes/transparent-jwt-validation.md +1 -2
- package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +121 -0
- package/catalog/frontmcp-config/examples/configure-deployment-targets/json-schema-ide-support.md +64 -0
- package/catalog/frontmcp-config/examples/configure-deployment-targets/multi-target-with-security.md +113 -0
- package/catalog/frontmcp-config/examples/configure-elicitation/basic-confirmation-gate.md +1 -2
- package/catalog/frontmcp-config/examples/configure-elicitation/distributed-elicitation-redis.md +1 -2
- package/catalog/frontmcp-config/examples/configure-http/entry-path-reverse-proxy.md +1 -2
- package/catalog/frontmcp-config/examples/configure-http/unix-socket-local.md +1 -2
- package/catalog/frontmcp-config/examples/configure-security-headers/csp-report-only.md +69 -0
- package/catalog/frontmcp-config/examples/configure-security-headers/full-production-headers.md +91 -0
- package/catalog/frontmcp-config/examples/configure-throttle/distributed-redis-throttle.md +1 -2
- package/catalog/frontmcp-config/examples/configure-throttle/per-tool-rate-limit.md +1 -2
- package/catalog/frontmcp-config/examples/configure-throttle/server-level-rate-limit.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport/custom-protocol-flags.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport/distributed-sessions-redis.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport/stateless-serverless.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/legacy-preset-nodejs.md +1 -2
- package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/stateless-api-serverless.md +1 -2
- package/catalog/frontmcp-config/references/configure-deployment-targets.md +214 -0
- package/catalog/frontmcp-config/references/configure-elicitation.md +1 -2
- package/catalog/frontmcp-config/references/configure-security-headers.md +198 -0
- package/catalog/frontmcp-deployment/SKILL.md +1 -0
- package/catalog/frontmcp-deployment/examples/build-for-cli/cli-binary-build.md +1 -2
- package/catalog/frontmcp-deployment/examples/build-for-cli/unix-socket-daemon.md +1 -2
- package/catalog/frontmcp-deployment/examples/build-for-mcpb/mcpb-bundle-build.md +117 -0
- package/catalog/frontmcp-deployment/examples/build-for-sdk/connect-openai.md +1 -3
- package/catalog/frontmcp-deployment/examples/build-for-sdk/create-flat-config.md +1 -2
- package/catalog/frontmcp-deployment/examples/build-for-sdk/multi-platform-connect.md +3 -3
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/basic-worker-deploy.md +1 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-custom-domain.md +1 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-with-kv-storage.md +1 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/lambda-handler-with-cors.md +1 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +1 -2
- package/catalog/frontmcp-deployment/examples/mcp-client-integration/http-remote.md +106 -0
- package/catalog/frontmcp-deployment/examples/mcp-client-integration/stdio-binary-with-env.md +107 -0
- package/catalog/frontmcp-deployment/examples/mcp-client-integration/stdio-npx.md +89 -0
- package/catalog/frontmcp-deployment/references/build-for-mcpb.md +209 -0
- package/catalog/frontmcp-deployment/references/build-for-sdk.md +1 -2
- package/catalog/frontmcp-deployment/references/mcp-client-integration.md +225 -0
- package/catalog/frontmcp-development/SKILL.md +4 -3
- package/catalog/frontmcp-development/examples/create-agent/basic-agent-with-tools.md +3 -6
- package/catalog/frontmcp-development/examples/create-agent/custom-multi-pass-agent.md +1 -2
- package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +2 -4
- package/catalog/frontmcp-development/examples/create-agent-llm-config/anthropic-config.md +1 -2
- package/catalog/frontmcp-development/examples/create-agent-llm-config/openai-config.md +1 -2
- package/catalog/frontmcp-development/examples/create-job/basic-report-job.md +1 -2
- package/catalog/frontmcp-development/examples/create-job/job-with-permissions.md +2 -3
- package/catalog/frontmcp-development/examples/create-job/job-with-retry.md +1 -2
- package/catalog/frontmcp-development/examples/create-plugin-hooks/tool-level-hooks-and-stage-replacement.md +2 -5
- package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +4 -3
- package/catalog/frontmcp-development/examples/create-skill-with-tools/directory-skill-with-tools.md +2 -3
- package/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md +1 -2
- package/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md +2 -2
- package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +1 -2
- package/catalog/frontmcp-development/examples/create-tool-annotations/destructive-delete-tool.md +2 -4
- package/catalog/frontmcp-development/examples/create-tool-annotations/readonly-query-tool.md +1 -2
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/primitive-and-media-outputs.md +3 -6
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-raw-shape-output.md +1 -2
- package/catalog/frontmcp-development/examples/create-tool-output-schema-types/zod-schema-advanced-output.md +2 -4
- package/catalog/frontmcp-development/examples/decorators-guide/agent-skill-job-workflow.md +3 -5
- package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md +5 -5
- package/catalog/frontmcp-development/examples/decorators-guide/multi-app-with-plugins-and-providers.md +4 -6
- package/catalog/frontmcp-development/examples/official-plugins/cache-and-feature-flags.md +3 -5
- package/catalog/frontmcp-development/examples/official-plugins/production-multi-plugin-setup.md +4 -5
- package/catalog/frontmcp-development/examples/official-plugins/remember-plugin-session-memory.md +3 -5
- package/catalog/frontmcp-development/examples/{official-adapters → openapi-adapter}/authenticated-adapter-with-polling.md +2 -2
- package/catalog/frontmcp-development/examples/{official-adapters → openapi-adapter}/basic-openapi-adapter.md +2 -2
- package/catalog/frontmcp-development/examples/openapi-adapter/format-resolution-and-custom-resolvers.md +108 -0
- package/catalog/frontmcp-development/examples/{official-adapters → openapi-adapter}/multi-api-hub-with-inline-spec.md +2 -2
- package/catalog/frontmcp-development/examples/openapi-adapter/ref-security-and-filtering.md +111 -0
- package/catalog/frontmcp-development/references/create-agent.md +4 -7
- package/catalog/frontmcp-development/references/create-job.md +3 -6
- package/catalog/frontmcp-development/references/create-plugin-hooks.md +12 -16
- package/catalog/frontmcp-development/references/create-skill-with-tools.md +2 -3
- package/catalog/frontmcp-development/references/create-tool.md +93 -23
- package/catalog/frontmcp-development/references/create-workflow.md +2 -3
- package/catalog/frontmcp-development/references/decorators-guide.md +32 -36
- package/catalog/frontmcp-development/references/official-adapters.md +24 -153
- package/catalog/frontmcp-development/references/openapi-adapter.md +431 -0
- package/catalog/frontmcp-extensibility/examples/vectoriadb/product-catalog-search.md +4 -4
- package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md +4 -4
- package/catalog/frontmcp-extensibility/examples/vectoriadb/tfidf-keyword-search.md +4 -3
- package/catalog/frontmcp-guides/SKILL.md +3 -3
- package/catalog/frontmcp-guides/examples/example-knowledge-base/agent-and-plugin.md +4 -5
- package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md +4 -3
- package/catalog/frontmcp-guides/examples/example-task-manager/auth-and-crud-tools.md +4 -4
- package/catalog/frontmcp-guides/examples/example-weather-api/weather-tool-with-schemas.md +1 -2
- package/catalog/frontmcp-guides/references/example-knowledge-base.md +22 -17
- package/catalog/frontmcp-guides/references/example-task-manager.md +16 -11
- package/catalog/frontmcp-guides/references/example-weather-api.md +6 -3
- package/catalog/frontmcp-observability/examples/telemetry-api/tool-custom-spans.md +2 -3
- package/catalog/frontmcp-observability/examples/tracing-setup/basic-tracing.md +4 -3
- package/catalog/frontmcp-observability/references/telemetry-api.md +2 -3
- package/catalog/frontmcp-production-readiness/examples/common-checklist/observability-setup.md +1 -2
- package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +3 -4
- package/catalog/frontmcp-production-readiness/examples/distributed-ha/ha-kubernetes-3-replicas.md +229 -0
- package/catalog/frontmcp-production-readiness/examples/production-browser/cross-platform-crypto.md +2 -3
- package/catalog/frontmcp-production-readiness/examples/production-cli-binary/stdio-transport-error-handling.md +1 -2
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/durable-objects-state.md +2 -4
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/workers-runtime-constraints.md +2 -3
- package/catalog/frontmcp-production-readiness/examples/production-lambda/cold-start-connection-reuse.md +3 -2
- package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md +2 -2
- package/catalog/frontmcp-production-readiness/examples/production-vercel/stateless-serverless-design.md +3 -3
- package/catalog/frontmcp-production-readiness/references/distributed-ha.md +194 -0
- package/catalog/frontmcp-setup/SKILL.md +11 -11
- package/catalog/frontmcp-setup/examples/project-structure-standalone/feature-folder-organization.md +5 -3
- package/catalog/frontmcp-setup/examples/project-structure-standalone/minimal-standalone-layout.md +4 -2
- package/catalog/frontmcp-setup/examples/setup-project/basic-node-server.md +4 -2
- package/catalog/frontmcp-setup/examples/setup-project/vercel-serverless-server.md +4 -2
- package/catalog/frontmcp-setup/examples/setup-redis/hybrid-vercel-kv-with-pubsub.md +8 -7
- package/catalog/frontmcp-setup/references/setup-project.md +10 -9
- package/catalog/frontmcp-setup/references/setup-redis.md +19 -16
- package/catalog/frontmcp-testing/examples/test-direct-client/basic-create-test.md +1 -3
- package/catalog/frontmcp-testing/examples/test-direct-client/openai-claude-format-test.md +1 -3
- package/catalog/frontmcp-testing/examples/test-tool-unit/schema-validation-test.md +2 -2
- package/catalog/frontmcp-testing/references/test-direct-client.md +1 -3
- package/catalog/frontmcp-testing/references/test-tool-unit.md +2 -2
- package/catalog/skills-manifest.json +364 -12
- package/package.json +1 -1
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: openapi-adapter
|
|
3
|
+
description: Convert OpenAPI 3.x specifications into MCP tools with authentication, polling, transforms, format resolution, and $ref security
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# OpenAPI Adapter
|
|
7
|
+
|
|
8
|
+
The OpenAPI adapter converts OpenAPI 3.x specifications into MCP tools — one tool per operation. It supports authentication, spec polling, operation filtering, input/output/tool transforms, format resolution, and built-in SSRF protection.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
### Must Use
|
|
13
|
+
|
|
14
|
+
- Converting an OpenAPI/Swagger 3.x specification into MCP tools automatically
|
|
15
|
+
- Integrating a REST API that provides a public OpenAPI spec (Petstore, GitHub, Jira, Slack)
|
|
16
|
+
- Setting up authentication (API key, bearer token, OAuth) for adapter-generated tools
|
|
17
|
+
|
|
18
|
+
### Recommended
|
|
19
|
+
|
|
20
|
+
- Enriching tool schemas with format resolution (uuid, date-time, email, etc.)
|
|
21
|
+
- Filtering which API operations become tools
|
|
22
|
+
- Hiding sensitive inputs and injecting server-side values via input transforms
|
|
23
|
+
- Enabling spec polling to auto-refresh tools when the upstream API changes
|
|
24
|
+
|
|
25
|
+
### Skip When
|
|
26
|
+
|
|
27
|
+
- The external API has no OpenAPI spec (see `create-adapter` for custom adapters)
|
|
28
|
+
- You need to build tools manually with custom logic (see `create-tool`)
|
|
29
|
+
- You only need adapters overview and comparison (see `official-adapters`)
|
|
30
|
+
|
|
31
|
+
> **Decision:** Use this skill when you have an OpenAPI 3.x spec and want comprehensive guidance on `OpenapiAdapter` configuration.
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { FrontMcp, App } from '@frontmcp/sdk';
|
|
37
|
+
import { OpenapiAdapter } from '@frontmcp/adapters';
|
|
38
|
+
|
|
39
|
+
@App({
|
|
40
|
+
name: 'MyApp',
|
|
41
|
+
adapters: [
|
|
42
|
+
OpenapiAdapter.init({
|
|
43
|
+
name: 'petstore',
|
|
44
|
+
url: 'https://petstore3.swagger.io/api/v3/openapi.json',
|
|
45
|
+
}),
|
|
46
|
+
],
|
|
47
|
+
})
|
|
48
|
+
class MyApp {}
|
|
49
|
+
|
|
50
|
+
@FrontMcp({
|
|
51
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
52
|
+
apps: [MyApp],
|
|
53
|
+
http: { port: 3000 },
|
|
54
|
+
})
|
|
55
|
+
class MyServer {}
|
|
56
|
+
// Generated tools: petstore:addPet, petstore:getPetById, petstore:deletePet, etc.
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Each OpenAPI operation becomes a tool named `<adapter-name>:<operationId>`.
|
|
60
|
+
|
|
61
|
+
## Authentication
|
|
62
|
+
|
|
63
|
+
Five strategies with different security risk levels:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// 1. Static Headers (Medium Risk) — server-to-server APIs
|
|
67
|
+
OpenapiAdapter.init({
|
|
68
|
+
name: 'my-api',
|
|
69
|
+
url: 'https://api.example.com/openapi.json',
|
|
70
|
+
baseUrl: 'https://api.example.com',
|
|
71
|
+
additionalHeaders: {
|
|
72
|
+
'x-api-key': process.env.API_KEY!,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// 2. Auth Provider Mapper (Low Risk) ⭐ Recommended — multi-provider
|
|
77
|
+
OpenapiAdapter.init({
|
|
78
|
+
name: 'multi-auth-api',
|
|
79
|
+
url: 'https://api.example.com/openapi.json',
|
|
80
|
+
baseUrl: 'https://api.example.com',
|
|
81
|
+
authProviderMapper: {
|
|
82
|
+
GitHubAuth: (ctx) => ctx.authInfo.user?.githubToken,
|
|
83
|
+
SlackAuth: (ctx) => ctx.authInfo.user?.slackToken,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// 3. Custom Security Resolver (Low Risk) — full control
|
|
88
|
+
OpenapiAdapter.init({
|
|
89
|
+
name: 'my-api',
|
|
90
|
+
url: 'https://api.example.com/openapi.json',
|
|
91
|
+
baseUrl: 'https://api.example.com',
|
|
92
|
+
securityResolver: (tool, ctx) => {
|
|
93
|
+
return { jwt: ctx.authInfo?.token };
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// 4. Static Auth (Medium Risk) — fixed credentials
|
|
98
|
+
OpenapiAdapter.init({
|
|
99
|
+
name: 'my-api',
|
|
100
|
+
url: 'https://api.example.com/openapi.json',
|
|
101
|
+
baseUrl: 'https://api.example.com',
|
|
102
|
+
staticAuth: {
|
|
103
|
+
jwt: process.env.API_TOKEN!,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// 5. Dynamic Headers & Body Mapping (Low Risk) — context injection
|
|
108
|
+
OpenapiAdapter.init({
|
|
109
|
+
name: 'my-api',
|
|
110
|
+
url: 'https://api.example.com/openapi.json',
|
|
111
|
+
baseUrl: 'https://api.example.com',
|
|
112
|
+
headersMapper: (ctx, headers) => {
|
|
113
|
+
headers.set('Authorization', `Bearer ${ctx.authInfo?.token}`);
|
|
114
|
+
return headers;
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
| Risk Level | Strategy | Description |
|
|
120
|
+
| ---------- | ------------------------------------------ | ---------------------------------------------------- |
|
|
121
|
+
| LOW | `authProviderMapper` or `securityResolver` | Auth from user context, not exposed to clients |
|
|
122
|
+
| MEDIUM | `staticAuth`, `additionalHeaders` | Static credentials |
|
|
123
|
+
| HIGH | `includeSecurityInInput: true` | Auth fields exposed to MCP clients (not recommended) |
|
|
124
|
+
|
|
125
|
+
## Spec Polling
|
|
126
|
+
|
|
127
|
+
Auto-refresh tool definitions when the upstream API changes:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
OpenapiAdapter.init({
|
|
131
|
+
name: 'evolving-api',
|
|
132
|
+
url: 'https://api.example.com/openapi.json',
|
|
133
|
+
polling: {
|
|
134
|
+
enabled: true,
|
|
135
|
+
intervalMs: 300000, // Re-fetch every 5 minutes
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Inline Spec
|
|
141
|
+
|
|
142
|
+
Provide the OpenAPI spec directly instead of fetching from URL:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
OpenapiAdapter.init({
|
|
146
|
+
name: 'my-api',
|
|
147
|
+
spec: {
|
|
148
|
+
openapi: '3.0.0',
|
|
149
|
+
info: { title: 'My API', version: '1.0.0' },
|
|
150
|
+
paths: {
|
|
151
|
+
'/users': {
|
|
152
|
+
get: {
|
|
153
|
+
operationId: 'listUsers',
|
|
154
|
+
summary: 'List all users',
|
|
155
|
+
responses: { '200': { description: 'OK' } },
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Multiple Adapters
|
|
164
|
+
|
|
165
|
+
Register adapters from different APIs in the same app:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
@App({
|
|
169
|
+
name: 'IntegrationHub',
|
|
170
|
+
adapters: [
|
|
171
|
+
OpenapiAdapter.init({ name: 'github', url: 'https://api.github.com/openapi.json' }),
|
|
172
|
+
OpenapiAdapter.init({ name: 'jira', url: 'https://jira.example.com/openapi.json' }),
|
|
173
|
+
OpenapiAdapter.init({ name: 'slack', url: 'https://slack.com/openapi.json' }),
|
|
174
|
+
],
|
|
175
|
+
})
|
|
176
|
+
class IntegrationHub {}
|
|
177
|
+
// Tools: github:createIssue, jira:createTicket, slack:postMessage, etc.
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Filtering Operations
|
|
181
|
+
|
|
182
|
+
Control which API operations become MCP tools:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// Filter by path prefix
|
|
186
|
+
OpenapiAdapter.init({
|
|
187
|
+
name: 'billing-api',
|
|
188
|
+
url: 'https://api.example.com/openapi.json',
|
|
189
|
+
generateOptions: {
|
|
190
|
+
filterFn: (op) => op.path.startsWith('/invoices') || op.path.startsWith('/customers'),
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Include only specific operations
|
|
195
|
+
OpenapiAdapter.init({
|
|
196
|
+
name: 'my-api',
|
|
197
|
+
url: 'https://api.example.com/openapi.json',
|
|
198
|
+
generateOptions: {
|
|
199
|
+
includeOperations: ['getUser', 'createUser', 'updateUser'],
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Exclude specific operations
|
|
204
|
+
OpenapiAdapter.init({
|
|
205
|
+
name: 'my-api',
|
|
206
|
+
url: 'https://api.example.com/openapi.json',
|
|
207
|
+
generateOptions: {
|
|
208
|
+
excludeOperations: ['deprecatedEndpoint', 'internalOnly'],
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Input Transforms
|
|
214
|
+
|
|
215
|
+
Hide inputs from AI/users and inject values server-side:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
OpenapiAdapter.init({
|
|
219
|
+
name: 'tenant-api',
|
|
220
|
+
url: 'https://api.example.com/openapi.json',
|
|
221
|
+
baseUrl: 'https://api.example.com',
|
|
222
|
+
inputTransforms: {
|
|
223
|
+
global: [
|
|
224
|
+
// Hide tenant header from AI, inject from user context
|
|
225
|
+
{ inputKey: 'X-Tenant-Id', inject: (ctx) => ctx.authInfo.user?.tenantId },
|
|
226
|
+
// Add correlation ID to all requests
|
|
227
|
+
{ inputKey: 'X-Correlation-Id', inject: () => crypto.randomUUID() },
|
|
228
|
+
],
|
|
229
|
+
perTool: {
|
|
230
|
+
createAuditLog: [{ inputKey: 'userId', inject: (ctx) => ctx.authInfo.user?.id }],
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Format Resolution
|
|
237
|
+
|
|
238
|
+
Enrich generated tool schemas with concrete constraints from OpenAPI `format` values (uuid, date-time, email, int32, etc.):
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
// Enable built-in format resolvers
|
|
242
|
+
OpenapiAdapter.init({
|
|
243
|
+
name: 'my-api',
|
|
244
|
+
url: 'https://api.example.com/openapi.json',
|
|
245
|
+
generateOptions: {
|
|
246
|
+
resolveFormats: true,
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Add custom format resolvers (merged with built-ins when resolveFormats: true)
|
|
251
|
+
OpenapiAdapter.init({
|
|
252
|
+
name: 'my-api',
|
|
253
|
+
url: 'https://api.example.com/openapi.json',
|
|
254
|
+
generateOptions: {
|
|
255
|
+
resolveFormats: true,
|
|
256
|
+
formatResolvers: {
|
|
257
|
+
phone: (schema) => ({
|
|
258
|
+
...schema,
|
|
259
|
+
pattern: '^\\+[1-9]\\d{1,14}$',
|
|
260
|
+
description: 'E.164 phone number',
|
|
261
|
+
}),
|
|
262
|
+
currency: (schema) => ({
|
|
263
|
+
...schema,
|
|
264
|
+
pattern: '^[A-Z]{3}$',
|
|
265
|
+
description: 'ISO 4217 currency code',
|
|
266
|
+
}),
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// Custom resolvers only (no built-ins)
|
|
272
|
+
OpenapiAdapter.init({
|
|
273
|
+
name: 'my-api',
|
|
274
|
+
url: 'https://api.example.com/openapi.json',
|
|
275
|
+
generateOptions: {
|
|
276
|
+
formatResolvers: {
|
|
277
|
+
phone: (schema) => ({ ...schema, pattern: '^\\+[1-9]\\d{1,14}$' }),
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
| Option | Type | Default | Description |
|
|
284
|
+
| ----------------- | -------------------------------- | ----------- | -------------------------------------------------------------------------------------------- |
|
|
285
|
+
| `resolveFormats` | `boolean` | `false` | Enable built-in format resolvers (uuid, date-time, email, int32, etc.) |
|
|
286
|
+
| `formatResolvers` | `Record<string, FormatResolver>` | `undefined` | Custom resolvers; merged with built-ins when `resolveFormats: true`, custom takes precedence |
|
|
287
|
+
|
|
288
|
+
## $ref Resolution Security
|
|
289
|
+
|
|
290
|
+
By default, the adapter blocks dangerous `$ref` resolution patterns to prevent SSRF attacks:
|
|
291
|
+
|
|
292
|
+
- `file://` protocol is blocked (prevents local file reads)
|
|
293
|
+
- Internal/private IPs are blocked (prevents cloud metadata theft, internal network probing)
|
|
294
|
+
- `http://` and `https://` to public hosts are allowed
|
|
295
|
+
|
|
296
|
+
Configure via `loadOptions.refResolution`:
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// Restrict $refs to specific hosts only
|
|
300
|
+
OpenapiAdapter.init({
|
|
301
|
+
name: 'my-api',
|
|
302
|
+
url: 'https://api.example.com/openapi.json',
|
|
303
|
+
loadOptions: {
|
|
304
|
+
refResolution: {
|
|
305
|
+
allowedHosts: ['schemas.example.com'],
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Allow file:// protocol (for specs referencing local schema files)
|
|
311
|
+
OpenapiAdapter.init({
|
|
312
|
+
name: 'my-api',
|
|
313
|
+
url: 'https://api.example.com/openapi.json',
|
|
314
|
+
loadOptions: {
|
|
315
|
+
refResolution: {
|
|
316
|
+
allowedProtocols: ['http', 'https', 'file'],
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Allow internal IPs (only in trusted environments)
|
|
322
|
+
OpenapiAdapter.init({
|
|
323
|
+
name: 'internal-api',
|
|
324
|
+
url: 'http://10.0.0.5:8080/openapi.json',
|
|
325
|
+
loadOptions: {
|
|
326
|
+
refResolution: {
|
|
327
|
+
allowInternalIPs: true,
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Block ALL external refs (only resolve local #/ pointers)
|
|
333
|
+
OpenapiAdapter.init({
|
|
334
|
+
name: 'my-api',
|
|
335
|
+
url: 'https://api.example.com/openapi.json',
|
|
336
|
+
loadOptions: {
|
|
337
|
+
refResolution: {
|
|
338
|
+
allowedProtocols: [],
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
| Option | Type | Default | Description |
|
|
345
|
+
| ------------------ | ---------- | ------------------- | ----------------------------------------------------------------------------------------- |
|
|
346
|
+
| `allowedProtocols` | `string[]` | `['http', 'https']` | Protocols allowed for external `$ref` resolution (http, https, ftp, ws, etc.) |
|
|
347
|
+
| `allowedHosts` | `string[]` | `undefined` | When set, only refs to these hostnames are resolved |
|
|
348
|
+
| `blockedHosts` | `string[]` | `undefined` | Additional hostnames/IPs to block beyond the built-in list |
|
|
349
|
+
| `allowInternalIPs` | `boolean` | `false` | Disable the built-in internal IP block list (127.x, 10.x, 172.16.x, 169.254.x, localhost) |
|
|
350
|
+
|
|
351
|
+
## Load Options
|
|
352
|
+
|
|
353
|
+
Configure how the OpenAPI spec is loaded:
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
OpenapiAdapter.init({
|
|
357
|
+
name: 'my-api',
|
|
358
|
+
url: 'https://api.example.com/openapi.json',
|
|
359
|
+
baseUrl: 'https://api.example.com',
|
|
360
|
+
loadOptions: {
|
|
361
|
+
headers: { authorization: `Bearer ${process.env.SPEC_ACCESS_TOKEN}` },
|
|
362
|
+
timeout: 10000,
|
|
363
|
+
validate: true,
|
|
364
|
+
dereference: true,
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Common Patterns
|
|
370
|
+
|
|
371
|
+
| Pattern | Correct | Incorrect | Why |
|
|
372
|
+
| -------------------- | ---------------------------------------------------------- | --------------------------------------------------- | ----------------------------------------------- |
|
|
373
|
+
| Adapter registration | `OpenapiAdapter.init({ ... })` in `adapters` array | Placing adapter in `plugins` array | Adapters go in `adapters`, not `plugins` |
|
|
374
|
+
| Tool naming | Tools auto-named as `<name>:<operationId>` | Expecting flat names like `listPets` | Adapter name prevents collisions |
|
|
375
|
+
| Auth configuration | `staticAuth: { jwt: process.env.API_TOKEN! }` | Hardcoding secrets: `staticAuth: { jwt: 'sk-xxx' }` | Always use environment variables |
|
|
376
|
+
| Spec source | Use `url` for hosted specs or `spec` for inline | Using both `url` and `spec` simultaneously | Only one source; `spec` takes precedence |
|
|
377
|
+
| Multiple APIs | Separate `OpenapiAdapter.init()` with unique `name` values | Same `name` for different adapters | Duplicate names cause tool collisions |
|
|
378
|
+
| $ref security | Use default `refResolution` (blocks file://, internal IPs) | Setting `allowInternalIPs: true` in production | Default protects against SSRF |
|
|
379
|
+
| Format resolution | `generateOptions: { resolveFormats: true }` | Writing manual patterns for standard formats | Built-in resolvers handle uuid, date-time, etc. |
|
|
380
|
+
|
|
381
|
+
## Verification Checklist
|
|
382
|
+
|
|
383
|
+
### Configuration
|
|
384
|
+
|
|
385
|
+
- [ ] `@frontmcp/adapters` package is installed
|
|
386
|
+
- [ ] `OpenapiAdapter.init()` is in the `adapters` array of `@App`
|
|
387
|
+
- [ ] Adapter has a unique `name` for tool namespacing
|
|
388
|
+
- [ ] `url` points to a valid, reachable OpenAPI JSON/YAML endpoint (or `spec` is inline)
|
|
389
|
+
|
|
390
|
+
### Runtime
|
|
391
|
+
|
|
392
|
+
- [ ] Generated tools appear in `tools/list` with `<name>:<operationId>` naming
|
|
393
|
+
- [ ] Auth headers are sent correctly on API calls
|
|
394
|
+
- [ ] Spec polling refreshes tool definitions at the configured interval
|
|
395
|
+
- [ ] Invalid spec URL produces a clear startup error
|
|
396
|
+
|
|
397
|
+
### Production
|
|
398
|
+
|
|
399
|
+
- [ ] API tokens and secrets are loaded from environment variables
|
|
400
|
+
- [ ] Polling interval is appropriate for the API's update frequency
|
|
401
|
+
- [ ] Multiple adapter registrations use distinct names
|
|
402
|
+
- [ ] $ref resolution defaults are appropriate (or explicitly configured)
|
|
403
|
+
|
|
404
|
+
## Troubleshooting
|
|
405
|
+
|
|
406
|
+
| Problem | Cause | Solution |
|
|
407
|
+
| ---------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
|
|
408
|
+
| No tools generated from spec | Spec URL returns non-OpenAPI content or is unreachable | Verify URL returns valid OpenAPI 3.x JSON; check network access |
|
|
409
|
+
| Authentication errors on API calls | Wrong auth config or missing credentials | Configure `staticAuth`, `securityResolver`, `authProviderMapper`, or `additionalHeaders`; verify env vars |
|
|
410
|
+
| Duplicate tool name error | Two adapters with the same `name` | Give each adapter a unique `name` |
|
|
411
|
+
| Stale tools after API update | Spec polling not configured | Add `polling: { intervalMs: 300000 }` |
|
|
412
|
+
| External $refs not resolving | Default SSRF protection blocks external refs | Add `loadOptions.refResolution.allowedHosts` or `allowedProtocols` |
|
|
413
|
+
| SSRF warning / $ref to internal IP | Spec contains $refs to internal services | Blocked by default; use `refResolution.allowInternalIPs: true` only in trusted environments |
|
|
414
|
+
| TypeScript error importing adapter | Wrong import path | Import from `@frontmcp/adapters` |
|
|
415
|
+
|
|
416
|
+
## Examples
|
|
417
|
+
|
|
418
|
+
| Example | Level | Description |
|
|
419
|
+
| ----------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
420
|
+
| [`basic-openapi-adapter`](../examples/openapi-adapter/basic-openapi-adapter.md) | Basic | Demonstrates converting an OpenAPI specification into MCP tools automatically using `OpenapiAdapter` with minimal configuration. |
|
|
421
|
+
| [`authenticated-adapter-with-polling`](../examples/openapi-adapter/authenticated-adapter-with-polling.md) | Intermediate | Demonstrates configuring authentication (API key and bearer token) and automatic spec polling for OpenAPI adapters. |
|
|
422
|
+
| [`format-resolution-and-custom-resolvers`](../examples/openapi-adapter/format-resolution-and-custom-resolvers.md) | Intermediate | Demonstrates using built-in and custom format resolvers to enrich tool input schemas with concrete constraints from OpenAPI format values. |
|
|
423
|
+
| [`ref-security-and-filtering`](../examples/openapi-adapter/ref-security-and-filtering.md) | Intermediate | Demonstrates configuring $ref resolution security to prevent SSRF attacks and filtering which API operations become MCP tools. |
|
|
424
|
+
| [`multi-api-hub-with-inline-spec`](../examples/openapi-adapter/multi-api-hub-with-inline-spec.md) | Advanced | Demonstrates registering multiple OpenAPI adapters from different APIs in a single app, including one with an inline spec definition instead of a remote URL. |
|
|
425
|
+
|
|
426
|
+
> See all examples in [`examples/openapi-adapter/`](../examples/openapi-adapter/)
|
|
427
|
+
|
|
428
|
+
## Reference
|
|
429
|
+
|
|
430
|
+
- [OpenAPI Adapter Documentation](https://docs.agentfront.dev/frontmcp/adapters/openapi-adapter)
|
|
431
|
+
- Related skills: `official-adapters`, `create-adapter`, `create-tool`
|
|
@@ -21,9 +21,9 @@ Shows advanced VectoriaDB usage with typed document metadata, batch operations,
|
|
|
21
21
|
|
|
22
22
|
```typescript
|
|
23
23
|
// src/providers/product-search.provider.ts
|
|
24
|
+
import { FileStorageAdapter, VectoriaDB, type DocumentMetadata } from 'vectoriadb';
|
|
25
|
+
|
|
24
26
|
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
25
|
-
import { VectoriaDB, FileStorageAdapter } from 'vectoriadb';
|
|
26
|
-
import type { DocumentMetadata } from 'vectoriadb';
|
|
27
27
|
|
|
28
28
|
export const ProductSearch = Symbol('ProductSearch');
|
|
29
29
|
|
|
@@ -104,8 +104,8 @@ export class ProductSearchProvider {
|
|
|
104
104
|
|
|
105
105
|
```typescript
|
|
106
106
|
// src/tools/find-products.tool.ts
|
|
107
|
-
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
108
|
-
|
|
107
|
+
import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
108
|
+
|
|
109
109
|
import { ProductSearch } from '../providers/product-search.provider';
|
|
110
110
|
|
|
111
111
|
@Tool({
|
package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md
CHANGED
|
@@ -21,9 +21,9 @@ Shows how to use `VectoriaDB` for semantic search with transformer models, filte
|
|
|
21
21
|
|
|
22
22
|
```typescript
|
|
23
23
|
// src/providers/knowledge-base.provider.ts
|
|
24
|
+
import { FileStorageAdapter, VectoriaDB, type DocumentMetadata } from 'vectoriadb';
|
|
25
|
+
|
|
24
26
|
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
25
|
-
import { VectoriaDB, FileStorageAdapter } from 'vectoriadb';
|
|
26
|
-
import type { DocumentMetadata } from 'vectoriadb';
|
|
27
27
|
|
|
28
28
|
export const KnowledgeBase = Symbol('KnowledgeBase');
|
|
29
29
|
|
|
@@ -80,8 +80,8 @@ export class KnowledgeBaseProvider {
|
|
|
80
80
|
|
|
81
81
|
```typescript
|
|
82
82
|
// src/tools/semantic-search.tool.ts
|
|
83
|
-
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
84
|
-
|
|
83
|
+
import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
84
|
+
|
|
85
85
|
import { KnowledgeBase } from '../providers/knowledge-base.provider';
|
|
86
86
|
|
|
87
87
|
@Tool({
|
|
@@ -20,9 +20,10 @@ Shows how to use `TFIDFVectoria` for zero-dependency keyword search in a FrontMC
|
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
// src/providers/faq-search.provider.ts
|
|
23
|
-
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
24
23
|
import { TFIDFVectoria } from 'vectoriadb';
|
|
25
24
|
|
|
25
|
+
import { Provider, ProviderScope } from '@frontmcp/sdk';
|
|
26
|
+
|
|
26
27
|
export const FAQSearch = Symbol('FAQSearch');
|
|
27
28
|
|
|
28
29
|
@Provider({ name: 'faq-search', provide: FAQSearch, scope: ProviderScope.GLOBAL })
|
|
@@ -55,8 +56,8 @@ export class FAQSearchProvider {
|
|
|
55
56
|
|
|
56
57
|
```typescript
|
|
57
58
|
// src/tools/search-faq.tool.ts
|
|
58
|
-
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
59
|
-
|
|
59
|
+
import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
60
|
+
|
|
60
61
|
import { FAQSearch } from '../providers/faq-search.provider';
|
|
61
62
|
|
|
62
63
|
@Tool({
|
|
@@ -120,6 +120,7 @@ weather-api/
|
|
|
120
120
|
|
|
121
121
|
```typescript
|
|
122
122
|
import { FrontMcp } from '@frontmcp/sdk';
|
|
123
|
+
|
|
123
124
|
import { WeatherApp } from './weather.app';
|
|
124
125
|
|
|
125
126
|
@FrontMcp({
|
|
@@ -132,8 +133,7 @@ export default class WeatherServer {}
|
|
|
132
133
|
**Tool** (`create-tool`):
|
|
133
134
|
|
|
134
135
|
```typescript
|
|
135
|
-
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
136
|
-
import { z } from 'zod';
|
|
136
|
+
import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
137
137
|
|
|
138
138
|
@Tool({
|
|
139
139
|
name: 'get_weather',
|
|
@@ -225,8 +225,8 @@ export default class TaskManagerServer {}
|
|
|
225
225
|
**Provider for shared storage** (`create-provider`):
|
|
226
226
|
|
|
227
227
|
```typescript
|
|
228
|
-
import { Provider } from '@frontmcp/sdk';
|
|
229
228
|
import type { Token } from '@frontmcp/di';
|
|
229
|
+
import { Provider } from '@frontmcp/sdk';
|
|
230
230
|
|
|
231
231
|
export interface TaskStore {
|
|
232
232
|
create(task: Task): Promise<Task>;
|
|
@@ -21,10 +21,10 @@ Shows an autonomous research agent with inner tools and configurable depth, and
|
|
|
21
21
|
|
|
22
22
|
```typescript
|
|
23
23
|
// src/research/agents/researcher.agent.ts
|
|
24
|
-
import { Agent, AgentContext } from '@frontmcp/sdk';
|
|
25
|
-
|
|
26
|
-
import { SearchDocsTool } from '../../search/tools/search-docs.tool';
|
|
24
|
+
import { Agent, AgentContext, z } from '@frontmcp/sdk';
|
|
25
|
+
|
|
27
26
|
import { IngestDocumentTool } from '../../ingestion/tools/ingest-document.tool';
|
|
27
|
+
import { SearchDocsTool } from '../../search/tools/search-docs.tool';
|
|
28
28
|
|
|
29
29
|
@Agent({
|
|
30
30
|
name: 'research_topic',
|
|
@@ -79,8 +79,7 @@ export class ResearcherAgent extends AgentContext {
|
|
|
79
79
|
|
|
80
80
|
```typescript
|
|
81
81
|
// src/plugins/audit-log.plugin.ts
|
|
82
|
-
import { Plugin } from '@frontmcp/sdk';
|
|
83
|
-
import type { PluginHookContext } from '@frontmcp/sdk';
|
|
82
|
+
import { Plugin, type PluginHookContext } from '@frontmcp/sdk';
|
|
84
83
|
|
|
85
84
|
@Plugin({
|
|
86
85
|
name: 'AuditLog',
|
package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md
CHANGED
|
@@ -20,8 +20,8 @@ Shows a semantic search tool with embedding generation and a resource template f
|
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
// src/search/tools/search-docs.tool.ts
|
|
23
|
-
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
24
|
-
|
|
23
|
+
import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
24
|
+
|
|
25
25
|
import { VECTOR_STORE } from '../../ingestion/providers/vector-store.provider';
|
|
26
26
|
|
|
27
27
|
@Tool({
|
|
@@ -81,8 +81,9 @@ export class SearchDocsTool extends ToolContext {
|
|
|
81
81
|
|
|
82
82
|
```typescript
|
|
83
83
|
// src/search/resources/doc.resource.ts
|
|
84
|
-
import { ResourceTemplate, ResourceContext } from '@frontmcp/sdk';
|
|
85
84
|
import type { ReadResourceResult } from '@frontmcp/protocol';
|
|
85
|
+
import { ResourceContext, ResourceTemplate } from '@frontmcp/sdk';
|
|
86
|
+
|
|
86
87
|
import { VECTOR_STORE } from '../../ingestion/providers/vector-store.provider';
|
|
87
88
|
|
|
88
89
|
@ResourceTemplate({
|
|
@@ -20,8 +20,8 @@ Shows how to create CRUD tools with authentication, using `this.context.session`
|
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
// src/tools/create-task.tool.ts
|
|
23
|
-
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
24
|
-
|
|
23
|
+
import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
24
|
+
|
|
25
25
|
import { TASK_STORE } from '../providers/task-store.provider';
|
|
26
26
|
|
|
27
27
|
@Tool({
|
|
@@ -70,8 +70,8 @@ export class CreateTaskTool extends ToolContext {
|
|
|
70
70
|
|
|
71
71
|
```typescript
|
|
72
72
|
// src/tools/list-tasks.tool.ts
|
|
73
|
-
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
74
|
-
|
|
73
|
+
import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
74
|
+
|
|
75
75
|
import { TASK_STORE } from '../providers/task-store.provider';
|
|
76
76
|
|
|
77
77
|
@Tool({
|
|
@@ -20,8 +20,7 @@ Shows how to create a tool with Zod input and output schemas, use `this.fetch()`
|
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
// src/tools/get-weather.tool.ts
|
|
23
|
-
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
24
|
-
import { z } from 'zod';
|
|
23
|
+
import { Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
25
24
|
|
|
26
25
|
@Tool({
|
|
27
26
|
name: 'get_weather',
|