@ecubelabs/atlassian-mcp 1.2.0-next.3 → 1.2.0-next.5

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.
@@ -1,8 +1,9 @@
1
- import { BaseApiService } from "./base-client.js";
2
- import { atlassianConfig } from "../config.js";
1
+ import { markdownToAdf } from 'marklassian';
2
+ import { atlassianConfig } from '../config.js';
3
+ import { BaseApiService } from './base-client.js';
3
4
  export class JiraService extends BaseApiService {
4
5
  constructor() {
5
- super(atlassianConfig.jira, "JiraService");
6
+ super(atlassianConfig.jira, 'JiraService');
6
7
  }
7
8
  /**
8
9
  * Issue 조회
@@ -10,7 +11,7 @@ export class JiraService extends BaseApiService {
10
11
  */
11
12
  async getIssue(issueKey, expand) {
12
13
  return this.makeRequest(() => this.client.get(`/issue/${issueKey}`, {
13
- params: expand ? { expand: expand.join(",") } : undefined,
14
+ params: expand ? { expand: expand.join(',') } : undefined,
14
15
  }));
15
16
  }
16
17
  /**
@@ -39,7 +40,7 @@ export class JiraService extends BaseApiService {
39
40
  body.failFast = failFast;
40
41
  if (reconcileIssues)
41
42
  body.reconcileIssues = reconcileIssues;
42
- const response = await this.makeRequest(() => this.client.post("/search/jql", body));
43
+ const response = await this.makeRequest(() => this.client.post('/search/jql', body));
43
44
  return {
44
45
  issues: response.issues || [],
45
46
  startAt: response.startAt,
@@ -64,9 +65,9 @@ export class JiraService extends BaseApiService {
64
65
  if (orderBy)
65
66
  params.orderBy = orderBy;
66
67
  if (id)
67
- params.id = id.join(",");
68
+ params.id = id.join(',');
68
69
  if (keys)
69
- params.keys = keys.join(",");
70
+ params.keys = keys.join(',');
70
71
  if (query)
71
72
  params.query = query;
72
73
  if (typeKey)
@@ -76,19 +77,19 @@ export class JiraService extends BaseApiService {
76
77
  if (action)
77
78
  params.action = action;
78
79
  if (expand)
79
- params.expand = expand.join(",");
80
+ params.expand = expand.join(',');
80
81
  if (status)
81
- params.status = status.join(",");
82
+ params.status = status.join(',');
82
83
  if (properties) {
83
84
  // Handle the nested StringList structure
84
85
  properties.forEach((prop, index) => {
85
- params[`properties[${index}]`] = prop.join(",");
86
+ params[`properties[${index}]`] = prop.join(',');
86
87
  });
87
88
  }
88
89
  if (propertyQuery)
89
90
  params.propertyQuery = propertyQuery;
90
91
  }
91
- return this.makeRequest(() => this.client.get("/project/search", { params }));
92
+ return this.makeRequest(() => this.client.get('/project/search', { params }));
92
93
  }
93
94
  /**
94
95
  * 이슈 댓글 목록 조회
@@ -106,7 +107,7 @@ export class JiraService extends BaseApiService {
106
107
  if (orderBy)
107
108
  params.orderBy = orderBy;
108
109
  if (expand)
109
- params.expand = expand.join(",");
110
+ params.expand = expand.join(',');
110
111
  }
111
112
  return this.makeRequest(() => this.client.get(`/issue/${issueKey}/comment`, { params }));
112
113
  }
@@ -143,16 +144,16 @@ export class JiraService extends BaseApiService {
143
144
  if (maxResults !== undefined)
144
145
  params.maxResults = maxResults;
145
146
  }
146
- return this.makeRequest(() => this.client.get("/field/search", { params }));
147
+ return this.makeRequest(() => this.client.get('/field/search', { params }));
147
148
  }
148
149
  /**
149
150
  * JQL 파싱 및 검증
150
151
  * @see https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-jql/#api-rest-api-3-jql-parse-post
151
152
  */
152
153
  async parseJql(query, validation) {
153
- return this.makeRequest(() => this.client.post("/jql/parse", {
154
+ return this.makeRequest(() => this.client.post('/jql/parse', {
154
155
  query,
155
- validation: validation || "strict",
156
+ validation: validation || 'strict',
156
157
  }));
157
158
  }
158
159
  /**
@@ -173,21 +174,7 @@ export class JiraService extends BaseApiService {
173
174
  }
174
175
  // Optional fields
175
176
  if (options.description) {
176
- fields.description = {
177
- type: "doc",
178
- version: 1,
179
- content: [
180
- {
181
- type: "paragraph",
182
- content: [
183
- {
184
- type: "text",
185
- text: options.description,
186
- },
187
- ],
188
- },
189
- ],
190
- };
177
+ fields.description = markdownToAdf(options.description);
191
178
  }
192
179
  if (options.assigneeAccountId) {
193
180
  fields.assignee = { accountId: options.assigneeAccountId };
@@ -205,7 +192,7 @@ export class JiraService extends BaseApiService {
205
192
  if (options.additionalFields) {
206
193
  Object.assign(fields, options.additionalFields);
207
194
  }
208
- return this.makeRequest(() => this.client.post("/issue", { fields }));
195
+ return this.makeRequest(() => this.client.post('/issue', { fields }));
209
196
  }
210
197
  /**
211
198
  * 이슈 담당자 변경
@@ -226,14 +213,14 @@ export class JiraService extends BaseApiService {
226
213
  }
227
214
  if (options.description) {
228
215
  fields.description = {
229
- type: "doc",
216
+ type: 'doc',
230
217
  version: 1,
231
218
  content: [
232
219
  {
233
- type: "paragraph",
220
+ type: 'paragraph',
234
221
  content: [
235
222
  {
236
- type: "text",
223
+ type: 'text',
237
224
  text: options.description,
238
225
  },
239
226
  ],
@@ -278,7 +265,7 @@ export class JiraService extends BaseApiService {
278
265
  if (property)
279
266
  params.property = property;
280
267
  }
281
- return this.makeRequest(() => this.client.get("/user/search", { params }));
268
+ return this.makeRequest(() => this.client.get('/user/search', { params }));
282
269
  }
283
270
  /**
284
271
  * 사용자 선택 자동완성
@@ -300,7 +287,7 @@ export class JiraService extends BaseApiService {
300
287
  params.avatarSize = options.avatarSize;
301
288
  if (options.excludeConnectUsers !== undefined)
302
289
  params.excludeConnectUsers = options.excludeConnectUsers;
303
- return this.makeRequest(() => this.client.get("/user/picker", { params }));
290
+ return this.makeRequest(() => this.client.get('/user/picker', { params }));
304
291
  }
305
292
  /**
306
293
  * 할당 가능한 사용자 검색
@@ -309,7 +296,7 @@ export class JiraService extends BaseApiService {
309
296
  async searchAssignableUsers(options) {
310
297
  const params = {};
311
298
  if (options.projectKeys)
312
- params.projectKeys = options.projectKeys.join(",");
299
+ params.projectKeys = options.projectKeys.join(',');
313
300
  if (options.query)
314
301
  params.query = options.query;
315
302
  if (options.username)
@@ -320,7 +307,7 @@ export class JiraService extends BaseApiService {
320
307
  params.startAt = options.startAt;
321
308
  if (options.maxResults !== undefined)
322
309
  params.maxResults = options.maxResults;
323
- return this.makeRequest(() => this.client.get("/user/assignable/search", { params }));
310
+ return this.makeRequest(() => this.client.get('/user/assignable/search', { params }));
324
311
  }
325
312
  /**
326
313
  * 권한별 사용자 검색
@@ -344,7 +331,7 @@ export class JiraService extends BaseApiService {
344
331
  params.startAt = options.startAt;
345
332
  if (options.maxResults !== undefined)
346
333
  params.maxResults = options.maxResults;
347
- return this.makeRequest(() => this.client.get("/user/permission/search", { params }));
334
+ return this.makeRequest(() => this.client.get('/user/permission/search', { params }));
348
335
  }
349
336
  /**
350
337
  * 현재 사용자 정보 조회
@@ -353,9 +340,9 @@ export class JiraService extends BaseApiService {
353
340
  async getMyself(expand) {
354
341
  const params = {};
355
342
  if (expand) {
356
- params.expand = expand.join(",");
343
+ params.expand = expand.join(',');
357
344
  }
358
- return this.makeRequest(() => this.client.get("/myself", { params }));
345
+ return this.makeRequest(() => this.client.get('/myself', { params }));
359
346
  }
360
347
  /**
361
348
  * 현재 사용자의 권한 조회
@@ -382,7 +369,7 @@ export class JiraService extends BaseApiService {
382
369
  if (commentId)
383
370
  params.commentId = commentId;
384
371
  }
385
- return this.makeRequest(() => this.client.get("/mypermissions", { params }));
372
+ return this.makeRequest(() => this.client.get('/mypermissions', { params }));
386
373
  }
387
374
  /**
388
375
  * 현재 사용자 설정 업데이트
@@ -398,7 +385,7 @@ export class JiraService extends BaseApiService {
398
385
  body.timeZone = options.timeZone;
399
386
  if (options.locale)
400
387
  body.locale = options.locale;
401
- return this.makeRequest(() => this.client.put("/myself", body));
388
+ return this.makeRequest(() => this.client.put('/myself', body));
402
389
  }
403
390
  /**
404
391
  * 현재 사용자의 설정 값 조회
@@ -409,7 +396,7 @@ export class JiraService extends BaseApiService {
409
396
  if (key) {
410
397
  params.key = key;
411
398
  }
412
- return this.makeRequest(() => this.client.get("/mypreferences", { params }));
399
+ return this.makeRequest(() => this.client.get('/mypreferences', { params }));
413
400
  }
414
401
  /**
415
402
  * 현재 사용자의 설정 값 업데이트
@@ -417,28 +404,28 @@ export class JiraService extends BaseApiService {
417
404
  */
418
405
  async updateMyPreferences(key, value) {
419
406
  const params = { key };
420
- return this.makeRequest(() => this.client.put("/mypreferences", value, { params }));
407
+ return this.makeRequest(() => this.client.put('/mypreferences', value, { params }));
421
408
  }
422
409
  /**
423
410
  * 현재 사용자의 로케일 조회
424
411
  * @see https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-myself/#api-rest-api-3-mypreferences-locale-get
425
412
  */
426
413
  async getMyLocale() {
427
- return this.makeRequest(() => this.client.get("/mypreferences/locale"));
414
+ return this.makeRequest(() => this.client.get('/mypreferences/locale'));
428
415
  }
429
416
  /**
430
417
  * 현재 사용자의 로케일 업데이트
431
418
  * @see https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-myself/#api-rest-api-3-mypreferences-locale-put
432
419
  */
433
420
  async updateMyLocale(locale) {
434
- return this.makeRequest(() => this.client.put("/mypreferences/locale", { locale }));
421
+ return this.makeRequest(() => this.client.put('/mypreferences/locale', { locale }));
435
422
  }
436
423
  /**
437
424
  * 모든 우선순위 조회
438
425
  * @see https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-priorities/#api-rest-api-3-priority-get
439
426
  */
440
427
  async getPriorities() {
441
- return this.makeRequest(() => this.client.get("/priority"));
428
+ return this.makeRequest(() => this.client.get('/priority'));
442
429
  }
443
430
  /**
444
431
  * 특정 우선순위 조회
@@ -460,15 +447,15 @@ export class JiraService extends BaseApiService {
460
447
  if (maxResults !== undefined)
461
448
  params.maxResults = maxResults;
462
449
  if (id)
463
- params.id = id.join(",");
450
+ params.id = id.join(',');
464
451
  if (projectId)
465
- params.projectId = projectId.join(",");
452
+ params.projectId = projectId.join(',');
466
453
  if (priorityName)
467
454
  params.priorityName = priorityName;
468
455
  if (onlyDefault !== undefined)
469
456
  params.onlyDefault = onlyDefault;
470
457
  }
471
- return this.makeRequest(() => this.client.get("/priority/search", { params }));
458
+ return this.makeRequest(() => this.client.get('/priority/search', { params }));
472
459
  }
473
460
  /**
474
461
  * 이슈의 가능한 전환 조회
@@ -477,7 +464,7 @@ export class JiraService extends BaseApiService {
477
464
  async getIssueTransitions(issueKey, expand) {
478
465
  const params = {};
479
466
  if (expand) {
480
- params.expand = expand.join(",");
467
+ params.expand = expand.join(',');
481
468
  }
482
469
  return this.makeRequest(() => this.client.get(`/issue/${issueKey}/transitions`, { params }));
483
470
  }
@@ -495,14 +482,14 @@ export class JiraService extends BaseApiService {
495
482
  {
496
483
  add: {
497
484
  body: {
498
- type: "doc",
485
+ type: 'doc',
499
486
  version: 1,
500
487
  content: [
501
488
  {
502
- type: "paragraph",
489
+ type: 'paragraph',
503
490
  content: [
504
491
  {
505
- type: "text",
492
+ type: 'text',
506
493
  text: options.comment.body,
507
494
  },
508
495
  ],
@@ -535,7 +522,7 @@ export class JiraService extends BaseApiService {
535
522
  * @see https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflow-statuses/#api-rest-api-3-status-get
536
523
  */
537
524
  async getStatuses() {
538
- return this.makeRequest(() => this.client.get("/status"));
525
+ return this.makeRequest(() => this.client.get('/status'));
539
526
  }
540
527
  /**
541
528
  * 특정 상태 조회
@@ -563,7 +550,7 @@ export class JiraService extends BaseApiService {
563
550
  if (expand)
564
551
  params.expand = expand;
565
552
  }
566
- return this.makeRequest(() => this.client.get("/statuses/search", { params }));
553
+ return this.makeRequest(() => this.client.get('/statuses/search', { params }));
567
554
  }
568
555
  /**
569
556
  * 이슈에 댓글 추가
@@ -571,21 +558,7 @@ export class JiraService extends BaseApiService {
571
558
  */
572
559
  async createComment(issueKey, options) {
573
560
  const body = {
574
- body: {
575
- type: "doc",
576
- version: 1,
577
- content: [
578
- {
579
- type: "paragraph",
580
- content: [
581
- {
582
- type: "text",
583
- text: options.body,
584
- },
585
- ],
586
- },
587
- ],
588
- },
561
+ body: markdownToAdf(options.body),
589
562
  };
590
563
  if (options.visibility) {
591
564
  body.visibility = options.visibility;
@@ -602,14 +575,14 @@ export class JiraService extends BaseApiService {
602
575
  async updateComment(issueKey, commentId, options) {
603
576
  const body = {
604
577
  body: {
605
- type: "doc",
578
+ type: 'doc',
606
579
  version: 1,
607
580
  content: [
608
581
  {
609
- type: "paragraph",
582
+ type: 'paragraph',
610
583
  content: [
611
584
  {
612
- type: "text",
585
+ type: 'text',
613
586
  text: options.body,
614
587
  },
615
588
  ],
@@ -648,7 +621,7 @@ export class JiraService extends BaseApiService {
648
621
  * @see https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-link-types/#api-rest-api-3-issuelinktype-get
649
622
  */
650
623
  async getIssueLinkTypes() {
651
- return this.makeRequest(() => this.client.get("/issueLinkType"));
624
+ return this.makeRequest(() => this.client.get('/issueLinkType'));
652
625
  }
653
626
  /**
654
627
  * 특정 이슈 링크 타입 조회
@@ -670,14 +643,14 @@ export class JiraService extends BaseApiService {
670
643
  if (options.comment) {
671
644
  body.comment = {
672
645
  body: {
673
- type: "doc",
646
+ type: 'doc',
674
647
  version: 1,
675
648
  content: [
676
649
  {
677
- type: "paragraph",
650
+ type: 'paragraph',
678
651
  content: [
679
652
  {
680
- type: "text",
653
+ type: 'text',
681
654
  text: options.comment.body,
682
655
  },
683
656
  ],
@@ -689,7 +662,7 @@ export class JiraService extends BaseApiService {
689
662
  }),
690
663
  };
691
664
  }
692
- return this.makeRequest(() => this.client.post("/issueLink", body));
665
+ return this.makeRequest(() => this.client.post('/issueLink', body));
693
666
  }
694
667
  /**
695
668
  * 이슈 링크 조회
@@ -710,7 +683,7 @@ export class JiraService extends BaseApiService {
710
683
  */
711
684
  async getIssueWithLinks(issueKey) {
712
685
  return this.makeRequest(() => this.client.get(`/issue/${issueKey}`, {
713
- params: { fields: "*all", expand: "issuelinks" },
686
+ params: { fields: '*all', expand: 'issuelinks' },
714
687
  }));
715
688
  }
716
689
  /**
@@ -727,7 +700,7 @@ export class JiraService extends BaseApiService {
727
700
  async addWatcher(issueKey, accountId) {
728
701
  return this.makeRequest(() => this.client.post(`/issue/${issueKey}/watchers`, `"${accountId}"`, {
729
702
  headers: {
730
- "Content-Type": "application/json",
703
+ 'Content-Type': 'application/json',
731
704
  },
732
705
  }));
733
706
  }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@ecubelabs/atlassian-mcp",
3
- "version": "1.2.0-next.3",
3
+ "version": "1.2.0-next.5",
4
4
  "bin": "./dist/index.js",
5
5
  "repository": {
6
6
  "url": "https://github.com/Ecube-Labs/skynet.git"
7
7
  },
8
8
  "scripts": {
9
+ "lint": "eslint \"./src/**/*.ts\"",
9
10
  "build": "tsc && node -e \"require('fs').chmodSync('dist/index.js', '755')\"",
10
11
  "prepack": "yarn build"
11
12
  },
@@ -22,12 +23,16 @@
22
23
  "axios": "^1.7.9",
23
24
  "axios-retry": "^4.5.0",
24
25
  "dotenv": "^17.2.0",
26
+ "marklassian": "^1.1.0",
25
27
  "p-limit": "^5.0.0",
26
28
  "winston": "^3.17.0",
27
29
  "zod": "^3.24.2"
28
30
  },
29
31
  "devDependencies": {
30
32
  "@types/node": "^20.14.8",
33
+ "eslint": "^8.57.0",
34
+ "eslint-config-skynet": "^0.0.0",
35
+ "prettier": "^3.5.1",
31
36
  "semantic-release": "^24.2.7",
32
37
  "semantic-release-yarn": "^3.0.2",
33
38
  "ts-node": "^10.9.2",