@testomatio/mcp 1.0.7 → 1.0.8
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 +6 -6
- package/index.js +49 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ A Model Context Protocol (MCP) server for Testomat.io API integration with AI as
|
|
|
13
13
|
### Run directly with npx
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
npx @testomatio/mcp --token <your-token> --project <project-id>
|
|
16
|
+
npx @testomatio/mcp@latest --token <your-token> --project <project-id>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
@@ -26,13 +26,13 @@ The MCP server can be started using command line arguments or environment variab
|
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
# Using short flags
|
|
29
|
-
npx @testomatio/mcp -t testomat_YOUR_TOKEN_HERE -p your-project-id
|
|
29
|
+
npx @testomatio/mcp@latest -t testomat_YOUR_TOKEN_HERE -p your-project-id
|
|
30
30
|
|
|
31
31
|
# Using long flags
|
|
32
|
-
npx @testomatio/mcp --token testomat_YOUR_TOKEN_HERE --project your-project-id
|
|
32
|
+
npx @testomatio/mcp@latest --token testomat_YOUR_TOKEN_HERE --project your-project-id
|
|
33
33
|
|
|
34
34
|
# With custom base URL
|
|
35
|
-
npx @testomatio/mcp --token testomat_YOUR_TOKEN_HERE --project your-project-id --base-url https://your-instance.testomat.io
|
|
35
|
+
npx @testomatio/mcp@latest --token testomat_YOUR_TOKEN_HERE --project your-project-id --base-url https://your-instance.testomat.io
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
#### Using Environment Variables
|
|
@@ -43,10 +43,10 @@ export TESTOMATIO_API_TOKEN=testomat_YOUR_TOKEN_HERE
|
|
|
43
43
|
export TESTOMATIO_BASE_URL=https://app.testomat.io # Optional, defaults to https://app.testomat.io
|
|
44
44
|
|
|
45
45
|
# Run with project ID
|
|
46
|
-
npx @testomatio/mcp --project your-project-id
|
|
46
|
+
npx @testomatio/mcp@latest --project your-project-id
|
|
47
47
|
|
|
48
48
|
# Or run directly with environment variables
|
|
49
|
-
TESTOMATIO_API_TOKEN=testomat_YOUR_TOKEN_HERE npx @testomatio/mcp --project your-project-id
|
|
49
|
+
TESTOMATIO_API_TOKEN=testomat_YOUR_TOKEN_HERE npx @testomatio/mcp@latest --project your-project-id
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
### Getting Your API Token
|
package/index.js
CHANGED
|
@@ -643,7 +643,8 @@ class TestomatioMCPServer {
|
|
|
643
643
|
this.jwtToken = null;
|
|
644
644
|
return this.makePostRequest(path, data);
|
|
645
645
|
}
|
|
646
|
-
|
|
646
|
+
const errorText = await response.text();
|
|
647
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}. Details: ${errorText}`);
|
|
647
648
|
}
|
|
648
649
|
|
|
649
650
|
return await response.json();
|
|
@@ -667,7 +668,8 @@ class TestomatioMCPServer {
|
|
|
667
668
|
this.jwtToken = null;
|
|
668
669
|
return this.makePutRequest(path, data);
|
|
669
670
|
}
|
|
670
|
-
|
|
671
|
+
const errorText = await response.text();
|
|
672
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}. Details: ${errorText}`);
|
|
671
673
|
}
|
|
672
674
|
|
|
673
675
|
return await response.json();
|
|
@@ -1073,29 +1075,24 @@ class TestomatioMCPServer {
|
|
|
1073
1075
|
async createTest(args) {
|
|
1074
1076
|
const { suite_id, labels_ids, fields, ...attributes } = args;
|
|
1075
1077
|
|
|
1076
|
-
//
|
|
1077
|
-
const
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
attributes: {
|
|
1081
|
-
...Object.fromEntries(Object.entries(attributes).map(([k, v]) => [k.replace(/_/g, '-'), v])),
|
|
1082
|
-
...(fields && { 'custom-fields': fields })
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
};
|
|
1078
|
+
// Convert attributes to use hyphens instead of underscores for API compatibility
|
|
1079
|
+
const apiAttributes = Object.fromEntries(
|
|
1080
|
+
Object.entries(attributes).map(([k, v]) => [k.replace(/_/g, '-'), v])
|
|
1081
|
+
);
|
|
1086
1082
|
|
|
1083
|
+
// Add suite_id to attributes if provided
|
|
1087
1084
|
if (suite_id) {
|
|
1088
|
-
|
|
1089
|
-
suite: {
|
|
1090
|
-
data: {
|
|
1091
|
-
type: 'suites',
|
|
1092
|
-
id: suite_id
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
};
|
|
1085
|
+
apiAttributes['suite_id'] = suite_id;
|
|
1096
1086
|
}
|
|
1097
1087
|
|
|
1098
|
-
|
|
1088
|
+
// Handle fields parameter for custom fields
|
|
1089
|
+
const requestData = {
|
|
1090
|
+
test: {
|
|
1091
|
+
...apiAttributes,
|
|
1092
|
+
...(labels_ids && { labels_ids: labels_ids }),
|
|
1093
|
+
...(fields && { custom_fields: fields })
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1099
1096
|
|
|
1100
1097
|
const data = await this.makePostRequest('/tests', requestData);
|
|
1101
1098
|
const formattedTest = this.formatModel(data.data, 'test', [
|
|
@@ -1116,31 +1113,43 @@ class TestomatioMCPServer {
|
|
|
1116
1113
|
async updateTest(args) {
|
|
1117
1114
|
const { test_id, suite_id, labels_ids, fields, ...attributes } = args;
|
|
1118
1115
|
|
|
1119
|
-
//
|
|
1120
|
-
const
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
attributes: {
|
|
1124
|
-
...Object.fromEntries(Object.entries(attributes).map(([k, v]) => [k.replace(/_/g, '-'), v])),
|
|
1125
|
-
...(fields && { 'custom-fields': fields })
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
};
|
|
1116
|
+
// Convert attributes to use hyphens instead of underscores for API compatibility
|
|
1117
|
+
const apiAttributes = Object.fromEntries(
|
|
1118
|
+
Object.entries(attributes).map(([k, v]) => [k.replace(/_/g, '-'), v])
|
|
1119
|
+
);
|
|
1129
1120
|
|
|
1121
|
+
// Add suite_id to attributes if provided
|
|
1130
1122
|
if (suite_id) {
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1123
|
+
apiAttributes['suite_id'] = suite_id;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
let data;
|
|
1127
|
+
|
|
1128
|
+
// Handle labels_ids using the bulk labels endpoint
|
|
1129
|
+
if (labels_ids && labels_ids.length > 0) {
|
|
1130
|
+
const labelsRequest = {
|
|
1131
|
+
items: {
|
|
1132
|
+
test: [test_id]
|
|
1133
|
+
},
|
|
1134
|
+
add_labels: labels_ids
|
|
1135
|
+
};
|
|
1136
|
+
|
|
1137
|
+
await this.makePutRequest('/bulk/labels', labelsRequest);
|
|
1138
|
+
|
|
1139
|
+
// After updating labels, fetch the updated test
|
|
1140
|
+
data = await this.makeRequest(`/tests/${test_id}`);
|
|
1141
|
+
} else {
|
|
1142
|
+
// Handle regular test attributes update
|
|
1143
|
+
const requestData = {
|
|
1144
|
+
test: {
|
|
1145
|
+
...apiAttributes,
|
|
1146
|
+
...(fields && { custom_fields: fields })
|
|
1137
1147
|
}
|
|
1138
1148
|
};
|
|
1139
|
-
}
|
|
1140
1149
|
|
|
1141
|
-
|
|
1150
|
+
data = await this.makePutRequest(`/tests/${test_id}`, requestData);
|
|
1151
|
+
}
|
|
1142
1152
|
|
|
1143
|
-
const data = await this.makePutRequest(`/tests/${test_id}`, requestData);
|
|
1144
1153
|
const formattedTest = this.formatModel(data.data, 'test', [
|
|
1145
1154
|
'title', 'description', 'code', 'priority',
|
|
1146
1155
|
'state', 'suite-id', 'tags', 'file'
|