fmea-api-mcp-server 1.0.5 → 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 CHANGED
@@ -99,5 +99,9 @@ When the package is published to NPM:
99
99
  ## Features
100
100
  - **Resources**: Can read JSON files in the `endpoints` folder.
101
101
  - **Tools**:
102
- - `search_apis`: Search APIs by keyword (returns summaries).
102
+ - **Tools**:
103
+ - `search_apis`:
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.
103
107
  - `get_api_details`: Get full details (schema, parameters) for a specific endpoint.
package/dist/index.js CHANGED
@@ -104,7 +104,19 @@ class ApiDocsServer {
104
104
  properties: {
105
105
  query: {
106
106
  type: "string",
107
- description: "Search query (e.g. 'user login', 'POST /api/v1')",
107
+ description: "Search query (e.g. 'user login', 'create project').",
108
+ },
109
+ method: {
110
+ type: "string",
111
+ description: "Filter by HTTP method (e.g. 'GET', 'POST'). Optional.",
112
+ },
113
+ version: {
114
+ type: "string",
115
+ description: "Filter by API version (e.g. 'v1', 'v2'). Optional.",
116
+ },
117
+ page: {
118
+ type: "integer",
119
+ description: "Page number for pagination (default: 1).",
108
120
  },
109
121
  },
110
122
  required: ["query"],
@@ -134,7 +146,10 @@ class ApiDocsServer {
134
146
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
135
147
  if (request.params.name === "search_apis") {
136
148
  const query = String(request.params.arguments?.query).toLowerCase();
137
- const results = await this.searchInFiles(query);
149
+ const method = request.params.arguments?.method ? String(request.params.arguments?.method).toUpperCase() : undefined;
150
+ const version = request.params.arguments?.version ? String(request.params.arguments?.version).toLowerCase() : undefined;
151
+ const page = request.params.arguments?.page ? Number(request.params.arguments?.page) : 1;
152
+ const results = await this.searchInFiles(query, method, version, page);
138
153
  return {
139
154
  content: [
140
155
  {
@@ -195,20 +210,50 @@ class ApiDocsServer {
195
210
  }
196
211
  return results;
197
212
  }
198
- // Simple search helper - returns summaries
199
- async searchInFiles(query) {
213
+ // Smart search helper with scoring, filtering, limits, and pagination
214
+ async searchInFiles(query, filterMethod, filterVersion, page = 1) {
200
215
  const files = await this.getAllFiles(ENDPOINTS_DIR);
201
- const matches = [];
216
+ let allMatches = [];
217
+ const isWildcard = query === "*" || query === "";
202
218
  for (const filePath of files) {
203
219
  try {
204
220
  const content = await fs.readFile(filePath, "utf-8");
205
221
  const json = JSON.parse(content);
206
222
  const fileName = path.relative(ENDPOINTS_DIR, filePath);
223
+ // Version Filtering
224
+ if (filterVersion) {
225
+ const fileVersion = fileName.split(path.sep)[0];
226
+ if (fileVersion !== filterVersion && json.version !== filterVersion) {
227
+ continue;
228
+ }
229
+ }
207
230
  if (json.endpoints && Array.isArray(json.endpoints)) {
208
231
  for (const endpoint of json.endpoints) {
209
- const str = JSON.stringify(endpoint).toLowerCase();
210
- if (str.includes(query)) {
211
- matches.push({
232
+ // Method Filtering
233
+ if (filterMethod && endpoint.method.toUpperCase() !== filterMethod) {
234
+ continue;
235
+ }
236
+ // Scoring Logic
237
+ let score = 0;
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
+ }
254
+ if (score > 0) {
255
+ allMatches.push({
256
+ score,
212
257
  file: fileName,
213
258
  method: endpoint.method,
214
259
  path: endpoint.path,
@@ -223,7 +268,40 @@ class ApiDocsServer {
223
268
  // Ignore parse errors
224
269
  }
225
270
  }
226
- return matches;
271
+ const totalFound = allMatches.length;
272
+ if (totalFound === 0) {
273
+ return {
274
+ results: [],
275
+ message: `No results found for '${query}'. Try using '*' to list all endpoints, or check your version/method filters.`
276
+ };
277
+ }
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
+ };
227
305
  }
228
306
  // Helper to get full details of an API
229
307
  async getApiDetails(apiPath, method) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fmea-api-mcp-server",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "MCP server for serving API documentation from endpoints directory",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",