swagger-mcp-server 1.0.0 → 1.0.2
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/build/swagger_mcp_server.js +28 -24
- package/build/swagger_parser.js +243 -65
- package/package.json +5 -4
|
@@ -98,6 +98,26 @@ export class SwaggerMcpServer {
|
|
|
98
98
|
};
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
|
+
formatBodyExample(body) {
|
|
102
|
+
if (!body.hasBody) {
|
|
103
|
+
return "";
|
|
104
|
+
}
|
|
105
|
+
if (body.isJson) {
|
|
106
|
+
return JSON.stringify(body.value ?? {}, null, 2);
|
|
107
|
+
}
|
|
108
|
+
return String(body.value ?? '<non-JSON response body>');
|
|
109
|
+
}
|
|
110
|
+
appendResponseExample(result, response) {
|
|
111
|
+
result += "```http\n";
|
|
112
|
+
result += `HTTP/2 ${response.statusCode}${response.statusText ? ` ${response.statusText}` : ''}\n`;
|
|
113
|
+
if (response.hasBody) {
|
|
114
|
+
result += `Content-Type: ${response.contentType || (response.isJson ? 'application/json' : 'application/octet-stream')}\n\n`;
|
|
115
|
+
result += this.formatBodyExample(response);
|
|
116
|
+
result += "\n";
|
|
117
|
+
}
|
|
118
|
+
result += "```";
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
101
121
|
formatEndpointDetails(endpoint) {
|
|
102
122
|
let result = "";
|
|
103
123
|
result += `## ${endpoint.operationId} ${endpoint.summary}\n`;
|
|
@@ -107,8 +127,7 @@ export class SwaggerMcpServer {
|
|
|
107
127
|
}
|
|
108
128
|
const pathParams = endpoint.parameters.filter(p => p.in === 'path');
|
|
109
129
|
const queryParams = endpoint.parameters.filter(p => p.in === 'query');
|
|
110
|
-
const
|
|
111
|
-
const otherParams = endpoint.parameters.filter(p => !['path', 'query', 'body'].includes(p.in));
|
|
130
|
+
const otherParams = endpoint.parameters.filter(p => !['path', 'query'].includes(p.in));
|
|
112
131
|
if (pathParams.length > 0) {
|
|
113
132
|
result += `### Path Parameters\n`;
|
|
114
133
|
for (const param of pathParams) {
|
|
@@ -123,13 +142,6 @@ export class SwaggerMcpServer {
|
|
|
123
142
|
}
|
|
124
143
|
result += `\n`;
|
|
125
144
|
}
|
|
126
|
-
if (bodyParams.length > 0) {
|
|
127
|
-
result += `### Body Parameters\n`;
|
|
128
|
-
for (const param of bodyParams) {
|
|
129
|
-
result += `- \`${param.name}\` (${param.type}${param.required ? ', required' : ''}): ${param.description}\n`;
|
|
130
|
-
}
|
|
131
|
-
result += `\n`;
|
|
132
|
-
}
|
|
133
145
|
if (otherParams.length > 0) {
|
|
134
146
|
result += `### Other Parameters\n`;
|
|
135
147
|
for (const param of otherParams) {
|
|
@@ -150,32 +162,24 @@ export class SwaggerMcpServer {
|
|
|
150
162
|
result += `### Example Request\n`;
|
|
151
163
|
result += "```http\n";
|
|
152
164
|
result += `${endpoint.method.toUpperCase()} ${exampleUrl}\n`;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
result += "Content-Type: application/json\n";
|
|
165
|
+
if (endpoint.requestBodyExample.hasBody) {
|
|
166
|
+
result += `Content-Type: ${endpoint.requestBodyExample.contentType || 'application/json'}\n`;
|
|
156
167
|
}
|
|
157
168
|
for (const param of otherParams) {
|
|
158
169
|
if (param.in === 'header') {
|
|
159
170
|
result += `${param.name}: ${param.example || 'example-value'}\n`;
|
|
160
171
|
}
|
|
161
172
|
}
|
|
162
|
-
if (
|
|
173
|
+
if (endpoint.requestBodyExample.hasBody) {
|
|
163
174
|
result += "\n";
|
|
164
|
-
result +=
|
|
175
|
+
result += this.formatBodyExample(endpoint.requestBodyExample);
|
|
165
176
|
}
|
|
166
177
|
result += "\n```\n\n";
|
|
167
178
|
result += `### Example Response\n`;
|
|
168
|
-
result
|
|
169
|
-
result += "
|
|
170
|
-
result += "Content-Type: application/json\n\n";
|
|
171
|
-
result += JSON.stringify(endpoint.successExampleResponse, null, 2);
|
|
172
|
-
result += "\n```\n\n";
|
|
179
|
+
result = this.appendResponseExample(result, endpoint.successExampleResponse);
|
|
180
|
+
result += "\n\n";
|
|
173
181
|
result += `### Error Response Example\n`;
|
|
174
|
-
result
|
|
175
|
-
result += "HTTP/2 400 Bad Request\n";
|
|
176
|
-
result += "Content-Type: application/json\n\n";
|
|
177
|
-
result += JSON.stringify(endpoint.errorExampleResponse, null, 2);
|
|
178
|
-
result += "\n```";
|
|
182
|
+
result = this.appendResponseExample(result, endpoint.errorExampleResponse);
|
|
179
183
|
return result;
|
|
180
184
|
}
|
|
181
185
|
async serve() {
|
package/build/swagger_parser.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { STATUS_CODES } from "node:http";
|
|
1
2
|
export class SwaggerParser {
|
|
2
3
|
name;
|
|
3
4
|
schema;
|
|
@@ -30,29 +31,185 @@ export class SwaggerParser {
|
|
|
30
31
|
default: return '';
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
resolveRef(ref) {
|
|
35
|
+
if (!ref.startsWith('#/')) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
const path = ref
|
|
39
|
+
.slice(2)
|
|
40
|
+
.split('/')
|
|
41
|
+
.map((part) => decodeURIComponent(part.replace(/~1/g, '/').replace(/~0/g, '~')));
|
|
42
|
+
let current = this.schema;
|
|
43
|
+
for (const part of path) {
|
|
44
|
+
if (current === undefined || current === null) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
current = current[part];
|
|
48
|
+
}
|
|
49
|
+
return current;
|
|
50
|
+
}
|
|
51
|
+
normalizeMediaType(mediaType) {
|
|
52
|
+
return mediaType.split(';', 1)[0].trim().toLowerCase();
|
|
53
|
+
}
|
|
54
|
+
isJsonMediaType(mediaType) {
|
|
55
|
+
const normalized = this.normalizeMediaType(mediaType);
|
|
56
|
+
return normalized === 'application/json'
|
|
57
|
+
|| normalized === 'application/*+json'
|
|
58
|
+
|| normalized.endsWith('+json');
|
|
59
|
+
}
|
|
60
|
+
resolveSchemaType(schema) {
|
|
61
|
+
if (Array.isArray(schema?.type)) {
|
|
62
|
+
return schema.type.find((type) => type !== 'null');
|
|
63
|
+
}
|
|
64
|
+
if (schema?.type) {
|
|
65
|
+
return schema.type;
|
|
66
|
+
}
|
|
67
|
+
if (schema?.properties || schema?.additionalProperties) {
|
|
68
|
+
return 'object';
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
schemaRepresentsBinary(schema, seenRefs = new Set()) {
|
|
73
|
+
if (!schema || typeof schema !== 'object') {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (schema.$ref) {
|
|
77
|
+
if (seenRefs.has(schema.$ref)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const resolved = this.resolveRef(schema.$ref);
|
|
81
|
+
if (!resolved) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
seenRefs.add(schema.$ref);
|
|
85
|
+
const result = this.schemaRepresentsBinary(resolved, seenRefs);
|
|
86
|
+
seenRefs.delete(schema.$ref);
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
const schemaType = this.resolveSchemaType(schema);
|
|
90
|
+
if (schemaType === 'string' && ['binary', 'byte'].includes(schema.format)) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
return ['oneOf', 'anyOf', 'allOf'].some((key) => Array.isArray(schema[key]) && schema[key].some((subSchema) => this.schemaRepresentsBinary(subSchema, seenRefs)));
|
|
94
|
+
}
|
|
95
|
+
wildcardContentLooksJson(media) {
|
|
96
|
+
if (!media) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
if (media.schema) {
|
|
100
|
+
return !this.schemaRepresentsBinary(media.schema);
|
|
101
|
+
}
|
|
102
|
+
return media.example !== undefined || this.extractFirstExample(media.examples) !== undefined;
|
|
103
|
+
}
|
|
104
|
+
selectJsonContent(content) {
|
|
105
|
+
if (!content || typeof content !== 'object') {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const entries = Object.entries(content);
|
|
109
|
+
const applicationJson = entries.find(([mediaType]) => this.normalizeMediaType(mediaType) === 'application/json');
|
|
110
|
+
if (applicationJson) {
|
|
111
|
+
return { mediaType: applicationJson[0], media: applicationJson[1] };
|
|
112
|
+
}
|
|
113
|
+
const jsonLike = entries.find(([mediaType]) => this.isJsonMediaType(mediaType));
|
|
114
|
+
if (jsonLike) {
|
|
115
|
+
return { mediaType: jsonLike[0], media: jsonLike[1] };
|
|
116
|
+
}
|
|
117
|
+
const wildcard = entries.find(([mediaType, media]) => this.normalizeMediaType(mediaType) === '*/*' && this.wildcardContentLooksJson(media));
|
|
118
|
+
if (wildcard) {
|
|
119
|
+
return { mediaType: 'application/json', media: wildcard[1] };
|
|
120
|
+
}
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
selectFirstContent(content) {
|
|
124
|
+
if (!content || typeof content !== 'object') {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
const [first] = Object.entries(content);
|
|
128
|
+
if (!first) {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
return { mediaType: first[0], media: first[1] };
|
|
132
|
+
}
|
|
133
|
+
extractFirstExample(examples) {
|
|
134
|
+
if (!examples || typeof examples !== 'object') {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
for (const example of Object.values(examples)) {
|
|
138
|
+
if (example && typeof example === 'object' && 'value' in example) {
|
|
139
|
+
return example.value;
|
|
140
|
+
}
|
|
141
|
+
if (example !== undefined && (typeof example !== 'object' || example === null)) {
|
|
142
|
+
return example;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
extractMediaValue(media) {
|
|
148
|
+
if (media?.example !== undefined) {
|
|
149
|
+
return media.example;
|
|
150
|
+
}
|
|
151
|
+
const example = this.extractFirstExample(media?.examples);
|
|
152
|
+
if (example !== undefined) {
|
|
153
|
+
return example;
|
|
154
|
+
}
|
|
155
|
+
if (media?.schema?.example !== undefined) {
|
|
156
|
+
return media.schema.example;
|
|
157
|
+
}
|
|
158
|
+
if (media?.schema) {
|
|
159
|
+
return this.generateSampleFromSchema(media.schema);
|
|
160
|
+
}
|
|
161
|
+
return {};
|
|
162
|
+
}
|
|
163
|
+
generateSampleFromSchema(schema, seenRefs = new Set()) {
|
|
34
164
|
if (!schema)
|
|
35
165
|
return {};
|
|
166
|
+
if (schema.example !== undefined) {
|
|
167
|
+
return schema.example;
|
|
168
|
+
}
|
|
36
169
|
if (schema.$ref) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
170
|
+
if (seenRefs.has(schema.$ref)) {
|
|
171
|
+
return {};
|
|
172
|
+
}
|
|
173
|
+
const resolvedSchema = this.resolveRef(schema.$ref);
|
|
174
|
+
if (resolvedSchema) {
|
|
175
|
+
seenRefs.add(schema.$ref);
|
|
176
|
+
const result = this.generateSampleFromSchema(resolvedSchema, seenRefs);
|
|
177
|
+
seenRefs.delete(schema.$ref);
|
|
178
|
+
return result;
|
|
41
179
|
}
|
|
42
180
|
return {};
|
|
43
181
|
}
|
|
44
|
-
|
|
182
|
+
if (schema.allOf && schema.allOf.length > 0) {
|
|
183
|
+
let result = {};
|
|
184
|
+
for (const subSchema of schema.allOf) {
|
|
185
|
+
result = { ...result, ...this.generateSampleFromSchema(subSchema, seenRefs) };
|
|
186
|
+
}
|
|
187
|
+
if (schema.properties) {
|
|
188
|
+
result = { ...result, ...this.generateSampleFromSchema({ type: 'object', properties: schema.properties }, seenRefs) };
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
if (schema.oneOf && schema.oneOf.length > 0) {
|
|
193
|
+
return this.generateSampleFromSchema(schema.oneOf[0], seenRefs);
|
|
194
|
+
}
|
|
195
|
+
if (schema.anyOf && schema.anyOf.length > 0) {
|
|
196
|
+
return this.generateSampleFromSchema(schema.anyOf[0], seenRefs);
|
|
197
|
+
}
|
|
198
|
+
switch (this.resolveSchemaType(schema)) {
|
|
45
199
|
case 'object':
|
|
46
200
|
const result = {};
|
|
47
201
|
if (schema.properties) {
|
|
48
202
|
for (const propName in schema.properties) {
|
|
49
|
-
result[propName] = this.generateSampleFromSchema(schema.properties[propName]);
|
|
203
|
+
result[propName] = this.generateSampleFromSchema(schema.properties[propName], seenRefs);
|
|
50
204
|
}
|
|
51
205
|
}
|
|
206
|
+
if (Object.keys(result).length === 0 && schema.additionalProperties && typeof schema.additionalProperties === 'object') {
|
|
207
|
+
result.additionalProperty = this.generateSampleFromSchema(schema.additionalProperties, seenRefs);
|
|
208
|
+
}
|
|
52
209
|
return result;
|
|
53
210
|
case 'array':
|
|
54
211
|
if (schema.items) {
|
|
55
|
-
return [this.generateSampleFromSchema(schema.items)];
|
|
212
|
+
return [this.generateSampleFromSchema(schema.items, seenRefs)];
|
|
56
213
|
}
|
|
57
214
|
return [];
|
|
58
215
|
case 'string':
|
|
@@ -76,56 +233,83 @@ export class SwaggerParser {
|
|
|
76
233
|
case 'null':
|
|
77
234
|
return null;
|
|
78
235
|
default:
|
|
79
|
-
if (schema.oneOf && schema.oneOf.length > 0) {
|
|
80
|
-
return this.generateSampleFromSchema(schema.oneOf[0]);
|
|
81
|
-
}
|
|
82
|
-
if (schema.anyOf && schema.anyOf.length > 0) {
|
|
83
|
-
return this.generateSampleFromSchema(schema.anyOf[0]);
|
|
84
|
-
}
|
|
85
|
-
if (schema.allOf && schema.allOf.length > 0) {
|
|
86
|
-
let result = {};
|
|
87
|
-
for (const subSchema of schema.allOf) {
|
|
88
|
-
result = { ...result, ...this.generateSampleFromSchema(subSchema) };
|
|
89
|
-
}
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
236
|
return {};
|
|
93
237
|
}
|
|
94
238
|
}
|
|
239
|
+
noBodyExample() {
|
|
240
|
+
return {
|
|
241
|
+
hasBody: false,
|
|
242
|
+
isJson: false
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
jsonBodyExample(contentType, media) {
|
|
246
|
+
const normalizedContentType = this.normalizeMediaType(contentType);
|
|
247
|
+
const displayContentType = normalizedContentType === 'application/*+json' ? 'application/json' : contentType;
|
|
248
|
+
return {
|
|
249
|
+
contentType: displayContentType,
|
|
250
|
+
hasBody: true,
|
|
251
|
+
isJson: true,
|
|
252
|
+
value: this.extractMediaValue(media)
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
nonJsonBodyExample(contentType, media) {
|
|
256
|
+
const normalizedContentType = this.normalizeMediaType(contentType);
|
|
257
|
+
const displayContentType = normalizedContentType === '*/*' ? 'application/octet-stream' : contentType;
|
|
258
|
+
const isBinary = normalizedContentType.startsWith('image/')
|
|
259
|
+
|| normalizedContentType === 'application/octet-stream'
|
|
260
|
+
|| this.schemaRepresentsBinary(media?.schema);
|
|
261
|
+
return {
|
|
262
|
+
contentType: displayContentType,
|
|
263
|
+
hasBody: true,
|
|
264
|
+
isJson: false,
|
|
265
|
+
value: isBinary ? '<binary response body>' : '<non-JSON response body>'
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
extractJsonBodyExampleFromContent(content) {
|
|
269
|
+
const selectedContent = this.selectJsonContent(content);
|
|
270
|
+
if (!selectedContent) {
|
|
271
|
+
return this.noBodyExample();
|
|
272
|
+
}
|
|
273
|
+
return this.jsonBodyExample(selectedContent.mediaType, selectedContent.media);
|
|
274
|
+
}
|
|
275
|
+
extractResponseBodyExample(content) {
|
|
276
|
+
const selectedJsonContent = this.selectJsonContent(content);
|
|
277
|
+
if (selectedJsonContent) {
|
|
278
|
+
return this.jsonBodyExample(selectedJsonContent.mediaType, selectedJsonContent.media);
|
|
279
|
+
}
|
|
280
|
+
const selectedContent = this.selectFirstContent(content);
|
|
281
|
+
if (selectedContent) {
|
|
282
|
+
return this.nonJsonBodyExample(selectedContent.mediaType, selectedContent.media);
|
|
283
|
+
}
|
|
284
|
+
return this.noBodyExample();
|
|
285
|
+
}
|
|
95
286
|
extractRequestBodyExample(operation) {
|
|
96
|
-
if (operation.requestBody
|
|
97
|
-
|
|
98
|
-
if (content) {
|
|
99
|
-
if (content.example) {
|
|
100
|
-
return content.example;
|
|
101
|
-
}
|
|
102
|
-
if (content.schema && content.schema.example) {
|
|
103
|
-
return content.schema.example;
|
|
104
|
-
}
|
|
105
|
-
if (content.schema) {
|
|
106
|
-
return this.generateSampleFromSchema(content.schema);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
287
|
+
if (operation.requestBody?.content) {
|
|
288
|
+
return this.extractJsonBodyExampleFromContent(operation.requestBody.content);
|
|
109
289
|
}
|
|
110
|
-
return
|
|
290
|
+
return this.noBodyExample();
|
|
291
|
+
}
|
|
292
|
+
statusText(statusCode) {
|
|
293
|
+
return STATUS_CODES[statusCode] || '';
|
|
294
|
+
}
|
|
295
|
+
responseExample(statusCode, body) {
|
|
296
|
+
return {
|
|
297
|
+
...body,
|
|
298
|
+
statusCode,
|
|
299
|
+
statusText: this.statusText(statusCode)
|
|
300
|
+
};
|
|
111
301
|
}
|
|
112
302
|
resolveSuccessExampleResponse(operation) {
|
|
113
|
-
if (operation.responses
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return content
|
|
119
|
-
}
|
|
120
|
-
if (content.schema && content.schema.example) {
|
|
121
|
-
return content.schema.example;
|
|
122
|
-
}
|
|
123
|
-
if (content.schema) {
|
|
124
|
-
return this.generateSampleFromSchema(content.schema);
|
|
303
|
+
if (operation.responses) {
|
|
304
|
+
for (const code in operation.responses) {
|
|
305
|
+
const codeNum = parseInt(code, 10);
|
|
306
|
+
if (!isNaN(codeNum) && Math.floor(codeNum / 100) === 2) {
|
|
307
|
+
const successResponse = operation.responses[code];
|
|
308
|
+
return this.responseExample(codeNum, this.extractResponseBodyExample(successResponse.content));
|
|
125
309
|
}
|
|
126
310
|
}
|
|
127
311
|
}
|
|
128
|
-
return
|
|
312
|
+
return this.responseExample(200, this.noBodyExample());
|
|
129
313
|
}
|
|
130
314
|
resolveErrorExampleResponse(operation) {
|
|
131
315
|
if (operation.responses) {
|
|
@@ -133,27 +317,21 @@ export class SwaggerParser {
|
|
|
133
317
|
const codeNum = parseInt(code, 10);
|
|
134
318
|
if (!isNaN(codeNum) && Math.floor(codeNum / 100) >= 4) {
|
|
135
319
|
const errorResponse = operation.responses[code];
|
|
136
|
-
|
|
137
|
-
const content = errorResponse.content['application/json'];
|
|
138
|
-
if (content.example) {
|
|
139
|
-
return content.example;
|
|
140
|
-
}
|
|
141
|
-
if (content.schema && content.schema.example) {
|
|
142
|
-
return content.schema.example;
|
|
143
|
-
}
|
|
144
|
-
if (content.schema) {
|
|
145
|
-
return this.generateSampleFromSchema(content.schema);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
320
|
+
return this.responseExample(codeNum, this.extractResponseBodyExample(errorResponse.content));
|
|
148
321
|
}
|
|
149
322
|
}
|
|
150
323
|
}
|
|
151
|
-
return {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
324
|
+
return this.responseExample(400, {
|
|
325
|
+
contentType: 'application/json',
|
|
326
|
+
hasBody: true,
|
|
327
|
+
isJson: true,
|
|
328
|
+
value: {
|
|
329
|
+
error: {
|
|
330
|
+
code: 400,
|
|
331
|
+
message: "Bad Request"
|
|
332
|
+
}
|
|
155
333
|
}
|
|
156
|
-
};
|
|
334
|
+
});
|
|
157
335
|
}
|
|
158
336
|
listEndpoints() {
|
|
159
337
|
const endpoints = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swagger-mcp-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc && chmod 755 build/index.js",
|
|
11
|
+
"test": "npm run build && node test/swagger_parser.test.mjs",
|
|
11
12
|
"run": "npx @modelcontextprotocol/inspector node build/index.js test_config.json",
|
|
12
13
|
"prepublishOnly": "npm run build"
|
|
13
14
|
},
|
|
@@ -24,12 +25,12 @@
|
|
|
24
25
|
"description": "Model Context Protocol server for swagger endpoints",
|
|
25
26
|
"repository": {
|
|
26
27
|
"type": "git",
|
|
27
|
-
"url": "git+https://github.com/
|
|
28
|
+
"url": "git+https://github.com/marcin-sucharski/swagger-mcp-server.git"
|
|
28
29
|
},
|
|
29
30
|
"bugs": {
|
|
30
|
-
"url": "https://github.com/
|
|
31
|
+
"url": "https://github.com/marcin-sucharski/swagger-mcp-server/issues"
|
|
31
32
|
},
|
|
32
|
-
"homepage": "https://github.com/
|
|
33
|
+
"homepage": "https://github.com/marcin-sucharski/swagger-mcp-server#readme",
|
|
33
34
|
"dependencies": {
|
|
34
35
|
"@modelcontextprotocol/sdk": "^1.7.0",
|
|
35
36
|
"zod": "^3.24.2"
|