@zereight/mcp-gitlab 1.0.30 → 1.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/build/index.js +82 -76
- package/package.json +4 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Roo
|
|
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/build/index.js
CHANGED
|
@@ -3,12 +3,16 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
5
|
import fetch from "node-fetch";
|
|
6
|
+
import { SocksProxyAgent } from 'socks-proxy-agent';
|
|
7
|
+
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
8
|
+
import { HttpProxyAgent } from 'http-proxy-agent';
|
|
6
9
|
import { z } from "zod";
|
|
7
10
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
8
11
|
import { fileURLToPath } from "url";
|
|
9
12
|
import { dirname } from "path";
|
|
10
13
|
import fs from "fs";
|
|
11
14
|
import path from "path";
|
|
15
|
+
import { URL } from 'url';
|
|
12
16
|
import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, ListIssuesSchema, GetIssueSchema, UpdateIssueSchema, DeleteIssueSchema, GitLabIssueLinkSchema, GitLabIssueWithLinkDetailsSchema, ListIssueLinksSchema, GetIssueLinkSchema, CreateIssueLinkSchema, DeleteIssueLinkSchema, ListNamespacesSchema, GetNamespaceSchema, VerifyNamespaceSchema, GetProjectSchema, ListProjectsSchema, ListLabelsSchema, GetLabelSchema, CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema, CreateNoteSchema, ListGroupProjectsSchema,
|
|
13
17
|
// Discussion Schemas
|
|
14
18
|
GitLabDiscussionNoteSchema, // Added
|
|
@@ -40,6 +44,44 @@ const server = new Server({
|
|
|
40
44
|
});
|
|
41
45
|
const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_PERSONAL_ACCESS_TOKEN;
|
|
42
46
|
const GITLAB_READ_ONLY_MODE = process.env.GITLAB_READ_ONLY_MODE === "true";
|
|
47
|
+
// Add proxy configuration
|
|
48
|
+
const HTTP_PROXY = process.env.HTTP_PROXY;
|
|
49
|
+
const HTTPS_PROXY = process.env.HTTPS_PROXY;
|
|
50
|
+
// Configure proxy agents if proxies are set
|
|
51
|
+
let httpAgent = undefined;
|
|
52
|
+
let httpsAgent = undefined;
|
|
53
|
+
if (HTTP_PROXY) {
|
|
54
|
+
if (HTTP_PROXY.startsWith('socks')) {
|
|
55
|
+
httpAgent = new SocksProxyAgent(HTTP_PROXY);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
httpAgent = new HttpProxyAgent(HTTP_PROXY);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (HTTPS_PROXY) {
|
|
62
|
+
if (HTTPS_PROXY.startsWith('socks')) {
|
|
63
|
+
httpsAgent = new SocksProxyAgent(HTTPS_PROXY);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
httpsAgent = new HttpsProxyAgent(HTTPS_PROXY);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Modify DEFAULT_HEADERS to include agent configuration
|
|
70
|
+
const DEFAULT_HEADERS = {
|
|
71
|
+
Accept: "application/json",
|
|
72
|
+
"Content-Type": "application/json",
|
|
73
|
+
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
74
|
+
};
|
|
75
|
+
// Create a default fetch configuration object that includes proxy agents if set
|
|
76
|
+
const DEFAULT_FETCH_CONFIG = {
|
|
77
|
+
headers: DEFAULT_HEADERS,
|
|
78
|
+
agent: (parsedUrl) => {
|
|
79
|
+
if (parsedUrl.protocol === 'https:') {
|
|
80
|
+
return httpsAgent;
|
|
81
|
+
}
|
|
82
|
+
return httpAgent;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
43
85
|
// Define all available tools
|
|
44
86
|
const allTools = [
|
|
45
87
|
{
|
|
@@ -259,15 +301,6 @@ if (!GITLAB_PERSONAL_ACCESS_TOKEN) {
|
|
|
259
301
|
console.error("GITLAB_PERSONAL_ACCESS_TOKEN environment variable is not set");
|
|
260
302
|
process.exit(1);
|
|
261
303
|
}
|
|
262
|
-
/**
|
|
263
|
-
* Common headers for GitLab API requests
|
|
264
|
-
* GitLab API 공통 헤더 (Common headers for GitLab API)
|
|
265
|
-
*/
|
|
266
|
-
const DEFAULT_HEADERS = {
|
|
267
|
-
Accept: "application/json",
|
|
268
|
-
"Content-Type": "application/json",
|
|
269
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
270
|
-
};
|
|
271
304
|
/**
|
|
272
305
|
* Utility function for handling GitLab API errors
|
|
273
306
|
* API 에러 처리를 위한 유틸리티 함수 (Utility function for handling API errors)
|
|
@@ -299,14 +332,13 @@ async function handleGitLabError(response) {
|
|
|
299
332
|
* @returns {Promise<GitLabFork>} The created fork
|
|
300
333
|
*/
|
|
301
334
|
async function forkProject(projectId, namespace) {
|
|
302
|
-
// API 엔드포인트 URL 생성
|
|
303
335
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/fork`);
|
|
304
336
|
if (namespace) {
|
|
305
337
|
url.searchParams.append("namespace", namespace);
|
|
306
338
|
}
|
|
307
339
|
const response = await fetch(url.toString(), {
|
|
340
|
+
...DEFAULT_FETCH_CONFIG,
|
|
308
341
|
method: "POST",
|
|
309
|
-
headers: DEFAULT_HEADERS,
|
|
310
342
|
});
|
|
311
343
|
// 이미 존재하는 프로젝트인 경우 처리
|
|
312
344
|
if (response.status === 409) {
|
|
@@ -327,8 +359,8 @@ async function forkProject(projectId, namespace) {
|
|
|
327
359
|
async function createBranch(projectId, options) {
|
|
328
360
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/branches`);
|
|
329
361
|
const response = await fetch(url.toString(), {
|
|
362
|
+
...DEFAULT_FETCH_CONFIG,
|
|
330
363
|
method: "POST",
|
|
331
|
-
headers: DEFAULT_HEADERS,
|
|
332
364
|
body: JSON.stringify({
|
|
333
365
|
branch: options.name,
|
|
334
366
|
ref: options.ref,
|
|
@@ -347,7 +379,7 @@ async function createBranch(projectId, options) {
|
|
|
347
379
|
async function getDefaultBranchRef(projectId) {
|
|
348
380
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`);
|
|
349
381
|
const response = await fetch(url.toString(), {
|
|
350
|
-
|
|
382
|
+
...DEFAULT_FETCH_CONFIG,
|
|
351
383
|
});
|
|
352
384
|
await handleGitLabError(response);
|
|
353
385
|
const project = GitLabRepositorySchema.parse(await response.json());
|
|
@@ -371,7 +403,7 @@ async function getFileContents(projectId, filePath, ref) {
|
|
|
371
403
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/files/${encodedPath}`);
|
|
372
404
|
url.searchParams.append("ref", ref);
|
|
373
405
|
const response = await fetch(url.toString(), {
|
|
374
|
-
|
|
406
|
+
...DEFAULT_FETCH_CONFIG,
|
|
375
407
|
});
|
|
376
408
|
// 파일을 찾을 수 없는 경우 처리
|
|
377
409
|
if (response.status === 404) {
|
|
@@ -398,8 +430,8 @@ async function getFileContents(projectId, filePath, ref) {
|
|
|
398
430
|
async function createIssue(projectId, options) {
|
|
399
431
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`);
|
|
400
432
|
const response = await fetch(url.toString(), {
|
|
433
|
+
...DEFAULT_FETCH_CONFIG,
|
|
401
434
|
method: "POST",
|
|
402
|
-
headers: DEFAULT_HEADERS,
|
|
403
435
|
body: JSON.stringify({
|
|
404
436
|
title: options.title,
|
|
405
437
|
description: options.description,
|
|
@@ -440,7 +472,7 @@ async function listIssues(projectId, options = {}) {
|
|
|
440
472
|
}
|
|
441
473
|
});
|
|
442
474
|
const response = await fetch(url.toString(), {
|
|
443
|
-
|
|
475
|
+
...DEFAULT_FETCH_CONFIG,
|
|
444
476
|
});
|
|
445
477
|
await handleGitLabError(response);
|
|
446
478
|
const data = await response.json();
|
|
@@ -457,7 +489,7 @@ async function listIssues(projectId, options = {}) {
|
|
|
457
489
|
async function getIssue(projectId, issueIid) {
|
|
458
490
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`);
|
|
459
491
|
const response = await fetch(url.toString(), {
|
|
460
|
-
|
|
492
|
+
...DEFAULT_FETCH_CONFIG,
|
|
461
493
|
});
|
|
462
494
|
await handleGitLabError(response);
|
|
463
495
|
const data = await response.json();
|
|
@@ -480,8 +512,8 @@ async function updateIssue(projectId, issueIid, options) {
|
|
|
480
512
|
body.labels = body.labels.join(",");
|
|
481
513
|
}
|
|
482
514
|
const response = await fetch(url.toString(), {
|
|
515
|
+
...DEFAULT_FETCH_CONFIG,
|
|
483
516
|
method: "PUT",
|
|
484
|
-
headers: DEFAULT_HEADERS,
|
|
485
517
|
body: JSON.stringify(body),
|
|
486
518
|
});
|
|
487
519
|
await handleGitLabError(response);
|
|
@@ -499,8 +531,8 @@ async function updateIssue(projectId, issueIid, options) {
|
|
|
499
531
|
async function deleteIssue(projectId, issueIid) {
|
|
500
532
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`);
|
|
501
533
|
const response = await fetch(url.toString(), {
|
|
534
|
+
...DEFAULT_FETCH_CONFIG,
|
|
502
535
|
method: "DELETE",
|
|
503
|
-
headers: DEFAULT_HEADERS,
|
|
504
536
|
});
|
|
505
537
|
await handleGitLabError(response);
|
|
506
538
|
}
|
|
@@ -515,7 +547,7 @@ async function deleteIssue(projectId, issueIid) {
|
|
|
515
547
|
async function listIssueLinks(projectId, issueIid) {
|
|
516
548
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links`);
|
|
517
549
|
const response = await fetch(url.toString(), {
|
|
518
|
-
|
|
550
|
+
...DEFAULT_FETCH_CONFIG,
|
|
519
551
|
});
|
|
520
552
|
await handleGitLabError(response);
|
|
521
553
|
const data = await response.json();
|
|
@@ -533,7 +565,7 @@ async function listIssueLinks(projectId, issueIid) {
|
|
|
533
565
|
async function getIssueLink(projectId, issueIid, issueLinkId) {
|
|
534
566
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links/${issueLinkId}`);
|
|
535
567
|
const response = await fetch(url.toString(), {
|
|
536
|
-
|
|
568
|
+
...DEFAULT_FETCH_CONFIG,
|
|
537
569
|
});
|
|
538
570
|
await handleGitLabError(response);
|
|
539
571
|
const data = await response.json();
|
|
@@ -553,8 +585,8 @@ async function getIssueLink(projectId, issueIid, issueLinkId) {
|
|
|
553
585
|
async function createIssueLink(projectId, issueIid, targetProjectId, targetIssueIid, linkType = "relates_to") {
|
|
554
586
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links`);
|
|
555
587
|
const response = await fetch(url.toString(), {
|
|
588
|
+
...DEFAULT_FETCH_CONFIG,
|
|
556
589
|
method: "POST",
|
|
557
|
-
headers: DEFAULT_HEADERS,
|
|
558
590
|
body: JSON.stringify({
|
|
559
591
|
target_project_id: targetProjectId,
|
|
560
592
|
target_issue_iid: targetIssueIid,
|
|
@@ -577,8 +609,8 @@ async function createIssueLink(projectId, issueIid, targetProjectId, targetIssue
|
|
|
577
609
|
async function deleteIssueLink(projectId, issueIid, issueLinkId) {
|
|
578
610
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links/${issueLinkId}`);
|
|
579
611
|
const response = await fetch(url.toString(), {
|
|
612
|
+
...DEFAULT_FETCH_CONFIG,
|
|
580
613
|
method: "DELETE",
|
|
581
|
-
headers: DEFAULT_HEADERS,
|
|
582
614
|
});
|
|
583
615
|
await handleGitLabError(response);
|
|
584
616
|
}
|
|
@@ -593,12 +625,8 @@ async function deleteIssueLink(projectId, issueIid, issueLinkId) {
|
|
|
593
625
|
async function createMergeRequest(projectId, options) {
|
|
594
626
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests`);
|
|
595
627
|
const response = await fetch(url.toString(), {
|
|
628
|
+
...DEFAULT_FETCH_CONFIG,
|
|
596
629
|
method: "POST",
|
|
597
|
-
headers: {
|
|
598
|
-
Accept: "application/json",
|
|
599
|
-
"Content-Type": "application/json",
|
|
600
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
601
|
-
},
|
|
602
630
|
body: JSON.stringify({
|
|
603
631
|
title: options.title,
|
|
604
632
|
description: options.description,
|
|
@@ -630,7 +658,7 @@ async function createMergeRequest(projectId, options) {
|
|
|
630
658
|
async function listMergeRequestDiscussions(projectId, mergeRequestIid) {
|
|
631
659
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}/discussions`);
|
|
632
660
|
const response = await fetch(url.toString(), {
|
|
633
|
-
|
|
661
|
+
...DEFAULT_FETCH_CONFIG,
|
|
634
662
|
});
|
|
635
663
|
await handleGitLabError(response);
|
|
636
664
|
const data = await response.json();
|
|
@@ -656,8 +684,8 @@ async function updateMergeRequestNote(projectId, mergeRequestIid, discussionId,
|
|
|
656
684
|
payload.resolved = resolved;
|
|
657
685
|
}
|
|
658
686
|
const response = await fetch(url.toString(), {
|
|
687
|
+
...DEFAULT_FETCH_CONFIG,
|
|
659
688
|
method: "PUT",
|
|
660
|
-
headers: DEFAULT_HEADERS,
|
|
661
689
|
body: JSON.stringify(payload),
|
|
662
690
|
});
|
|
663
691
|
await handleGitLabError(response);
|
|
@@ -723,12 +751,8 @@ async function createOrUpdateFile(projectId, filePath, content, commitMessage, b
|
|
|
723
751
|
}
|
|
724
752
|
}
|
|
725
753
|
const response = await fetch(url.toString(), {
|
|
754
|
+
...DEFAULT_FETCH_CONFIG,
|
|
726
755
|
method,
|
|
727
|
-
headers: {
|
|
728
|
-
Accept: "application/json",
|
|
729
|
-
"Content-Type": "application/json",
|
|
730
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
731
|
-
},
|
|
732
756
|
body: JSON.stringify(body),
|
|
733
757
|
});
|
|
734
758
|
if (!response.ok) {
|
|
@@ -753,12 +777,8 @@ async function createTree(projectId, files, ref) {
|
|
|
753
777
|
url.searchParams.append("ref", ref);
|
|
754
778
|
}
|
|
755
779
|
const response = await fetch(url.toString(), {
|
|
780
|
+
...DEFAULT_FETCH_CONFIG,
|
|
756
781
|
method: "POST",
|
|
757
|
-
headers: {
|
|
758
|
-
Accept: "application/json",
|
|
759
|
-
"Content-Type": "application/json",
|
|
760
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
761
|
-
},
|
|
762
782
|
body: JSON.stringify({
|
|
763
783
|
files: files.map((file) => ({
|
|
764
784
|
file_path: file.path,
|
|
@@ -791,12 +811,8 @@ async function createTree(projectId, files, ref) {
|
|
|
791
811
|
async function createCommit(projectId, message, branch, actions) {
|
|
792
812
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/commits`);
|
|
793
813
|
const response = await fetch(url.toString(), {
|
|
814
|
+
...DEFAULT_FETCH_CONFIG,
|
|
794
815
|
method: "POST",
|
|
795
|
-
headers: {
|
|
796
|
-
Accept: "application/json",
|
|
797
|
-
"Content-Type": "application/json",
|
|
798
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
799
|
-
},
|
|
800
816
|
body: JSON.stringify({
|
|
801
817
|
branch,
|
|
802
818
|
commit_message: message,
|
|
@@ -836,11 +852,7 @@ async function searchProjects(query, page = 1, perPage = 20) {
|
|
|
836
852
|
url.searchParams.append("order_by", "id");
|
|
837
853
|
url.searchParams.append("sort", "desc");
|
|
838
854
|
const response = await fetch(url.toString(), {
|
|
839
|
-
|
|
840
|
-
Accept: "application/json",
|
|
841
|
-
"Content-Type": "application/json",
|
|
842
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
843
|
-
},
|
|
855
|
+
...DEFAULT_FETCH_CONFIG,
|
|
844
856
|
});
|
|
845
857
|
if (!response.ok) {
|
|
846
858
|
const errorBody = await response.text();
|
|
@@ -867,12 +879,8 @@ async function searchProjects(query, page = 1, perPage = 20) {
|
|
|
867
879
|
*/
|
|
868
880
|
async function createRepository(options) {
|
|
869
881
|
const response = await fetch(`${GITLAB_API_URL}/projects`, {
|
|
882
|
+
...DEFAULT_FETCH_CONFIG,
|
|
870
883
|
method: "POST",
|
|
871
|
-
headers: {
|
|
872
|
-
Accept: "application/json",
|
|
873
|
-
"Content-Type": "application/json",
|
|
874
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
875
|
-
},
|
|
876
884
|
body: JSON.stringify({
|
|
877
885
|
name: options.name,
|
|
878
886
|
description: options.description,
|
|
@@ -900,7 +908,7 @@ async function createRepository(options) {
|
|
|
900
908
|
async function getMergeRequest(projectId, mergeRequestIid) {
|
|
901
909
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}`);
|
|
902
910
|
const response = await fetch(url.toString(), {
|
|
903
|
-
|
|
911
|
+
...DEFAULT_FETCH_CONFIG,
|
|
904
912
|
});
|
|
905
913
|
await handleGitLabError(response);
|
|
906
914
|
return GitLabMergeRequestSchema.parse(await response.json());
|
|
@@ -920,7 +928,7 @@ async function getMergeRequestDiffs(projectId, mergeRequestIid, view) {
|
|
|
920
928
|
url.searchParams.append("view", view);
|
|
921
929
|
}
|
|
922
930
|
const response = await fetch(url.toString(), {
|
|
923
|
-
|
|
931
|
+
...DEFAULT_FETCH_CONFIG,
|
|
924
932
|
});
|
|
925
933
|
await handleGitLabError(response);
|
|
926
934
|
const data = (await response.json());
|
|
@@ -938,8 +946,8 @@ async function getMergeRequestDiffs(projectId, mergeRequestIid, view) {
|
|
|
938
946
|
async function updateMergeRequest(projectId, mergeRequestIid, options) {
|
|
939
947
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}`);
|
|
940
948
|
const response = await fetch(url.toString(), {
|
|
949
|
+
...DEFAULT_FETCH_CONFIG,
|
|
941
950
|
method: "PUT",
|
|
942
|
-
headers: DEFAULT_HEADERS,
|
|
943
951
|
body: JSON.stringify(options),
|
|
944
952
|
});
|
|
945
953
|
await handleGitLabError(response);
|
|
@@ -962,8 +970,8 @@ noteableIid, body) {
|
|
|
962
970
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/${noteableType}s/${noteableIid}/notes` // Using plural form (issues/merge_requests) as per GitLab API documentation
|
|
963
971
|
);
|
|
964
972
|
const response = await fetch(url.toString(), {
|
|
973
|
+
...DEFAULT_FETCH_CONFIG,
|
|
965
974
|
method: "POST",
|
|
966
|
-
headers: DEFAULT_HEADERS,
|
|
967
975
|
body: JSON.stringify({ body }),
|
|
968
976
|
});
|
|
969
977
|
if (!response.ok) {
|
|
@@ -994,7 +1002,7 @@ async function listNamespaces(options) {
|
|
|
994
1002
|
url.searchParams.append("top_level_only", "true");
|
|
995
1003
|
}
|
|
996
1004
|
const response = await fetch(url.toString(), {
|
|
997
|
-
|
|
1005
|
+
...DEFAULT_FETCH_CONFIG,
|
|
998
1006
|
});
|
|
999
1007
|
await handleGitLabError(response);
|
|
1000
1008
|
const data = await response.json();
|
|
@@ -1010,7 +1018,7 @@ async function listNamespaces(options) {
|
|
|
1010
1018
|
async function getNamespace(id) {
|
|
1011
1019
|
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(id)}`);
|
|
1012
1020
|
const response = await fetch(url.toString(), {
|
|
1013
|
-
|
|
1021
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1014
1022
|
});
|
|
1015
1023
|
await handleGitLabError(response);
|
|
1016
1024
|
const data = await response.json();
|
|
@@ -1030,7 +1038,7 @@ async function verifyNamespaceExistence(namespacePath, parentId) {
|
|
|
1030
1038
|
url.searchParams.append("parent_id", parentId.toString());
|
|
1031
1039
|
}
|
|
1032
1040
|
const response = await fetch(url.toString(), {
|
|
1033
|
-
|
|
1041
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1034
1042
|
});
|
|
1035
1043
|
await handleGitLabError(response);
|
|
1036
1044
|
const data = await response.json();
|
|
@@ -1059,7 +1067,7 @@ async function getProject(projectId, options = {}) {
|
|
|
1059
1067
|
url.searchParams.append("with_custom_attributes", "true");
|
|
1060
1068
|
}
|
|
1061
1069
|
const response = await fetch(url.toString(), {
|
|
1062
|
-
|
|
1070
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1063
1071
|
});
|
|
1064
1072
|
await handleGitLabError(response);
|
|
1065
1073
|
const data = await response.json();
|
|
@@ -1087,8 +1095,7 @@ async function listProjects(options = {}) {
|
|
|
1087
1095
|
}
|
|
1088
1096
|
// Make the API request
|
|
1089
1097
|
const response = await fetch(`${GITLAB_API_URL}/projects?${params.toString()}`, {
|
|
1090
|
-
|
|
1091
|
-
headers: DEFAULT_HEADERS,
|
|
1098
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1092
1099
|
});
|
|
1093
1100
|
// Handle errors
|
|
1094
1101
|
await handleGitLabError(response);
|
|
@@ -1119,7 +1126,7 @@ async function listLabels(projectId, options = {}) {
|
|
|
1119
1126
|
});
|
|
1120
1127
|
// Make the API request
|
|
1121
1128
|
const response = await fetch(url.toString(), {
|
|
1122
|
-
|
|
1129
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1123
1130
|
});
|
|
1124
1131
|
// Handle errors
|
|
1125
1132
|
await handleGitLabError(response);
|
|
@@ -1143,7 +1150,7 @@ async function getLabel(projectId, labelId, includeAncestorGroups) {
|
|
|
1143
1150
|
}
|
|
1144
1151
|
// Make the API request
|
|
1145
1152
|
const response = await fetch(url.toString(), {
|
|
1146
|
-
|
|
1153
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1147
1154
|
});
|
|
1148
1155
|
// Handle errors
|
|
1149
1156
|
await handleGitLabError(response);
|
|
@@ -1161,8 +1168,8 @@ async function getLabel(projectId, labelId, includeAncestorGroups) {
|
|
|
1161
1168
|
async function createLabel(projectId, options) {
|
|
1162
1169
|
// Make the API request
|
|
1163
1170
|
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`, {
|
|
1171
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1164
1172
|
method: "POST",
|
|
1165
|
-
headers: DEFAULT_HEADERS,
|
|
1166
1173
|
body: JSON.stringify(options),
|
|
1167
1174
|
});
|
|
1168
1175
|
// Handle errors
|
|
@@ -1182,8 +1189,8 @@ async function createLabel(projectId, options) {
|
|
|
1182
1189
|
async function updateLabel(projectId, labelId, options) {
|
|
1183
1190
|
// Make the API request
|
|
1184
1191
|
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`, {
|
|
1192
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1185
1193
|
method: "PUT",
|
|
1186
|
-
headers: DEFAULT_HEADERS,
|
|
1187
1194
|
body: JSON.stringify(options),
|
|
1188
1195
|
});
|
|
1189
1196
|
// Handle errors
|
|
@@ -1201,8 +1208,8 @@ async function updateLabel(projectId, labelId, options) {
|
|
|
1201
1208
|
async function deleteLabel(projectId, labelId) {
|
|
1202
1209
|
// Make the API request
|
|
1203
1210
|
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`, {
|
|
1211
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1204
1212
|
method: "DELETE",
|
|
1205
|
-
headers: DEFAULT_HEADERS,
|
|
1206
1213
|
});
|
|
1207
1214
|
// Handle errors
|
|
1208
1215
|
await handleGitLabError(response);
|
|
@@ -1249,8 +1256,7 @@ async function listGroupProjects(options) {
|
|
|
1249
1256
|
if (options.with_security_reports !== undefined)
|
|
1250
1257
|
url.searchParams.append("with_security_reports", options.with_security_reports.toString());
|
|
1251
1258
|
const response = await fetch(url.toString(), {
|
|
1252
|
-
|
|
1253
|
-
headers: DEFAULT_HEADERS,
|
|
1259
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1254
1260
|
});
|
|
1255
1261
|
await handleGitLabError(response);
|
|
1256
1262
|
const projects = await response.json();
|
|
@@ -1425,7 +1431,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1425
1431
|
url.searchParams.append("owned", args.owned.toString());
|
|
1426
1432
|
}
|
|
1427
1433
|
const response = await fetch(url.toString(), {
|
|
1428
|
-
|
|
1434
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1429
1435
|
});
|
|
1430
1436
|
await handleGitLabError(response);
|
|
1431
1437
|
const data = await response.json();
|
|
@@ -1440,7 +1446,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1440
1446
|
const args = GetNamespaceSchema.parse(request.params.arguments);
|
|
1441
1447
|
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(args.namespace_id)}`);
|
|
1442
1448
|
const response = await fetch(url.toString(), {
|
|
1443
|
-
|
|
1449
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1444
1450
|
});
|
|
1445
1451
|
await handleGitLabError(response);
|
|
1446
1452
|
const data = await response.json();
|
|
@@ -1453,7 +1459,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1453
1459
|
const args = VerifyNamespaceSchema.parse(request.params.arguments);
|
|
1454
1460
|
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(args.path)}/exists`);
|
|
1455
1461
|
const response = await fetch(url.toString(), {
|
|
1456
|
-
|
|
1462
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1457
1463
|
});
|
|
1458
1464
|
await handleGitLabError(response);
|
|
1459
1465
|
const data = await response.json();
|
|
@@ -1468,7 +1474,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1468
1474
|
const args = GetProjectSchema.parse(request.params.arguments);
|
|
1469
1475
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(args.project_id)}`);
|
|
1470
1476
|
const response = await fetch(url.toString(), {
|
|
1471
|
-
|
|
1477
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1472
1478
|
});
|
|
1473
1479
|
await handleGitLabError(response);
|
|
1474
1480
|
const data = await response.json();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zereight/mcp-gitlab",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.31",
|
|
4
4
|
"description": "MCP server for using the GitLab API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "zereight",
|
|
@@ -24,7 +24,10 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@modelcontextprotocol/sdk": "1.8.0",
|
|
26
26
|
"@types/node-fetch": "^2.6.12",
|
|
27
|
+
"http-proxy-agent": "^7.0.2",
|
|
28
|
+
"https-proxy-agent": "^7.0.6",
|
|
27
29
|
"node-fetch": "^3.3.2",
|
|
30
|
+
"socks-proxy-agent": "^8.0.5",
|
|
28
31
|
"zod-to-json-schema": "^3.23.5"
|
|
29
32
|
},
|
|
30
33
|
"devDependencies": {
|