@smartbear/mcp 0.3.0 → 0.5.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/README.md +86 -25
- package/dist/api-hub/client.js +298 -52
- package/dist/{insight-hub → bugsnag}/client/api/CurrentUser.js +2 -1
- package/dist/{insight-hub → bugsnag}/client/api/Error.js +37 -4
- package/dist/{insight-hub → bugsnag}/client/api/Project.js +2 -1
- package/dist/{insight-hub → bugsnag}/client/api/base.js +18 -1
- package/dist/{insight-hub → bugsnag}/client/api/filters.js +2 -2
- package/dist/bugsnag/client.js +687 -0
- package/dist/common/info.js +1 -1
- package/dist/common/server.js +148 -0
- package/dist/index.js +38 -29
- package/dist/pactflow/client/ai.js +146 -0
- package/dist/pactflow/client/base.js +6 -0
- package/dist/pactflow/client/tools.js +55 -0
- package/dist/pactflow/client/utils.js +70 -0
- package/dist/pactflow/client.js +180 -0
- package/dist/reflect/client.js +100 -18
- package/package.json +8 -4
- package/dist/common/templates.js +0 -57
- package/dist/insight-hub/client.js +0 -621
- package/dist/package.json +0 -59
- package/dist/tests/unit/common/templates.test.js +0 -149
- package/dist/tests/unit/insight-hub/api-utilities.test.js +0 -31
- package/dist/tests/unit/insight-hub/client.test.js +0 -920
- package/dist/tests/unit/insight-hub/filters.test.js +0 -93
- package/dist/vitest.config.js +0 -57
- /package/dist/{insight-hub → bugsnag}/client/api/index.js +0 -0
- /package/dist/{insight-hub → bugsnag}/client/configuration.js +0 -0
- /package/dist/{insight-hub → bugsnag}/client/index.js +0 -0
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
</div>
|
|
19
19
|
<br />
|
|
20
20
|
|
|
21
|
-
A Model Context Protocol (MCP) server which provides AI assistants with seamless access to SmartBear's suite of testing and monitoring tools, including [
|
|
21
|
+
A Model Context Protocol (MCP) server which provides AI assistants with seamless access to SmartBear's suite of testing and monitoring tools, including [BugSnag](https://www.bugsnag.com/), [Reflect](https://reflect.run), [API Hub](https://www.smartbear.com/api-hub), [PactFlow](https://pactflow.io/) and [Pact Broker](https://docs.pact.io/)
|
|
22
22
|
|
|
23
23
|
## What is MCP?
|
|
24
24
|
|
|
@@ -28,22 +28,23 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction)
|
|
|
28
28
|
|
|
29
29
|
See individual guides for suggested prompts and supported tools and resources:
|
|
30
30
|
|
|
31
|
-
- [
|
|
31
|
+
- [BugSnag](https://developer.smartbear.com/smartbear-mcp/docs/bugsnag-integration) - Comprehensive error monitoring and debugging capabilities
|
|
32
32
|
- [Test Hub](https://developer.smartbear.com/smartbear-mcp/docs/test-hub-integration) - Test management and execution capabilities
|
|
33
33
|
- [API Hub](https://developer.smartbear.com/smartbear-mcp/docs/api-hub-integration) - Portal management capabilities
|
|
34
|
+
- [PactFlow](https://developer.smartbear.com/pactflow/default/getting-started) - Contract testing capabilities
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
## Prerequisites
|
|
37
38
|
|
|
38
39
|
- Node.js 20+ and npm
|
|
39
|
-
- Access to SmartBear products (
|
|
40
|
+
- Access to SmartBear products (BugSnag, Reflect, or API Hub)
|
|
40
41
|
- Valid API tokens for the products you want to integrate
|
|
41
42
|
|
|
42
43
|
## Installation
|
|
43
44
|
|
|
44
45
|
The MCP server is distributed as an npm package [`@smartbear/mcp`](https://www.npmjs.com/package/@smartbear/mcp), making it easy to integrate into your development workflow.
|
|
45
46
|
|
|
46
|
-
The server is started with the API key or auth token that you use with your SmartBear product(s). They are optional and can be removed from your configuration if you aren't using the product. For
|
|
47
|
+
The server is started with the API key or auth token that you use with your SmartBear product(s). They are optional and can be removed from your configuration if you aren't using the product. For BugSnag, if you provide a project API key it will narrow down all searches to a single project in your BugSnag dashboard. Leave this field blank if you wish to interact across multiple projects at a time.
|
|
47
48
|
|
|
48
49
|
### VS Code with Copilot
|
|
49
50
|
|
|
@@ -65,24 +66,28 @@ Alternatively, you can use `npx` (or globally install) the `@smartbear/mcp` pack
|
|
|
65
66
|
"@smartbear/mcp@latest"
|
|
66
67
|
],
|
|
67
68
|
"env": {
|
|
68
|
-
"
|
|
69
|
-
"
|
|
69
|
+
"BUGSNAG_AUTH_TOKEN": "${input:bugsnag_auth_token}",
|
|
70
|
+
"BUGSNAG_PROJECT_API_KEY": "${input:bugsnag_project_api_key}",
|
|
70
71
|
"REFLECT_API_TOKEN": "${input:reflect_api_token}",
|
|
71
|
-
"API_HUB_API_KEY": "${input:api_hub_api_key}"
|
|
72
|
+
"API_HUB_API_KEY": "${input:api_hub_api_key}",
|
|
73
|
+
"PACT_BROKER_BASE_URL": "${input:pact_broker_base_url}",
|
|
74
|
+
"PACT_BROKER_TOKEN": "${input:pact_broker_token}",
|
|
75
|
+
"PACT_BROKER_USERNAME": "${input:pact_broker_username}",
|
|
76
|
+
"PACT_BROKER_PASSWORD": "${input:pact_broker_password}"
|
|
72
77
|
}
|
|
73
78
|
}
|
|
74
79
|
},
|
|
75
80
|
"inputs": [
|
|
76
81
|
{
|
|
77
|
-
"id": "
|
|
82
|
+
"id": "bugsnag_auth_token",
|
|
78
83
|
"type": "promptString",
|
|
79
|
-
"description": "
|
|
84
|
+
"description": "BugSnag Auth Token - leave blank to disable BugSnag tools",
|
|
80
85
|
"password": true
|
|
81
86
|
},
|
|
82
87
|
{
|
|
83
|
-
"id": "
|
|
88
|
+
"id": "bugsnag_project_api_key",
|
|
84
89
|
"type": "promptString",
|
|
85
|
-
"description": "
|
|
90
|
+
"description": "BugSnag Project API Key - for single project interactions",
|
|
86
91
|
"password": false
|
|
87
92
|
},
|
|
88
93
|
{
|
|
@@ -96,7 +101,31 @@ Alternatively, you can use `npx` (or globally install) the `@smartbear/mcp` pack
|
|
|
96
101
|
"type": "promptString",
|
|
97
102
|
"description": "API Hub API Key - leave blank to disable API Hub tools",
|
|
98
103
|
"password": true
|
|
99
|
-
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": "pact_broker_base_url",
|
|
107
|
+
"type": "promptString",
|
|
108
|
+
"description": "PactFlow or Pact Broker base url - leave blank to disable the tools",
|
|
109
|
+
"password": true
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"id": "pact_broker_token",
|
|
113
|
+
"type": "promptString",
|
|
114
|
+
"description": "PactFlow Authentication Token",
|
|
115
|
+
"password": true
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"id": "pact_broker_username",
|
|
119
|
+
"type": "promptString",
|
|
120
|
+
"description": "Pact Broker Username",
|
|
121
|
+
"password": true
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"id": "pact_broker_password",
|
|
125
|
+
"type": "promptString",
|
|
126
|
+
"description": "Pact Broker Password",
|
|
127
|
+
"password": true
|
|
128
|
+
},
|
|
100
129
|
]
|
|
101
130
|
}
|
|
102
131
|
```
|
|
@@ -116,10 +145,14 @@ Add the following configuration to your `claude_desktop_config.json` to launch t
|
|
|
116
145
|
"@smartbear/mcp@latest"
|
|
117
146
|
],
|
|
118
147
|
"env": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
148
|
+
"BUGSNAG_AUTH_TOKEN": "your_personal_auth_token",
|
|
149
|
+
"BUGSNAG_PROJECT_API_KEY": "your_project_api_key",
|
|
121
150
|
"REFLECT_API_TOKEN": "your_reflect_token",
|
|
122
|
-
"API_HUB_API_KEY": "your_api_hub_key"
|
|
151
|
+
"API_HUB_API_KEY": "your_api_hub_key",
|
|
152
|
+
"PACT_BROKER_BASE_URL": "your_pactflow_or_pactbroker_base_url",
|
|
153
|
+
"PACT_BROKER_TOKEN": "your_pactflow_token",
|
|
154
|
+
"PACT_BROKER_USERNAME": "your_pact_broker_username",
|
|
155
|
+
"PACT_BROKER_PASSWORD": "your_pact_broker_password",
|
|
123
156
|
}
|
|
124
157
|
}
|
|
125
158
|
}
|
|
@@ -169,24 +202,28 @@ For developers who want to contribute to the SmartBear MCP server, customize its
|
|
|
169
202
|
},
|
|
170
203
|
"args": ["<PATH_TO_SMARTBEAR_MCP_REPO>/dist/index.js"],
|
|
171
204
|
"env": {
|
|
172
|
-
"
|
|
173
|
-
"
|
|
205
|
+
"BUGSNAG_AUTH_TOKEN": "${input:bugsnag_auth_token}",
|
|
206
|
+
"BUGSNAG_PROJECT_API_KEY": "${input:bugsnag_project_api_key}",
|
|
174
207
|
"REFLECT_API_TOKEN": "${input:reflect_api_token}",
|
|
175
|
-
"API_HUB_API_KEY": "${input:api_hub_api_key}"
|
|
208
|
+
"API_HUB_API_KEY": "${input:api_hub_api_key}",
|
|
209
|
+
"PACT_BROKER_BASE_URL": "${input:pact_broker_base_url}",
|
|
210
|
+
"PACT_BROKER_TOKEN": "${input:pact_broker_token}",
|
|
211
|
+
"PACT_BROKER_USERNAME": "${input:pact_broker_username}",
|
|
212
|
+
"PACT_BROKER_PASSWORD": "${input:pact_broker_password}"
|
|
176
213
|
}
|
|
177
214
|
}
|
|
178
215
|
},
|
|
179
216
|
"inputs": [
|
|
180
217
|
{
|
|
181
|
-
"id": "
|
|
218
|
+
"id": "bugsnag_auth_token",
|
|
182
219
|
"type": "promptString",
|
|
183
|
-
"description": "
|
|
220
|
+
"description": "BugSnag Auth Token - leave blank to disable BugSnag tools",
|
|
184
221
|
"password": true
|
|
185
222
|
},
|
|
186
223
|
{
|
|
187
|
-
"id": "
|
|
224
|
+
"id": "bugsnag_project_api_key",
|
|
188
225
|
"type": "promptString",
|
|
189
|
-
"description": "
|
|
226
|
+
"description": "BugSnag Project API Key - for single project interactions",
|
|
190
227
|
"password": false
|
|
191
228
|
},
|
|
192
229
|
{
|
|
@@ -200,7 +237,31 @@ For developers who want to contribute to the SmartBear MCP server, customize its
|
|
|
200
237
|
"type": "promptString",
|
|
201
238
|
"description": "API Hub API Key - leave blank to disable API Hub tools",
|
|
202
239
|
"password": true
|
|
203
|
-
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"id": "pact_broker_base_url",
|
|
243
|
+
"type": "promptString",
|
|
244
|
+
"description": "PactFlow or Pact Broker base url - leave blank to disable PactFlow tools",
|
|
245
|
+
"password": true
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"id": "pact_broker_token",
|
|
249
|
+
"type": "promptString",
|
|
250
|
+
"description": "PactFlow Authentication Token",
|
|
251
|
+
"password": true
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"id": "pact_broker_username",
|
|
255
|
+
"type": "promptString",
|
|
256
|
+
"description": "Pact Broker Username",
|
|
257
|
+
"password": true
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"id": "pact_broker_password",
|
|
261
|
+
"type": "promptString",
|
|
262
|
+
"description": "Pact Broker Password",
|
|
263
|
+
"password": true
|
|
264
|
+
},
|
|
204
265
|
]
|
|
205
266
|
}
|
|
206
267
|
```
|
|
@@ -209,7 +270,7 @@ For developers who want to contribute to the SmartBear MCP server, customize its
|
|
|
209
270
|
5. **Local testing** using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) web interface:
|
|
210
271
|
|
|
211
272
|
```bash
|
|
212
|
-
|
|
273
|
+
BUGSNAG_AUTH_TOKEN="your_token" REFLECT_API_TOKEN="your_reflect_token" API_HUB_API_KEY="your_api_hub_key" PACT_BROKER_BASE_URL="your-pactflow-url" PACT_BROKER_TOKEN="your-pactflow-token" PACT_BROKER_USERNAME="your-pact-broker-username" PACT_BROKER_PASSWORD="your-pact-broker-password" npx @modelcontextprotocol/inspector npx @smartbear/mcp@latest
|
|
213
274
|
```
|
|
214
275
|
|
|
215
276
|
## License
|
|
@@ -224,4 +285,4 @@ This MCP server is licensed under the MIT License. This means you are free to us
|
|
|
224
285
|
|
|
225
286
|
---
|
|
226
287
|
|
|
227
|
-
**SmartBear MCP Server** - Bringing the power of SmartBear's testing and monitoring ecosystem to your AI-powered development workflow.
|
|
288
|
+
**SmartBear MCP Server** - Bringing the power of SmartBear's testing and monitoring ecosystem to your AI-powered development workflow.
|
package/dist/api-hub/client.js
CHANGED
|
@@ -3,6 +3,8 @@ import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
|
|
|
3
3
|
// Tool definitions for API Hub API client
|
|
4
4
|
export class ApiHubClient {
|
|
5
5
|
headers;
|
|
6
|
+
name = "API Hub";
|
|
7
|
+
prefix = "api_hub";
|
|
6
8
|
constructor(token) {
|
|
7
9
|
this.headers = {
|
|
8
10
|
"Authorization": `Bearer ${token}`,
|
|
@@ -82,99 +84,343 @@ export class ApiHubClient {
|
|
|
82
84
|
});
|
|
83
85
|
return response.json();
|
|
84
86
|
}
|
|
85
|
-
registerTools(
|
|
86
|
-
|
|
87
|
+
registerTools(register, _getInput) {
|
|
88
|
+
register({
|
|
89
|
+
title: "List Portals",
|
|
90
|
+
summary: "Search for available portals within API Hub. Only portals where you have at least a designer role, either at the product level or organization level, are returned.",
|
|
91
|
+
parameters: [],
|
|
92
|
+
}, async (_args, _extra) => {
|
|
87
93
|
const response = await this.getPortals();
|
|
88
94
|
return {
|
|
89
95
|
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
90
96
|
};
|
|
91
97
|
});
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
register({
|
|
99
|
+
title: "Create Portal",
|
|
100
|
+
summary: "Create a new portal within API Hub.",
|
|
101
|
+
parameters: [
|
|
102
|
+
{
|
|
103
|
+
name: "name",
|
|
104
|
+
type: z.string(),
|
|
105
|
+
required: false,
|
|
106
|
+
description: "The portal name.",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: "subdomain",
|
|
110
|
+
type: z.string(),
|
|
111
|
+
required: true,
|
|
112
|
+
description: "The portal subdomain.",
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: "offline",
|
|
116
|
+
type: z.boolean(),
|
|
117
|
+
required: false,
|
|
118
|
+
description: "If set to true the portal will not be visible to customers.",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "routing",
|
|
122
|
+
type: z.string(),
|
|
123
|
+
required: false,
|
|
124
|
+
description: "Determines the routing strategy ('browser' or 'proxy').",
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: "credentialsEnabled",
|
|
128
|
+
type: z.string(),
|
|
129
|
+
required: false,
|
|
130
|
+
description: "Indicates if credentials are enabled for the portal.",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "swaggerHubOrganizationId",
|
|
134
|
+
type: z.string(),
|
|
135
|
+
required: true,
|
|
136
|
+
description: "The corresponding API Hub (formerly SwaggerHub) organization UUID.",
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "openapiRenderer",
|
|
140
|
+
type: z.string(),
|
|
141
|
+
required: false,
|
|
142
|
+
description: "Portal level setting for the OpenAPI renderer. SWAGGER_UI - Use the Swagger UI renderer. ELEMENTS - Use the Elements renderer. TOGGLE - Switch between the two renderers with elements set as the default.",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: "pageContentFormat",
|
|
146
|
+
type: z.string(),
|
|
147
|
+
required: false,
|
|
148
|
+
description: "The format of the page content.",
|
|
149
|
+
}
|
|
150
|
+
],
|
|
101
151
|
}, async (args, _extra) => {
|
|
102
|
-
const
|
|
152
|
+
const createPortalArgs = args;
|
|
153
|
+
const response = await this.createPortal(createPortalArgs);
|
|
103
154
|
return {
|
|
104
155
|
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
105
156
|
};
|
|
106
157
|
});
|
|
107
|
-
|
|
108
|
-
|
|
158
|
+
register({
|
|
159
|
+
title: "Get Portal",
|
|
160
|
+
summary: "Retrieve information about a specific portal.",
|
|
161
|
+
parameters: [
|
|
162
|
+
{
|
|
163
|
+
name: "portalId",
|
|
164
|
+
type: z.string(),
|
|
165
|
+
description: "Portal UUID or subdomain.",
|
|
166
|
+
required: true
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
}, async (args, _extra) => {
|
|
170
|
+
const portalArgs = args;
|
|
171
|
+
const response = await this.getPortal(portalArgs.portalId);
|
|
109
172
|
return {
|
|
110
173
|
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
111
174
|
};
|
|
112
175
|
});
|
|
113
|
-
|
|
114
|
-
|
|
176
|
+
register({
|
|
177
|
+
title: "Delete Portal",
|
|
178
|
+
summary: "Delete a specific portal.",
|
|
179
|
+
parameters: [
|
|
180
|
+
{
|
|
181
|
+
name: "portalId",
|
|
182
|
+
type: z.string(),
|
|
183
|
+
description: "Portal UUID or subdomain.",
|
|
184
|
+
required: true
|
|
185
|
+
}
|
|
186
|
+
],
|
|
187
|
+
}, async (args, _extra) => {
|
|
188
|
+
const portalArgs = args;
|
|
189
|
+
await this.deletePortal(portalArgs.portalId);
|
|
115
190
|
return {
|
|
116
191
|
content: [{ type: "text", text: "Portal deleted successfully." }],
|
|
117
192
|
};
|
|
118
193
|
});
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
194
|
+
register({
|
|
195
|
+
title: "Update Portal",
|
|
196
|
+
summary: "Update a specific portal's configuration.",
|
|
197
|
+
parameters: [
|
|
198
|
+
{
|
|
199
|
+
name: "portalId",
|
|
200
|
+
type: z.string(),
|
|
201
|
+
description: "Portal UUID or subdomain.",
|
|
202
|
+
required: true
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: "name",
|
|
206
|
+
type: z.string(),
|
|
207
|
+
description: "The portal name.",
|
|
208
|
+
required: false
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "subdomain",
|
|
212
|
+
type: z.string(),
|
|
213
|
+
description: "The portal subdomain.",
|
|
214
|
+
required: false
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: "customDomain",
|
|
218
|
+
type: z.boolean(),
|
|
219
|
+
description: "Indicates if the portal has a custom domain.",
|
|
220
|
+
required: false
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: "gtmKey",
|
|
224
|
+
type: z.string(),
|
|
225
|
+
description: "Google Tag Manager key for the portal.",
|
|
226
|
+
required: false
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
name: "offline",
|
|
230
|
+
type: z.boolean(),
|
|
231
|
+
description: "If set to true the portal will not be visible to customers.",
|
|
232
|
+
required: false
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "routing",
|
|
236
|
+
type: z.string(),
|
|
237
|
+
description: "Determines the routing strategy ('browser' or 'proxy').",
|
|
238
|
+
required: false
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: "credentialsEnabled",
|
|
242
|
+
type: z.boolean(),
|
|
243
|
+
description: "Indicates if credentials are enabled for the portal.",
|
|
244
|
+
required: false
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: "openapiRenderer",
|
|
248
|
+
type: z.string(),
|
|
249
|
+
description: "Portal level setting for the OpenAPI renderer. SWAGGER_UI - Use the Swagger UI renderer. ELEMENTS - Use the Elements renderer. TOGGLE - Switch between the two renderers with elements set as the default.",
|
|
250
|
+
required: false
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: "pageContentFormat",
|
|
254
|
+
type: z.string(),
|
|
255
|
+
description: "The format of the page content.",
|
|
256
|
+
required: false
|
|
257
|
+
}
|
|
258
|
+
],
|
|
130
259
|
}, async (args, _extra) => {
|
|
131
|
-
const
|
|
260
|
+
const updatePortalArgs = args;
|
|
261
|
+
const response = await this.updatePortal(updatePortalArgs.portalId, updatePortalArgs);
|
|
132
262
|
return {
|
|
133
263
|
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
134
264
|
};
|
|
135
265
|
});
|
|
136
|
-
|
|
137
|
-
|
|
266
|
+
register({
|
|
267
|
+
title: "List Portal Products",
|
|
268
|
+
summary: "Get products for a specific portal that match your criteria.",
|
|
269
|
+
parameters: [
|
|
270
|
+
{
|
|
271
|
+
name: "portalId",
|
|
272
|
+
type: z.string(),
|
|
273
|
+
description: "Portal UUID or subdomain.",
|
|
274
|
+
required: true
|
|
275
|
+
}
|
|
276
|
+
],
|
|
277
|
+
}, async (args, _extra) => {
|
|
278
|
+
const portalArgs = args;
|
|
279
|
+
const response = await this.getPortalProducts(portalArgs.portalId);
|
|
138
280
|
return {
|
|
139
281
|
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
140
282
|
};
|
|
141
283
|
});
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
284
|
+
register({
|
|
285
|
+
title: "Create Portal Product",
|
|
286
|
+
summary: "Create a new product for a specific portal.",
|
|
287
|
+
parameters: [
|
|
288
|
+
{
|
|
289
|
+
name: "portalId",
|
|
290
|
+
type: z.string(),
|
|
291
|
+
description: "Portal UUID or subdomain.",
|
|
292
|
+
required: true
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: "type",
|
|
296
|
+
type: z.string(),
|
|
297
|
+
description: "Product type (Allowed values: 'new', 'copy').",
|
|
298
|
+
required: true
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
name: "name",
|
|
302
|
+
type: z.string(),
|
|
303
|
+
description: "Product name.",
|
|
304
|
+
required: true
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: "slug",
|
|
308
|
+
type: z.string(),
|
|
309
|
+
description: "URL component for this product. Must be unique within the portal.",
|
|
310
|
+
required: true
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: "description",
|
|
314
|
+
type: z.string(),
|
|
315
|
+
description: "Product description.",
|
|
316
|
+
required: false
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: "public",
|
|
320
|
+
type: z.boolean(),
|
|
321
|
+
description: "Indicates if the product is public.",
|
|
322
|
+
required: false
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
name: "hidden",
|
|
326
|
+
type: z.string(),
|
|
327
|
+
description: "Indicates if the product is hidden.",
|
|
328
|
+
required: false
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
name: "role",
|
|
332
|
+
type: z.boolean(),
|
|
333
|
+
description: "Indicates if the product has a role.",
|
|
334
|
+
required: false
|
|
335
|
+
}
|
|
336
|
+
],
|
|
151
337
|
}, async (args, _extra) => {
|
|
152
|
-
const
|
|
338
|
+
const createProductArgs = args;
|
|
339
|
+
const response = await this.createPortalProduct(createProductArgs.portalId, createProductArgs);
|
|
153
340
|
return {
|
|
154
341
|
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
155
342
|
};
|
|
156
343
|
});
|
|
157
|
-
|
|
158
|
-
|
|
344
|
+
register({
|
|
345
|
+
title: "Get Portal Product",
|
|
346
|
+
summary: "Retrieve information about a specific product resource.",
|
|
347
|
+
parameters: [
|
|
348
|
+
{
|
|
349
|
+
name: "productId",
|
|
350
|
+
type: z.string(),
|
|
351
|
+
description: "Product UUID, or identifier in the format.",
|
|
352
|
+
required: true
|
|
353
|
+
}
|
|
354
|
+
],
|
|
355
|
+
}, async (args, _extra) => {
|
|
356
|
+
const productArgs = args;
|
|
357
|
+
const response = await this.getPortalProduct(productArgs.productId);
|
|
159
358
|
return {
|
|
160
359
|
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
161
360
|
};
|
|
162
361
|
});
|
|
163
|
-
|
|
164
|
-
|
|
362
|
+
register({
|
|
363
|
+
title: "Delete Portal Product",
|
|
364
|
+
summary: "Delete a product from a specific portal",
|
|
365
|
+
parameters: [
|
|
366
|
+
{
|
|
367
|
+
name: "productId",
|
|
368
|
+
type: z.string(),
|
|
369
|
+
description: "Product UUID, or identifier in the format.",
|
|
370
|
+
required: true
|
|
371
|
+
}
|
|
372
|
+
],
|
|
373
|
+
}, async (args, _extra) => {
|
|
374
|
+
const productArgs = args;
|
|
375
|
+
await this.deletePortalProduct(productArgs.productId);
|
|
165
376
|
return {
|
|
166
377
|
content: [{ type: "text", text: "Product deleted successfully." }],
|
|
167
378
|
};
|
|
168
379
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
380
|
+
register({
|
|
381
|
+
title: "Update Portal Product",
|
|
382
|
+
summary: "Update a product's settings within a specific portal.",
|
|
383
|
+
parameters: [
|
|
384
|
+
{
|
|
385
|
+
name: "productId",
|
|
386
|
+
type: z.string(),
|
|
387
|
+
description: "Product UUID, or identifier in the format.",
|
|
388
|
+
required: true
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
name: "name",
|
|
392
|
+
type: z.string(),
|
|
393
|
+
description: "Product name.",
|
|
394
|
+
required: false
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
name: "slug",
|
|
398
|
+
type: z.string(),
|
|
399
|
+
description: "URL component for this product. Must be unique within the portal.",
|
|
400
|
+
required: false
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
name: "description",
|
|
404
|
+
type: z.string(),
|
|
405
|
+
description: "Product description.",
|
|
406
|
+
required: false
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
name: "public",
|
|
410
|
+
type: z.boolean(),
|
|
411
|
+
description: "Indicates if the product is public.",
|
|
412
|
+
required: false
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
name: "hidden",
|
|
416
|
+
type: z.string(),
|
|
417
|
+
description: "Indicates if the product is hidden.",
|
|
418
|
+
required: false
|
|
419
|
+
}
|
|
420
|
+
],
|
|
176
421
|
}, async (args, _extra) => {
|
|
177
|
-
const
|
|
422
|
+
const updateProductArgs = args;
|
|
423
|
+
const response = await this.updatePortalProduct(updateProductArgs.productId, updateProductArgs);
|
|
178
424
|
return {
|
|
179
425
|
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
180
426
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { BaseAPI, pickFieldsFromArray } from './base.js';
|
|
2
2
|
// --- API Class ---
|
|
3
3
|
export class CurrentUserAPI extends BaseAPI {
|
|
4
|
+
static filterFields = ["collaborators_url", "projects_url", "upgrade_url"];
|
|
4
5
|
static organizationFields = ['id', 'name', 'slug'];
|
|
5
6
|
static projectFields = ['id', 'name', 'slug', 'api_key'];
|
|
6
7
|
constructor(configuration) {
|
|
7
|
-
super(configuration);
|
|
8
|
+
super(configuration, CurrentUserAPI.filterFields);
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
11
|
* List the current user's organizations
|