@postman/postman-mcp-server 2.4.2 ā 2.5.1
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 +31 -15
- package/dist/package.json +11 -20
- package/dist/src/clients/postman.js +2 -4
- package/dist/src/constants.js +5 -0
- package/dist/src/enabledResources.js +24 -2
- package/dist/src/index.js +11 -6
- package/dist/src/tools/createCollection.js +35 -35
- package/dist/src/tools/createCollectionComment.js +1 -5
- package/dist/src/tools/createCollectionFolder.js +1 -5
- package/dist/src/tools/createCollectionFork.js +1 -5
- package/dist/src/tools/createCollectionRequest.js +1 -5
- package/dist/src/tools/createCollectionResponse.js +1 -5
- package/dist/src/tools/createEnvironment.js +1 -5
- package/dist/src/tools/createFolderComment.js +1 -5
- package/dist/src/tools/createMock.js +1 -5
- package/dist/src/tools/createMonitor.js +1 -5
- package/dist/src/tools/createRequestComment.js +1 -5
- package/dist/src/tools/createResponseComment.js +1 -5
- package/dist/src/tools/createSpec.js +1 -5
- package/dist/src/tools/createSpecFile.js +1 -5
- package/dist/src/tools/createWorkspace.js +1 -5
- package/dist/src/tools/deleteApiCollectionComment.js +1 -5
- package/dist/src/tools/deleteCollection.js +1 -5
- package/dist/src/tools/deleteCollectionComment.js +1 -5
- package/dist/src/tools/deleteCollectionFolder.js +1 -5
- package/dist/src/tools/deleteCollectionRequest.js +1 -5
- package/dist/src/tools/deleteCollectionResponse.js +1 -5
- package/dist/src/tools/deleteEnvironment.js +1 -5
- package/dist/src/tools/deleteFolderComment.js +1 -5
- package/dist/src/tools/deleteMock.js +1 -5
- package/dist/src/tools/deleteMonitor.js +1 -5
- package/dist/src/tools/deletePanElementOrFolder.js +1 -5
- package/dist/src/tools/deleteRequestComment.js +1 -5
- package/dist/src/tools/deleteResponseComment.js +1 -5
- package/dist/src/tools/deleteSpec.js +1 -5
- package/dist/src/tools/deleteSpecFile.js +1 -5
- package/dist/src/tools/deleteWorkspace.js +1 -5
- package/dist/src/tools/duplicateCollection.js +1 -5
- package/dist/src/tools/generateCollection.js +1 -5
- package/dist/src/tools/generateSpecFromCollection.js +1 -5
- package/dist/src/tools/getAllElementsAndFolders.js +1 -5
- package/dist/src/tools/getAllPanAddElementRequests.js +1 -5
- package/dist/src/tools/getAllSpecs.js +1 -5
- package/dist/src/tools/getAsyncSpecTaskStatus.js +1 -5
- package/dist/src/tools/getAuthenticatedUser.js +1 -5
- package/dist/src/tools/getCodeGenerationInstructions.js +439 -0
- package/dist/src/tools/getCollection.js +1 -5
- package/dist/src/tools/getCollectionComments.js +1 -5
- package/dist/src/tools/getCollectionFolder.js +1 -5
- package/dist/src/tools/getCollectionForks.js +1 -5
- package/dist/src/tools/getCollectionMap.js +101 -0
- package/dist/src/tools/getCollectionRequest.js +1 -5
- package/dist/src/tools/getCollectionResponse.js +1 -5
- package/dist/src/tools/getCollectionTags.js +1 -5
- package/dist/src/tools/getCollectionUpdatesTasks.js +1 -5
- package/dist/src/tools/getCollections.js +1 -5
- package/dist/src/tools/getCollectionsForkedByUser.js +1 -5
- package/dist/src/tools/getDuplicateCollectionTaskStatus.js +1 -5
- package/dist/src/tools/getEnabledTools.js +51 -0
- package/dist/src/tools/getEnvironment.js +1 -5
- package/dist/src/tools/getEnvironments.js +1 -5
- package/dist/src/tools/getFolderComments.js +1 -5
- package/dist/src/tools/getGeneratedCollectionSpecs.js +1 -5
- package/dist/src/tools/getMock.js +1 -5
- package/dist/src/tools/getMocks.js +1 -5
- package/dist/src/tools/getMonitor.js +1 -5
- package/dist/src/tools/getMonitors.js +1 -5
- package/dist/src/tools/getRequestComments.js +1 -5
- package/dist/src/tools/getResponseComments.js +1 -5
- package/dist/src/tools/getSourceCollectionStatus.js +1 -5
- package/dist/src/tools/getSpec.js +1 -5
- package/dist/src/tools/getSpecCollections.js +1 -5
- package/dist/src/tools/getSpecDefinition.js +1 -5
- package/dist/src/tools/getSpecFile.js +1 -5
- package/dist/src/tools/getSpecFiles.js +1 -5
- package/dist/src/tools/getStatusOfAnAsyncApiTask.js +1 -5
- package/dist/src/tools/getTaggedEntities.js +1 -5
- package/dist/src/tools/getWorkspace.js +1 -5
- package/dist/src/tools/getWorkspaceGlobalVariables.js +1 -5
- package/dist/src/tools/getWorkspaceTags.js +1 -5
- package/dist/src/tools/getWorkspaces.js +1 -5
- package/dist/src/tools/mergeCollectionFork.js +1 -5
- package/dist/src/tools/patchCollection.js +13 -17
- package/dist/src/tools/patchEnvironment.js +1 -5
- package/dist/src/tools/postPanElementOrFolder.js +1 -5
- package/dist/src/tools/publishDocumentation.js +1 -5
- package/dist/src/tools/publishMock.js +1 -5
- package/dist/src/tools/pullCollectionChanges.js +1 -5
- package/dist/src/tools/putCollection.js +36 -36
- package/dist/src/tools/putEnvironment.js +1 -5
- package/dist/src/tools/resolveCommentThread.js +1 -5
- package/dist/src/tools/runCollection.js +4 -82
- package/dist/src/tools/runMonitor.js +1 -5
- package/dist/src/tools/runner/executor.js +165 -0
- package/dist/src/tools/runner/fetchers.js +33 -0
- package/dist/src/tools/runner/index.js +20 -0
- package/dist/src/tools/runner/models.js +1 -0
- package/dist/src/tools/runner/parsers.js +8 -0
- package/dist/src/tools/runner/telemetry.js +178 -0
- package/dist/src/tools/searchPostmanElements.js +69 -0
- package/dist/src/tools/syncCollectionWithSpec.js +1 -5
- package/dist/src/tools/syncSpecWithCollection.js +1 -5
- package/dist/src/tools/transferCollectionFolders.js +1 -5
- package/dist/src/tools/transferCollectionRequests.js +1 -5
- package/dist/src/tools/transferCollectionResponses.js +1 -5
- package/dist/src/tools/unpublishDocumentation.js +1 -5
- package/dist/src/tools/unpublishMock.js +1 -5
- package/dist/src/tools/updateApiCollectionComment.js +1 -5
- package/dist/src/tools/updateCollectionComment.js +1 -5
- package/dist/src/tools/updateCollectionFolder.js +1 -5
- package/dist/src/tools/updateCollectionRequest.js +1 -5
- package/dist/src/tools/updateCollectionResponse.js +1 -5
- package/dist/src/tools/updateCollectionTags.js +1 -5
- package/dist/src/tools/updateFolderComment.js +1 -5
- package/dist/src/tools/updateMock.js +1 -5
- package/dist/src/tools/updateMonitor.js +1 -5
- package/dist/src/tools/updatePanElementOrFolder.js +1 -5
- package/dist/src/tools/updateRequestComment.js +1 -5
- package/dist/src/tools/updateResponseComment.js +1 -5
- package/dist/src/tools/updateSpecFile.js +1 -5
- package/dist/src/tools/updateSpecProperties.js +1 -5
- package/dist/src/tools/updateWorkspace.js +1 -5
- package/dist/src/tools/updateWorkspaceGlobalVariables.js +1 -5
- package/dist/src/tools/updateWorkspaceTags.js +1 -5
- package/dist/src/tools/utils/toolHelpers.js +6 -0
- package/package.json +11 -20
- package/dist/src/tools/utils/runner.js +0 -84
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ContentType } from '../clients/postman.js';
|
|
3
|
-
import {
|
|
4
|
-
function asMcpError(error) {
|
|
5
|
-
const cause = error?.cause ?? String(error);
|
|
6
|
-
return new McpError(ErrorCode.InternalError, cause);
|
|
7
|
-
}
|
|
3
|
+
import { asMcpError, McpError } from './utils/toolHelpers.js';
|
|
8
4
|
export const method = 'putCollection';
|
|
9
5
|
export const description = "Replaces the contents of a collection using the [Postman Collection v2.1.0 schema format](https://schema.postman.com/collection/json/v2.1.0/draft-07/docs/index.html). Include the collection's ID values in the request body. If you do not, the endpoint removes the existing items and creates new items.\n\nTo perform an update asynchronously, use the \\`Prefer\\` header with the \\`respond-async\\` value. When performing an async update, this endpoint returns a HTTP \\`202 Accepted\\` response.\n\n**Note:**\n\n- The maximum collection size this endpoint accepts cannot exceed 100 MB.\n- If you don't include the collection items' ID values from the request body, the endpoint **removes** the existing items and recreates the items with new ID values.\n- To copy another collection's contents to the given collection, remove all ID values before you pass it in this endpoint. If you do not, this endpoint returns an error. These values include the \\`id\\`, \\`uid\\`, and \\`postman_id\\` values.\n- For protocol profile behavior, refer to Postman's [Protocol Profile Behavior documentation](https://github.com/postmanlabs/postman-runtime/blob/develop/docs/protocol-profile-behavior.md).\n";
|
|
10
6
|
export const parameters = z.object({
|
|
@@ -164,7 +160,7 @@ export const parameters = z.object({
|
|
|
164
160
|
.object({
|
|
165
161
|
key: z.string().describe("The auth method's key value."),
|
|
166
162
|
value: z
|
|
167
|
-
.union([z.string(), z.array(z.record(z.
|
|
163
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
168
164
|
.describe("The key's value.")
|
|
169
165
|
.optional(),
|
|
170
166
|
type: z
|
|
@@ -180,7 +176,7 @@ export const parameters = z.object({
|
|
|
180
176
|
.object({
|
|
181
177
|
key: z.string().describe("The auth method's key value."),
|
|
182
178
|
value: z
|
|
183
|
-
.union([z.string(), z.array(z.record(z.
|
|
179
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
184
180
|
.describe("The key's value.")
|
|
185
181
|
.optional(),
|
|
186
182
|
type: z
|
|
@@ -196,7 +192,7 @@ export const parameters = z.object({
|
|
|
196
192
|
.object({
|
|
197
193
|
key: z.string().describe("The auth method's key value."),
|
|
198
194
|
value: z
|
|
199
|
-
.union([z.string(), z.array(z.record(z.
|
|
195
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
200
196
|
.describe("The key's value.")
|
|
201
197
|
.optional(),
|
|
202
198
|
type: z
|
|
@@ -212,7 +208,7 @@ export const parameters = z.object({
|
|
|
212
208
|
.object({
|
|
213
209
|
key: z.string().describe("The auth method's key value."),
|
|
214
210
|
value: z
|
|
215
|
-
.union([z.string(), z.array(z.record(z.
|
|
211
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
216
212
|
.describe("The key's value.")
|
|
217
213
|
.optional(),
|
|
218
214
|
type: z
|
|
@@ -228,7 +224,7 @@ export const parameters = z.object({
|
|
|
228
224
|
.object({
|
|
229
225
|
key: z.string().describe("The auth method's key value."),
|
|
230
226
|
value: z
|
|
231
|
-
.union([z.string(), z.array(z.record(z.
|
|
227
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
232
228
|
.describe("The key's value.")
|
|
233
229
|
.optional(),
|
|
234
230
|
type: z
|
|
@@ -244,7 +240,7 @@ export const parameters = z.object({
|
|
|
244
240
|
.object({
|
|
245
241
|
key: z.string().describe("The auth method's key value."),
|
|
246
242
|
value: z
|
|
247
|
-
.union([z.string(), z.array(z.record(z.
|
|
243
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
248
244
|
.describe("The key's value.")
|
|
249
245
|
.optional(),
|
|
250
246
|
type: z
|
|
@@ -260,7 +256,7 @@ export const parameters = z.object({
|
|
|
260
256
|
.object({
|
|
261
257
|
key: z.string().describe("The auth method's key value."),
|
|
262
258
|
value: z
|
|
263
|
-
.union([z.string(), z.array(z.record(z.
|
|
259
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
264
260
|
.describe("The key's value.")
|
|
265
261
|
.optional(),
|
|
266
262
|
type: z
|
|
@@ -276,7 +272,7 @@ export const parameters = z.object({
|
|
|
276
272
|
.object({
|
|
277
273
|
key: z.string().describe("The auth method's key value."),
|
|
278
274
|
value: z
|
|
279
|
-
.union([z.string(), z.array(z.record(z.
|
|
275
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
280
276
|
.describe("The key's value.")
|
|
281
277
|
.optional(),
|
|
282
278
|
type: z
|
|
@@ -292,7 +288,7 @@ export const parameters = z.object({
|
|
|
292
288
|
.object({
|
|
293
289
|
key: z.string().describe("The auth method's key value."),
|
|
294
290
|
value: z
|
|
295
|
-
.union([z.string(), z.array(z.record(z.
|
|
291
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
296
292
|
.describe("The key's value.")
|
|
297
293
|
.optional(),
|
|
298
294
|
type: z
|
|
@@ -308,7 +304,7 @@ export const parameters = z.object({
|
|
|
308
304
|
.object({
|
|
309
305
|
key: z.string().describe("The auth method's key value."),
|
|
310
306
|
value: z
|
|
311
|
-
.union([z.string(), z.array(z.record(z.
|
|
307
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
312
308
|
.describe("The key's value.")
|
|
313
309
|
.optional(),
|
|
314
310
|
type: z
|
|
@@ -324,7 +320,7 @@ export const parameters = z.object({
|
|
|
324
320
|
.object({
|
|
325
321
|
key: z.string().describe("The auth method's key value."),
|
|
326
322
|
value: z
|
|
327
|
-
.union([z.string(), z.array(z.record(z.
|
|
323
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
328
324
|
.describe("The key's value.")
|
|
329
325
|
.optional(),
|
|
330
326
|
type: z
|
|
@@ -340,7 +336,7 @@ export const parameters = z.object({
|
|
|
340
336
|
.object({
|
|
341
337
|
key: z.string().describe("The auth method's key value."),
|
|
342
338
|
value: z
|
|
343
|
-
.union([z.string(), z.array(z.record(z.
|
|
339
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
344
340
|
.describe("The key's value.")
|
|
345
341
|
.optional(),
|
|
346
342
|
type: z
|
|
@@ -399,7 +395,7 @@ export const parameters = z.object({
|
|
|
399
395
|
.describe('A list of x-www-form-encoded key/value pairs.')
|
|
400
396
|
.optional(),
|
|
401
397
|
formdata: z
|
|
402
|
-
.array(z.record(z.
|
|
398
|
+
.array(z.record(z.string(), z.unknown()).and(z.union([
|
|
403
399
|
z.object({
|
|
404
400
|
key: z.string().describe('The key value.').optional(),
|
|
405
401
|
value: z.string().describe("The key's value.").optional(),
|
|
@@ -417,7 +413,7 @@ export const parameters = z.object({
|
|
|
417
413
|
z.object({
|
|
418
414
|
key: z.string().describe('The key value.').optional(),
|
|
419
415
|
src: z
|
|
420
|
-
.
|
|
416
|
+
.unknown()
|
|
421
417
|
.superRefine((x, ctx) => {
|
|
422
418
|
const schemas = [z.string().nullable(), z.array(z.string())];
|
|
423
419
|
const errors = schemas.reduce((errors, schema) => ((result) => result.error ? [...errors, result.error] : errors)(schema.safeParse(x)), []);
|
|
@@ -467,7 +463,7 @@ export const parameters = z.object({
|
|
|
467
463
|
.describe('If the `mode` value is `graphql`, an object containing the GraphQL request information.')
|
|
468
464
|
.optional(),
|
|
469
465
|
options: z
|
|
470
|
-
.record(z.
|
|
466
|
+
.record(z.string(), z.unknown())
|
|
471
467
|
.describe('Additional configurations and options set for various modes.')
|
|
472
468
|
.optional(),
|
|
473
469
|
})
|
|
@@ -476,6 +472,10 @@ export const parameters = z.object({
|
|
|
476
472
|
})
|
|
477
473
|
.describe('Information about the collection request.')
|
|
478
474
|
.optional(),
|
|
475
|
+
response: z
|
|
476
|
+
.array(z.unknown().describe("Information about the request's response."))
|
|
477
|
+
.describe("A list of the collection's responses.")
|
|
478
|
+
.optional(),
|
|
479
479
|
protocolProfileBehavior: z
|
|
480
480
|
.object({
|
|
481
481
|
strictSSL: z
|
|
@@ -617,7 +617,7 @@ export const parameters = z.object({
|
|
|
617
617
|
.object({
|
|
618
618
|
key: z.string().describe("The auth method's key value."),
|
|
619
619
|
value: z
|
|
620
|
-
.union([z.string(), z.array(z.record(z.
|
|
620
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
621
621
|
.describe("The key's value.")
|
|
622
622
|
.optional(),
|
|
623
623
|
type: z
|
|
@@ -633,7 +633,7 @@ export const parameters = z.object({
|
|
|
633
633
|
.object({
|
|
634
634
|
key: z.string().describe("The auth method's key value."),
|
|
635
635
|
value: z
|
|
636
|
-
.union([z.string(), z.array(z.record(z.
|
|
636
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
637
637
|
.describe("The key's value.")
|
|
638
638
|
.optional(),
|
|
639
639
|
type: z
|
|
@@ -649,7 +649,7 @@ export const parameters = z.object({
|
|
|
649
649
|
.object({
|
|
650
650
|
key: z.string().describe("The auth method's key value."),
|
|
651
651
|
value: z
|
|
652
|
-
.union([z.string(), z.array(z.record(z.
|
|
652
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
653
653
|
.describe("The key's value.")
|
|
654
654
|
.optional(),
|
|
655
655
|
type: z
|
|
@@ -665,7 +665,7 @@ export const parameters = z.object({
|
|
|
665
665
|
.object({
|
|
666
666
|
key: z.string().describe("The auth method's key value."),
|
|
667
667
|
value: z
|
|
668
|
-
.union([z.string(), z.array(z.record(z.
|
|
668
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
669
669
|
.describe("The key's value.")
|
|
670
670
|
.optional(),
|
|
671
671
|
type: z
|
|
@@ -681,7 +681,7 @@ export const parameters = z.object({
|
|
|
681
681
|
.object({
|
|
682
682
|
key: z.string().describe("The auth method's key value."),
|
|
683
683
|
value: z
|
|
684
|
-
.union([z.string(), z.array(z.record(z.
|
|
684
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
685
685
|
.describe("The key's value.")
|
|
686
686
|
.optional(),
|
|
687
687
|
type: z
|
|
@@ -697,7 +697,7 @@ export const parameters = z.object({
|
|
|
697
697
|
.object({
|
|
698
698
|
key: z.string().describe("The auth method's key value."),
|
|
699
699
|
value: z
|
|
700
|
-
.union([z.string(), z.array(z.record(z.
|
|
700
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
701
701
|
.describe("The key's value.")
|
|
702
702
|
.optional(),
|
|
703
703
|
type: z
|
|
@@ -713,7 +713,7 @@ export const parameters = z.object({
|
|
|
713
713
|
.object({
|
|
714
714
|
key: z.string().describe("The auth method's key value."),
|
|
715
715
|
value: z
|
|
716
|
-
.union([z.string(), z.array(z.record(z.
|
|
716
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
717
717
|
.describe("The key's value.")
|
|
718
718
|
.optional(),
|
|
719
719
|
type: z
|
|
@@ -729,7 +729,7 @@ export const parameters = z.object({
|
|
|
729
729
|
.object({
|
|
730
730
|
key: z.string().describe("The auth method's key value."),
|
|
731
731
|
value: z
|
|
732
|
-
.union([z.string(), z.array(z.record(z.
|
|
732
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
733
733
|
.describe("The key's value.")
|
|
734
734
|
.optional(),
|
|
735
735
|
type: z
|
|
@@ -745,7 +745,7 @@ export const parameters = z.object({
|
|
|
745
745
|
.object({
|
|
746
746
|
key: z.string().describe("The auth method's key value."),
|
|
747
747
|
value: z
|
|
748
|
-
.union([z.string(), z.array(z.record(z.
|
|
748
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
749
749
|
.describe("The key's value.")
|
|
750
750
|
.optional(),
|
|
751
751
|
type: z
|
|
@@ -761,7 +761,7 @@ export const parameters = z.object({
|
|
|
761
761
|
.object({
|
|
762
762
|
key: z.string().describe("The auth method's key value."),
|
|
763
763
|
value: z
|
|
764
|
-
.union([z.string(), z.array(z.record(z.
|
|
764
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
765
765
|
.describe("The key's value.")
|
|
766
766
|
.optional(),
|
|
767
767
|
type: z
|
|
@@ -777,7 +777,7 @@ export const parameters = z.object({
|
|
|
777
777
|
.object({
|
|
778
778
|
key: z.string().describe("The auth method's key value."),
|
|
779
779
|
value: z
|
|
780
|
-
.union([z.string(), z.array(z.record(z.
|
|
780
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
781
781
|
.describe("The key's value.")
|
|
782
782
|
.optional(),
|
|
783
783
|
type: z
|
|
@@ -793,7 +793,7 @@ export const parameters = z.object({
|
|
|
793
793
|
.object({
|
|
794
794
|
key: z.string().describe("The auth method's key value."),
|
|
795
795
|
value: z
|
|
796
|
-
.union([z.string(), z.array(z.record(z.
|
|
796
|
+
.union([z.string(), z.array(z.record(z.string(), z.unknown()))])
|
|
797
797
|
.describe("The key's value.")
|
|
798
798
|
.optional(),
|
|
799
799
|
type: z
|
|
@@ -882,14 +882,14 @@ export const annotations = {
|
|
|
882
882
|
destructiveHint: false,
|
|
883
883
|
idempotentHint: true,
|
|
884
884
|
};
|
|
885
|
-
export async function handler(
|
|
885
|
+
export async function handler(args, extra) {
|
|
886
886
|
try {
|
|
887
|
-
const endpoint = `/collections/${
|
|
887
|
+
const endpoint = `/collections/${args.collectionId}`;
|
|
888
888
|
const query = new URLSearchParams();
|
|
889
889
|
const url = query.toString() ? `${endpoint}?${query.toString()}` : endpoint;
|
|
890
890
|
const bodyPayload = {};
|
|
891
|
-
if (
|
|
892
|
-
bodyPayload.collection =
|
|
891
|
+
if (args.collection !== undefined)
|
|
892
|
+
bodyPayload.collection = args.collection;
|
|
893
893
|
const options = {
|
|
894
894
|
body: JSON.stringify(bodyPayload),
|
|
895
895
|
contentType: ContentType.Json,
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ContentType } from '../clients/postman.js';
|
|
3
|
-
import {
|
|
4
|
-
function asMcpError(error) {
|
|
5
|
-
const cause = error?.cause ?? String(error);
|
|
6
|
-
return new McpError(ErrorCode.InternalError, cause);
|
|
7
|
-
}
|
|
3
|
+
import { asMcpError, McpError } from './utils/toolHelpers.js';
|
|
8
4
|
export const method = 'putEnvironment';
|
|
9
5
|
export const description = 'Replaces all the contents of an environment with the given information.\n\n**Note:**\n\n- The request body size cannot exceed the maximum allowed size of 30MB.\n- If you receive an HTTP \\`411 Length Required\\` error response, manually pass the \\`Content-Length\\` header and its value in the request header.\n';
|
|
10
6
|
export const parameters = z.object({
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
function asMcpError(error) {
|
|
4
|
-
const cause = error?.cause ?? String(error);
|
|
5
|
-
return new McpError(ErrorCode.InternalError, cause);
|
|
6
|
-
}
|
|
2
|
+
import { asMcpError, McpError } from './utils/toolHelpers.js';
|
|
7
3
|
export const method = 'resolveCommentThread';
|
|
8
4
|
export const description = 'Resolves a comment and any associated replies. On success, this returns an HTTP \\`204 No Content\\` response.\n\nComment thread IDs return in the GET comments response for [APIs](https://www.postman.com/postman/workspace/postman-public-workspace/request/12959542-2103ea20-f7de-4628-90e6-b823b3084a52), [collections](https://www.postman.com/postman/workspace/postman-public-workspace/request/12959542-a6582e0a-9382-4760-8b91-53a8aa6cb8d7), and [collection items](https://www.postman.com/postman/workspace/postman-public-workspace/folder/12959542-efeda219-66e1-474c-a83b-253d15723bf7).\n';
|
|
9
5
|
export const parameters = z.object({
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { TestTracker, OutputBuilder, buildNewmanOptions } from './utils/runner.js';
|
|
5
|
-
function asMcpError(error) {
|
|
6
|
-
const cause = error?.cause ?? String(error);
|
|
7
|
-
return new McpError(ErrorCode.InternalError, cause);
|
|
8
|
-
}
|
|
2
|
+
import { asMcpError, McpError } from './utils/toolHelpers.js';
|
|
3
|
+
import { runCollection } from './runner/index.js';
|
|
9
4
|
export const method = 'runCollection';
|
|
10
5
|
export const description = 'Runs a Postman collection by ID with detailed test results and execution statistics. Supports optional environment for variable substitution. Note: Advanced parameters like custom delays and other runtime options are not yet available.';
|
|
11
6
|
export const parameters = z.object({
|
|
@@ -41,85 +36,12 @@ export const annotations = {
|
|
|
41
36
|
};
|
|
42
37
|
export async function handler(params, extra) {
|
|
43
38
|
try {
|
|
44
|
-
const
|
|
45
|
-
const output = new OutputBuilder();
|
|
46
|
-
output.add(`š Fetching collection with ID: ${params.collectionId}`);
|
|
47
|
-
const response = await extra.client.get(`/collections/${params.collectionId}`);
|
|
48
|
-
const collectionJSON = response.collection || response;
|
|
49
|
-
output.add(`ā
Successfully fetched collection: ${collectionJSON.info?.name || 'Unknown'}\n`);
|
|
50
|
-
let environmentJSON;
|
|
51
|
-
if (params.environmentId) {
|
|
52
|
-
output.add(`š Fetching environment with ID: ${params.environmentId}`);
|
|
53
|
-
const envResponse = await extra.client.get(`/environments/${params.environmentId}`);
|
|
54
|
-
environmentJSON = envResponse.environment || envResponse;
|
|
55
|
-
output.add(`ā
Successfully fetched environment: ${environmentJSON.name || 'Unknown'}\n`);
|
|
56
|
-
}
|
|
57
|
-
const newmanOptions = buildNewmanOptions(params, collectionJSON, environmentJSON);
|
|
58
|
-
const startTime = Date.now();
|
|
59
|
-
await new Promise((resolve, reject) => {
|
|
60
|
-
newman
|
|
61
|
-
.run(newmanOptions)
|
|
62
|
-
.on('start', () => {
|
|
63
|
-
output.add('šÆ Starting collection run...\n');
|
|
64
|
-
})
|
|
65
|
-
.on('assertion', (_err, args) => {
|
|
66
|
-
if (args.assertion) {
|
|
67
|
-
tracker.addAssertion({
|
|
68
|
-
passed: !args.error,
|
|
69
|
-
assertion: args.assertion,
|
|
70
|
-
name: args.assertion,
|
|
71
|
-
error: args.error,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
.on('item', (_err, args) => {
|
|
76
|
-
if (args.item) {
|
|
77
|
-
const testResults = tracker.displayCurrentResults();
|
|
78
|
-
if (testResults) {
|
|
79
|
-
output.add(`\nš Request: ${args.item.name}`);
|
|
80
|
-
output.add(testResults);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
})
|
|
84
|
-
.on('done', (err, summary) => {
|
|
85
|
-
const endTime = Date.now();
|
|
86
|
-
const durationMs = endTime - startTime;
|
|
87
|
-
const durationSec = (durationMs / 1000).toFixed(2);
|
|
88
|
-
if (err) {
|
|
89
|
-
output.add('\nā Run error: ' + err.message);
|
|
90
|
-
output.add(`ā±ļø Duration: ${durationSec}s`);
|
|
91
|
-
reject(err);
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
output.add('\n=== ā
Run completed! ===');
|
|
95
|
-
output.add(`ā±ļø Duration: ${durationSec}s`);
|
|
96
|
-
const testStats = tracker.getTotalStats();
|
|
97
|
-
if (testStats.total > 0) {
|
|
98
|
-
output.add('\nš Overall Test Statistics:');
|
|
99
|
-
output.add(` Total tests: ${testStats.total}`);
|
|
100
|
-
output.add(` Passed: ${testStats.passed} ā
`);
|
|
101
|
-
output.add(` Failed: ${testStats.failed} ā`);
|
|
102
|
-
output.add(` Success rate: ${((testStats.passed / testStats.total) * 100).toFixed(1)}%`);
|
|
103
|
-
}
|
|
104
|
-
if (summary?.run?.stats) {
|
|
105
|
-
output.add('\nš Request Summary:');
|
|
106
|
-
output.add(` Total requests: ${summary.run.stats.requests?.total || 0}`);
|
|
107
|
-
output.add(` Failed requests: ${summary.run.stats.requests?.failed || 0}`);
|
|
108
|
-
output.add(` Total assertions: ${summary.run.stats.assertions?.total || 0}`);
|
|
109
|
-
output.add(` Failed assertions: ${summary.run.stats.assertions?.failed || 0}`);
|
|
110
|
-
if (summary.run.stats.iterations) {
|
|
111
|
-
output.add(` Total iterations: ${summary.run.stats.iterations.total || 0}`);
|
|
112
|
-
output.add(` Failed iterations: ${summary.run.stats.iterations.failed || 0}`);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
resolve();
|
|
116
|
-
});
|
|
117
|
-
});
|
|
39
|
+
const output = await runCollection(params, extra.client);
|
|
118
40
|
return {
|
|
119
41
|
content: [
|
|
120
42
|
{
|
|
121
43
|
type: 'text',
|
|
122
|
-
text: output
|
|
44
|
+
text: output,
|
|
123
45
|
},
|
|
124
46
|
],
|
|
125
47
|
};
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
function asMcpError(error) {
|
|
4
|
-
const cause = error?.cause ?? String(error);
|
|
5
|
-
return new McpError(ErrorCode.InternalError, cause);
|
|
6
|
-
}
|
|
2
|
+
import { asMcpError, McpError } from './utils/toolHelpers.js';
|
|
7
3
|
export const method = 'runMonitor';
|
|
8
4
|
export const description = "Runs a monitor and returns its run results.\n\n**Note:**\n\n- If you pass the \\`async=true\\` query parameter, the response does not return the \\`stats\\`, \\`executions\\`, and \\`failures\\` responses. To get this information for an asynchronous run, call the GET \\`/monitors/{id}\\` endpoint.\n- If the call exceeds 300 seconds, the endpoint returns an HTTP \\`202 Accepted\\` response. Use the GET \\`/monitors/{id}\\` endpoint to check the run's status in the response's \\`lastRun\\` property. To avoid this, it is recommended that you include the \\`async=true\\` query parameter when using this endpoint.\n";
|
|
9
5
|
export const parameters = z.object({
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import newman from 'newman';
|
|
2
|
+
export class OutputBuilder {
|
|
3
|
+
lines = [];
|
|
4
|
+
add(line) {
|
|
5
|
+
this.lines.push(line);
|
|
6
|
+
}
|
|
7
|
+
build() {
|
|
8
|
+
return this.lines.join('\n');
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class TestTracker {
|
|
12
|
+
assertions = [];
|
|
13
|
+
totalTests = 0;
|
|
14
|
+
totalPassed = 0;
|
|
15
|
+
totalFailed = 0;
|
|
16
|
+
addAssertion(assertion) {
|
|
17
|
+
this.assertions.push(assertion);
|
|
18
|
+
this.totalTests++;
|
|
19
|
+
if (assertion.passed) {
|
|
20
|
+
this.totalPassed++;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this.totalFailed++;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
displayCurrentResults() {
|
|
27
|
+
if (this.assertions.length === 0) {
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
30
|
+
const lines = [' š Test Results:'];
|
|
31
|
+
this.assertions.forEach((assertion) => {
|
|
32
|
+
const status = assertion.passed ? 'ā' : 'ā';
|
|
33
|
+
const name = assertion.assertion || assertion.name || 'Unnamed test';
|
|
34
|
+
lines.push(` ${status} ${name}`);
|
|
35
|
+
if (!assertion.passed && assertion.error) {
|
|
36
|
+
const errorMessage = typeof assertion.error === 'string'
|
|
37
|
+
? assertion.error
|
|
38
|
+
: assertion.error.message || 'Unknown error';
|
|
39
|
+
lines.push(` āā Error: ${errorMessage}`);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
const passed = this.assertions.filter((a) => a.passed).length;
|
|
43
|
+
const failed = this.assertions.filter((a) => !a.passed).length;
|
|
44
|
+
lines.push(` āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā`);
|
|
45
|
+
lines.push(` ${this.assertions.length} tests | ā ${passed} passed | ā ${failed} failed\n`);
|
|
46
|
+
this.assertions.length = 0;
|
|
47
|
+
return lines.join('\n');
|
|
48
|
+
}
|
|
49
|
+
getTotalStats() {
|
|
50
|
+
return {
|
|
51
|
+
total: this.totalTests,
|
|
52
|
+
passed: this.totalPassed,
|
|
53
|
+
failed: this.totalFailed,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
reset() {
|
|
57
|
+
this.assertions.length = 0;
|
|
58
|
+
this.totalTests = 0;
|
|
59
|
+
this.totalPassed = 0;
|
|
60
|
+
this.totalFailed = 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export function buildNewmanOptions(params, collection, environment) {
|
|
64
|
+
return {
|
|
65
|
+
collection: collection,
|
|
66
|
+
environment: environment,
|
|
67
|
+
iterationCount: params.iterationCount || 1,
|
|
68
|
+
timeout: params.requestTimeout || 60000,
|
|
69
|
+
timeoutRequest: params.requestTimeout || 60000,
|
|
70
|
+
timeoutScript: params.scriptTimeout || 5000,
|
|
71
|
+
delayRequest: 1000,
|
|
72
|
+
ignoreRedirects: false,
|
|
73
|
+
insecure: false,
|
|
74
|
+
bail: params.stopOnFailure ? ['failure'] : false,
|
|
75
|
+
suppressExitCode: true,
|
|
76
|
+
reporters: [],
|
|
77
|
+
reporter: {},
|
|
78
|
+
color: 'off',
|
|
79
|
+
verbose: false,
|
|
80
|
+
requestAgents: {
|
|
81
|
+
http: undefined,
|
|
82
|
+
https: undefined,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export async function executeCollection(context) {
|
|
87
|
+
const tracker = new TestTracker();
|
|
88
|
+
const output = new OutputBuilder();
|
|
89
|
+
output.add(`š Starting collection: ${context.collection.name}`);
|
|
90
|
+
if (context.environment) {
|
|
91
|
+
output.add(`š Using environment: ${context.environment.name}\n`);
|
|
92
|
+
}
|
|
93
|
+
const newmanOptions = buildNewmanOptions(context.params, context.collection.json, context.environment?.json);
|
|
94
|
+
const startTime = Date.now();
|
|
95
|
+
const summary = await runNewman(newmanOptions, tracker, output);
|
|
96
|
+
const endTime = Date.now();
|
|
97
|
+
const durationMs = endTime - startTime;
|
|
98
|
+
return {
|
|
99
|
+
output: output.build(),
|
|
100
|
+
testStats: tracker.getTotalStats(),
|
|
101
|
+
summary,
|
|
102
|
+
startTime,
|
|
103
|
+
endTime,
|
|
104
|
+
durationMs,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function runNewman(options, tracker, output) {
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
newman
|
|
110
|
+
.run(options)
|
|
111
|
+
.on('start', () => {
|
|
112
|
+
output.add('šÆ Starting collection run...\n');
|
|
113
|
+
})
|
|
114
|
+
.on('assertion', (_err, args) => {
|
|
115
|
+
if (args.assertion) {
|
|
116
|
+
tracker.addAssertion({
|
|
117
|
+
passed: !args.error,
|
|
118
|
+
assertion: args.assertion,
|
|
119
|
+
name: args.assertion,
|
|
120
|
+
error: args.error,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
.on('item', (_err, args) => {
|
|
125
|
+
if (args.item) {
|
|
126
|
+
const testResults = tracker.displayCurrentResults();
|
|
127
|
+
if (testResults) {
|
|
128
|
+
output.add(`\nš Request: ${args.item.name}`);
|
|
129
|
+
output.add(testResults);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
.on('done', (err, summary) => {
|
|
134
|
+
if (err) {
|
|
135
|
+
output.add('\nā Run error: ' + err.message);
|
|
136
|
+
reject(err);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
output.add('\n=== ā
Run completed! ===');
|
|
140
|
+
appendSummaryToOutput(output, tracker, summary);
|
|
141
|
+
resolve(summary);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function appendSummaryToOutput(output, tracker, summary) {
|
|
146
|
+
const testStats = tracker.getTotalStats();
|
|
147
|
+
if (testStats.total > 0) {
|
|
148
|
+
output.add('\nš Overall Test Statistics:');
|
|
149
|
+
output.add(` Total tests: ${testStats.total}`);
|
|
150
|
+
output.add(` Passed: ${testStats.passed} ā
`);
|
|
151
|
+
output.add(` Failed: ${testStats.failed} ā`);
|
|
152
|
+
output.add(` Success rate: ${((testStats.passed / testStats.total) * 100).toFixed(1)}%`);
|
|
153
|
+
}
|
|
154
|
+
if (summary?.run?.stats) {
|
|
155
|
+
output.add('\nš Request Summary:');
|
|
156
|
+
output.add(` Total requests: ${summary.run.stats.requests?.total || 0}`);
|
|
157
|
+
output.add(` Failed requests: ${summary.run.stats.requests?.failed || 0}`);
|
|
158
|
+
output.add(` Total assertions: ${summary.run.stats.assertions?.total || 0}`);
|
|
159
|
+
output.add(` Failed assertions: ${summary.run.stats.assertions?.failed || 0}`);
|
|
160
|
+
if (summary.run.stats.iterations) {
|
|
161
|
+
output.add(` Total iterations: ${summary.run.stats.iterations.total || 0}`);
|
|
162
|
+
output.add(` Failed iterations: ${summary.run.stats.iterations.failed || 0}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
export async function fetchCollection(collectionId, client) {
|
|
3
|
+
try {
|
|
4
|
+
const response = await client.get(`/collections/${collectionId}`);
|
|
5
|
+
const collectionJSON = response.collection || response;
|
|
6
|
+
return {
|
|
7
|
+
json: collectionJSON,
|
|
8
|
+
name: collectionJSON.info?.name || 'Unknown',
|
|
9
|
+
id: collectionId,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
throw new McpError(ErrorCode.InternalError, `Failed to fetch collection: ${collectionId}`, {
|
|
14
|
+
cause: error,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export async function fetchEnvironment(environmentId, client) {
|
|
19
|
+
try {
|
|
20
|
+
const response = await client.get(`/environments/${environmentId}`);
|
|
21
|
+
const environmentJSON = response.environment || response;
|
|
22
|
+
return {
|
|
23
|
+
json: environmentJSON,
|
|
24
|
+
name: environmentJSON.name || 'Unknown',
|
|
25
|
+
id: environmentId,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
throw new McpError(ErrorCode.InternalError, `Failed to fetch environment: ${environmentId}`, {
|
|
30
|
+
cause: error,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { fetchCollection, fetchEnvironment } from './fetchers.js';
|
|
2
|
+
import { executeCollection } from './executor.js';
|
|
3
|
+
import { parseToTelemetry, formatUserOutput } from './parsers.js';
|
|
4
|
+
import { reportTelemetryAsync } from './telemetry.js';
|
|
5
|
+
export async function runCollection(params, client) {
|
|
6
|
+
const collection = await fetchCollection(params.collectionId, client);
|
|
7
|
+
let environment;
|
|
8
|
+
if (params.environmentId) {
|
|
9
|
+
environment = await fetchEnvironment(params.environmentId, client);
|
|
10
|
+
}
|
|
11
|
+
const result = await executeCollection({
|
|
12
|
+
collection,
|
|
13
|
+
environment,
|
|
14
|
+
params,
|
|
15
|
+
});
|
|
16
|
+
const telemetryPayload = parseToTelemetry(result, params.collectionId, collection.name);
|
|
17
|
+
const userOutput = formatUserOutput(result);
|
|
18
|
+
reportTelemetryAsync(telemetryPayload, client);
|
|
19
|
+
return userOutput;
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { buildTelemetryPayload } from './telemetry.js';
|
|
2
|
+
export function parseToTelemetry(result, collectionId, collectionName) {
|
|
3
|
+
return buildTelemetryPayload(collectionId, collectionName, result);
|
|
4
|
+
}
|
|
5
|
+
export function formatUserOutput(result) {
|
|
6
|
+
const durationSec = (result.durationMs / 1000).toFixed(2);
|
|
7
|
+
return `${result.output}\nā±ļø Duration: ${durationSec}s`;
|
|
8
|
+
}
|