fmea-api-mcp-server 1.0.6 → 1.0.7
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/README.md +3 -3
- package/dist/index.js +57 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -101,7 +101,7 @@ When the package is published to NPM:
|
|
|
101
101
|
- **Tools**:
|
|
102
102
|
- **Tools**:
|
|
103
103
|
- `search_apis`:
|
|
104
|
-
- Smart search with relevance scoring
|
|
105
|
-
- Supports filters: `query
|
|
106
|
-
- Results limited to
|
|
104
|
+
- Smart search with relevance scoring and pagination.
|
|
105
|
+
- Supports filters: `query` (use `*` for all), `method`, `version`, `page` (default 1).
|
|
106
|
+
- Results limited to 10 per page. Returns meta info (total, totalPages) and guidance.
|
|
107
107
|
- `get_api_details`: Get full details (schema, parameters) for a specific endpoint.
|
package/dist/index.js
CHANGED
|
@@ -114,6 +114,10 @@ class ApiDocsServer {
|
|
|
114
114
|
type: "string",
|
|
115
115
|
description: "Filter by API version (e.g. 'v1', 'v2'). Optional.",
|
|
116
116
|
},
|
|
117
|
+
page: {
|
|
118
|
+
type: "integer",
|
|
119
|
+
description: "Page number for pagination (default: 1).",
|
|
120
|
+
},
|
|
117
121
|
},
|
|
118
122
|
required: ["query"],
|
|
119
123
|
},
|
|
@@ -144,7 +148,8 @@ class ApiDocsServer {
|
|
|
144
148
|
const query = String(request.params.arguments?.query).toLowerCase();
|
|
145
149
|
const method = request.params.arguments?.method ? String(request.params.arguments?.method).toUpperCase() : undefined;
|
|
146
150
|
const version = request.params.arguments?.version ? String(request.params.arguments?.version).toLowerCase() : undefined;
|
|
147
|
-
const
|
|
151
|
+
const page = request.params.arguments?.page ? Number(request.params.arguments?.page) : 1;
|
|
152
|
+
const results = await this.searchInFiles(query, method, version, page);
|
|
148
153
|
return {
|
|
149
154
|
content: [
|
|
150
155
|
{
|
|
@@ -205,19 +210,19 @@ class ApiDocsServer {
|
|
|
205
210
|
}
|
|
206
211
|
return results;
|
|
207
212
|
}
|
|
208
|
-
// Smart search helper with scoring, filtering, and
|
|
209
|
-
async searchInFiles(query, filterMethod, filterVersion) {
|
|
213
|
+
// Smart search helper with scoring, filtering, limits, and pagination
|
|
214
|
+
async searchInFiles(query, filterMethod, filterVersion, page = 1) {
|
|
210
215
|
const files = await this.getAllFiles(ENDPOINTS_DIR);
|
|
211
216
|
let allMatches = [];
|
|
217
|
+
const isWildcard = query === "*" || query === "";
|
|
212
218
|
for (const filePath of files) {
|
|
213
219
|
try {
|
|
214
220
|
const content = await fs.readFile(filePath, "utf-8");
|
|
215
221
|
const json = JSON.parse(content);
|
|
216
222
|
const fileName = path.relative(ENDPOINTS_DIR, filePath);
|
|
217
|
-
// Version Filtering
|
|
218
|
-
// Check if file path contains version (e.g. "v1/...") or json has version field
|
|
223
|
+
// Version Filtering
|
|
219
224
|
if (filterVersion) {
|
|
220
|
-
const fileVersion = fileName.split(path.sep)[0];
|
|
225
|
+
const fileVersion = fileName.split(path.sep)[0];
|
|
221
226
|
if (fileVersion !== filterVersion && json.version !== filterVersion) {
|
|
222
227
|
continue;
|
|
223
228
|
}
|
|
@@ -230,17 +235,22 @@ class ApiDocsServer {
|
|
|
230
235
|
}
|
|
231
236
|
// Scoring Logic
|
|
232
237
|
let score = 0;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
238
|
+
if (isWildcard) {
|
|
239
|
+
score = 1; // All match in wildcard mode
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
const summary = (endpoint.summary || "").toLowerCase();
|
|
243
|
+
const description = (endpoint.description || "").toLowerCase();
|
|
244
|
+
const apiPath = (endpoint.path || "").toLowerCase();
|
|
245
|
+
const operationId = (endpoint.operationId || "").toLowerCase();
|
|
246
|
+
// Exact/High relevance matches
|
|
247
|
+
if (summary.includes(query) || operationId.includes(query))
|
|
248
|
+
score += 10;
|
|
249
|
+
if (description.includes(query))
|
|
250
|
+
score += 5;
|
|
251
|
+
if (apiPath.includes(query))
|
|
252
|
+
score += 3;
|
|
253
|
+
}
|
|
244
254
|
if (score > 0) {
|
|
245
255
|
allMatches.push({
|
|
246
256
|
score,
|
|
@@ -258,19 +268,40 @@ class ApiDocsServer {
|
|
|
258
268
|
// Ignore parse errors
|
|
259
269
|
}
|
|
260
270
|
}
|
|
261
|
-
// Sort by score descending
|
|
262
|
-
allMatches.sort((a, b) => b.score - a.score);
|
|
263
|
-
// Limit results
|
|
264
|
-
const LIMIT = 10;
|
|
265
271
|
const totalFound = allMatches.length;
|
|
266
|
-
|
|
267
|
-
if (totalFound > LIMIT) {
|
|
272
|
+
if (totalFound === 0) {
|
|
268
273
|
return {
|
|
269
|
-
results:
|
|
270
|
-
|
|
274
|
+
results: [],
|
|
275
|
+
message: `No results found for '${query}'. Try using '*' to list all endpoints, or check your version/method filters.`
|
|
271
276
|
};
|
|
272
277
|
}
|
|
273
|
-
|
|
278
|
+
// Sort by score descending (only meaningful if not wildcard)
|
|
279
|
+
if (!isWildcard) {
|
|
280
|
+
allMatches.sort((a, b) => b.score - a.score);
|
|
281
|
+
}
|
|
282
|
+
// Pagination
|
|
283
|
+
const LIMIT = 10;
|
|
284
|
+
const totalPages = Math.ceil(totalFound / LIMIT);
|
|
285
|
+
const currentPage = Math.max(1, page); // Ensure page is at least 1
|
|
286
|
+
const start = (currentPage - 1) * LIMIT;
|
|
287
|
+
const end = start + LIMIT;
|
|
288
|
+
const slicedResults = allMatches.slice(start, end).map(({ score, ...rest }) => rest);
|
|
289
|
+
let warning = undefined;
|
|
290
|
+
if (totalPages > 1) {
|
|
291
|
+
warning = `Found ${totalFound} results. Showing page ${currentPage} of ${totalPages}.`;
|
|
292
|
+
if (currentPage < totalPages) {
|
|
293
|
+
warning += ` Use 'page: ${currentPage + 1}' to see next results.`;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
results: slicedResults,
|
|
298
|
+
meta: {
|
|
299
|
+
total: totalFound,
|
|
300
|
+
page: currentPage,
|
|
301
|
+
totalPages: totalPages
|
|
302
|
+
},
|
|
303
|
+
warning
|
|
304
|
+
};
|
|
274
305
|
}
|
|
275
306
|
// Helper to get full details of an API
|
|
276
307
|
async getApiDetails(apiPath, method) {
|