@testomatio/mcp 2.0.0 → 2.0.1-beta.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 +76 -13
- package/package.json +3 -2
- package/src/api/http-client.js +12 -3
- package/src/api/testomatio-client.js +89 -8
- package/src/index.js +23 -2
- package/src/mcp/configs/entity-crud-config.js +12 -4
- package/src/mcp/definitions/labels.js +0 -25
- package/src/mcp/definitions/milestones.js +43 -0
- package/src/mcp/definitions/plans.js +38 -2
- package/src/mcp/definitions/requirements.js +163 -0
- package/src/mcp/definitions/rungroups.js +0 -25
- package/src/mcp/definitions/runs.js +18 -18
- package/src/mcp/definitions/snippets.js +2 -25
- package/src/mcp/definitions/steps.js +2 -25
- package/src/mcp/definitions/suites.js +6 -8
- package/src/mcp/definitions/testruns.js +194 -2
- package/src/mcp/definitions/tests.js +12 -36
- package/src/mcp/definitions/tql-reference.js +133 -0
- package/src/mcp/registry/handlers.js +17 -2
- package/src/mcp/registry/listings.js +101 -43
- package/src/mcp/registry/payloads.js +89 -8
- package/src/mcp/server.js +47 -4
- package/src/mcp/tool-definitions.js +4 -0
- package/src/mcp/tool-registry.js +7 -2
package/README.md
CHANGED
|
@@ -6,12 +6,16 @@ Model Context Protocol (MCP) server that enables AI assistants (Claude, Cursor,
|
|
|
6
6
|
|
|
7
7
|
- **Full CRUD** for core entities:
|
|
8
8
|
- Tests, Suites, Plans, Runs, TestRuns, RunGroups, Steps, Snippets, Labels
|
|
9
|
-
- Tags (read-only access)
|
|
9
|
+
- Tags and Milestones (read-only access)
|
|
10
10
|
- Issues (global + scoped helpers for tests/suites/runs/testruns/plans)
|
|
11
|
-
-
|
|
11
|
+
- Requirements (including file uploads from local file paths)
|
|
12
|
+
- **Smart Search** - delegates to list endpoints with OpenAPI-aligned query/filter forwarding
|
|
12
13
|
- **Issue Linking** - link/unlink issues to any resource
|
|
13
14
|
- **API Compatibility** - automatic handling of payload format differences (flat vs wrapped)
|
|
15
|
+
- **Automatic API Sessions** - groups MCP changes in Testomat.io history using API sessions
|
|
14
16
|
- **Run Management** - status transitions via `status_event` parameter
|
|
17
|
+
- **TQL-Only Search** - `tests_list/tests_search` and `runs_list/runs_search` use `tql` as the single search/filter input
|
|
18
|
+
- **Built-In TQL Reference** - MCP tool descriptions include exact TQL fields, syntax, and examples for agents
|
|
15
19
|
|
|
16
20
|
## Quick Start
|
|
17
21
|
|
|
@@ -21,6 +25,8 @@ Model Context Protocol (MCP) server that enables AI assistants (Claude, Cursor,
|
|
|
21
25
|
npm install -g @testomatio/mcp@latest
|
|
22
26
|
```
|
|
23
27
|
|
|
28
|
+
Need enterprise analytics tools? Install `@testomatio/mcp-enterprise@latest` instead. Details are in the `Enterprise Analytics` section below.
|
|
29
|
+
|
|
24
30
|
### Configuration
|
|
25
31
|
|
|
26
32
|
**Required credentials:**
|
|
@@ -133,7 +139,7 @@ Add this config to `opencode.json` in your project root, or to `~/.config/openco
|
|
|
133
139
|
```json
|
|
134
140
|
{
|
|
135
141
|
"name": "tests_list",
|
|
136
|
-
"arguments": { "page": 1, "per_page": 50 }
|
|
142
|
+
"arguments": { "page": 1, "per_page": 50, "tql": "priority == 'high'" }
|
|
137
143
|
}
|
|
138
144
|
```
|
|
139
145
|
|
|
@@ -178,16 +184,16 @@ Complete tool reference: [docs/tools.md](./docs/tools.md)
|
|
|
178
184
|
|
|
179
185
|
## Project Structure
|
|
180
186
|
|
|
181
|
-
```
|
|
187
|
+
```text
|
|
182
188
|
src/
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
|- config/ # Config loading, defaults
|
|
190
|
+
|- core/ # Errors, logger
|
|
191
|
+
|- api/ # HTTP client, Testomat.io API client
|
|
192
|
+
|- mcp/ # MCP server, tools, registry
|
|
193
|
+
| |- definitions/ # Tool definitions by entity
|
|
194
|
+
| |- configs/ # Registry generation configs
|
|
195
|
+
| `- registry/ # Tool handlers
|
|
196
|
+
`- cli/ # CLI bootstrap
|
|
191
197
|
```
|
|
192
198
|
|
|
193
199
|
## Environment Variables
|
|
@@ -236,8 +242,13 @@ NODE_EXTRA_CA_CERTS=/path/to/company-root-ca.pem testomatio-mcp --token <TOKEN>
|
|
|
236
242
|
## Important Notes
|
|
237
243
|
|
|
238
244
|
- **Run Status** - Use `runs_update` with `status_event` for transitions (finish, launch, rerun, etc.)
|
|
239
|
-
- **Search** - No dedicated `/search` endpoints
|
|
245
|
+
- **Search** - No dedicated `/search` endpoints. MCP search tools delegate to list tools; for `tests` and `runs` the MCP interface is intentionally simplified to `tql`, while other entities stay closer to Public API v2 filters
|
|
246
|
+
- **TQL** - Use `tql` as the single search/filter input for `tests_list/tests_search` and `runs_list/runs_search`
|
|
247
|
+
- **TQL Syntax** - For user-facing syntax details and more examples, see the official TQL docs: https://docs.testomat.io/advanced/tql/
|
|
248
|
+
- **TQL Scope** - The full agent-oriented whitelist of documented fields lives inside MCP tool descriptions for `tests` and `runs`
|
|
240
249
|
- **Issue Linking** - Scoped helpers available: `{entity}_issues_link/unlink`
|
|
250
|
+
- **Enterprise Package** - Analytics tools are intentionally exposed only by `@testomatio/mcp-enterprise`, not by the standard `@testomatio/mcp` package
|
|
251
|
+
- **API Sessions** - The server automatically starts a Testomat.io session before the first `POST`, `PUT`, or `DELETE` request, sends the returned session hash as `X-Session-Hash` on later mutating requests, and stops the session when the MCP server shuts down. `GET` requests do not start or use sessions.
|
|
241
252
|
|
|
242
253
|
## Development
|
|
243
254
|
|
|
@@ -258,3 +269,55 @@ For local MCP development, point Claude Desktop to the checked-out entrypoint:
|
|
|
258
269
|
}
|
|
259
270
|
}
|
|
260
271
|
```
|
|
272
|
+
|
|
273
|
+
## Enterprise Analytics
|
|
274
|
+
|
|
275
|
+
Enterprise analytics is available only in the separate `@testomatio/mcp-enterprise` package.
|
|
276
|
+
|
|
277
|
+
Installation:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
npm install -g @testomatio/mcp-enterprise@latest
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Run:
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
testomatio-mcp-enterprise --token <PROJECT_TOKEN> --project <PROJECT_ID>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Included tools:
|
|
290
|
+
|
|
291
|
+
- `analytics_tests` - `GET /api/v2/{project_id}/analytics/tests/{kind}`
|
|
292
|
+
- `analytics_stats` - `GET /api/v2/{project_id}/analytics/stats/{kind}`
|
|
293
|
+
|
|
294
|
+
Analytics endpoints require the `api_analytics` subscription feature. Use `q` as the TQL filter parameter for analytics tools.
|
|
295
|
+
|
|
296
|
+
Example `analytics_tests` call:
|
|
297
|
+
|
|
298
|
+
```json
|
|
299
|
+
{
|
|
300
|
+
"name": "analytics_tests",
|
|
301
|
+
"arguments": {
|
|
302
|
+
"kind": "flaky",
|
|
303
|
+
"q": "priority == 'high'",
|
|
304
|
+
"days": 30,
|
|
305
|
+
"page": 1,
|
|
306
|
+
"per_page": 20
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Example `analytics_stats` call:
|
|
312
|
+
|
|
313
|
+
```json
|
|
314
|
+
{
|
|
315
|
+
"name": "analytics_stats",
|
|
316
|
+
"arguments": {
|
|
317
|
+
"kind": "success-rate-by-date",
|
|
318
|
+
"q": "tag IN ['@smoke']",
|
|
319
|
+
"from": "2026-04-01",
|
|
320
|
+
"to": "2026-04-30"
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testomatio/mcp",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1-beta.1",
|
|
4
4
|
"description": "Model Context Protocol server for Testomatio API",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "node index.js",
|
|
12
|
-
"dev": "node index.js"
|
|
12
|
+
"dev": "node index.js",
|
|
13
|
+
"sync:enterprise-package": "node scripts/sync-enterprise-package.js"
|
|
13
14
|
},
|
|
14
15
|
"keywords": [
|
|
15
16
|
"testomatio",
|
package/src/api/http-client.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ApiError } from '../core/errors.js';
|
|
2
2
|
|
|
3
|
+
function isFormData(body) {
|
|
4
|
+
return typeof FormData !== 'undefined' && body instanceof FormData;
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
function buildUrl(baseUrl, path, query = {}) {
|
|
4
8
|
const url = new URL(path, `${baseUrl}/`);
|
|
5
9
|
|
|
@@ -26,12 +30,13 @@ export class HttpClient {
|
|
|
26
30
|
this.logger = logger;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
async request(method, path, { query, body } = {}) {
|
|
33
|
+
async request(method, path, { query, body, headers: requestHeaders = {} } = {}) {
|
|
30
34
|
const url = buildUrl(this.baseUrl, path, query);
|
|
31
35
|
|
|
32
36
|
const headers = {
|
|
33
37
|
Accept: 'application/json',
|
|
34
38
|
Authorization: `Bearer ${this.token}`,
|
|
39
|
+
...requestHeaders,
|
|
35
40
|
};
|
|
36
41
|
|
|
37
42
|
const options = {
|
|
@@ -40,8 +45,12 @@ export class HttpClient {
|
|
|
40
45
|
};
|
|
41
46
|
|
|
42
47
|
if (body !== undefined) {
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
if (isFormData(body)) {
|
|
49
|
+
options.body = body;
|
|
50
|
+
} else {
|
|
51
|
+
headers['Content-Type'] = 'application/json';
|
|
52
|
+
options.body = JSON.stringify(body);
|
|
53
|
+
}
|
|
45
54
|
}
|
|
46
55
|
|
|
47
56
|
this.logger.debug('HTTP request', { method, url });
|
|
@@ -3,6 +3,9 @@ import { HttpClient } from './http-client.js';
|
|
|
3
3
|
export class TestomatioApiClient {
|
|
4
4
|
constructor({ baseUrl, projectId, token, logger }) {
|
|
5
5
|
this.projectId = projectId;
|
|
6
|
+
this.logger = logger;
|
|
7
|
+
this.sessionHash = null;
|
|
8
|
+
this.sessionPromise = null;
|
|
6
9
|
this.http = new HttpClient({
|
|
7
10
|
baseUrl,
|
|
8
11
|
token,
|
|
@@ -24,23 +27,101 @@ export class TestomatioApiClient {
|
|
|
24
27
|
return this.http.request('GET', this.buildPath(resource, id), { query });
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
create(resource, body = {}) {
|
|
28
|
-
return this.
|
|
30
|
+
async create(resource, body = {}) {
|
|
31
|
+
return this.mutate('POST', this.buildPath(resource), { body });
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
return this.
|
|
34
|
+
async createMultipart(resource, formData) {
|
|
35
|
+
return this.mutate('POST', this.buildPath(resource), { body: formData });
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
return this.
|
|
38
|
+
async createWithQuery(resource, { query = {}, body = {} } = {}) {
|
|
39
|
+
return this.mutate('POST', this.buildPath(resource), { query, body });
|
|
37
40
|
}
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
return this.
|
|
42
|
+
async update(resource, id, body = {}) {
|
|
43
|
+
return this.mutate('PUT', this.buildPath(resource, id), { body });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async patch(resource, id, body = {}) {
|
|
47
|
+
return this.mutate('PATCH', this.buildPath(resource, id), { body });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async patchMultipart(resource, id, formData) {
|
|
51
|
+
return this.mutate('PATCH', this.buildPath(resource, id), { body: formData });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async delete(resource, id, query = {}) {
|
|
55
|
+
return this.mutate('DELETE', this.buildPath(resource, id), { query });
|
|
41
56
|
}
|
|
42
57
|
|
|
43
58
|
search(resource, query = {}) {
|
|
44
59
|
return this.list(resource, query);
|
|
45
60
|
}
|
|
61
|
+
|
|
62
|
+
async mutate(method, path, options = {}) {
|
|
63
|
+
const sessionHash = await this.ensureSession();
|
|
64
|
+
return this.http.request(method, path, {
|
|
65
|
+
...options,
|
|
66
|
+
headers: {
|
|
67
|
+
...options.headers,
|
|
68
|
+
'X-Session-Hash': sessionHash,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async ensureSession() {
|
|
74
|
+
if (this.sessionHash) {
|
|
75
|
+
return this.sessionHash;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!this.sessionPromise) {
|
|
79
|
+
this.sessionPromise = this.startSession().finally(() => {
|
|
80
|
+
this.sessionPromise = null;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return this.sessionPromise;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async startSession() {
|
|
88
|
+
const response = await this.http.request('POST', this.buildPath('sessions'), {
|
|
89
|
+
body: { description: 'MCP session' },
|
|
90
|
+
});
|
|
91
|
+
const sessionHash = response?.data?.hash || response?.hash;
|
|
92
|
+
|
|
93
|
+
if (!sessionHash) {
|
|
94
|
+
throw new Error('Failed to start Testomat.io API session: missing session hash');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this.sessionHash = sessionHash;
|
|
98
|
+
return sessionHash;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async stopSession() {
|
|
102
|
+
if (this.sessionPromise) {
|
|
103
|
+
try {
|
|
104
|
+
await this.sessionPromise;
|
|
105
|
+
} catch {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!this.sessionHash) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const sessionHash = this.sessionHash;
|
|
115
|
+
this.sessionHash = null;
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
await this.http.request('DELETE', this.buildPath('sessions', sessionHash));
|
|
119
|
+
} catch (error) {
|
|
120
|
+
if (error?.status !== 404) {
|
|
121
|
+
this.logger?.error('Failed to stop Testomat.io API session', {
|
|
122
|
+
error: error?.message || error,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
46
127
|
}
|
package/src/index.js
CHANGED
|
@@ -1,15 +1,36 @@
|
|
|
1
1
|
import { TestomatioApiClient } from './api/testomatio-client.js';
|
|
2
2
|
import { loadConfig } from './config/load-config.js';
|
|
3
|
+
import { ConfigurationError } from './core/errors.js';
|
|
3
4
|
import { createLogger } from './core/logger.js';
|
|
4
5
|
import { TestomatioMCPServer } from './mcp/server.js';
|
|
6
|
+
import { TOOL_DEFINITIONS } from './mcp/tool-definitions.js';
|
|
7
|
+
import {
|
|
8
|
+
ANALYTICS_STATS_TQL_INPUT_DESCRIPTION,
|
|
9
|
+
ANALYTICS_STATS_TQL_REFERENCE,
|
|
10
|
+
ANALYTICS_TESTS_TQL_INPUT_DESCRIPTION,
|
|
11
|
+
ANALYTICS_TESTS_TQL_REFERENCE,
|
|
12
|
+
} from './mcp/definitions/tql-reference.js';
|
|
5
13
|
|
|
6
14
|
export { TestomatioMCPServer };
|
|
15
|
+
export {
|
|
16
|
+
ANALYTICS_STATS_TQL_INPUT_DESCRIPTION,
|
|
17
|
+
ANALYTICS_STATS_TQL_REFERENCE,
|
|
18
|
+
ANALYTICS_TESTS_TQL_INPUT_DESCRIPTION,
|
|
19
|
+
ANALYTICS_TESTS_TQL_REFERENCE,
|
|
20
|
+
ConfigurationError,
|
|
21
|
+
TOOL_DEFINITIONS,
|
|
22
|
+
};
|
|
7
23
|
|
|
8
|
-
export function createApplication(argvOptions = {}) {
|
|
24
|
+
export function createApplication(argvOptions = {}, serverOptions = {}) {
|
|
9
25
|
const config = loadConfig(argvOptions);
|
|
10
26
|
const logger = createLogger();
|
|
11
27
|
const apiClient = new TestomatioApiClient({ ...config, logger });
|
|
12
|
-
const mcpServer = new TestomatioMCPServer({
|
|
28
|
+
const mcpServer = new TestomatioMCPServer({
|
|
29
|
+
config,
|
|
30
|
+
apiClient,
|
|
31
|
+
logger,
|
|
32
|
+
...serverOptions,
|
|
33
|
+
});
|
|
13
34
|
|
|
14
35
|
return {
|
|
15
36
|
config,
|
|
@@ -46,7 +46,6 @@ export const ENTITY_CRUD_CONFIGS = [
|
|
|
46
46
|
resource: 'rungroups',
|
|
47
47
|
idArg: 'rungroup_id',
|
|
48
48
|
listMethod: 'listRungroups',
|
|
49
|
-
searchMethod: 'searchRungroups',
|
|
50
49
|
payloadBuilder: 'buildRungroupPayload',
|
|
51
50
|
wrapperKey: 'rungroup',
|
|
52
51
|
createMode: 'wrapped',
|
|
@@ -57,7 +56,6 @@ export const ENTITY_CRUD_CONFIGS = [
|
|
|
57
56
|
resource: 'steps',
|
|
58
57
|
idArg: 'step_id',
|
|
59
58
|
listMethod: 'listSteps',
|
|
60
|
-
searchMethod: 'searchSteps',
|
|
61
59
|
payloadBuilder: 'buildStepPayload',
|
|
62
60
|
wrapperKey: 'step',
|
|
63
61
|
createMode: 'wrapped',
|
|
@@ -68,7 +66,6 @@ export const ENTITY_CRUD_CONFIGS = [
|
|
|
68
66
|
resource: 'snippets',
|
|
69
67
|
idArg: 'snippet_id',
|
|
70
68
|
listMethod: 'listSnippets',
|
|
71
|
-
searchMethod: 'searchSnippets',
|
|
72
69
|
payloadBuilder: 'buildSnippetPayload',
|
|
73
70
|
wrapperKey: 'snippet',
|
|
74
71
|
createMode: 'wrapped',
|
|
@@ -79,7 +76,6 @@ export const ENTITY_CRUD_CONFIGS = [
|
|
|
79
76
|
resource: 'labels',
|
|
80
77
|
idArg: 'label_id',
|
|
81
78
|
listMethod: 'listLabels',
|
|
82
|
-
searchMethod: 'searchLabels',
|
|
83
79
|
payloadBuilder: 'buildLabelPayload',
|
|
84
80
|
wrapperKey: 'label',
|
|
85
81
|
createMode: 'wrapped',
|
|
@@ -96,4 +92,16 @@ export const ENTITY_CRUD_CONFIGS = [
|
|
|
96
92
|
createMode: 'wrapped',
|
|
97
93
|
updateMode: 'wrapped',
|
|
98
94
|
},
|
|
95
|
+
{
|
|
96
|
+
toolPrefix: 'requirements',
|
|
97
|
+
resource: 'requirements',
|
|
98
|
+
idArg: 'requirement_id',
|
|
99
|
+
listMethod: 'listRequirements',
|
|
100
|
+
searchMethod: 'searchRequirements',
|
|
101
|
+
payloadBuilder: 'buildRequirementPayload',
|
|
102
|
+
wrapperKey: 'requirement',
|
|
103
|
+
createMode: 'requirement',
|
|
104
|
+
updateMode: 'requirement',
|
|
105
|
+
updateMethod: 'patch',
|
|
106
|
+
},
|
|
99
107
|
];
|
|
@@ -13,9 +13,6 @@ export const LABELS_TOOLS = [
|
|
|
13
13
|
"type": "integer",
|
|
14
14
|
"minimum": 1,
|
|
15
15
|
"maximum": 100
|
|
16
|
-
},
|
|
17
|
-
"query": {
|
|
18
|
-
"type": "string"
|
|
19
16
|
}
|
|
20
17
|
},
|
|
21
18
|
"additionalProperties": false
|
|
@@ -148,26 +145,4 @@ export const LABELS_TOOLS = [
|
|
|
148
145
|
"additionalProperties": false
|
|
149
146
|
}
|
|
150
147
|
},
|
|
151
|
-
{
|
|
152
|
-
"name": "labels_search",
|
|
153
|
-
"description": "Search labels (delegates to labels list; docs has no dedicated search parameter)",
|
|
154
|
-
"inputSchema": {
|
|
155
|
-
"type": "object",
|
|
156
|
-
"properties": {
|
|
157
|
-
"query": {
|
|
158
|
-
"type": "string"
|
|
159
|
-
},
|
|
160
|
-
"page": {
|
|
161
|
-
"type": "integer",
|
|
162
|
-
"minimum": 1
|
|
163
|
-
},
|
|
164
|
-
"per_page": {
|
|
165
|
-
"type": "integer",
|
|
166
|
-
"minimum": 1,
|
|
167
|
-
"maximum": 100
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
"additionalProperties": false
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
148
|
];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const MILESTONES_TOOLS = [
|
|
2
|
+
{
|
|
3
|
+
name: 'milestones_list',
|
|
4
|
+
description: 'List milestones (/api/v2/{project_id}/milestones)',
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: 'object',
|
|
7
|
+
properties: {
|
|
8
|
+
page: {
|
|
9
|
+
type: 'integer',
|
|
10
|
+
minimum: 1,
|
|
11
|
+
},
|
|
12
|
+
per_page: {
|
|
13
|
+
type: 'integer',
|
|
14
|
+
minimum: 1,
|
|
15
|
+
maximum: 100,
|
|
16
|
+
},
|
|
17
|
+
type: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Filter by milestone type (title), e.g. Sprint or Release.',
|
|
20
|
+
},
|
|
21
|
+
status: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
enum: ['created', 'active', 'closed'],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'milestones_get',
|
|
31
|
+
description: 'Get milestone by ID',
|
|
32
|
+
inputSchema: {
|
|
33
|
+
type: 'object',
|
|
34
|
+
properties: {
|
|
35
|
+
milestone_id: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ['milestone_id'],
|
|
40
|
+
additionalProperties: false,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
];
|
|
@@ -14,7 +14,24 @@ export const PLANS_TOOLS = [
|
|
|
14
14
|
"minimum": 1,
|
|
15
15
|
"maximum": 100
|
|
16
16
|
},
|
|
17
|
-
"
|
|
17
|
+
"kind": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"enum": [
|
|
20
|
+
"manual",
|
|
21
|
+
"automated",
|
|
22
|
+
"mixed"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"hidden": {
|
|
26
|
+
"type": "boolean"
|
|
27
|
+
},
|
|
28
|
+
"labels": {
|
|
29
|
+
"type": "array",
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "string"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"search_text": {
|
|
18
35
|
"type": "string"
|
|
19
36
|
}
|
|
20
37
|
},
|
|
@@ -95,6 +112,7 @@ export const PLANS_TOOLS = [
|
|
|
95
112
|
"label",
|
|
96
113
|
"custom_field",
|
|
97
114
|
"tag",
|
|
115
|
+
"milestone",
|
|
98
116
|
"issue",
|
|
99
117
|
"jira"
|
|
100
118
|
]
|
|
@@ -179,6 +197,7 @@ export const PLANS_TOOLS = [
|
|
|
179
197
|
"label",
|
|
180
198
|
"custom_field",
|
|
181
199
|
"tag",
|
|
200
|
+
"milestone",
|
|
182
201
|
"issue",
|
|
183
202
|
"jira"
|
|
184
203
|
]
|
|
@@ -224,7 +243,7 @@ export const PLANS_TOOLS = [
|
|
|
224
243
|
"inputSchema": {
|
|
225
244
|
"type": "object",
|
|
226
245
|
"properties": {
|
|
227
|
-
"
|
|
246
|
+
"search_text": {
|
|
228
247
|
"type": "string"
|
|
229
248
|
},
|
|
230
249
|
"page": {
|
|
@@ -235,6 +254,23 @@ export const PLANS_TOOLS = [
|
|
|
235
254
|
"type": "integer",
|
|
236
255
|
"minimum": 1,
|
|
237
256
|
"maximum": 100
|
|
257
|
+
},
|
|
258
|
+
"kind": {
|
|
259
|
+
"type": "string",
|
|
260
|
+
"enum": [
|
|
261
|
+
"manual",
|
|
262
|
+
"automated",
|
|
263
|
+
"mixed"
|
|
264
|
+
]
|
|
265
|
+
},
|
|
266
|
+
"hidden": {
|
|
267
|
+
"type": "boolean"
|
|
268
|
+
},
|
|
269
|
+
"labels": {
|
|
270
|
+
"type": "array",
|
|
271
|
+
"items": {
|
|
272
|
+
"type": "string"
|
|
273
|
+
}
|
|
238
274
|
}
|
|
239
275
|
},
|
|
240
276
|
"additionalProperties": false
|