fmea-api-mcp-server 1.0.4 → 1.0.6

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.
Files changed (34) hide show
  1. package/README.md +7 -1
  2. package/dist/index.js +131 -13
  3. package/endpoints/README.md +40 -0
  4. package/endpoints/v1/projects/core.json +156 -0
  5. package/endpoints/v1/projects/data.json +64 -0
  6. package/endpoints/v1/projects/lifecycle.json +85 -0
  7. package/endpoints/v1/projects/recommendations.json +58 -0
  8. package/endpoints/v2/worksheets/excel.json +161 -0
  9. package/endpoints/v2/{worksheets.json → worksheets/management.json} +2 -183
  10. package/endpoints/v2/worksheets/templates.json +34 -0
  11. package/package.json +1 -1
  12. package/endpoints/v1/projects.json +0 -342
  13. /package/endpoints/v1/{authentication.json → authentication/core.json} +0 -0
  14. /package/endpoints/v1/{block-diagrams.json → block-diagrams/core.json} +0 -0
  15. /package/endpoints/v1/{divisions.json → divisions/core.json} +0 -0
  16. /package/endpoints/v1/{failure-modes.json → failure-modes/core.json} +0 -0
  17. /package/endpoints/v1/{files.json → files/core.json} +0 -0
  18. /package/endpoints/v1/{fta.json → fta/core.json} +0 -0
  19. /package/endpoints/v1/{knowledge-base.json → knowledge-base/core.json} +0 -0
  20. /package/endpoints/v1/{synonyms.json → synonyms/core.json} +0 -0
  21. /package/endpoints/v1/{terms.json → terms/core.json} +0 -0
  22. /package/endpoints/v1/{users.json → users/core.json} +0 -0
  23. /package/endpoints/v1/{worksheets.json → worksheets/core.json} +0 -0
  24. /package/endpoints/v2/{api-keys.json → api-keys/core.json} +0 -0
  25. /package/endpoints/v2/{block-diagrams.json → block-diagrams/core.json} +0 -0
  26. /package/endpoints/v2/{divisions.json → divisions/core.json} +0 -0
  27. /package/endpoints/v2/{documents.json → documents/core.json} +0 -0
  28. /package/endpoints/v2/{failure-modes.json → failure-modes/core.json} +0 -0
  29. /package/endpoints/v2/{files.json → files/core.json} +0 -0
  30. /package/endpoints/v2/{fourm.json → fourm/core.json} +0 -0
  31. /package/endpoints/v2/{projects.json → projects/core.json} +0 -0
  32. /package/endpoints/v2/{system.json → system/core.json} +0 -0
  33. /package/endpoints/v2/{templates.json → templates/core.json} +0 -0
  34. /package/endpoints/v2/{users.json → users/core.json} +0 -0
package/README.md CHANGED
@@ -98,4 +98,10 @@ When the package is published to NPM:
98
98
 
99
99
  ## Features
100
100
  - **Resources**: Can read JSON files in the `endpoints` folder.
101
- - **Tools**: Use the `search_apis` tool to search APIs by keyword.
101
+ - **Tools**:
102
+ - **Tools**:
103
+ - `search_apis`:
104
+ - Smart search with relevance scoring (Summary > Description > Path).
105
+ - Supports filters: `query`, `method` (GET/POST), `version` (v1/v2).
106
+ - Results limited to top 10 by default to prevent context pollution.
107
+ - `get_api_details`: Get full details (schema, parameters) for a specific endpoint.
package/dist/index.js CHANGED
@@ -98,25 +98,53 @@ class ApiDocsServer {
98
98
  tools: [
99
99
  {
100
100
  name: "search_apis",
101
- description: "Search for API endpoints by keyword across all documentation files",
101
+ description: "Search for API endpoints by keyword across all documentation files. Returns summarized results.",
102
102
  inputSchema: {
103
103
  type: "object",
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.",
108
116
  },
109
117
  },
110
118
  required: ["query"],
111
119
  },
112
120
  },
121
+ {
122
+ name: "get_api_details",
123
+ description: "Get full details including schema and parameters for a specific API endpoint.",
124
+ inputSchema: {
125
+ type: "object",
126
+ properties: {
127
+ path: {
128
+ type: "string",
129
+ description: "API Path (e.g. '/api/v1/projects')",
130
+ },
131
+ method: {
132
+ type: "string",
133
+ description: "HTTP Method (e.g. 'POST', 'GET')",
134
+ },
135
+ },
136
+ required: ["path"],
137
+ },
138
+ },
113
139
  ],
114
140
  };
115
141
  });
116
142
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
117
143
  if (request.params.name === "search_apis") {
118
144
  const query = String(request.params.arguments?.query).toLowerCase();
119
- const results = await this.searchInFiles(query);
145
+ const method = request.params.arguments?.method ? String(request.params.arguments?.method).toUpperCase() : undefined;
146
+ const version = request.params.arguments?.version ? String(request.params.arguments?.version).toLowerCase() : undefined;
147
+ const results = await this.searchInFiles(query, method, version);
120
148
  return {
121
149
  content: [
122
150
  {
@@ -126,6 +154,30 @@ class ApiDocsServer {
126
154
  ],
127
155
  };
128
156
  }
157
+ if (request.params.name === "get_api_details") {
158
+ const apiPath = String(request.params.arguments?.path);
159
+ const method = request.params.arguments?.method ? String(request.params.arguments?.method).toUpperCase() : undefined;
160
+ const result = await this.getApiDetails(apiPath, method);
161
+ if (!result) {
162
+ return {
163
+ isError: true,
164
+ content: [
165
+ {
166
+ type: "text",
167
+ text: `API endpoint not found: ${method ? method + " " : ""}${apiPath}`,
168
+ },
169
+ ],
170
+ };
171
+ }
172
+ return {
173
+ content: [
174
+ {
175
+ type: "text",
176
+ text: JSON.stringify(result, null, 2),
177
+ },
178
+ ],
179
+ };
180
+ }
129
181
  throw new McpError(ErrorCode.MethodNotFound, "Tool not found");
130
182
  });
131
183
  }
@@ -153,23 +205,50 @@ class ApiDocsServer {
153
205
  }
154
206
  return results;
155
207
  }
156
- // Simple search helper
157
- async searchInFiles(query) {
208
+ // Smart search helper with scoring, filtering, and limits
209
+ async searchInFiles(query, filterMethod, filterVersion) {
158
210
  const files = await this.getAllFiles(ENDPOINTS_DIR);
159
- const matches = [];
211
+ let allMatches = [];
160
212
  for (const filePath of files) {
161
213
  try {
162
214
  const content = await fs.readFile(filePath, "utf-8");
163
215
  const json = JSON.parse(content);
164
216
  const fileName = path.relative(ENDPOINTS_DIR, filePath);
165
- // Assuming structure has "endpoints" array
217
+ // Version Filtering (File level or content level check)
218
+ // Check if file path contains version (e.g. "v1/...") or json has version field
219
+ if (filterVersion) {
220
+ const fileVersion = fileName.split(path.sep)[0]; // e.g. "v1" from "v1/projects/..."
221
+ if (fileVersion !== filterVersion && json.version !== filterVersion) {
222
+ continue;
223
+ }
224
+ }
166
225
  if (json.endpoints && Array.isArray(json.endpoints)) {
167
226
  for (const endpoint of json.endpoints) {
168
- const str = JSON.stringify(endpoint).toLowerCase();
169
- if (str.includes(query)) {
170
- matches.push({
171
- source: fileName,
172
- ...endpoint
227
+ // Method Filtering
228
+ if (filterMethod && endpoint.method.toUpperCase() !== filterMethod) {
229
+ continue;
230
+ }
231
+ // Scoring Logic
232
+ let score = 0;
233
+ const summary = (endpoint.summary || "").toLowerCase();
234
+ const description = (endpoint.description || "").toLowerCase();
235
+ const apiPath = (endpoint.path || "").toLowerCase();
236
+ const operationId = (endpoint.operationId || "").toLowerCase();
237
+ // 1. Exact/High relevance matches
238
+ if (summary.includes(query) || operationId.includes(query))
239
+ score += 10;
240
+ if (description.includes(query))
241
+ score += 5;
242
+ if (apiPath.includes(query))
243
+ score += 3;
244
+ if (score > 0) {
245
+ allMatches.push({
246
+ score,
247
+ file: fileName,
248
+ method: endpoint.method,
249
+ path: endpoint.path,
250
+ summary: endpoint.summary,
251
+ description: endpoint.description
173
252
  });
174
253
  }
175
254
  }
@@ -179,7 +258,46 @@ class ApiDocsServer {
179
258
  // Ignore parse errors
180
259
  }
181
260
  }
182
- return matches;
261
+ // Sort by score descending
262
+ allMatches.sort((a, b) => b.score - a.score);
263
+ // Limit results
264
+ const LIMIT = 10;
265
+ const totalFound = allMatches.length;
266
+ const limitedResults = allMatches.slice(0, LIMIT).map(({ score, ...rest }) => rest); // Remove score from output
267
+ if (totalFound > LIMIT) {
268
+ return {
269
+ results: limitedResults,
270
+ warning: `Found ${totalFound} results. Showing top ${LIMIT}. Please refine your search query or use filters.`
271
+ };
272
+ }
273
+ return limitedResults;
274
+ }
275
+ // Helper to get full details of an API
276
+ async getApiDetails(apiPath, method) {
277
+ const files = await this.getAllFiles(ENDPOINTS_DIR);
278
+ for (const filePath of files) {
279
+ try {
280
+ const content = await fs.readFile(filePath, "utf-8");
281
+ const json = JSON.parse(content);
282
+ if (json.endpoints && Array.isArray(json.endpoints)) {
283
+ for (const endpoint of json.endpoints) {
284
+ if (endpoint.path === apiPath) {
285
+ if (method && endpoint.method.toUpperCase() !== method) {
286
+ continue;
287
+ }
288
+ return {
289
+ sourceFile: path.relative(ENDPOINTS_DIR, filePath),
290
+ ...endpoint
291
+ };
292
+ }
293
+ }
294
+ }
295
+ }
296
+ catch (e) {
297
+ // Ignore parse errors
298
+ }
299
+ }
300
+ return null;
183
301
  }
184
302
  async run() {
185
303
  const transport = new StdioServerTransport();
@@ -0,0 +1,40 @@
1
+ # API Documentation Structure
2
+
3
+ This directory contains the API definitions for the FMEA system, organized by version and resource.
4
+
5
+ ## Directory Pattern
6
+
7
+ All endpoints MUST follow this strictly nested directory structure:
8
+
9
+ ```
10
+ endpoints/
11
+ ├── v1/
12
+ │ └── {resource}/
13
+ │ ├── core.json # Basic CRUD operations
14
+ │ ├── {feature}.json # Feature-specific endpoints (e.g., export.json)
15
+ │ └── ...
16
+ └── v2/
17
+ └── {resource}/
18
+ └── ...
19
+ ```
20
+
21
+ ### Rules
22
+
23
+ 1. **Directory Required**: Every resource (e.g., `projects`, `users`) MUST be a directory, even if it only contains one file.
24
+ 2. **Core File**: The main file for a resource should be named `core.json`. This typically contains the basic CRUD operations.
25
+ 3. **Feature Files**: Distinct sub-features should be separated into their own JSON files with descriptive names (e.g., `excel.json`, `lifecycle.json`).
26
+ 4. **JSON Structure**: Each file must contain a valid JSON object with:
27
+ - `category`: String (Resource category name)
28
+ - `version`: String ("v1" or "v2")
29
+ - `description`: String (Resource description)
30
+ - `endpoints`: Array of endpoint objects.
31
+
32
+ ### Example
33
+
34
+ ```
35
+ endpoints/v1/projects/
36
+ ├── core.json
37
+ ├── lifecycle.json
38
+ ├── data.json
39
+ └── recommendations.json
40
+ ```
@@ -0,0 +1,156 @@
1
+ {
2
+ "category": "Project Management",
3
+ "version": "v1",
4
+ "description": "Core Project Operations",
5
+ "endpoints": [
6
+ {
7
+ "path": "/api/v1/projects",
8
+ "method": "POST",
9
+ "operationId": "save_5",
10
+ "summary": "Create project",
11
+ "description": "Create a new project",
12
+ "tags": [],
13
+ "parameters": [],
14
+ "requestBody": {
15
+ "content": {
16
+ "application/json": {
17
+ "schema": {
18
+ "$ref": "#/components/schemas/ProjectCreationDTO"
19
+ }
20
+ }
21
+ }
22
+ },
23
+ "responses": {
24
+ "default": {
25
+ "description": "default response",
26
+ "content": {
27
+ "application/json": {}
28
+ }
29
+ }
30
+ }
31
+ },
32
+ {
33
+ "path": "/api/v1/projects/my",
34
+ "method": "GET",
35
+ "operationId": "findAllByUserId",
36
+ "summary": "Get user projects",
37
+ "description": "Get all projects for the current user",
38
+ "tags": [],
39
+ "parameters": [
40
+ {
41
+ "name": "size",
42
+ "in": "query",
43
+ "schema": {
44
+ "type": "integer",
45
+ "format": "int32",
46
+ "default": 20
47
+ }
48
+ },
49
+ {
50
+ "name": "page",
51
+ "in": "query",
52
+ "schema": {
53
+ "type": "integer",
54
+ "format": "int32",
55
+ "default": 1
56
+ }
57
+ }
58
+ ],
59
+ "responses": {
60
+ "default": {
61
+ "description": "default response",
62
+ "content": {
63
+ "application/json": {}
64
+ }
65
+ }
66
+ }
67
+ },
68
+ {
69
+ "path": "/api/v1/projects/{id}",
70
+ "method": "GET",
71
+ "operationId": "findById_4",
72
+ "summary": "Get project by ID",
73
+ "description": "Get a project by its ID",
74
+ "tags": [],
75
+ "parameters": [
76
+ {
77
+ "name": "id",
78
+ "in": "path",
79
+ "required": true,
80
+ "schema": {
81
+ "type": "string"
82
+ }
83
+ }
84
+ ],
85
+ "responses": {
86
+ "default": {
87
+ "description": "default response",
88
+ "content": {
89
+ "application/json": {}
90
+ }
91
+ }
92
+ }
93
+ },
94
+ {
95
+ "path": "/api/v1/projects/{id}",
96
+ "method": "PUT",
97
+ "operationId": "update",
98
+ "summary": "Update project",
99
+ "description": "Update an existing project",
100
+ "tags": [],
101
+ "parameters": [
102
+ {
103
+ "name": "id",
104
+ "in": "path",
105
+ "required": true,
106
+ "schema": {
107
+ "type": "string"
108
+ }
109
+ }
110
+ ],
111
+ "requestBody": {
112
+ "content": {
113
+ "application/json": {
114
+ "schema": {
115
+ "$ref": "#/components/schemas/ProjectUpdateDTO"
116
+ }
117
+ }
118
+ }
119
+ },
120
+ "responses": {
121
+ "default": {
122
+ "description": "default response",
123
+ "content": {
124
+ "application/json": {}
125
+ }
126
+ }
127
+ }
128
+ },
129
+ {
130
+ "path": "/api/v1/projects/{id}",
131
+ "method": "DELETE",
132
+ "operationId": "delete",
133
+ "summary": "Delete project",
134
+ "description": "Delete a project by its ID",
135
+ "tags": [],
136
+ "parameters": [
137
+ {
138
+ "name": "id",
139
+ "in": "path",
140
+ "required": true,
141
+ "schema": {
142
+ "type": "string"
143
+ }
144
+ }
145
+ ],
146
+ "responses": {
147
+ "default": {
148
+ "description": "default response",
149
+ "content": {
150
+ "application/json": {}
151
+ }
152
+ }
153
+ }
154
+ }
155
+ ]
156
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "category": "Project Management",
3
+ "version": "v1",
4
+ "description": "Project Data Operations",
5
+ "endpoints": [
6
+ {
7
+ "path": "/api/v1/projects/{id}/export",
8
+ "method": "GET",
9
+ "operationId": "exportData",
10
+ "summary": "Export project data",
11
+ "description": "Export project data",
12
+ "tags": [],
13
+ "parameters": [
14
+ {
15
+ "name": "id",
16
+ "in": "path",
17
+ "required": true,
18
+ "schema": {
19
+ "type": "string"
20
+ }
21
+ }
22
+ ],
23
+ "responses": {
24
+ "default": {
25
+ "description": "default response",
26
+ "content": {
27
+ "application/json": {}
28
+ }
29
+ }
30
+ }
31
+ },
32
+ {
33
+ "path": "/api/v1/projects/import",
34
+ "method": "POST",
35
+ "operationId": "importData",
36
+ "summary": "Import project data",
37
+ "description": "Import project data from a file",
38
+ "tags": [],
39
+ "parameters": [],
40
+ "requestBody": {
41
+ "content": {
42
+ "multipart/form-data": {
43
+ "schema": {
44
+ "type": "object",
45
+ "properties": {
46
+ "file": {
47
+ "$ref": "#/components/schemas/FormDataContentDisposition"
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ },
54
+ "responses": {
55
+ "default": {
56
+ "description": "default response",
57
+ "content": {
58
+ "application/json": {}
59
+ }
60
+ }
61
+ }
62
+ }
63
+ ]
64
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "category": "Project Management",
3
+ "version": "v1",
4
+ "description": "Project Lifecycle Actions",
5
+ "endpoints": [
6
+ {
7
+ "path": "/api/v1/projects/{id}/activate",
8
+ "method": "PUT",
9
+ "operationId": "activateProject",
10
+ "summary": "Activate project",
11
+ "description": "Activate a project",
12
+ "tags": [],
13
+ "parameters": [
14
+ {
15
+ "name": "id",
16
+ "in": "path",
17
+ "required": true,
18
+ "schema": {
19
+ "type": "string"
20
+ }
21
+ }
22
+ ],
23
+ "responses": {
24
+ "default": {
25
+ "description": "default response",
26
+ "content": {
27
+ "application/json": {}
28
+ }
29
+ }
30
+ }
31
+ },
32
+ {
33
+ "path": "/api/v1/projects/{id}/deactivate",
34
+ "method": "PUT",
35
+ "operationId": "deactivateProject",
36
+ "summary": "Deactivate project",
37
+ "description": "Deactivate a project",
38
+ "tags": [],
39
+ "parameters": [
40
+ {
41
+ "name": "id",
42
+ "in": "path",
43
+ "required": true,
44
+ "schema": {
45
+ "type": "string"
46
+ }
47
+ }
48
+ ],
49
+ "responses": {
50
+ "default": {
51
+ "description": "default response",
52
+ "content": {
53
+ "application/json": {}
54
+ }
55
+ }
56
+ }
57
+ },
58
+ {
59
+ "path": "/api/v1/projects/{id}/copy",
60
+ "method": "POST",
61
+ "operationId": "copy",
62
+ "summary": "Copy project",
63
+ "description": "Copy a project",
64
+ "tags": [],
65
+ "parameters": [
66
+ {
67
+ "name": "id",
68
+ "in": "path",
69
+ "required": true,
70
+ "schema": {
71
+ "type": "string"
72
+ }
73
+ }
74
+ ],
75
+ "responses": {
76
+ "default": {
77
+ "description": "default response",
78
+ "content": {
79
+ "application/json": {}
80
+ }
81
+ }
82
+ }
83
+ }
84
+ ]
85
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "category": "Project Management",
3
+ "version": "v1",
4
+ "description": "Project Recommendations",
5
+ "endpoints": [
6
+ {
7
+ "path": "/api/v1/projects/recommendations",
8
+ "method": "GET",
9
+ "operationId": "getProjects",
10
+ "summary": "Get project recommendations",
11
+ "description": "Get recommended projects",
12
+ "tags": [],
13
+ "parameters": [],
14
+ "responses": {
15
+ "default": {
16
+ "description": "default response",
17
+ "content": {
18
+ "application/json": {}
19
+ }
20
+ }
21
+ }
22
+ },
23
+ {
24
+ "path": "/api/v1/projects/{id}/recommendations",
25
+ "method": "GET",
26
+ "operationId": "getRecommendationsByProjectId",
27
+ "summary": "Get project recommendations by ID",
28
+ "description": "Get recommendations for a specific project",
29
+ "tags": [],
30
+ "parameters": [
31
+ {
32
+ "name": "id",
33
+ "in": "path",
34
+ "required": true,
35
+ "schema": {
36
+ "type": "string"
37
+ }
38
+ },
39
+ {
40
+ "name": "status",
41
+ "in": "query",
42
+ "schema": {
43
+ "pattern": "NotCompleted|In-Progress|Delay|Completed|All",
44
+ "type": "string"
45
+ }
46
+ }
47
+ ],
48
+ "responses": {
49
+ "default": {
50
+ "description": "default response",
51
+ "content": {
52
+ "application/json": {}
53
+ }
54
+ }
55
+ }
56
+ }
57
+ ]
58
+ }