@postman/postman-mcp-server 2.7.1 → 2.8.0
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/dist/package.json +6 -4
- package/dist/src/clients/postman.js +2 -0
- package/dist/src/enabledResources.js +7 -5
- package/dist/src/index.js +29 -1
- package/dist/src/tools/addWorkspaceToPrivateNetwork.js +47 -0
- package/dist/src/tools/createCollectionRequest.js +9 -12
- package/dist/src/tools/createCollectionResponse.js +109 -398
- package/dist/src/tools/createWorkspace.js +2 -2
- package/dist/src/tools/deleteWorkspace.js +1 -1
- package/dist/src/tools/getAnalyticsData.js +107 -0
- package/dist/src/tools/getAnalyticsMetadata.js +55 -0
- package/dist/src/tools/getWorkspace.js +1 -1
- package/dist/src/tools/{getAllPanAddElementRequests.js → listPrivateNetworkAddRequests.js} +9 -16
- package/dist/src/tools/{getAllElementsAndFolders.js → listPrivateNetworkWorkspaces.js} +27 -34
- package/dist/src/tools/publishDocumentation.js +1 -1
- package/dist/src/tools/putCollection.js +1 -1
- package/dist/src/tools/removeWorkspaceFromPrivateNetwork.js +36 -0
- package/dist/src/tools/resolveCommentThread.js +1 -1
- package/dist/src/tools/respondPrivateNetworkAddRequest.js +56 -0
- package/dist/src/tools/updateCollectionRequest.js +6 -12
- package/dist/src/tools/updateCollectionResponse.js +113 -0
- package/dist/src/tools/updateWorkspace.js +1 -1
- package/dist/src/tools/utils/errorTemplateRenderer.js +23 -0
- package/dist/src/views/errors/getCollectionFolder.404.njk +5 -0
- package/dist/src/views/errors/getCollectionRequest.404.njk +5 -0
- package/dist/src/views/errors/getCollectionResponse.404.njk +5 -0
- package/dist/src/views/errors/getEnvironment.404.njk +5 -0
- package/dist/src/views/errors/getMock.404.njk +5 -0
- package/dist/src/views/errors/getMonitor.404.njk +5 -0
- package/dist/src/views/errors/getSpec.404.njk +5 -0
- package/dist/src/views/errors/getWorkspace.404.njk +5 -0
- package/package.json +15 -15
- package/dist/src/tools/deletePanElementOrFolder.js +0 -41
- package/dist/src/tools/postPanElementOrFolder.js +0 -84
- package/dist/src/tools/updatePanElementOrFolder.js +0 -100
package/dist/package.json
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postman/postman-mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "A simple MCP server to operate on the Postman API",
|
|
5
5
|
"mcpName": "com.postman/postman-mcp-server",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"packageManager": "pnpm@10.6.2",
|
|
8
9
|
"scripts": {
|
|
10
|
+
"preinstall": "npx only-allow pnpm",
|
|
9
11
|
"start:stdio": "node dist/src/index.js",
|
|
10
12
|
"build": "eslint --fix ./src && prettier --write \"src/**/*.ts\" && tsc",
|
|
11
|
-
"prepack": "
|
|
13
|
+
"prepack": "pnpm run build",
|
|
12
14
|
"test": "vitest",
|
|
13
15
|
"lint": "eslint",
|
|
14
16
|
"lint:fix": "eslint --fix",
|
|
15
|
-
"preversion": "
|
|
17
|
+
"preversion": "pnpm run build",
|
|
16
18
|
"version": "git add dist/",
|
|
17
|
-
"release": "
|
|
19
|
+
"release": "pnpm version",
|
|
18
20
|
"release-custom": "node scripts/release.js"
|
|
19
21
|
},
|
|
20
22
|
"bin": "dist/src/index.js",
|
|
@@ -94,10 +94,12 @@ export class PostmanAPIClient {
|
|
|
94
94
|
case 403:
|
|
95
95
|
throw new McpError(ErrorCode.InvalidParams, `API request failed: ${response.status} ${errorText}`, {
|
|
96
96
|
cause: errorText,
|
|
97
|
+
httpStatus: response.status,
|
|
97
98
|
});
|
|
98
99
|
default:
|
|
99
100
|
throw new McpError(ErrorCode.InternalError, `API request failed: ${response.status}`, {
|
|
100
101
|
cause: errorText,
|
|
102
|
+
httpStatus: response.status,
|
|
101
103
|
});
|
|
102
104
|
}
|
|
103
105
|
}
|
|
@@ -92,11 +92,11 @@ const full = [
|
|
|
92
92
|
'updateWorkspaceGlobalVariables',
|
|
93
93
|
'getWorkspaceTags',
|
|
94
94
|
'updateWorkspaceTags',
|
|
95
|
-
'
|
|
96
|
-
'
|
|
97
|
-
'
|
|
98
|
-
'
|
|
99
|
-
'
|
|
95
|
+
'listPrivateNetworkWorkspaces',
|
|
96
|
+
'listPrivateNetworkAddRequests',
|
|
97
|
+
'removeWorkspaceFromPrivateNetwork',
|
|
98
|
+
'addWorkspaceToPrivateNetwork',
|
|
99
|
+
'respondPrivateNetworkAddRequest',
|
|
100
100
|
'publishDocumentation',
|
|
101
101
|
'unpublishDocumentation',
|
|
102
102
|
'getAsyncSpecTaskStatus',
|
|
@@ -114,6 +114,8 @@ const full = [
|
|
|
114
114
|
'getEnabledTools',
|
|
115
115
|
'searchPostmanElementsInPublicNetwork',
|
|
116
116
|
'searchPostmanElementsInPrivateNetwork',
|
|
117
|
+
'getAnalyticsData',
|
|
118
|
+
'getAnalyticsMetadata',
|
|
117
119
|
];
|
|
118
120
|
const minimal = [
|
|
119
121
|
'createCollection',
|
package/dist/src/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import { PostmanAPIClient } from './clients/postman.js';
|
|
|
11
11
|
import { SERVER_NAME, APP_VERSION } from './constants.js';
|
|
12
12
|
import { env } from './env.js';
|
|
13
13
|
import { createTemplateRenderer } from './tools/utils/templateRenderer.js';
|
|
14
|
+
import { createErrorTemplateRenderer } from './tools/utils/errorTemplateRenderer.js';
|
|
14
15
|
const SUPPORTED_REGIONS = {
|
|
15
16
|
us: 'https://api.postman.com',
|
|
16
17
|
eu: 'https://api.eu.postman.com',
|
|
@@ -148,6 +149,8 @@ async function run() {
|
|
|
148
149
|
const __dirname = dirname(__filename);
|
|
149
150
|
const viewsDir = join(__dirname, './views');
|
|
150
151
|
const renderTemplate = createTemplateRenderer(viewsDir);
|
|
152
|
+
const errorsDir = join(__dirname, './views/errors');
|
|
153
|
+
const renderErrorTemplate = createErrorTemplateRenderer(errorsDir);
|
|
151
154
|
const client = new PostmanAPIClient(apiKey, undefined, serverContext);
|
|
152
155
|
log('info', 'Registering tools with McpServer');
|
|
153
156
|
for (const tool of tools) {
|
|
@@ -184,8 +187,33 @@ async function run() {
|
|
|
184
187
|
catch (error) {
|
|
185
188
|
const errMsg = String(error?.message || error);
|
|
186
189
|
logBoth(server, 'error', `Tool invocation failed: ${toolName}: ${errMsg}`, { toolName });
|
|
187
|
-
if (error instanceof McpError)
|
|
190
|
+
if (error instanceof McpError) {
|
|
191
|
+
const httpStatus = error.data?.httpStatus;
|
|
192
|
+
if (typeof httpStatus === 'number') {
|
|
193
|
+
const rawBody = String(error.data?.cause ?? '');
|
|
194
|
+
let parsedBody = null;
|
|
195
|
+
try {
|
|
196
|
+
parsedBody = JSON.parse(rawBody);
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
}
|
|
200
|
+
const errorObj = parsedBody?.error && typeof parsedBody.error === 'object'
|
|
201
|
+
? parsedBody.error
|
|
202
|
+
: parsedBody;
|
|
203
|
+
const rendered = renderErrorTemplate(toolName, httpStatus, {
|
|
204
|
+
toolName,
|
|
205
|
+
statusCode: httpStatus,
|
|
206
|
+
args,
|
|
207
|
+
errorMessage: error.message,
|
|
208
|
+
errorBody: rawBody,
|
|
209
|
+
error: errorObj,
|
|
210
|
+
});
|
|
211
|
+
if (rendered) {
|
|
212
|
+
throw new McpError(error.code, rendered, error.data);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
188
215
|
throw error;
|
|
216
|
+
}
|
|
189
217
|
throw new McpError(ErrorCode.InternalError, `API error: ${error.message}`);
|
|
190
218
|
}
|
|
191
219
|
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ContentType } from '../clients/postman.js';
|
|
3
|
+
import { asMcpError, McpError } from './utils/toolHelpers.js';
|
|
4
|
+
export const method = 'addWorkspaceToPrivateNetwork';
|
|
5
|
+
export const description = "Publishes a workspace to your team's Private API Network.\n\nWARNING: This tool is for Private API Network management, not for general workspace operations. For workspace management use: getWorkspaces, getWorkspace, createWorkspace, updateWorkspace, deleteWorkspace.\n";
|
|
6
|
+
export const parameters = z.object({
|
|
7
|
+
workspace: z.object({
|
|
8
|
+
id: z.string().describe("The workspace's ID."),
|
|
9
|
+
parentFolderId: z.number().int().describe('The `0` value.').default(0),
|
|
10
|
+
}),
|
|
11
|
+
});
|
|
12
|
+
export const annotations = {
|
|
13
|
+
title: "Publishes a workspace to your team's Private API Network.",
|
|
14
|
+
readOnlyHint: false,
|
|
15
|
+
destructiveHint: false,
|
|
16
|
+
idempotentHint: false,
|
|
17
|
+
};
|
|
18
|
+
export async function handler(args, extra) {
|
|
19
|
+
try {
|
|
20
|
+
const endpoint = `/network/private`;
|
|
21
|
+
const query = new URLSearchParams();
|
|
22
|
+
const url = query.toString() ? `${endpoint}?${query.toString()}` : endpoint;
|
|
23
|
+
const bodyPayload = {};
|
|
24
|
+
if (args.workspace !== undefined)
|
|
25
|
+
bodyPayload.workspace = args.workspace;
|
|
26
|
+
const options = {
|
|
27
|
+
body: JSON.stringify(bodyPayload),
|
|
28
|
+
contentType: ContentType.Json,
|
|
29
|
+
headers: extra.headers,
|
|
30
|
+
};
|
|
31
|
+
const result = await extra.client.post(url, options);
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: 'text',
|
|
36
|
+
text: `${typeof result === 'string' ? result : JSON.stringify(result, null, 2)}`,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
if (e instanceof McpError) {
|
|
43
|
+
throw e;
|
|
44
|
+
}
|
|
45
|
+
throw asMcpError(e);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -9,7 +9,10 @@ export const parameters = z.object({
|
|
|
9
9
|
.string()
|
|
10
10
|
.describe('The folder ID in which to create the request. By default, the system will create the request at the collection level.')
|
|
11
11
|
.optional(),
|
|
12
|
-
name: z
|
|
12
|
+
name: z
|
|
13
|
+
.string()
|
|
14
|
+
.describe("The request's name. It is recommended that you pass the `name` property in the request body. If you do not, the system uses a null value. As a result, this creates a request with a blank name.")
|
|
15
|
+
.optional(),
|
|
13
16
|
description: z.string().nullable().describe("The request's description.").optional(),
|
|
14
17
|
method: z
|
|
15
18
|
.enum([
|
|
@@ -29,7 +32,6 @@ export const parameters = z.object({
|
|
|
29
32
|
'PROPFIND',
|
|
30
33
|
'VIEW',
|
|
31
34
|
])
|
|
32
|
-
.nullable()
|
|
33
35
|
.describe("The request's HTTP method.")
|
|
34
36
|
.optional(),
|
|
35
37
|
url: z.string().nullable().describe("The request's URL.").optional(),
|
|
@@ -37,7 +39,7 @@ export const parameters = z.object({
|
|
|
37
39
|
.array(z.object({
|
|
38
40
|
key: z.string().describe("The header's key.").optional(),
|
|
39
41
|
value: z.string().describe("The header's value.").optional(),
|
|
40
|
-
description: z.string().
|
|
42
|
+
description: z.string().describe("The header's description.").optional(),
|
|
41
43
|
}))
|
|
42
44
|
.describe("The request's headers.")
|
|
43
45
|
.optional(),
|
|
@@ -45,25 +47,20 @@ export const parameters = z.object({
|
|
|
45
47
|
.array(z.object({
|
|
46
48
|
key: z.string().describe("The query parameter's key.").optional(),
|
|
47
49
|
value: z.string().describe("The query parameter's value.").optional(),
|
|
48
|
-
description: z
|
|
49
|
-
.string()
|
|
50
|
-
.nullable()
|
|
51
|
-
.describe("The query parameter's description.")
|
|
52
|
-
.optional(),
|
|
50
|
+
description: z.string().describe("The query parameter's description.").optional(),
|
|
53
51
|
enabled: z.boolean().describe('If true, the query parameter is enabled.').optional(),
|
|
54
52
|
}))
|
|
55
53
|
.describe("The request's query parameters.")
|
|
56
54
|
.optional(),
|
|
57
55
|
dataMode: z
|
|
58
56
|
.enum(['raw', 'urlencoded', 'formdata', 'binary', 'graphql'])
|
|
59
|
-
.nullable()
|
|
60
57
|
.describe("The request body's data mode.")
|
|
61
58
|
.optional(),
|
|
62
59
|
data: z
|
|
63
60
|
.array(z.object({
|
|
64
61
|
key: z.string().describe("The form data's key.").optional(),
|
|
65
62
|
value: z.string().describe("The form data's value.").optional(),
|
|
66
|
-
description: z.string().
|
|
63
|
+
description: z.string().describe("The form data's description.").optional(),
|
|
67
64
|
enabled: z.boolean().describe('If true, the form data entry is enabled.').optional(),
|
|
68
65
|
type: z.enum(['text', 'file']).describe("The form data's type.").optional(),
|
|
69
66
|
uuid: z.string().describe("The form data entry's unique identifier.").optional(),
|
|
@@ -84,7 +81,6 @@ export const parameters = z.object({
|
|
|
84
81
|
.object({
|
|
85
82
|
raw: z
|
|
86
83
|
.object({ language: z.string().describe("The raw mode data's language type.").optional() })
|
|
87
|
-
.catchall(z.unknown())
|
|
88
84
|
.describe('Options for the `raw` data mode.')
|
|
89
85
|
.optional(),
|
|
90
86
|
urlencoded: z
|
|
@@ -324,7 +320,7 @@ export const parameters = z.object({
|
|
|
324
320
|
.optional(),
|
|
325
321
|
events: z
|
|
326
322
|
.array(z.object({
|
|
327
|
-
listen: z.enum(['test', 'prerequest']).describe('The event type.'),
|
|
323
|
+
listen: z.enum(['test', 'prerequest']).describe('The event type.').optional(),
|
|
328
324
|
script: z
|
|
329
325
|
.object({
|
|
330
326
|
id: z.string().describe("The script's ID.").optional(),
|
|
@@ -340,6 +336,7 @@ export const parameters = z.object({
|
|
|
340
336
|
.describe('Information about the Javascript code that can be used to to perform setup or teardown operations in a response.')
|
|
341
337
|
.optional(),
|
|
342
338
|
}))
|
|
339
|
+
.nullable()
|
|
343
340
|
.describe('A list of scripts configured to run when specific events occur.')
|
|
344
341
|
.optional(),
|
|
345
342
|
});
|