@smartbear/mcp 0.17.0 → 0.18.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/bugsnag/client.js +43 -4
- package/dist/collaborator/client.js +15 -4
- package/dist/common/request-context.js +20 -0
- package/dist/common/server.js +3 -0
- package/dist/common/transport-http.js +77 -14
- package/dist/common/transport-stdio.js +1 -0
- package/dist/package.json.js +1 -1
- package/dist/pactflow/client/base.js +433 -2
- package/dist/pactflow/client/tools.js +765 -1
- package/dist/pactflow/client.js +1698 -19
- package/dist/qmetry/client.js +10 -2
- package/dist/reflect/client.js +26 -12
- package/dist/reflect/tool/recording/connect-to-session.js +1 -0
- package/dist/swagger/client/api.js +5 -2
- package/dist/swagger/client/configuration.js +15 -7
- package/dist/swagger/client.js +16 -2
- package/dist/zephyr/client.js +16 -2
- package/dist/zephyr/common/api-client.js +20 -6
- package/package.json +1 -1
package/dist/qmetry/client.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import zod__default from "zod";
|
|
2
|
+
import { getRequestHeader } from "../common/request-context.js";
|
|
2
3
|
import { findAutoResolveConfig, autoResolveViewIdAndFolderPath } from "./client/auto-resolve.js";
|
|
3
4
|
import { QMETRY_HANDLER_MAP } from "./client/handlers.js";
|
|
4
5
|
import { getProjectInfo } from "./client/project.js";
|
|
5
6
|
import { TOOLS } from "./client/tools/index.js";
|
|
6
7
|
import { QMETRY_DEFAULTS } from "./config/constants.js";
|
|
7
8
|
const ConfigurationSchema = zod__default.object({
|
|
8
|
-
api_key: zod__default.string().describe("QMetry API key for authentication"),
|
|
9
|
+
api_key: zod__default.string().describe("QMetry API key for authentication").optional(),
|
|
9
10
|
base_url: zod__default.string().url().optional().describe(
|
|
10
11
|
"Optional QMetry base URL for custom or region-specific endpoints"
|
|
11
12
|
)
|
|
@@ -25,9 +26,16 @@ class QmetryClient {
|
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
isConfigured() {
|
|
28
|
-
return
|
|
29
|
+
return true;
|
|
29
30
|
}
|
|
30
31
|
getToken() {
|
|
32
|
+
let contextToken = getRequestHeader("Qmetry-Token") || getRequestHeader("apikey");
|
|
33
|
+
if (Array.isArray(contextToken)) {
|
|
34
|
+
contextToken = contextToken[0];
|
|
35
|
+
}
|
|
36
|
+
if (contextToken) {
|
|
37
|
+
return contextToken;
|
|
38
|
+
}
|
|
31
39
|
if (!this.token) throw new Error("Client not configured");
|
|
32
40
|
return this.token;
|
|
33
41
|
}
|
package/dist/reflect/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
|
|
3
|
+
import { getRequestHeader } from "../common/request-context.js";
|
|
3
4
|
import { ToolError } from "../common/tools.js";
|
|
4
5
|
import { API_KEY_HEADER } from "./config/constants.js";
|
|
5
6
|
import { SapTest } from "./prompt/sap-test.js";
|
|
@@ -18,11 +19,10 @@ import { ListSegments } from "./tool/tests/list-segments.js";
|
|
|
18
19
|
import { ListTests } from "./tool/tests/list-tests.js";
|
|
19
20
|
import { RunTest } from "./tool/tests/run-test.js";
|
|
20
21
|
const ConfigurationSchema = z.object({
|
|
21
|
-
api_token: z.string().describe("Reflect API authentication token")
|
|
22
|
+
api_token: z.string().describe("Reflect API authentication token").optional()
|
|
22
23
|
});
|
|
23
24
|
class ReflectClient {
|
|
24
|
-
|
|
25
|
-
apiToken = "";
|
|
25
|
+
_apiToken;
|
|
26
26
|
activeConnections = /* @__PURE__ */ new Map();
|
|
27
27
|
sessionStates = /* @__PURE__ */ new Map();
|
|
28
28
|
mcpSessionConnections = /* @__PURE__ */ new Map();
|
|
@@ -31,21 +31,35 @@ class ReflectClient {
|
|
|
31
31
|
configPrefix = "Reflect";
|
|
32
32
|
config = ConfigurationSchema;
|
|
33
33
|
async configure(_server, config, _cache) {
|
|
34
|
-
this.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
this._apiToken = config.api_token;
|
|
35
|
+
}
|
|
36
|
+
getAuthToken() {
|
|
37
|
+
const contextHeader = getRequestHeader("Reflect-Api-Token") || getRequestHeader("X-API-KEY") || getRequestHeader("Authorization");
|
|
38
|
+
if (contextHeader) {
|
|
39
|
+
let token = Array.isArray(contextHeader) ? contextHeader[0] : contextHeader;
|
|
40
|
+
if (token.startsWith("Bearer ")) {
|
|
41
|
+
token = token.substring(7);
|
|
42
|
+
}
|
|
43
|
+
return token;
|
|
44
|
+
}
|
|
45
|
+
return this._apiToken || null;
|
|
40
46
|
}
|
|
41
47
|
isConfigured() {
|
|
42
|
-
return
|
|
48
|
+
return true;
|
|
43
49
|
}
|
|
44
50
|
getApiToken() {
|
|
45
|
-
return this.
|
|
51
|
+
return this.getAuthToken() || "";
|
|
46
52
|
}
|
|
47
53
|
getHeaders() {
|
|
48
|
-
|
|
54
|
+
const token = this.getAuthToken();
|
|
55
|
+
if (!token) {
|
|
56
|
+
throw new Error("Reflect API token not found");
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
[API_KEY_HEADER]: token,
|
|
60
|
+
"Content-Type": "application/json",
|
|
61
|
+
"User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
|
|
62
|
+
};
|
|
49
63
|
}
|
|
50
64
|
getSessionState(sessionId) {
|
|
51
65
|
return this.sessionStates.get(sessionId);
|
|
@@ -30,6 +30,7 @@ class ConnectToSession extends Tool {
|
|
|
30
30
|
if (!sessionId) throw new ToolError("sessionId argument is required");
|
|
31
31
|
if (this.client.isSessionConnected(sessionId)) {
|
|
32
32
|
const state = this.client.getSessionState(sessionId);
|
|
33
|
+
if (!state) throw new ToolError("Failed to get session state");
|
|
33
34
|
const { platform: platform2, test: test2 } = state;
|
|
34
35
|
return {
|
|
35
36
|
content: [
|
|
@@ -11,10 +11,13 @@ function hasErrorsFound(value) {
|
|
|
11
11
|
}
|
|
12
12
|
class SwaggerAPI {
|
|
13
13
|
config;
|
|
14
|
-
|
|
14
|
+
userAgent;
|
|
15
15
|
constructor(config, userAgent) {
|
|
16
16
|
this.config = config;
|
|
17
|
-
this.
|
|
17
|
+
this.userAgent = userAgent;
|
|
18
|
+
}
|
|
19
|
+
get headers() {
|
|
20
|
+
return this.config.getHeaders(this.userAgent);
|
|
18
21
|
}
|
|
19
22
|
/**
|
|
20
23
|
* Core response parsing logic shared between different response handlers.
|
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
class SwaggerConfiguration {
|
|
2
|
-
|
|
2
|
+
tokenProvider;
|
|
3
3
|
portalBasePath;
|
|
4
4
|
registryBasePath;
|
|
5
5
|
uiBasePath;
|
|
6
6
|
userManagementBasePath;
|
|
7
|
-
|
|
7
|
+
defaultHeaders;
|
|
8
8
|
constructor(param) {
|
|
9
|
-
|
|
9
|
+
if (typeof param.token === "string") {
|
|
10
|
+
this.tokenProvider = () => param.token;
|
|
11
|
+
} else {
|
|
12
|
+
this.tokenProvider = param.token;
|
|
13
|
+
}
|
|
10
14
|
this.portalBasePath = param.portalBasePath || "https://api.portal.swaggerhub.com/v1";
|
|
11
15
|
this.registryBasePath = param.registryBasePath || "https://api.swaggerhub.com";
|
|
12
16
|
this.uiBasePath = param.uiBasePath || "https://app.swaggerhub.com";
|
|
13
17
|
this.userManagementBasePath = param.userManagementBasePath || `${this.registryBasePath}/user-management/v1`;
|
|
14
|
-
this.
|
|
15
|
-
Authorization: `Bearer ${this.token}`,
|
|
18
|
+
this.defaultHeaders = {
|
|
16
19
|
"Content-Type": "application/json",
|
|
17
20
|
...param.headers
|
|
18
21
|
};
|
|
19
22
|
}
|
|
20
23
|
/**
|
|
21
|
-
* Get headers with User-Agent included
|
|
24
|
+
* Get headers with User-Agent included and dynamic Auth token
|
|
22
25
|
*/
|
|
23
26
|
getHeaders(userAgent) {
|
|
27
|
+
const token = this.tokenProvider();
|
|
28
|
+
if (!token) {
|
|
29
|
+
throw new Error("Swagger API token not found");
|
|
30
|
+
}
|
|
24
31
|
return {
|
|
25
|
-
|
|
32
|
+
Authorization: `Bearer ${token}`,
|
|
33
|
+
...this.defaultHeaders,
|
|
26
34
|
"User-Agent": userAgent
|
|
27
35
|
};
|
|
28
36
|
}
|
package/dist/swagger/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
|
|
3
|
+
import { getRequestHeader } from "../common/request-context.js";
|
|
3
4
|
import "./config-utils.js";
|
|
4
5
|
import { SwaggerAPI } from "./client/api.js";
|
|
5
6
|
import { SwaggerConfiguration } from "./client/configuration.js";
|
|
@@ -8,21 +9,23 @@ import "./client/registry-types.js";
|
|
|
8
9
|
import { TOOLS } from "./client/tools.js";
|
|
9
10
|
import "./client/user-management-types.js";
|
|
10
11
|
const ConfigurationSchema = z.object({
|
|
11
|
-
api_key: z.string().describe("Swagger API key for authentication"),
|
|
12
|
+
api_key: z.string().describe("Swagger API key for authentication").optional(),
|
|
12
13
|
portal_base_path: z.string().optional().describe("Base path for Portal API requests (optional)"),
|
|
13
14
|
registry_base_path: z.string().optional().describe("Base path for Registry API requests (optional)"),
|
|
14
15
|
ui_base_path: z.string().optional().describe("Base URL for the SwaggerHub UI (optional)")
|
|
15
16
|
});
|
|
16
17
|
class SwaggerClient {
|
|
17
18
|
api;
|
|
19
|
+
_apiKey;
|
|
18
20
|
name = "Swagger";
|
|
19
21
|
toolPrefix = "swagger";
|
|
20
22
|
configPrefix = "Swagger";
|
|
21
23
|
config = ConfigurationSchema;
|
|
22
24
|
async configure(_server, config, _cache) {
|
|
25
|
+
this._apiKey = config.api_key;
|
|
23
26
|
this.api = new SwaggerAPI(
|
|
24
27
|
new SwaggerConfiguration({
|
|
25
|
-
token:
|
|
28
|
+
token: () => this.getAuthToken(),
|
|
26
29
|
portalBasePath: config.portal_base_path,
|
|
27
30
|
registryBasePath: config.registry_base_path,
|
|
28
31
|
uiBasePath: config.ui_base_path
|
|
@@ -30,6 +33,17 @@ class SwaggerClient {
|
|
|
30
33
|
`${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
|
|
31
34
|
);
|
|
32
35
|
}
|
|
36
|
+
getAuthToken() {
|
|
37
|
+
const contextHeader = getRequestHeader("Swagger-Api-Key") || getRequestHeader("Authorization");
|
|
38
|
+
if (contextHeader) {
|
|
39
|
+
let token = Array.isArray(contextHeader) ? contextHeader[0] : contextHeader;
|
|
40
|
+
if (token.startsWith("Bearer ")) {
|
|
41
|
+
token = token.substring(7);
|
|
42
|
+
}
|
|
43
|
+
return token;
|
|
44
|
+
}
|
|
45
|
+
return this._apiKey || null;
|
|
46
|
+
}
|
|
33
47
|
isConfigured() {
|
|
34
48
|
return this.api !== void 0;
|
|
35
49
|
}
|
package/dist/zephyr/client.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import zod__default from "zod";
|
|
2
|
+
import { getRequestHeader } from "../common/request-context.js";
|
|
2
3
|
import { ApiClient } from "./common/api-client.js";
|
|
3
4
|
import { GetEnvironments } from "./tool/environment/get-environments.js";
|
|
4
5
|
import { CreateFolder } from "./tool/folder/create-folder.js";
|
|
@@ -37,21 +38,34 @@ import { UpdateTestExecution } from "./tool/test-execution/update-test-execution
|
|
|
37
38
|
import { UpdateTestExecutionSteps } from "./tool/test-execution/update-test-steps.js";
|
|
38
39
|
const BASE_URL_DEFAULT = "https://api.zephyrscale.smartbear.com/v2";
|
|
39
40
|
const ConfigurationSchema = zod__default.object({
|
|
40
|
-
api_token: zod__default.string().describe("Zephyr Scale API token for authentication"),
|
|
41
|
+
api_token: zod__default.string().describe("Zephyr Scale API token for authentication").optional(),
|
|
41
42
|
base_url: zod__default.string().url().optional().describe("Zephyr Scale API base URL").default(BASE_URL_DEFAULT)
|
|
42
43
|
});
|
|
43
44
|
class ZephyrClient {
|
|
44
45
|
apiClient;
|
|
46
|
+
_apiToken;
|
|
45
47
|
name = "Zephyr";
|
|
46
48
|
toolPrefix = "zephyr";
|
|
47
49
|
configPrefix = "Zephyr";
|
|
48
50
|
config = ConfigurationSchema;
|
|
49
51
|
async configure(_server, config, _cache) {
|
|
52
|
+
this._apiToken = config.api_token;
|
|
50
53
|
this.apiClient = new ApiClient(
|
|
51
|
-
|
|
54
|
+
() => this.getAuthToken(),
|
|
52
55
|
config.base_url || BASE_URL_DEFAULT
|
|
53
56
|
);
|
|
54
57
|
}
|
|
58
|
+
getAuthToken() {
|
|
59
|
+
const contextHeader = getRequestHeader("Zephyr-Api-Token") || getRequestHeader("Authorization");
|
|
60
|
+
if (contextHeader) {
|
|
61
|
+
let token = Array.isArray(contextHeader) ? contextHeader[0] : contextHeader;
|
|
62
|
+
if (token.startsWith("Bearer ")) {
|
|
63
|
+
token = token.substring(7);
|
|
64
|
+
}
|
|
65
|
+
return token;
|
|
66
|
+
}
|
|
67
|
+
return this._apiToken || null;
|
|
68
|
+
}
|
|
55
69
|
isConfigured() {
|
|
56
70
|
return this.apiClient !== void 0;
|
|
57
71
|
}
|
|
@@ -2,10 +2,24 @@ import { ToolError } from "../../common/tools.js";
|
|
|
2
2
|
import { AuthService } from "./auth-service.js";
|
|
3
3
|
class ApiClient {
|
|
4
4
|
baseUrl;
|
|
5
|
-
|
|
6
|
-
constructor(
|
|
5
|
+
tokenProvider;
|
|
6
|
+
constructor(tokenOrProvider, baseUrl) {
|
|
7
7
|
this.baseUrl = baseUrl.trim().replace(/\/$/, "");
|
|
8
|
-
|
|
8
|
+
if (typeof tokenOrProvider === "string") {
|
|
9
|
+
this.tokenProvider = () => tokenOrProvider;
|
|
10
|
+
} else {
|
|
11
|
+
this.tokenProvider = tokenOrProvider;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
get defaultHeaders() {
|
|
15
|
+
return this.getHeaders();
|
|
16
|
+
}
|
|
17
|
+
getHeaders() {
|
|
18
|
+
const token = this.tokenProvider();
|
|
19
|
+
if (!token) {
|
|
20
|
+
throw new ToolError("Zephyr API token not found");
|
|
21
|
+
}
|
|
22
|
+
return new AuthService(token).getAuthHeaders();
|
|
9
23
|
}
|
|
10
24
|
getUrl(endpoint, params) {
|
|
11
25
|
const url = new URL(this.baseUrl + endpoint);
|
|
@@ -21,7 +35,7 @@ class ApiClient {
|
|
|
21
35
|
async get(endpoint, params) {
|
|
22
36
|
const response = await fetch(this.getUrl(endpoint, params), {
|
|
23
37
|
method: "GET",
|
|
24
|
-
headers: this.
|
|
38
|
+
headers: this.getHeaders()
|
|
25
39
|
});
|
|
26
40
|
return await this.validateAndGetResponseBody(response);
|
|
27
41
|
}
|
|
@@ -29,7 +43,7 @@ class ApiClient {
|
|
|
29
43
|
const response = await fetch(this.getUrl(endpoint), {
|
|
30
44
|
method: "POST",
|
|
31
45
|
headers: {
|
|
32
|
-
...this.
|
|
46
|
+
...this.getHeaders(),
|
|
33
47
|
"Content-Type": "application/json"
|
|
34
48
|
},
|
|
35
49
|
body: JSON.stringify(body)
|
|
@@ -40,7 +54,7 @@ class ApiClient {
|
|
|
40
54
|
const response = await fetch(this.getUrl(endpoint), {
|
|
41
55
|
method: "PUT",
|
|
42
56
|
headers: {
|
|
43
|
-
...this.
|
|
57
|
+
...this.getHeaders(),
|
|
44
58
|
"Content-Type": "application/json"
|
|
45
59
|
},
|
|
46
60
|
body: JSON.stringify(body)
|