@abdullahtas/youtrack-mcp-server 0.1.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.
Files changed (82) hide show
  1. package/.github/workflows/publish.yml +27 -0
  2. package/LICENSE +21 -0
  3. package/README.md +161 -0
  4. package/dist/client.d.ts +13 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +68 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/index.d.ts +3 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +46 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/tools/activities.d.ts +4 -0
  13. package/dist/tools/activities.d.ts.map +1 -0
  14. package/dist/tools/activities.js +41 -0
  15. package/dist/tools/activities.js.map +1 -0
  16. package/dist/tools/attachments.d.ts +4 -0
  17. package/dist/tools/attachments.d.ts.map +1 -0
  18. package/dist/tools/attachments.js +31 -0
  19. package/dist/tools/attachments.js.map +1 -0
  20. package/dist/tools/commands.d.ts +4 -0
  21. package/dist/tools/commands.d.ts.map +1 -0
  22. package/dist/tools/commands.js +43 -0
  23. package/dist/tools/commands.js.map +1 -0
  24. package/dist/tools/comments.d.ts +4 -0
  25. package/dist/tools/comments.d.ts.map +1 -0
  26. package/dist/tools/comments.js +55 -0
  27. package/dist/tools/comments.js.map +1 -0
  28. package/dist/tools/custom-fields.d.ts +4 -0
  29. package/dist/tools/custom-fields.d.ts.map +1 -0
  30. package/dist/tools/custom-fields.js +41 -0
  31. package/dist/tools/custom-fields.js.map +1 -0
  32. package/dist/tools/issues.d.ts +4 -0
  33. package/dist/tools/issues.d.ts.map +1 -0
  34. package/dist/tools/issues.js +128 -0
  35. package/dist/tools/issues.js.map +1 -0
  36. package/dist/tools/projects.d.ts +4 -0
  37. package/dist/tools/projects.d.ts.map +1 -0
  38. package/dist/tools/projects.js +46 -0
  39. package/dist/tools/projects.js.map +1 -0
  40. package/dist/tools/saved-queries.d.ts +4 -0
  41. package/dist/tools/saved-queries.d.ts.map +1 -0
  42. package/dist/tools/saved-queries.js +28 -0
  43. package/dist/tools/saved-queries.js.map +1 -0
  44. package/dist/tools/sprints.d.ts +4 -0
  45. package/dist/tools/sprints.d.ts.map +1 -0
  46. package/dist/tools/sprints.js +143 -0
  47. package/dist/tools/sprints.js.map +1 -0
  48. package/dist/tools/tags.d.ts +4 -0
  49. package/dist/tools/tags.d.ts.map +1 -0
  50. package/dist/tools/tags.js +67 -0
  51. package/dist/tools/tags.js.map +1 -0
  52. package/dist/tools/time-tracking.d.ts +4 -0
  53. package/dist/tools/time-tracking.d.ts.map +1 -0
  54. package/dist/tools/time-tracking.js +78 -0
  55. package/dist/tools/time-tracking.js.map +1 -0
  56. package/dist/tools/users.d.ts +4 -0
  57. package/dist/tools/users.d.ts.map +1 -0
  58. package/dist/tools/users.js +36 -0
  59. package/dist/tools/users.js.map +1 -0
  60. package/dist/types.d.ts +160 -0
  61. package/dist/types.d.ts.map +1 -0
  62. package/dist/types.js +2 -0
  63. package/dist/types.js.map +1 -0
  64. package/package.json +34 -0
  65. package/src/.gitkeep +0 -0
  66. package/src/client.ts +86 -0
  67. package/src/index.ts +52 -0
  68. package/src/tools/.gitkeep +0 -0
  69. package/src/tools/activities.ts +67 -0
  70. package/src/tools/attachments.ts +47 -0
  71. package/src/tools/commands.ts +64 -0
  72. package/src/tools/comments.ts +90 -0
  73. package/src/tools/custom-fields.ts +79 -0
  74. package/src/tools/issues.ts +174 -0
  75. package/src/tools/projects.ts +70 -0
  76. package/src/tools/saved-queries.ts +45 -0
  77. package/src/tools/sprints.ts +205 -0
  78. package/src/tools/tags.ts +94 -0
  79. package/src/tools/time-tracking.ts +111 -0
  80. package/src/tools/users.ts +54 -0
  81. package/src/types.ts +129 -0
  82. package/tsconfig.json +18 -0
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+ const CUSTOM_FIELD_FIELDS = 'id,name,$type,value(id,name,login,text,minutes,presentation)';
3
+ const PROJECT_CUSTOM_FIELD_FIELDS = 'id,field(id,name,fieldType(id)),canBeEmpty,emptyFieldText,defaultValues(id,name)';
4
+ export function registerCustomFieldTools(server, client) {
5
+ server.registerTool('get_issue_custom_fields', {
6
+ description: 'Get all custom fields for a specific issue',
7
+ inputSchema: z.object({
8
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
9
+ }),
10
+ }, async (params) => {
11
+ const result = await client.get(`/issues/${params.issueId}/customFields`, { fields: CUSTOM_FIELD_FIELDS });
12
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
13
+ });
14
+ server.registerTool('update_custom_field', {
15
+ description: 'Update a custom field value on an issue. The value should be the JSON value to set directly (e.g. { "name": "In Progress" } for enum, { "login": "john" } for user, or a plain value for text/number).',
16
+ inputSchema: z.object({
17
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
18
+ fieldName: z.string().describe('Name of the custom field'),
19
+ value: z.unknown().describe('The value to set. Structure depends on field type.'),
20
+ }),
21
+ }, async (params) => {
22
+ // First, get the custom fields to find the field ID by name
23
+ const fields = await client.get(`/issues/${params.issueId}/customFields`, { fields: 'id,name' });
24
+ const field = fields.find((f) => f.name === params.fieldName);
25
+ if (!field) {
26
+ throw new Error(`Custom field "${params.fieldName}" not found on issue ${params.issueId}. Available fields: ${fields.map((f) => f.name).join(', ')}`);
27
+ }
28
+ const result = await client.post(`/issues/${params.issueId}/customFields/${field.id}`, { value: params.value }, { fields: CUSTOM_FIELD_FIELDS });
29
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
30
+ });
31
+ server.registerTool('get_project_custom_fields', {
32
+ description: 'Get all custom field definitions for a project',
33
+ inputSchema: z.object({
34
+ projectId: z.string().describe('Project ID or shortName'),
35
+ }),
36
+ }, async (params) => {
37
+ const result = await client.get(`/admin/projects/${params.projectId}/customFields`, { fields: PROJECT_CUSTOM_FIELD_FIELDS });
38
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
39
+ });
40
+ }
41
+ //# sourceMappingURL=custom-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-fields.js","sourceRoot":"","sources":["../../src/tools/custom-fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,mBAAmB,GACvB,8DAA8D,CAAC;AAEjE,MAAM,2BAA2B,GAC/B,kFAAkF,CAAC;AAErF,MAAM,UAAU,wBAAwB,CAAC,MAAiB,EAAE,MAAsB;IAChF,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,WAAW,EAAE,4CAA4C;QACzD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;SACjE,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAC7B,WAAW,MAAM,CAAC,OAAO,eAAe,EACxC,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAChC,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,WAAW,EACT,wMAAwM;QAC1M,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YAChE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YAC1D,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;SAClF,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,4DAA4D;QAC5D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAC7B,WAAW,MAAM,CAAC,OAAO,eAAe,EACxC,EAAE,MAAM,EAAE,SAAS,EAAE,CACtB,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACb,iBAAiB,MAAM,CAAC,SAAS,wBAAwB,MAAM,CAAC,OAAO,uBAAuB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrI,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,WAAW,MAAM,CAAC,OAAO,iBAAiB,KAAK,CAAC,EAAE,EAAE,EACpD,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EACvB,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAChC,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,2BAA2B,EAC3B;QACE,WAAW,EAAE,gDAAgD;QAC7D,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;SAC1D,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAC7B,mBAAmB,MAAM,CAAC,SAAS,eAAe,EAClD,EAAE,MAAM,EAAE,2BAA2B,EAAE,CACxC,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { YouTrackClient } from '../client.js';
3
+ export declare function registerIssueTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=issues.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issues.d.ts","sourceRoot":"","sources":["../../src/tools/issues.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAenD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CA4JlF"}
@@ -0,0 +1,128 @@
1
+ import { z } from 'zod';
2
+ const ISSUE_FIELDS = 'id,idReadable,summary,description,created,updated,project(id,name,shortName),reporter(login,name),customFields(id,name,$type,value(id,name,login,text,minutes,presentation)),tags(id,name)';
3
+ const ISSUE_DETAIL_FIELDS = 'id,idReadable,summary,description,created,updated,resolved,project(id,name,shortName),reporter(login,name),updater(login,name),customFields(id,name,$type,value(id,name,login,text,minutes,presentation)),tags(id,name,color(id)),comments(id,text,author(login,name),created)';
4
+ const ISSUE_LIST_FIELDS = 'id,idReadable,summary,resolved,project(id,name,shortName),customFields(id,name,$type,value(id,name)),tags(id,name)';
5
+ const LINK_FIELDS = 'id,direction,linkType(name,sourceToTarget,targetToSource),issues(id,idReadable,summary)';
6
+ export function registerIssueTools(server, client) {
7
+ server.registerTool('create_issue', {
8
+ description: 'Create a new issue in a YouTrack project',
9
+ inputSchema: z.object({
10
+ project: z.string().describe('Project ID or shortName'),
11
+ summary: z.string().describe('Issue summary/title'),
12
+ description: z.string().optional().describe('Issue description'),
13
+ customFields: z
14
+ .array(z.object({
15
+ name: z.string(),
16
+ $type: z.string(),
17
+ value: z.unknown(),
18
+ }))
19
+ .optional()
20
+ .describe('Custom field values'),
21
+ }),
22
+ }, async (params) => {
23
+ const body = {
24
+ project: { id: params.project },
25
+ summary: params.summary,
26
+ };
27
+ if (params.description !== undefined)
28
+ body.description = params.description;
29
+ if (params.customFields !== undefined)
30
+ body.customFields = params.customFields;
31
+ const result = await client.post('/issues', body, { fields: ISSUE_FIELDS });
32
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
33
+ });
34
+ server.registerTool('get_issue', {
35
+ description: 'Get details of a specific issue by its readable ID (e.g. "BC-123")',
36
+ inputSchema: z.object({
37
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
38
+ }),
39
+ }, async (params) => {
40
+ const result = await client.get(`/issues/${params.issueId}`, {
41
+ fields: ISSUE_DETAIL_FIELDS,
42
+ });
43
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
44
+ });
45
+ server.registerTool('update_issue', {
46
+ description: 'Update an existing issue (summary and/or description)',
47
+ inputSchema: z.object({
48
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
49
+ summary: z.string().optional().describe('New summary'),
50
+ description: z.string().optional().describe('New description'),
51
+ }),
52
+ }, async (params) => {
53
+ const body = {};
54
+ if (params.summary !== undefined)
55
+ body.summary = params.summary;
56
+ if (params.description !== undefined)
57
+ body.description = params.description;
58
+ const result = await client.post(`/issues/${params.issueId}`, body, {
59
+ fields: ISSUE_DETAIL_FIELDS,
60
+ });
61
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
62
+ });
63
+ server.registerTool('delete_issue', {
64
+ description: 'Delete an issue by its readable ID',
65
+ inputSchema: z.object({
66
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
67
+ }),
68
+ }, async (params) => {
69
+ await client.delete(`/issues/${params.issueId}`);
70
+ return {
71
+ content: [
72
+ { type: 'text', text: `Issue ${params.issueId} has been deleted successfully.` },
73
+ ],
74
+ };
75
+ });
76
+ server.registerTool('search_issues', {
77
+ description: 'Search for issues using YouTrack query language',
78
+ inputSchema: z.object({
79
+ query: z.string().describe('YouTrack search query'),
80
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
81
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
82
+ }),
83
+ }, async (params) => {
84
+ const result = await client.list('/issues', ISSUE_LIST_FIELDS, {
85
+ top: params.top,
86
+ skip: params.skip,
87
+ }, {
88
+ query: params.query,
89
+ });
90
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
91
+ });
92
+ server.registerTool('link_issues', {
93
+ description: 'Link two issues together with a specified link type (e.g. "Depends on", "Relates to", "Subtask of", "Parent for")',
94
+ inputSchema: z.object({
95
+ issueId: z.string().describe('Source issue readable ID'),
96
+ targetIssueId: z.string().describe('Target issue readable ID'),
97
+ linkType: z
98
+ .string()
99
+ .describe('Link type name, e.g. "Depends on", "Relates to", "Subtask of", "Parent for"'),
100
+ }),
101
+ }, async (params) => {
102
+ const body = {
103
+ query: `${params.linkType} ${params.targetIssueId}`,
104
+ issues: [{ idReadable: params.issueId }],
105
+ };
106
+ await client.post('/commands', body);
107
+ return {
108
+ content: [
109
+ {
110
+ type: 'text',
111
+ text: `Successfully linked ${params.issueId} -> "${params.linkType}" -> ${params.targetIssueId}`,
112
+ },
113
+ ],
114
+ };
115
+ });
116
+ server.registerTool('get_issue_links', {
117
+ description: 'Get all links for a specific issue',
118
+ inputSchema: z.object({
119
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
120
+ }),
121
+ }, async (params) => {
122
+ const result = await client.get(`/issues/${params.issueId}/links`, {
123
+ fields: LINK_FIELDS,
124
+ });
125
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
126
+ });
127
+ }
128
+ //# sourceMappingURL=issues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issues.js","sourceRoot":"","sources":["../../src/tools/issues.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { YouTrackClient } from '../client.js';
3
+ export declare function registerProjectTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAOnD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CA4DpF"}
@@ -0,0 +1,46 @@
1
+ import { z } from 'zod';
2
+ const PROJECT_FIELDS = 'id,name,shortName,description,leader(login,name)';
3
+ const PROJECT_ISSUE_FIELDS = 'id,idReadable,summary,resolved,customFields(id,name,$type,value(id,name)),tags(id,name)';
4
+ export function registerProjectTools(server, client) {
5
+ server.registerTool('list_projects', {
6
+ description: 'List all projects in YouTrack',
7
+ inputSchema: z.object({
8
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
9
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
10
+ }),
11
+ }, async (params) => {
12
+ const result = await client.list('/admin/projects', PROJECT_FIELDS, {
13
+ top: params.top,
14
+ skip: params.skip,
15
+ });
16
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
17
+ });
18
+ server.registerTool('get_project', {
19
+ description: 'Get details of a specific project',
20
+ inputSchema: z.object({
21
+ projectId: z.string().describe('Project ID or shortName'),
22
+ }),
23
+ }, async (params) => {
24
+ const result = await client.get(`/admin/projects/${params.projectId}`, {
25
+ fields: PROJECT_FIELDS,
26
+ });
27
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
28
+ });
29
+ server.registerTool('get_project_issues', {
30
+ description: 'Get issues belonging to a specific project, optionally filtered by query',
31
+ inputSchema: z.object({
32
+ projectId: z.string().describe('Project ID or shortName'),
33
+ query: z.string().optional().describe('YouTrack search query to filter issues'),
34
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
35
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
36
+ }),
37
+ }, async (params) => {
38
+ const extraParams = {};
39
+ if (params.query) {
40
+ extraParams.query = params.query;
41
+ }
42
+ const result = await client.list(`/admin/projects/${params.projectId}/issues`, PROJECT_ISSUE_FIELDS, { top: params.top, skip: params.skip }, extraParams);
43
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
44
+ });
45
+ }
46
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { YouTrackClient } from '../client.js';
3
+ export declare function registerSavedQueryTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=saved-queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saved-queries.d.ts","sourceRoot":"","sources":["../../src/tools/saved-queries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAKnD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAqCvF"}
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ const SAVED_QUERY_FIELDS = 'id,name,query';
3
+ export function registerSavedQueryTools(server, client) {
4
+ server.registerTool('list_saved_queries', {
5
+ description: 'List all saved search queries in YouTrack',
6
+ inputSchema: z.object({
7
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
8
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
9
+ }),
10
+ }, async (params) => {
11
+ const result = await client.list('/savedQueries', SAVED_QUERY_FIELDS, {
12
+ top: params.top,
13
+ skip: params.skip,
14
+ });
15
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
16
+ });
17
+ server.registerTool('create_saved_query', {
18
+ description: 'Create a new saved search query',
19
+ inputSchema: z.object({
20
+ name: z.string().describe('Name for the saved query'),
21
+ query: z.string().describe('YouTrack search query string'),
22
+ }),
23
+ }, async (params) => {
24
+ const result = await client.post('/savedQueries', { name: params.name, query: params.query }, { fields: SAVED_QUERY_FIELDS });
25
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
26
+ });
27
+ }
28
+ //# sourceMappingURL=saved-queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saved-queries.js","sourceRoot":"","sources":["../../src/tools/saved-queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAE3C,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,MAAsB;IAC/E,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,WAAW,EAAE,2CAA2C;QACxD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC;YACzF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,uCAAuC,CAAC;SACzF,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAa,eAAe,EAAE,kBAAkB,EAAE;YAChF,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,WAAW,EAAE,iCAAiC;QAC9C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YACrD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;SAC3D,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,eAAe,EACf,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAC1C,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAC/B,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { YouTrackClient } from '../client.js';
3
+ export declare function registerSprintTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=sprints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprints.d.ts","sourceRoot":"","sources":["../../src/tools/sprints.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAenD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CA2LnF"}
@@ -0,0 +1,143 @@
1
+ import { z } from 'zod';
2
+ const BOARD_LIST_FIELDS = 'id,name,projects(id,name,shortName)';
3
+ const BOARD_DETAIL_FIELDS = 'id,name,projects(id,name,shortName),sprints(id,name,archived)';
4
+ const SPRINT_LIST_FIELDS = 'id,name,goal,start,finish,archived,unresolvedIssuesCount';
5
+ const SPRINT_DETAIL_FIELDS = 'id,name,goal,start,finish,archived,unresolvedIssuesCount,issues(id,idReadable,summary,customFields(id,name,$type,value(id,name)))';
6
+ const CURRENT_SPRINT_FIELDS = 'currentSprint(id,name,goal,start,finish,archived,unresolvedIssuesCount,issues(id,idReadable,summary,customFields(id,name,$type,value(id,name))))';
7
+ function isoToTimestamp(iso) {
8
+ return new Date(iso).getTime();
9
+ }
10
+ export function registerSprintTools(server, client) {
11
+ server.registerTool('list_agile_boards', {
12
+ description: 'List all agile boards in YouTrack',
13
+ inputSchema: z.object({
14
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
15
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
16
+ }),
17
+ }, async (params) => {
18
+ const result = await client.list('/agiles', BOARD_LIST_FIELDS, {
19
+ top: params.top,
20
+ skip: params.skip,
21
+ });
22
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
23
+ });
24
+ server.registerTool('get_agile_board', {
25
+ description: 'Get details of a specific agile board including its sprints',
26
+ inputSchema: z.object({
27
+ boardId: z.string().describe('Agile board ID'),
28
+ }),
29
+ }, async (params) => {
30
+ const result = await client.get(`/agiles/${params.boardId}`, {
31
+ fields: BOARD_DETAIL_FIELDS,
32
+ });
33
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
34
+ });
35
+ server.registerTool('list_sprints', {
36
+ description: 'List all sprints for a specific agile board',
37
+ inputSchema: z.object({
38
+ boardId: z.string().describe('Agile board ID'),
39
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
40
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
41
+ }),
42
+ }, async (params) => {
43
+ const result = await client.list(`/agiles/${params.boardId}/sprints`, SPRINT_LIST_FIELDS, { top: params.top, skip: params.skip });
44
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
45
+ });
46
+ server.registerTool('get_sprint', {
47
+ description: 'Get details of a specific sprint including its issues',
48
+ inputSchema: z.object({
49
+ boardId: z.string().describe('Agile board ID'),
50
+ sprintId: z.string().describe('Sprint ID'),
51
+ }),
52
+ }, async (params) => {
53
+ const result = await client.get(`/agiles/${params.boardId}/sprints/${params.sprintId}`, { fields: SPRINT_DETAIL_FIELDS });
54
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
55
+ });
56
+ server.registerTool('get_current_sprint', {
57
+ description: 'Get the current active sprint for a specific agile board',
58
+ inputSchema: z.object({
59
+ boardId: z.string().describe('Agile board ID'),
60
+ }),
61
+ }, async (params) => {
62
+ const result = await client.get(`/agiles/${params.boardId}`, { fields: CURRENT_SPRINT_FIELDS });
63
+ if (!result.currentSprint) {
64
+ return {
65
+ content: [{ type: 'text', text: 'No current sprint found for this board.' }],
66
+ };
67
+ }
68
+ return {
69
+ content: [
70
+ { type: 'text', text: JSON.stringify(result.currentSprint, null, 2) },
71
+ ],
72
+ };
73
+ });
74
+ server.registerTool('create_sprint', {
75
+ description: 'Create a new sprint on an agile board',
76
+ inputSchema: z.object({
77
+ boardId: z.string().describe('Agile board ID'),
78
+ name: z.string().describe('Sprint name'),
79
+ goal: z.string().optional().describe('Sprint goal'),
80
+ start: z.string().optional().describe('Sprint start date (ISO 8601 format)'),
81
+ finish: z.string().optional().describe('Sprint end date (ISO 8601 format)'),
82
+ }),
83
+ }, async (params) => {
84
+ const body = { name: params.name };
85
+ if (params.goal !== undefined)
86
+ body.goal = params.goal;
87
+ if (params.start !== undefined)
88
+ body.start = isoToTimestamp(params.start);
89
+ if (params.finish !== undefined)
90
+ body.finish = isoToTimestamp(params.finish);
91
+ const result = await client.post(`/agiles/${params.boardId}/sprints`, body, { fields: 'id,name,goal,start,finish' });
92
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
93
+ });
94
+ server.registerTool('update_sprint', {
95
+ description: 'Update an existing sprint on an agile board',
96
+ inputSchema: z.object({
97
+ boardId: z.string().describe('Agile board ID'),
98
+ sprintId: z.string().describe('Sprint ID'),
99
+ name: z.string().optional().describe('New sprint name'),
100
+ goal: z.string().optional().describe('New sprint goal'),
101
+ start: z.string().optional().describe('New sprint start date (ISO 8601 format)'),
102
+ finish: z.string().optional().describe('New sprint end date (ISO 8601 format)'),
103
+ }),
104
+ }, async (params) => {
105
+ const body = {};
106
+ if (params.name !== undefined)
107
+ body.name = params.name;
108
+ if (params.goal !== undefined)
109
+ body.goal = params.goal;
110
+ if (params.start !== undefined)
111
+ body.start = isoToTimestamp(params.start);
112
+ if (params.finish !== undefined)
113
+ body.finish = isoToTimestamp(params.finish);
114
+ const result = await client.post(`/agiles/${params.boardId}/sprints/${params.sprintId}`, body, { fields: 'id,name,goal,start,finish,archived' });
115
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
116
+ });
117
+ server.registerTool('add_issue_to_sprint', {
118
+ description: 'Add an issue to a sprint using its readable ID (e.g. "BC-123")',
119
+ inputSchema: z.object({
120
+ boardId: z.string().describe('Agile board ID'),
121
+ sprintId: z.string().describe('Sprint ID'),
122
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
123
+ }),
124
+ }, async (params) => {
125
+ const sprint = await client.get(`/agiles/${params.boardId}/sprints/${params.sprintId}`, { fields: 'name' });
126
+ const board = await client.get(`/agiles/${params.boardId}`, {
127
+ fields: 'name',
128
+ });
129
+ await client.post('/commands', {
130
+ query: `Board ${board.name}: ${sprint.name}`,
131
+ issues: [{ idReadable: params.issueId }],
132
+ });
133
+ return {
134
+ content: [
135
+ {
136
+ type: 'text',
137
+ text: `Issue ${params.issueId} added to sprint "${sprint.name}" on board "${board.name}".`,
138
+ },
139
+ ],
140
+ };
141
+ });
142
+ }
143
+ //# sourceMappingURL=sprints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprints.js","sourceRoot":"","sources":["../../src/tools/sprints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { YouTrackClient } from '../client.js';
3
+ export declare function registerTagTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/tools/tags.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAKnD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAsFhF"}
@@ -0,0 +1,67 @@
1
+ import { z } from 'zod';
2
+ const TAG_FIELDS = 'id,name,color(id)';
3
+ export function registerTagTools(server, client) {
4
+ server.registerTool('list_tags', {
5
+ description: 'List all issue tags in YouTrack',
6
+ inputSchema: z.object({
7
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
8
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
9
+ }),
10
+ }, async (params) => {
11
+ const result = await client.list('/issueTags', TAG_FIELDS, {
12
+ top: params.top,
13
+ skip: params.skip,
14
+ });
15
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
16
+ });
17
+ server.registerTool('create_tag', {
18
+ description: 'Create a new issue tag',
19
+ inputSchema: z.object({
20
+ name: z.string().describe('Tag name'),
21
+ }),
22
+ }, async (params) => {
23
+ const result = await client.post('/issueTags', { name: params.name }, { fields: TAG_FIELDS });
24
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
25
+ });
26
+ server.registerTool('add_tag', {
27
+ description: 'Add a tag to an issue',
28
+ inputSchema: z.object({
29
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
30
+ tagName: z.string().describe('Tag name to add'),
31
+ }),
32
+ }, async (params) => {
33
+ await client.post('/commands', {
34
+ query: `tag ${params.tagName}`,
35
+ issues: [{ idReadable: params.issueId }],
36
+ });
37
+ return {
38
+ content: [
39
+ {
40
+ type: 'text',
41
+ text: `Tag "${params.tagName}" has been added to issue ${params.issueId}.`,
42
+ },
43
+ ],
44
+ };
45
+ });
46
+ server.registerTool('remove_tag', {
47
+ description: 'Remove a tag from an issue',
48
+ inputSchema: z.object({
49
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
50
+ tagName: z.string().describe('Tag name to remove'),
51
+ }),
52
+ }, async (params) => {
53
+ await client.post('/commands', {
54
+ query: `untag ${params.tagName}`,
55
+ issues: [{ idReadable: params.issueId }],
56
+ });
57
+ return {
58
+ content: [
59
+ {
60
+ type: 'text',
61
+ text: `Tag "${params.tagName}" has been removed from issue ${params.issueId}.`,
62
+ },
63
+ ],
64
+ };
65
+ });
66
+ }
67
+ //# sourceMappingURL=tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/tools/tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAEvC,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAsB;IACxE,MAAM,CAAC,YAAY,CACjB,WAAW,EACX;QACE,WAAW,EAAE,iCAAiC;QAC9C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC;YACzF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,uCAAuC,CAAC;SACzF,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAM,YAAY,EAAE,UAAU,EAAE;YAC9D,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,WAAW,EAAE,wBAAwB;QACrC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;SACtC,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,YAAY,EACZ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EACrB,EAAE,MAAM,EAAE,UAAU,EAAE,CACvB,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,WAAW,EAAE,uBAAuB;QACpC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YAChE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;SAChD,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;YAC7B,KAAK,EAAE,OAAO,MAAM,CAAC,OAAO,EAAE;YAC9B,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;SACzC,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,QAAQ,MAAM,CAAC,OAAO,6BAA6B,MAAM,CAAC,OAAO,GAAG;iBAC3E;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,WAAW,EAAE,4BAA4B;QACzC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YAChE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;SACnD,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;YAC7B,KAAK,EAAE,SAAS,MAAM,CAAC,OAAO,EAAE;YAChC,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;SACzC,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,QAAQ,MAAM,CAAC,OAAO,iCAAiC,MAAM,CAAC,OAAO,GAAG;iBAC/E;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { YouTrackClient } from '../client.js';
3
+ export declare function registerTimeTrackingTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=time-tracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-tracking.d.ts","sourceRoot":"","sources":["../../src/tools/time-tracking.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAsGzF"}