@mmtr-tech/yandex-tracker-mcp 0.1.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.
@@ -0,0 +1,256 @@
1
+ import { z } from 'zod';
2
+ import { registerTool } from './index.js';
3
+ const createLinkSchema = z.object({
4
+ issueId: z.string().min(1).describe('Source issue key or id'),
5
+ relationship: z.string().min(1)
6
+ .describe('relates | depends on | is dependent by | is subtask for | is parent task for | duplicates | is duplicated by | is epic of | has epic'),
7
+ linkedIssueId: z.string().min(1).describe('Target issue key or id'),
8
+ });
9
+ const deleteLinkSchema = z.object({
10
+ issueId: z.string().min(1).describe('Issue key or id'),
11
+ linkId: z.union([z.string().min(1), z.coerce.number()]).describe('Link id from get_issue_links'),
12
+ });
13
+ const followersSchema = z.object({
14
+ issueId: z.string().min(1).describe('Issue key or id'),
15
+ users: z.array(z.string().min(1)).min(1).describe('Logins or uids'),
16
+ version: z.coerce.number().int().positive().optional(),
17
+ });
18
+ const worklogListSchema = z.object({
19
+ issueId: z.string().min(1),
20
+ perPage: z.coerce.number().int().positive().max(100).optional(),
21
+ afterId: z.coerce.number().int().positive().optional(),
22
+ });
23
+ const addWorklogSchema = z.object({
24
+ issueId: z.string().min(1),
25
+ duration: z.string().min(1).describe('ISO 8601 duration, e.g. PT1H, PT30M, P1D'),
26
+ start: z.string().optional().describe('Start datetime YYYY-MM-DDThh:mm:ss.sss±hhmm'),
27
+ comment: z.string().optional(),
28
+ });
29
+ const countIssuesSchema = z
30
+ .object({
31
+ query: z.string().min(1).optional(),
32
+ filter: z.record(z.unknown()).optional(),
33
+ })
34
+ .superRefine((val, ctx) => {
35
+ const modes = [val.query, val.filter].filter((v) => v !== undefined);
36
+ if (modes.length !== 1) {
37
+ ctx.addIssue({
38
+ code: z.ZodIssueCode.custom,
39
+ message: 'Provide exactly one of: query or filter',
40
+ });
41
+ }
42
+ });
43
+ const checklistItemSchema = z
44
+ .object({
45
+ issueId: z.string().min(1),
46
+ itemId: z.string().min(1),
47
+ checked: z.boolean().optional(),
48
+ text: z.string().min(1).optional(),
49
+ })
50
+ .superRefine((val, ctx) => {
51
+ if (val.checked === undefined && val.text === undefined) {
52
+ ctx.addIssue({
53
+ code: z.ZodIssueCode.custom,
54
+ message: 'Provide checked and/or text',
55
+ });
56
+ }
57
+ });
58
+ const uploadSchema = z.object({
59
+ issueId: z.string().min(1),
60
+ filePath: z.string().min(1).describe('Absolute path to a local file to upload'),
61
+ filename: z.string().min(1).optional().describe('Override filename stored in Tracker'),
62
+ });
63
+ const issueIdSchema = z.object({
64
+ issueId: z.string().min(1),
65
+ });
66
+ export function registerIssueExtraTools() {
67
+ registerTool({
68
+ zodSchema: createLinkSchema,
69
+ schema: {
70
+ name: 'create_issue_link',
71
+ description: 'CREATE a link between two issues (POST /issues/{issueId}/links). Side effect. relationship e.g. relates, depends on, is subtask for.',
72
+ inputSchema: {
73
+ type: 'object',
74
+ properties: {
75
+ issueId: { type: 'string', description: 'Source issue key or id' },
76
+ relationship: {
77
+ type: 'string',
78
+ description: 'Link type: relates, depends on, is dependent by, …',
79
+ },
80
+ linkedIssueId: { type: 'string', description: 'Target issue key or id' },
81
+ },
82
+ required: ['issueId', 'relationship', 'linkedIssueId'],
83
+ },
84
+ },
85
+ execute: async (args, getClient) => {
86
+ return await getClient().createIssueLink(args);
87
+ },
88
+ });
89
+ registerTool({
90
+ zodSchema: deleteLinkSchema,
91
+ schema: {
92
+ name: 'delete_issue_link',
93
+ description: 'DELETE an issue link (DELETE /issues/{issueId}/links/{linkId}). Side effect. Take linkId from get_issue_links.',
94
+ inputSchema: {
95
+ type: 'object',
96
+ properties: {
97
+ issueId: { type: 'string' },
98
+ linkId: { description: 'Link id', oneOf: [{ type: 'string' }, { type: 'number' }] },
99
+ },
100
+ required: ['issueId', 'linkId'],
101
+ },
102
+ },
103
+ execute: async (args, getClient) => {
104
+ return await getClient().deleteIssueLink(args);
105
+ },
106
+ });
107
+ registerTool({
108
+ zodSchema: followersSchema,
109
+ schema: {
110
+ name: 'add_issue_followers',
111
+ description: 'ADD watchers/followers to an issue (PATCH followers.add). Side effect.',
112
+ inputSchema: {
113
+ type: 'object',
114
+ properties: {
115
+ issueId: { type: 'string' },
116
+ users: { type: 'array', items: { type: 'string' }, description: 'Logins or uids' },
117
+ version: { type: 'number' },
118
+ },
119
+ required: ['issueId', 'users'],
120
+ },
121
+ },
122
+ execute: async (args, getClient) => {
123
+ return await getClient().addIssueFollowers(args);
124
+ },
125
+ });
126
+ registerTool({
127
+ zodSchema: followersSchema,
128
+ schema: {
129
+ name: 'remove_issue_followers',
130
+ description: 'REMOVE watchers/followers from an issue (PATCH followers.remove). Side effect.',
131
+ inputSchema: {
132
+ type: 'object',
133
+ properties: {
134
+ issueId: { type: 'string' },
135
+ users: { type: 'array', items: { type: 'string' }, description: 'Logins or uids' },
136
+ version: { type: 'number' },
137
+ },
138
+ required: ['issueId', 'users'],
139
+ },
140
+ },
141
+ execute: async (args, getClient) => {
142
+ return await getClient().removeIssueFollowers(args);
143
+ },
144
+ });
145
+ registerTool({
146
+ zodSchema: worklogListSchema,
147
+ schema: {
148
+ name: 'get_issue_worklog',
149
+ description: 'List worklog entries for an issue (GET /issues/{issueId}/worklog).',
150
+ inputSchema: {
151
+ type: 'object',
152
+ properties: {
153
+ issueId: { type: 'string' },
154
+ perPage: { type: 'number' },
155
+ afterId: { type: 'number', description: 'Pagination cursor (worklog id)' },
156
+ },
157
+ required: ['issueId'],
158
+ },
159
+ },
160
+ execute: async (args, getClient) => {
161
+ return await getClient().getIssueWorklog(args);
162
+ },
163
+ });
164
+ registerTool({
165
+ zodSchema: addWorklogSchema,
166
+ schema: {
167
+ name: 'add_issue_worklog',
168
+ description: 'ADD a worklog entry (POST /issues/{issueId}/worklog). Side effect. duration is ISO 8601 (PT1H, PT30M).',
169
+ inputSchema: {
170
+ type: 'object',
171
+ properties: {
172
+ issueId: { type: 'string' },
173
+ duration: { type: 'string', description: 'ISO 8601 duration, e.g. PT1H' },
174
+ start: { type: 'string' },
175
+ comment: { type: 'string' },
176
+ },
177
+ required: ['issueId', 'duration'],
178
+ },
179
+ },
180
+ execute: async (args, getClient) => {
181
+ return await getClient().addIssueWorklog(args);
182
+ },
183
+ });
184
+ registerTool({
185
+ zodSchema: countIssuesSchema,
186
+ schema: {
187
+ name: 'count_issues',
188
+ description: 'Count issues matching query or filter (POST /issues/_count) without fetching the list. Provide exactly one of query or filter.',
189
+ inputSchema: {
190
+ type: 'object',
191
+ properties: {
192
+ query: { type: 'string', description: 'Tracker query language' },
193
+ filter: { type: 'object', additionalProperties: true },
194
+ },
195
+ },
196
+ },
197
+ execute: async (args, getClient) => {
198
+ return await getClient().countIssues(args);
199
+ },
200
+ });
201
+ registerTool({
202
+ zodSchema: issueIdSchema,
203
+ schema: {
204
+ name: 'get_issue_checklist',
205
+ description: 'Get checklist items for an issue (GET /issues/{issueId}/checklistItems).',
206
+ inputSchema: {
207
+ type: 'object',
208
+ properties: { issueId: { type: 'string' } },
209
+ required: ['issueId'],
210
+ },
211
+ },
212
+ execute: async (args, getClient) => {
213
+ return await getClient().getIssueChecklist(args.issueId);
214
+ },
215
+ });
216
+ registerTool({
217
+ zodSchema: checklistItemSchema,
218
+ schema: {
219
+ name: 'update_checklist_item',
220
+ description: 'UPDATE a checklist item (PATCH …/checklistItems/{itemId}). Side effect. Set checked and/or text.',
221
+ inputSchema: {
222
+ type: 'object',
223
+ properties: {
224
+ issueId: { type: 'string' },
225
+ itemId: { type: 'string' },
226
+ checked: { type: 'boolean' },
227
+ text: { type: 'string' },
228
+ },
229
+ required: ['issueId', 'itemId'],
230
+ },
231
+ },
232
+ execute: async (args, getClient) => {
233
+ return await getClient().updateChecklistItem(args);
234
+ },
235
+ });
236
+ registerTool({
237
+ zodSchema: uploadSchema,
238
+ schema: {
239
+ name: 'upload_issue_attachment',
240
+ description: 'UPLOAD a local file to an issue (POST /issues/{issueId}/attachments/). Side effect. Pass absolute filePath on the machine running the MCP server.',
241
+ inputSchema: {
242
+ type: 'object',
243
+ properties: {
244
+ issueId: { type: 'string' },
245
+ filePath: { type: 'string', description: 'Absolute local file path' },
246
+ filename: { type: 'string' },
247
+ },
248
+ required: ['issueId', 'filePath'],
249
+ },
250
+ },
251
+ execute: async (args, getClient) => {
252
+ return await getClient().uploadIssueAttachment(args);
253
+ },
254
+ });
255
+ }
256
+ //# sourceMappingURL=issue-extras.js.map
@@ -0,0 +1,2 @@
1
+ export declare function registerIssueTools(): void;
2
+ //# sourceMappingURL=issues.d.ts.map