@robinmordasiewicz/f5xc-api-mcp 2.0.21-2601081307 → 2.0.21-2601081701

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.
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Schema Loader Module
3
+ *
4
+ * Provides infrastructure for loading OpenAPI component schemas from spec files
5
+ * and resolving $ref pointers to produce fully resolved schemas.
6
+ *
7
+ * This enables AI assistants to understand the exact structure required for
8
+ * API payloads without guessing.
9
+ */
10
+ import { readFileSync, existsSync } from "fs";
11
+ import { join, dirname } from "path";
12
+ import { fileURLToPath } from "url";
13
+ import { getToolByName } from "../registry.js";
14
+ // Get specs directory path
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+ const SPECS_DIR = join(__dirname, "../../../specs/domains");
18
+ // Module-level cache for domain schemas
19
+ const schemaCache = new Map();
20
+ // Maximum depth for $ref resolution to prevent infinite loops
21
+ const MAX_RESOLUTION_DEPTH = 10;
22
+ /**
23
+ * Map tool domain names to spec file names
24
+ * Some domains have different naming conventions
25
+ */
26
+ function getDomainSpecFileName(domain) {
27
+ // Convert domain name to spec file name (e.g., "virtual" -> "virtual.json")
28
+ return `${domain}.json`;
29
+ }
30
+ /**
31
+ * Load all schemas from a domain's spec file
32
+ *
33
+ * @param domain - Domain name (e.g., "virtual", "dns", "waf")
34
+ * @returns Cached domain schema data or null if not found
35
+ */
36
+ export function loadDomainSchemas(domain) {
37
+ // Check cache first
38
+ const cached = schemaCache.get(domain);
39
+ if (cached) {
40
+ return cached;
41
+ }
42
+ const specFileName = getDomainSpecFileName(domain);
43
+ const specPath = join(SPECS_DIR, specFileName);
44
+ if (!existsSync(specPath)) {
45
+ // Try alternative naming (replace underscores with hyphens)
46
+ const altPath = join(SPECS_DIR, domain.replace(/_/g, "-") + ".json");
47
+ if (!existsSync(altPath)) {
48
+ return null;
49
+ }
50
+ }
51
+ try {
52
+ const specContent = readFileSync(specPath, "utf-8");
53
+ const spec = JSON.parse(specContent);
54
+ const cacheEntry = {
55
+ schemas: spec.components?.schemas || {},
56
+ loadedAt: Date.now(),
57
+ };
58
+ schemaCache.set(domain, cacheEntry);
59
+ return cacheEntry;
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
65
+ /**
66
+ * Parse a $ref string to extract the schema name
67
+ *
68
+ * @param ref - Reference string (e.g., "#/components/schemas/http_loadbalancerCreateRequest")
69
+ * @returns Schema name or null if invalid format
70
+ */
71
+ export function parseSchemaRef(ref) {
72
+ if (!ref || typeof ref !== "string") {
73
+ return null;
74
+ }
75
+ // Handle standard OpenAPI $ref format
76
+ const match = ref.match(/^#\/components\/schemas\/(.+)$/);
77
+ if (match && match[1]) {
78
+ return match[1];
79
+ }
80
+ return null;
81
+ }
82
+ /**
83
+ * Resolve a $ref pointer to its actual schema
84
+ *
85
+ * @param ref - Reference string
86
+ * @param domain - Domain to look up schemas from
87
+ * @returns Resolved schema or null if not found
88
+ */
89
+ export function resolveSchemaRef(ref, domain) {
90
+ const schemaName = parseSchemaRef(ref);
91
+ if (!schemaName) {
92
+ return null;
93
+ }
94
+ const domainCache = loadDomainSchemas(domain);
95
+ if (!domainCache) {
96
+ return null;
97
+ }
98
+ const schema = domainCache.schemas[schemaName];
99
+ if (!schema) {
100
+ // Schema might be in a different domain - try loading from all cached domains
101
+ for (const [, cache] of schemaCache) {
102
+ if (cache.schemas[schemaName]) {
103
+ return cache.schemas[schemaName];
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ return schema;
109
+ }
110
+ /**
111
+ * Recursively resolve all $ref pointers in a schema
112
+ *
113
+ * @param schema - Schema object (may contain $refs)
114
+ * @param domain - Primary domain for lookups
115
+ * @param depth - Current recursion depth
116
+ * @param visited - Set of already visited refs to detect cycles
117
+ * @returns Fully resolved schema
118
+ */
119
+ export function resolveNestedRefs(schema, domain, depth = 0, visited = new Set()) {
120
+ // Depth limit check
121
+ if (depth > MAX_RESOLUTION_DEPTH) {
122
+ return schema;
123
+ }
124
+ // Handle null/undefined
125
+ if (!schema || typeof schema !== "object") {
126
+ return schema;
127
+ }
128
+ const obj = schema;
129
+ // Handle $ref
130
+ if ("$ref" in obj && typeof obj["$ref"] === "string") {
131
+ const ref = obj["$ref"];
132
+ // Cycle detection
133
+ if (visited.has(ref)) {
134
+ return { $ref: ref, _circular: true };
135
+ }
136
+ visited.add(ref);
137
+ const resolved = resolveSchemaRef(ref, domain);
138
+ if (resolved) {
139
+ // Continue resolving nested refs in the resolved schema
140
+ return resolveNestedRefs(resolved, domain, depth + 1, new Set(visited));
141
+ }
142
+ // Couldn't resolve - return original ref
143
+ return obj;
144
+ }
145
+ // Handle arrays
146
+ if (Array.isArray(obj)) {
147
+ return obj.map((item) => resolveNestedRefs(item, domain, depth + 1, visited));
148
+ }
149
+ // Handle objects - recursively resolve all properties
150
+ const result = {};
151
+ for (const [key, value] of Object.entries(obj)) {
152
+ if (key === "properties" && typeof value === "object" && value !== null) {
153
+ // Resolve each property schema
154
+ const props = {};
155
+ for (const [propKey, propValue] of Object.entries(value)) {
156
+ props[propKey] = resolveNestedRefs(propValue, domain, depth + 1, visited);
157
+ }
158
+ result[key] = props;
159
+ }
160
+ else if (key === "items" && typeof value === "object") {
161
+ // Resolve array items schema
162
+ result[key] = resolveNestedRefs(value, domain, depth + 1, visited);
163
+ }
164
+ else if ((key === "oneOf" || key === "anyOf" || key === "allOf") && Array.isArray(value)) {
165
+ // Resolve composition schemas
166
+ result[key] = value.map((item) => resolveNestedRefs(item, domain, depth + 1, visited));
167
+ }
168
+ else if (key === "additionalProperties" && typeof value === "object" && value !== null) {
169
+ // Resolve additionalProperties schema
170
+ result[key] = resolveNestedRefs(value, domain, depth + 1, visited);
171
+ }
172
+ else {
173
+ result[key] = value;
174
+ }
175
+ }
176
+ return result;
177
+ }
178
+ /**
179
+ * Get fully resolved request body schema for a tool
180
+ *
181
+ * @param toolName - Tool name (e.g., "f5xc-api-virtual-http-loadbalancer-create")
182
+ * @returns Fully resolved schema or null if not found
183
+ */
184
+ export function getResolvedRequestBodySchema(toolName) {
185
+ const tool = getToolByName(toolName);
186
+ if (!tool || !tool.requestBodySchema) {
187
+ return null;
188
+ }
189
+ const schema = tool.requestBodySchema;
190
+ // If schema has a $ref, resolve it
191
+ if ("$ref" in schema && typeof schema["$ref"] === "string") {
192
+ const resolved = resolveSchemaRef(schema["$ref"], tool.domain);
193
+ if (resolved) {
194
+ return resolveNestedRefs(resolved, tool.domain);
195
+ }
196
+ }
197
+ // Schema is already inline - just resolve any nested refs
198
+ return resolveNestedRefs(schema, tool.domain);
199
+ }
200
+ /**
201
+ * Get the x-f5xc-minimum-configuration from a tool's request body schema
202
+ *
203
+ * @param toolName - Tool name
204
+ * @returns Minimum configuration or null if not found
205
+ */
206
+ export function getMinimumConfigurationFromSchema(toolName) {
207
+ const tool = getToolByName(toolName);
208
+ if (!tool || !tool.requestBodySchema) {
209
+ return null;
210
+ }
211
+ const schema = tool.requestBodySchema;
212
+ // If schema has a $ref, resolve it first
213
+ if ("$ref" in schema && typeof schema["$ref"] === "string") {
214
+ const resolved = resolveSchemaRef(schema["$ref"], tool.domain);
215
+ if (resolved && "x-f5xc-minimum-configuration" in resolved) {
216
+ return resolved["x-f5xc-minimum-configuration"];
217
+ }
218
+ }
219
+ // Check inline schema
220
+ if ("x-f5xc-minimum-configuration" in schema) {
221
+ return schema["x-f5xc-minimum-configuration"];
222
+ }
223
+ return null;
224
+ }
225
+ /**
226
+ * Extract required fields from a resolved schema
227
+ *
228
+ * @param schema - Resolved schema
229
+ * @param path - Current path prefix for nested fields
230
+ * @returns Array of required field paths
231
+ */
232
+ export function extractRequiredFields(schema, path = "") {
233
+ const required = [];
234
+ // Add directly required fields
235
+ if (schema.required && Array.isArray(schema.required)) {
236
+ for (const field of schema.required) {
237
+ required.push(path ? `${path}.${field}` : field);
238
+ }
239
+ }
240
+ // Recursively check nested properties
241
+ if (schema.properties) {
242
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
243
+ const propPath = path ? `${path}.${key}` : key;
244
+ required.push(...extractRequiredFields(propSchema, propPath));
245
+ }
246
+ }
247
+ return required;
248
+ }
249
+ /**
250
+ * Extract oneOf/anyOf groups from a schema
251
+ *
252
+ * @param schema - Resolved schema
253
+ * @param path - Current path prefix
254
+ * @returns Array of mutually exclusive groups
255
+ */
256
+ export function extractMutuallyExclusiveGroups(schema, path = "") {
257
+ const groups = [];
258
+ // Check for x-ves-oneof-field annotations
259
+ for (const [key, value] of Object.entries(schema)) {
260
+ if (key.startsWith("x-ves-oneof-field-") && typeof value === "string") {
261
+ try {
262
+ const options = JSON.parse(value);
263
+ const choiceField = key.replace("x-ves-oneof-field-", "");
264
+ groups.push({
265
+ fieldPath: path ? `${path}.${choiceField}` : choiceField,
266
+ options: options.map((opt) => ({ fieldName: opt })),
267
+ reason: `Choose one of: ${options.join(", ")}`,
268
+ });
269
+ }
270
+ catch {
271
+ // Invalid JSON, skip
272
+ }
273
+ }
274
+ }
275
+ // Check for standard oneOf/anyOf
276
+ if (schema.oneOf && Array.isArray(schema.oneOf)) {
277
+ groups.push({
278
+ fieldPath: path || "root",
279
+ options: schema.oneOf.map((opt, idx) => ({
280
+ fieldName: typeof opt.title === "string" ? opt.title : `option${idx + 1}`,
281
+ description: typeof opt.description === "string" ? opt.description : undefined,
282
+ })),
283
+ reason: "Choose one of the following options",
284
+ });
285
+ }
286
+ if (schema.anyOf && Array.isArray(schema.anyOf)) {
287
+ groups.push({
288
+ fieldPath: path || "root",
289
+ options: schema.anyOf.map((opt, idx) => ({
290
+ fieldName: typeof opt.title === "string" ? opt.title : `option${idx + 1}`,
291
+ description: typeof opt.description === "string" ? opt.description : undefined,
292
+ })),
293
+ reason: "Choose one or more of the following options",
294
+ });
295
+ }
296
+ // Recursively check properties
297
+ if (schema.properties) {
298
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
299
+ const propPath = path ? `${path}.${key}` : key;
300
+ groups.push(...extractMutuallyExclusiveGroups(propSchema, propPath));
301
+ }
302
+ }
303
+ return groups;
304
+ }
305
+ /**
306
+ * Clear the schema cache (useful for testing)
307
+ */
308
+ export function clearSchemaCache() {
309
+ schemaCache.clear();
310
+ }
311
+ /**
312
+ * Get cache statistics
313
+ */
314
+ export function getSchemaCacheStats() {
315
+ const cachedDomains = Array.from(schemaCache.keys());
316
+ let totalSchemas = 0;
317
+ for (const cache of schemaCache.values()) {
318
+ totalSchemas += Object.keys(cache.schemas).length;
319
+ }
320
+ return { cachedDomains, totalSchemas };
321
+ }
322
+ //# sourceMappingURL=schema-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-loader.js","sourceRoot":"","sources":["../../../src/tools/discovery/schema-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Schema Retrieval Module
3
+ *
4
+ * Provides full JSON schemas for F5XC API request bodies to eliminate
5
+ * guessing by AI assistants when constructing API payloads.
6
+ *
7
+ * Enhanced with $ref resolution, minimum configuration extraction,
8
+ * and smart example generation.
9
+ */
10
+ import { type ResolvedSchema, type MinimumConfiguration, type MutuallyExclusiveGroup } from "./schema-loader.js";
11
+ export type { ResolvedSchema, MinimumConfiguration, MutuallyExclusiveGroup };
12
+ /**
13
+ * Get the raw JSON schema for a tool's request body (may contain $refs)
14
+ *
15
+ * @param toolName - The exact tool name
16
+ * @returns Raw JSON schema or null if not found
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const schema = getRequestBodySchema("f5xc-api-virtual-http-loadbalancer-create");
21
+ * if (schema) {
22
+ * console.log(JSON.stringify(schema, null, 2));
23
+ * }
24
+ * ```
25
+ */
26
+ export declare function getRequestBodySchema(toolName: string): Record<string, unknown> | null;
27
+ /**
28
+ * Get fully resolved request body schema (all $refs expanded)
29
+ *
30
+ * This is the recommended function for AI assistants as it provides
31
+ * the complete schema structure without any unresolved references.
32
+ *
33
+ * @param toolName - The exact tool name
34
+ * @returns Fully resolved schema or null if not found
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const schema = getResolvedRequestBodySchema("f5xc-api-virtual-http-loadbalancer-create");
39
+ * if (schema) {
40
+ * // schema.properties contains all nested structures
41
+ * console.log(schema.properties);
42
+ * }
43
+ * ```
44
+ */
45
+ export declare function getResolvedRequestBodySchema(toolName: string): ResolvedSchema | null;
46
+ /**
47
+ * Get the full JSON schema for a tool's response
48
+ *
49
+ * @param toolName - The exact tool name
50
+ * @returns Complete JSON schema or null if not found
51
+ */
52
+ export declare function getResponseSchema(toolName: string): Record<string, unknown> | null;
53
+ /**
54
+ * Get both request and response schemas for a tool
55
+ *
56
+ * @param toolName - The exact tool name
57
+ * @returns Object with request and response schemas
58
+ */
59
+ export declare function getToolSchemas(toolName: string): {
60
+ requestBody?: Record<string, unknown>;
61
+ response?: Record<string, unknown>;
62
+ };
63
+ /**
64
+ * Get x-f5xc-minimum-configuration from a tool's request body schema
65
+ *
66
+ * This contains rich examples (JSON, YAML, cURL), required fields,
67
+ * and mutually exclusive field groups from the OpenAPI spec.
68
+ *
69
+ * @param toolName - The exact tool name
70
+ * @returns Minimum configuration or null if not found
71
+ */
72
+ export declare function getMinimumConfiguration(toolName: string): MinimumConfiguration | null;
73
+ /**
74
+ * Get all required fields for a tool's request body
75
+ *
76
+ * Combines required fields from:
77
+ * 1. Schema 'required' arrays (recursively)
78
+ * 2. x-f5xc-minimum-configuration.required_fields
79
+ *
80
+ * @param toolName - The exact tool name
81
+ * @returns Array of required field paths (e.g., ["metadata.name", "spec.domains"])
82
+ */
83
+ export declare function getRequiredFields(toolName: string): string[];
84
+ /**
85
+ * Get mutually exclusive field groups for a tool
86
+ *
87
+ * These indicate fields where only one option should be specified.
88
+ *
89
+ * @param toolName - The exact tool name
90
+ * @returns Array of mutually exclusive groups
91
+ */
92
+ export declare function getMutuallyExclusiveFields(toolName: string): MutuallyExclusiveGroup[];
93
+ /**
94
+ * Generate example payload from request body schema (legacy function)
95
+ *
96
+ * This helps AI assistants understand the structure of complex nested objects
97
+ * without having to guess the format.
98
+ *
99
+ * @param toolName - The exact tool name
100
+ * @returns Example payload or null if no schema found
101
+ *
102
+ * @deprecated Use generateSmartExamplePayload for better results with $ref resolution
103
+ */
104
+ export declare function generateExamplePayload(toolName: string): unknown;
105
+ /**
106
+ * Generate smart example payload with $ref resolution and intelligent defaults
107
+ *
108
+ * This is the recommended function for generating example payloads as it:
109
+ * 1. Resolves all $ref pointers
110
+ * 2. Uses smart defaults based on field names
111
+ * 3. Falls back to x-f5xc-minimum-configuration examples when available
112
+ *
113
+ * @param toolName - The exact tool name
114
+ * @returns Complete example payload or null if no schema found
115
+ */
116
+ export declare function generateSmartExamplePayload(toolName: string): Record<string, unknown> | null;
117
+ /**
118
+ * Get comprehensive schema information for a tool
119
+ *
120
+ * This combines all schema-related data into a single response,
121
+ * ideal for AI assistants that need full context.
122
+ *
123
+ * @param toolName - The exact tool name
124
+ * @returns Comprehensive schema info or null if not found
125
+ */
126
+ export declare function getComprehensiveSchemaInfo(toolName: string): {
127
+ resolvedSchema: ResolvedSchema;
128
+ requiredFields: string[];
129
+ mutuallyExclusiveGroups: MutuallyExclusiveGroup[];
130
+ examplePayload: Record<string, unknown> | null;
131
+ minimumConfiguration: MinimumConfiguration | null;
132
+ curlExample: string | null;
133
+ } | null;
134
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/tools/discovery/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,CAAC;AAE7E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQrF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAEpF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQlF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAWA;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAErF;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAoB5D;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB,EAAE,CAsBrF;AA0LD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQhE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAmB5F;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG;IAC5D,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,uBAAuB,EAAE,sBAAsB,EAAE,CAAC;IAClD,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/C,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,IAAI,CAgBP"}