@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,27 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ release:
5
+ types: [created]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ contents: read
12
+ id-token: write
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: actions/setup-node@v4
17
+ with:
18
+ node-version: '20'
19
+ registry-url: 'https://registry.npmjs.org'
20
+
21
+ - run: npm ci
22
+
23
+ - run: npm run build
24
+
25
+ - run: npm publish --provenance --access public
26
+ env:
27
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 abdullahtas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # YouTrack MCP Server
2
+
3
+ A comprehensive Model Context Protocol (MCP) server for JetBrains YouTrack. Provides full REST API access through 44 tools for AI agents.
4
+
5
+ ## Features
6
+
7
+ - 44 tools covering issues, comments, projects, sprints, custom fields, time tracking, tags, users, activities, attachments, saved queries, and batch commands
8
+ - Works with any YouTrack instance (Cloud or Server)
9
+ - Zero config -- just set two environment variables
10
+ - Full YouTrack query language support
11
+ - Optimized API calls with selective field loading
12
+
13
+ ## Quick Start
14
+
15
+ ```bash
16
+ npx @abdullahtas/youtrack-mcp-server
17
+ ```
18
+
19
+ Requires two environment variables:
20
+
21
+ | Variable | Required | Description |
22
+ |----------|----------|-------------|
23
+ | `YOUTRACK_URL` | Yes | Your YouTrack instance URL (e.g. `https://your-org.youtrack.cloud`) |
24
+ | `YOUTRACK_TOKEN` | Yes | Permanent token for authentication |
25
+
26
+ **How to get a token:** YouTrack Profile -> Authentication -> New token. Grant the scope needed for your use case (typically `YouTrack`).
27
+
28
+ ## Usage with Claude Desktop
29
+
30
+ Add the following to your Claude Desktop configuration file:
31
+
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "youtrack": {
36
+ "command": "npx",
37
+ "args": ["-y", "@abdullahtas/youtrack-mcp-server"],
38
+ "env": {
39
+ "YOUTRACK_URL": "https://your-instance.youtrack.cloud",
40
+ "YOUTRACK_TOKEN": "perm:your-token-here"
41
+ }
42
+ }
43
+ }
44
+ }
45
+ ```
46
+
47
+ ## Usage with Claude Code
48
+
49
+ ```bash
50
+ claude mcp add youtrack -- env YOUTRACK_URL=https://your-instance.youtrack.cloud YOUTRACK_TOKEN=perm:xxx npx -y @abdullahtas/youtrack-mcp-server
51
+ ```
52
+
53
+ ## Available Tools
54
+
55
+ ### Issues
56
+
57
+ | Tool | Description |
58
+ |------|-------------|
59
+ | `create_issue` | Create a new issue in a YouTrack project |
60
+ | `get_issue` | Get details of a specific issue by its readable ID (e.g. "BC-123") |
61
+ | `update_issue` | Update an existing issue (summary and/or description) |
62
+ | `delete_issue` | Delete an issue by its readable ID |
63
+ | `search_issues` | Search for issues using YouTrack query language |
64
+ | `link_issues` | Link two issues together with a specified link type |
65
+ | `get_issue_links` | Get all links for a specific issue |
66
+
67
+ ### Comments
68
+
69
+ | Tool | Description |
70
+ |------|-------------|
71
+ | `get_comments` | Get comments for a specific issue |
72
+ | `add_comment` | Add a comment to an issue |
73
+ | `update_comment` | Update an existing comment on an issue |
74
+ | `delete_comment` | Delete a comment from an issue |
75
+
76
+ ### Projects
77
+
78
+ | Tool | Description |
79
+ |------|-------------|
80
+ | `list_projects` | List all projects in YouTrack |
81
+ | `get_project` | Get details of a specific project |
82
+ | `get_project_issues` | Get issues belonging to a specific project, optionally filtered by query |
83
+
84
+ ### Agile & Sprints
85
+
86
+ | Tool | Description |
87
+ |------|-------------|
88
+ | `list_agile_boards` | List all agile boards in YouTrack |
89
+ | `get_agile_board` | Get details of a specific agile board including its sprints |
90
+ | `list_sprints` | List all sprints for a specific agile board |
91
+ | `get_sprint` | Get details of a specific sprint including its issues |
92
+ | `get_current_sprint` | Get the current active sprint for a specific agile board |
93
+ | `create_sprint` | Create a new sprint on an agile board |
94
+ | `update_sprint` | Update an existing sprint on an agile board |
95
+ | `add_issue_to_sprint` | Add an issue to a sprint using its readable ID |
96
+
97
+ ### Custom Fields
98
+
99
+ | Tool | Description |
100
+ |------|-------------|
101
+ | `get_issue_custom_fields` | Get all custom fields for a specific issue |
102
+ | `update_custom_field` | Update a custom field value on an issue |
103
+ | `get_project_custom_fields` | Get all custom field definitions for a project |
104
+
105
+ ### Time Tracking
106
+
107
+ | Tool | Description |
108
+ |------|-------------|
109
+ | `get_work_items` | Get time tracking work items for an issue |
110
+ | `add_work_item` | Add a time tracking work item to an issue |
111
+ | `update_work_item` | Update an existing time tracking work item |
112
+ | `delete_work_item` | Delete a time tracking work item from an issue |
113
+
114
+ ### Tags
115
+
116
+ | Tool | Description |
117
+ |------|-------------|
118
+ | `list_tags` | List all issue tags in YouTrack |
119
+ | `create_tag` | Create a new issue tag |
120
+ | `add_tag` | Add a tag to an issue |
121
+ | `remove_tag` | Remove a tag from an issue |
122
+
123
+ ### Users
124
+
125
+ | Tool | Description |
126
+ |------|-------------|
127
+ | `get_current_user` | Get the currently authenticated YouTrack user |
128
+ | `list_users` | List YouTrack users |
129
+ | `get_user` | Get a specific YouTrack user by ID |
130
+
131
+ ### Activities
132
+
133
+ | Tool | Description |
134
+ |------|-------------|
135
+ | `get_issue_activities` | Get activity history for a specific issue |
136
+ | `get_activities` | Get global activity stream across all issues |
137
+
138
+ ### Attachments
139
+
140
+ | Tool | Description |
141
+ |------|-------------|
142
+ | `get_attachments` | Get all attachments for an issue |
143
+ | `delete_attachment` | Delete an attachment from an issue |
144
+
145
+ ### Saved Queries
146
+
147
+ | Tool | Description |
148
+ |------|-------------|
149
+ | `list_saved_queries` | List all saved search queries in YouTrack |
150
+ | `create_saved_query` | Create a new saved search query |
151
+
152
+ ### Power Tools
153
+
154
+ | Tool | Description |
155
+ |------|-------------|
156
+ | `execute_command` | Execute a YouTrack command on one or more issues (e.g. "State In Progress", "Assignee me") |
157
+ | `raw_query` | Execute a raw YouTrack query and return issues with custom fields specification |
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,13 @@
1
+ import type { YouTrackConfig, PaginationParams } from './types.js';
2
+ export declare class YouTrackClient {
3
+ private baseUrl;
4
+ private token;
5
+ constructor(config: YouTrackConfig);
6
+ private get headers();
7
+ private buildUrl;
8
+ get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T>;
9
+ post<T>(path: string, body?: unknown, params?: Record<string, string | number | undefined>): Promise<T>;
10
+ delete(path: string, params?: Record<string, string | number | undefined>): Promise<void>;
11
+ list<T>(path: string, fields: string, pagination?: PaginationParams, extraParams?: Record<string, string>): Promise<T[]>;
12
+ }
13
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAElF,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,cAAc;IAKlC,OAAO,KAAK,OAAO,GAMlB;IAED,OAAO,CAAC,QAAQ;IAYV,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAYtF,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAiBvG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAWzF,IAAI,CAAC,CAAC,EACV,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,gBAAgB,EAC7B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,OAAO,CAAC,CAAC,EAAE,CAAC;CAShB"}
package/dist/client.js ADDED
@@ -0,0 +1,68 @@
1
+ export class YouTrackClient {
2
+ baseUrl;
3
+ token;
4
+ constructor(config) {
5
+ this.baseUrl = config.baseUrl.replace(/\/+$/, '');
6
+ this.token = config.token;
7
+ }
8
+ get headers() {
9
+ return {
10
+ Authorization: `Bearer ${this.token}`,
11
+ Accept: 'application/json',
12
+ 'Content-Type': 'application/json',
13
+ };
14
+ }
15
+ buildUrl(path, params) {
16
+ const url = new URL(`${this.baseUrl}/api${path}`);
17
+ if (params) {
18
+ for (const [key, value] of Object.entries(params)) {
19
+ if (value !== undefined) {
20
+ url.searchParams.set(key, String(value));
21
+ }
22
+ }
23
+ }
24
+ return url.toString();
25
+ }
26
+ async get(path, params) {
27
+ const url = this.buildUrl(path, params);
28
+ const response = await fetch(url, { method: 'GET', headers: this.headers });
29
+ if (!response.ok) {
30
+ const error = (await response.json().catch(() => ({ error: response.statusText })));
31
+ throw new Error(`YouTrack API error (${response.status}): ${error.error_description || error.error || response.statusText}`);
32
+ }
33
+ return response.json();
34
+ }
35
+ async post(path, body, params) {
36
+ const url = this.buildUrl(path, params);
37
+ const response = await fetch(url, {
38
+ method: 'POST',
39
+ headers: this.headers,
40
+ body: body ? JSON.stringify(body) : undefined,
41
+ });
42
+ if (!response.ok) {
43
+ const error = (await response.json().catch(() => ({ error: response.statusText })));
44
+ throw new Error(`YouTrack API error (${response.status}): ${error.error_description || error.error || response.statusText}`);
45
+ }
46
+ if (response.status === 204)
47
+ return {};
48
+ return response.json();
49
+ }
50
+ async delete(path, params) {
51
+ const url = this.buildUrl(path, params);
52
+ const response = await fetch(url, { method: 'DELETE', headers: this.headers });
53
+ if (!response.ok) {
54
+ const error = (await response.json().catch(() => ({ error: response.statusText })));
55
+ throw new Error(`YouTrack API error (${response.status}): ${error.error_description || error.error || response.statusText}`);
56
+ }
57
+ }
58
+ async list(path, fields, pagination, extraParams) {
59
+ const params = {
60
+ fields,
61
+ $top: pagination?.top ?? 50,
62
+ $skip: pagination?.skip ?? 0,
63
+ ...extraParams,
64
+ };
65
+ return this.get(path, params);
66
+ }
67
+ }
68
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { YouTrackClient } from './client.js';
5
+ import { registerIssueTools } from './tools/issues.js';
6
+ import { registerCommentTools } from './tools/comments.js';
7
+ import { registerProjectTools } from './tools/projects.js';
8
+ import { registerSprintTools } from './tools/sprints.js';
9
+ import { registerCustomFieldTools } from './tools/custom-fields.js';
10
+ import { registerTimeTrackingTools } from './tools/time-tracking.js';
11
+ import { registerTagTools } from './tools/tags.js';
12
+ import { registerUserTools } from './tools/users.js';
13
+ import { registerActivityTools } from './tools/activities.js';
14
+ import { registerAttachmentTools } from './tools/attachments.js';
15
+ import { registerSavedQueryTools } from './tools/saved-queries.js';
16
+ import { registerCommandTools } from './tools/commands.js';
17
+ const YOUTRACK_URL = process.env.YOUTRACK_URL;
18
+ const YOUTRACK_TOKEN = process.env.YOUTRACK_TOKEN;
19
+ if (!YOUTRACK_URL || !YOUTRACK_TOKEN) {
20
+ console.error('Error: YOUTRACK_URL and YOUTRACK_TOKEN environment variables are required.');
21
+ console.error('');
22
+ console.error('Usage:');
23
+ console.error(' YOUTRACK_URL=https://your-instance.youtrack.cloud YOUTRACK_TOKEN=perm:xxx youtrack-mcp-server');
24
+ process.exit(1);
25
+ }
26
+ const client = new YouTrackClient({ baseUrl: YOUTRACK_URL, token: YOUTRACK_TOKEN });
27
+ const server = new McpServer({
28
+ name: 'youtrack-mcp-server',
29
+ version: '0.1.0',
30
+ });
31
+ registerIssueTools(server, client);
32
+ registerCommentTools(server, client);
33
+ registerProjectTools(server, client);
34
+ registerSprintTools(server, client);
35
+ registerCustomFieldTools(server, client);
36
+ registerTimeTrackingTools(server, client);
37
+ registerTagTools(server, client);
38
+ registerUserTools(server, client);
39
+ registerActivityTools(server, client);
40
+ registerAttachmentTools(server, client);
41
+ registerSavedQueryTools(server, client);
42
+ registerCommandTools(server, client);
43
+ const transport = new StdioServerTransport();
44
+ await server.connect(transport);
45
+ console.error('YouTrack MCP Server running on stdio');
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;AAC9C,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;AAElD,IAAI,CAAC,YAAY,IAAI,CAAC,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAC;IAC5F,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACxB,OAAO,CAAC,KAAK,CAAC,iGAAiG,CAAC,CAAC;IACjH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;AAEpF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,qBAAqB;IAC3B,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpC,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACzC,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC1C,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACjC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAChC,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,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 registerActivityTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=activities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activities.d.ts","sourceRoot":"","sources":["../../src/tools/activities.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AASnD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAuDrF"}
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+ const ISSUE_ACTIVITY_FIELDS = 'id,timestamp,author(login,name),category(id),field(name,$type),added(id,name,login,text),removed(id,name,login,text)';
3
+ const ACTIVITY_FIELDS = 'id,timestamp,author(login,name),category(id),target(id,idReadable),field(name,$type),added(id,name,login,text),removed(id,name,login,text)';
4
+ export function registerActivityTools(server, client) {
5
+ server.registerTool('get_issue_activities', {
6
+ description: 'Get activity history for a specific issue',
7
+ inputSchema: z.object({
8
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
9
+ categories: z
10
+ .string()
11
+ .optional()
12
+ .describe('Comma-separated activity categories, e.g. "CommentsCategory,CustomFieldCategory"'),
13
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
14
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
15
+ }),
16
+ }, async (params) => {
17
+ const extraParams = {};
18
+ if (params.categories)
19
+ extraParams.categories = params.categories;
20
+ const result = await client.list(`/issues/${params.issueId}/activities`, ISSUE_ACTIVITY_FIELDS, { top: params.top, skip: params.skip }, extraParams);
21
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
22
+ });
23
+ server.registerTool('get_activities', {
24
+ description: 'Get global activity stream across all issues',
25
+ inputSchema: z.object({
26
+ categories: z
27
+ .string()
28
+ .optional()
29
+ .describe('Comma-separated activity categories, e.g. "CommentsCategory,CustomFieldCategory"'),
30
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
31
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
32
+ }),
33
+ }, async (params) => {
34
+ const extraParams = {};
35
+ if (params.categories)
36
+ extraParams.categories = params.categories;
37
+ const result = await client.list('/activities', ACTIVITY_FIELDS, { top: params.top, skip: params.skip }, extraParams);
38
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
39
+ });
40
+ }
41
+ //# sourceMappingURL=activities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activities.js","sourceRoot":"","sources":["../../src/tools/activities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,qBAAqB,GACzB,sHAAsH,CAAC;AAEzH,MAAM,eAAe,GACnB,4IAA4I,CAAC;AAE/I,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,MAAsB;IAC7E,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,WAAW,EAAE,2CAA2C;QACxD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YAChE,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,kFAAkF,CAAC;YAC/F,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,WAAW,GAA2B,EAAE,CAAC;QAC/C,IAAI,MAAM,CAAC,UAAU;YAAE,WAAW,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAElE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,WAAW,MAAM,CAAC,OAAO,aAAa,EACtC,qBAAqB,EACrB,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EACtC,WAAW,CACZ,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,gBAAgB,EAChB;QACE,WAAW,EAAE,8CAA8C;QAC3D,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,kFAAkF,CAAC;YAC/F,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,WAAW,GAA2B,EAAE,CAAC;QAC/C,IAAI,MAAM,CAAC,UAAU;YAAE,WAAW,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAElE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,aAAa,EACb,eAAe,EACf,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EACtC,WAAW,CACZ,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 registerAttachmentTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=attachments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/tools/attachments.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,CAuCvF"}
@@ -0,0 +1,31 @@
1
+ import { z } from 'zod';
2
+ const ATTACHMENT_FIELDS = 'id,name,url,size,mimeType,created,author(login,name)';
3
+ export function registerAttachmentTools(server, client) {
4
+ server.registerTool('get_attachments', {
5
+ description: 'Get all attachments for an issue',
6
+ inputSchema: z.object({
7
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
8
+ }),
9
+ }, async (params) => {
10
+ const result = await client.get(`/issues/${params.issueId}/attachments`, { fields: ATTACHMENT_FIELDS });
11
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
12
+ });
13
+ server.registerTool('delete_attachment', {
14
+ description: 'Delete an attachment from an issue',
15
+ inputSchema: z.object({
16
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
17
+ attachmentId: z.string().describe('Attachment ID'),
18
+ }),
19
+ }, async (params) => {
20
+ await client.delete(`/issues/${params.issueId}/attachments/${params.attachmentId}`);
21
+ return {
22
+ content: [
23
+ {
24
+ type: 'text',
25
+ text: `Attachment ${params.attachmentId} has been deleted from issue ${params.issueId}.`,
26
+ },
27
+ ],
28
+ };
29
+ });
30
+ }
31
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/tools/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,iBAAiB,GAAG,sDAAsD,CAAC;AAEjF,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,MAAsB;IAC/E,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,WAAW,EAAE,kCAAkC;QAC/C,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,cAAc,EACvC,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAC9B,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,mBAAmB,EACnB;QACE,WAAW,EAAE,oCAAoC;QACjD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YAChE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;SACnD,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,CAAC,MAAM,CAAC,WAAW,MAAM,CAAC,OAAO,gBAAgB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QACpF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,cAAc,MAAM,CAAC,YAAY,gCAAgC,MAAM,CAAC,OAAO,GAAG;iBACzF;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 registerCommandTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/tools/commands.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAuDpF"}
@@ -0,0 +1,43 @@
1
+ import { z } from 'zod';
2
+ const ISSUE_LIST_FIELDS = 'id,idReadable,summary,resolved,project(id,name,shortName),customFields(id,name,$type,value(id,name)),tags(id,name)';
3
+ export function registerCommandTools(server, client) {
4
+ server.registerTool('execute_command', {
5
+ description: 'Execute a YouTrack command on one or more issues (e.g. "State In Progress", "Assignee me", "Priority Critical")',
6
+ inputSchema: z.object({
7
+ query: z.string().describe('YouTrack command string, e.g. "State In Progress"'),
8
+ issues: z
9
+ .array(z.string())
10
+ .describe('Array of issue readable IDs, e.g. ["BC-1", "BC-2"]'),
11
+ }),
12
+ }, async (params) => {
13
+ await client.post('/commands', {
14
+ query: params.query,
15
+ issues: params.issues.map((id) => ({ idReadable: id })),
16
+ });
17
+ return {
18
+ content: [
19
+ {
20
+ type: 'text',
21
+ text: `Command "${params.query}" executed successfully on issues: ${params.issues.join(', ')}`,
22
+ },
23
+ ],
24
+ };
25
+ });
26
+ server.registerTool('raw_query', {
27
+ description: 'Execute a raw YouTrack query and return issues with custom fields specification. Power-user tool for advanced queries.',
28
+ inputSchema: z.object({
29
+ query: z.string().describe('YouTrack search query string'),
30
+ fields: z
31
+ .string()
32
+ .optional()
33
+ .default(ISSUE_LIST_FIELDS)
34
+ .describe('Fields specification for the response'),
35
+ top: z.number().optional().default(50).describe('Maximum number of results (default 50)'),
36
+ skip: z.number().optional().default(0).describe('Number of results to skip (default 0)'),
37
+ }),
38
+ }, async (params) => {
39
+ const result = await client.list('/issues', params.fields, { top: params.top, skip: params.skip }, { query: params.query });
40
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
41
+ });
42
+ }
43
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/tools/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,iBAAiB,GACrB,oHAAoH,CAAC;AAEvH,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,MAAsB;IAC5E,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,WAAW,EACT,iHAAiH;QACnH,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;YAC/E,MAAM,EAAE,CAAC;iBACN,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,QAAQ,CAAC,oDAAoD,CAAC;SAClE,CAAC;KACH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;YAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;SACxD,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,YAAY,MAAM,CAAC,KAAK,sCAAsC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBAC/F;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,WAAW,EACX;QACE,WAAW,EACT,wHAAwH;QAC1H,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;YAC1D,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,OAAO,CAAC,iBAAiB,CAAC;iBAC1B,QAAQ,CAAC,uCAAuC,CAAC;YACpD,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,CAC9B,SAAS,EACT,MAAM,CAAC,MAAM,EACb,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EACtC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CACxB,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 registerCommentTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/tools/comments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAiFpF"}
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+ const COMMENT_FIELDS = 'id,text,author(login,name),created,updated';
3
+ const COMMENT_CREATE_FIELDS = 'id,text,author(login,name),created';
4
+ export function registerCommentTools(server, client) {
5
+ server.registerTool('get_comments', {
6
+ description: 'Get comments for a specific issue',
7
+ inputSchema: z.object({
8
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
9
+ top: z.number().optional().describe('Maximum number of comments to return'),
10
+ skip: z.number().optional().describe('Number of comments to skip'),
11
+ }),
12
+ }, async (params) => {
13
+ const result = await client.list(`/issues/${params.issueId}/comments`, COMMENT_FIELDS, { top: params.top, skip: params.skip });
14
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
15
+ });
16
+ server.registerTool('add_comment', {
17
+ description: 'Add a comment to an issue',
18
+ inputSchema: z.object({
19
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
20
+ text: z.string().describe('Comment text'),
21
+ }),
22
+ }, async (params) => {
23
+ const result = await client.post(`/issues/${params.issueId}/comments`, { text: params.text }, { fields: COMMENT_CREATE_FIELDS });
24
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
25
+ });
26
+ server.registerTool('update_comment', {
27
+ description: 'Update an existing comment on an issue',
28
+ inputSchema: z.object({
29
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
30
+ commentId: z.string().describe('Comment ID'),
31
+ text: z.string().describe('Updated comment text'),
32
+ }),
33
+ }, async (params) => {
34
+ const result = await client.post(`/issues/${params.issueId}/comments/${params.commentId}`, { text: params.text }, { fields: COMMENT_FIELDS });
35
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
36
+ });
37
+ server.registerTool('delete_comment', {
38
+ description: 'Delete a comment from an issue',
39
+ inputSchema: z.object({
40
+ issueId: z.string().describe('Issue readable ID, e.g. "BC-123"'),
41
+ commentId: z.string().describe('Comment ID'),
42
+ }),
43
+ }, async (params) => {
44
+ await client.delete(`/issues/${params.issueId}/comments/${params.commentId}`);
45
+ return {
46
+ content: [
47
+ {
48
+ type: 'text',
49
+ text: `Comment ${params.commentId} has been deleted from issue ${params.issueId}.`,
50
+ },
51
+ ],
52
+ };
53
+ });
54
+ }
55
+ //# sourceMappingURL=comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/tools/comments.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 registerCustomFieldTools(server: McpServer, client: YouTrackClient): void;
4
+ //# sourceMappingURL=custom-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-fields.d.ts","sourceRoot":"","sources":["../../src/tools/custom-fields.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AASnD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAmExF"}