fmea-api-mcp-server 1.1.30 → 1.1.32
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/dist/index.js
CHANGED
|
@@ -28,7 +28,7 @@ class ApiDocsServer {
|
|
|
28
28
|
constructor() {
|
|
29
29
|
this.server = new Server({
|
|
30
30
|
name: "api-docs-mcp",
|
|
31
|
-
version: "1.1.
|
|
31
|
+
version: "1.1.32",
|
|
32
32
|
}, {
|
|
33
33
|
capabilities: {
|
|
34
34
|
resources: {},
|
|
@@ -163,6 +163,15 @@ class ApiDocsServer {
|
|
|
163
163
|
required: [],
|
|
164
164
|
},
|
|
165
165
|
},
|
|
166
|
+
{
|
|
167
|
+
name: "list_all_apis",
|
|
168
|
+
description: "List all available API endpoints (method + path). No parameters required. Use this to get a complete overview of the API surface.",
|
|
169
|
+
inputSchema: {
|
|
170
|
+
type: "object",
|
|
171
|
+
properties: {},
|
|
172
|
+
required: [],
|
|
173
|
+
},
|
|
174
|
+
},
|
|
166
175
|
{
|
|
167
176
|
name: "get_api_details",
|
|
168
177
|
description: "Get full details including schema and parameters for a specific API endpoint.",
|
|
@@ -237,6 +246,17 @@ class ApiDocsServer {
|
|
|
237
246
|
],
|
|
238
247
|
};
|
|
239
248
|
}
|
|
249
|
+
if (request.params.name === "list_all_apis") {
|
|
250
|
+
const result = await this.searchService.listAll();
|
|
251
|
+
return {
|
|
252
|
+
content: [
|
|
253
|
+
{
|
|
254
|
+
type: "text",
|
|
255
|
+
text: JSON.stringify(result, null, 2),
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
240
260
|
if (request.params.name === "get_api_details") {
|
|
241
261
|
const apiPath = String(request.params.arguments?.path);
|
|
242
262
|
const method = request.params.arguments?.method ? String(request.params.arguments?.method).toUpperCase() : undefined;
|
|
@@ -236,6 +236,26 @@ export class FileSearchService {
|
|
|
236
236
|
message: "Use 'search_apis' with a query to find specific endpoints, or 'get_api_details' to see full schemas."
|
|
237
237
|
};
|
|
238
238
|
}
|
|
239
|
+
async listAll() {
|
|
240
|
+
const files = await getAllFiles(this.endpointsDir);
|
|
241
|
+
const endpoints = [];
|
|
242
|
+
for (const filePath of files) {
|
|
243
|
+
try {
|
|
244
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
245
|
+
const json = JSON.parse(content);
|
|
246
|
+
if (json.endpoints && Array.isArray(json.endpoints)) {
|
|
247
|
+
for (const ep of json.endpoints) {
|
|
248
|
+
endpoints.push({ method: ep.method, path: ep.path });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (_e) {
|
|
253
|
+
// Ignore parse errors
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
endpoints.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
|
|
257
|
+
return { total: endpoints.length, endpoints };
|
|
258
|
+
}
|
|
239
259
|
// Efficiently check if an endpoint exists without reading files if content is not needed
|
|
240
260
|
async findEndpointInFiles(files, apiPath, method) {
|
|
241
261
|
for (const filePath of files) {
|
|
@@ -53,7 +53,8 @@ export class OramaSearchService {
|
|
|
53
53
|
// Initialize embedding model (fastembed / onnxruntime-node)
|
|
54
54
|
try {
|
|
55
55
|
const { FlagEmbedding, EmbeddingModel } = await import('fastembed');
|
|
56
|
-
|
|
56
|
+
const cacheDir = path.join(process.env.HOME || '~', '.cache', 'fastembed');
|
|
57
|
+
this.extractor = await FlagEmbedding.init({ model: EmbeddingModel.BGESmallENV15, cacheDir });
|
|
57
58
|
console.error('✅ OramaSearchService: Index loaded and model ready (hybrid mode).');
|
|
58
59
|
}
|
|
59
60
|
catch (embeddingError) {
|
|
@@ -365,6 +366,20 @@ export class OramaSearchService {
|
|
|
365
366
|
}
|
|
366
367
|
return Array.from(categories).map(c => ({ name: c, count: 0 }));
|
|
367
368
|
}
|
|
369
|
+
async listAll() {
|
|
370
|
+
await this.initPromise;
|
|
371
|
+
const endpoints = [];
|
|
372
|
+
for (const key of this.lookup.keys()) {
|
|
373
|
+
const colonIdx = key.indexOf(':');
|
|
374
|
+
if (colonIdx === -1)
|
|
375
|
+
continue;
|
|
376
|
+
const method = key.substring(0, colonIdx);
|
|
377
|
+
const path = key.substring(colonIdx + 1);
|
|
378
|
+
endpoints.push({ method, path });
|
|
379
|
+
}
|
|
380
|
+
endpoints.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
|
|
381
|
+
return { total: endpoints.length, endpoints };
|
|
382
|
+
}
|
|
368
383
|
detectIntent(query) {
|
|
369
384
|
const lower = query.toLowerCase();
|
|
370
385
|
// Action Detection - Use ACTION_PRIORITY for correct order
|