@zereight/mcp-gitlab 1.0.12 → 1.0.14
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/build/index.js +156 -13
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -10,7 +10,9 @@ import { dirname } from "path";
|
|
|
10
10
|
import fs from "fs";
|
|
11
11
|
import path from "path";
|
|
12
12
|
import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, CreateNoteSchema, } from "./schemas.js";
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Read version from package.json
|
|
15
|
+
*/
|
|
14
16
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
17
|
const __dirname = dirname(__filename);
|
|
16
18
|
const packageJsonPath = path.resolve(__dirname, '../package.json');
|
|
@@ -33,7 +35,12 @@ const server = new Server({
|
|
|
33
35
|
},
|
|
34
36
|
});
|
|
35
37
|
const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_PERSONAL_ACCESS_TOKEN;
|
|
36
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Smart URL handling for GitLab API
|
|
40
|
+
*
|
|
41
|
+
* @param {string | undefined} url - Input GitLab API URL
|
|
42
|
+
* @returns {string} Normalized GitLab API URL with /api/v4 path
|
|
43
|
+
*/
|
|
37
44
|
function normalizeGitLabApiUrl(url) {
|
|
38
45
|
if (!url) {
|
|
39
46
|
return "https://gitlab.com/api/v4";
|
|
@@ -59,20 +66,36 @@ if (!GITLAB_PERSONAL_ACCESS_TOKEN) {
|
|
|
59
66
|
console.error("GITLAB_PERSONAL_ACCESS_TOKEN environment variable is not set");
|
|
60
67
|
process.exit(1);
|
|
61
68
|
}
|
|
62
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Common headers for GitLab API requests
|
|
71
|
+
* GitLab API 공통 헤더 (Common headers for GitLab API)
|
|
72
|
+
*/
|
|
63
73
|
const DEFAULT_HEADERS = {
|
|
64
74
|
Accept: "application/json",
|
|
65
75
|
"Content-Type": "application/json",
|
|
66
76
|
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
67
77
|
};
|
|
68
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Utility function for handling GitLab API errors
|
|
80
|
+
* API 에러 처리를 위한 유틸리티 함수 (Utility function for handling API errors)
|
|
81
|
+
*
|
|
82
|
+
* @param {import("node-fetch").Response} response - The response from GitLab API
|
|
83
|
+
* @throws {Error} Throws an error with response details if the request failed
|
|
84
|
+
*/
|
|
69
85
|
async function handleGitLabError(response) {
|
|
70
86
|
if (!response.ok) {
|
|
71
87
|
const errorBody = await response.text();
|
|
72
88
|
throw new Error(`GitLab API error: ${response.status} ${response.statusText}\n${errorBody}`);
|
|
73
89
|
}
|
|
74
90
|
}
|
|
75
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Create a fork of a GitLab project
|
|
93
|
+
* 프로젝트 포크 생성 (Create a project fork)
|
|
94
|
+
*
|
|
95
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
96
|
+
* @param {string} [namespace] - The namespace to fork the project to
|
|
97
|
+
* @returns {Promise<GitLabFork>} The created fork
|
|
98
|
+
*/
|
|
76
99
|
async function forkProject(projectId, namespace) {
|
|
77
100
|
// API 엔드포인트 URL 생성
|
|
78
101
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/fork`);
|
|
@@ -91,7 +114,14 @@ async function forkProject(projectId, namespace) {
|
|
|
91
114
|
const data = await response.json();
|
|
92
115
|
return GitLabForkSchema.parse(data);
|
|
93
116
|
}
|
|
94
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Create a new branch in a GitLab project
|
|
119
|
+
* 새로운 브랜치 생성 (Create a new branch)
|
|
120
|
+
*
|
|
121
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
122
|
+
* @param {z.infer<typeof CreateBranchOptionsSchema>} options - Branch creation options
|
|
123
|
+
* @returns {Promise<GitLabReference>} The created branch reference
|
|
124
|
+
*/
|
|
95
125
|
async function createBranch(projectId, options) {
|
|
96
126
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/branches`);
|
|
97
127
|
const response = await fetch(url.toString(), {
|
|
@@ -105,7 +135,13 @@ async function createBranch(projectId, options) {
|
|
|
105
135
|
await handleGitLabError(response);
|
|
106
136
|
return GitLabReferenceSchema.parse(await response.json());
|
|
107
137
|
}
|
|
108
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Get the default branch for a GitLab project
|
|
140
|
+
* 프로젝트의 기본 브랜치 조회 (Get the default branch of a project)
|
|
141
|
+
*
|
|
142
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
143
|
+
* @returns {Promise<string>} The name of the default branch
|
|
144
|
+
*/
|
|
109
145
|
async function getDefaultBranchRef(projectId) {
|
|
110
146
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`);
|
|
111
147
|
const response = await fetch(url.toString(), {
|
|
@@ -115,7 +151,15 @@ async function getDefaultBranchRef(projectId) {
|
|
|
115
151
|
const project = GitLabRepositorySchema.parse(await response.json());
|
|
116
152
|
return project.default_branch ?? "main";
|
|
117
153
|
}
|
|
118
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Get the contents of a file from a GitLab project
|
|
156
|
+
* 파일 내용 조회 (Get file contents)
|
|
157
|
+
*
|
|
158
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
159
|
+
* @param {string} filePath - The path of the file to get
|
|
160
|
+
* @param {string} [ref] - The name of the branch, tag or commit
|
|
161
|
+
* @returns {Promise<GitLabContent>} The file content
|
|
162
|
+
*/
|
|
119
163
|
async function getFileContents(projectId, filePath, ref) {
|
|
120
164
|
const encodedPath = encodeURIComponent(filePath);
|
|
121
165
|
// ref가 없는 경우 default branch를 가져옴
|
|
@@ -141,7 +185,14 @@ async function getFileContents(projectId, filePath, ref) {
|
|
|
141
185
|
}
|
|
142
186
|
return parsedData;
|
|
143
187
|
}
|
|
144
|
-
|
|
188
|
+
/**
|
|
189
|
+
* Create a new issue in a GitLab project
|
|
190
|
+
* 이슈 생성 (Create an issue)
|
|
191
|
+
*
|
|
192
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
193
|
+
* @param {z.infer<typeof CreateIssueOptionsSchema>} options - Issue creation options
|
|
194
|
+
* @returns {Promise<GitLabIssue>} The created issue
|
|
195
|
+
*/
|
|
145
196
|
async function createIssue(projectId, options) {
|
|
146
197
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`);
|
|
147
198
|
const response = await fetch(url.toString(), {
|
|
@@ -164,6 +215,14 @@ async function createIssue(projectId, options) {
|
|
|
164
215
|
const data = await response.json();
|
|
165
216
|
return GitLabIssueSchema.parse(data);
|
|
166
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Create a new merge request in a GitLab project
|
|
220
|
+
* 병합 요청 생성
|
|
221
|
+
*
|
|
222
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
223
|
+
* @param {z.infer<typeof CreateMergeRequestOptionsSchema>} options - Merge request creation options
|
|
224
|
+
* @returns {Promise<GitLabMergeRequest>} The created merge request
|
|
225
|
+
*/
|
|
167
226
|
async function createMergeRequest(projectId, options) {
|
|
168
227
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests`);
|
|
169
228
|
const response = await fetch(url.toString(), {
|
|
@@ -193,6 +252,18 @@ async function createMergeRequest(projectId, options) {
|
|
|
193
252
|
const data = await response.json();
|
|
194
253
|
return GitLabMergeRequestSchema.parse(data);
|
|
195
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Create or update a file in a GitLab project
|
|
257
|
+
* 파일 생성 또는 업데이트
|
|
258
|
+
*
|
|
259
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
260
|
+
* @param {string} filePath - The path of the file to create or update
|
|
261
|
+
* @param {string} content - The content of the file
|
|
262
|
+
* @param {string} commitMessage - The commit message
|
|
263
|
+
* @param {string} branch - The branch name
|
|
264
|
+
* @param {string} [previousPath] - The previous path of the file in case of rename
|
|
265
|
+
* @returns {Promise<GitLabCreateUpdateFileResponse>} The file update response
|
|
266
|
+
*/
|
|
196
267
|
async function createOrUpdateFile(projectId, filePath, content, commitMessage, branch, previousPath) {
|
|
197
268
|
const encodedPath = encodeURIComponent(filePath);
|
|
198
269
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/files/${encodedPath}`);
|
|
@@ -231,6 +302,15 @@ async function createOrUpdateFile(projectId, filePath, content, commitMessage, b
|
|
|
231
302
|
const data = await response.json();
|
|
232
303
|
return GitLabCreateUpdateFileResponseSchema.parse(data);
|
|
233
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Create a tree structure in a GitLab project repository
|
|
307
|
+
* 저장소에 트리 구조 생성
|
|
308
|
+
*
|
|
309
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
310
|
+
* @param {FileOperation[]} files - Array of file operations
|
|
311
|
+
* @param {string} [ref] - The name of the branch, tag or commit
|
|
312
|
+
* @returns {Promise<GitLabTree>} The created tree
|
|
313
|
+
*/
|
|
234
314
|
async function createTree(projectId, files, ref) {
|
|
235
315
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/tree`);
|
|
236
316
|
if (ref) {
|
|
@@ -262,6 +342,16 @@ async function createTree(projectId, files, ref) {
|
|
|
262
342
|
const data = await response.json();
|
|
263
343
|
return GitLabTreeSchema.parse(data);
|
|
264
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
* Create a commit in a GitLab project repository
|
|
347
|
+
* 저장소에 커밋 생성
|
|
348
|
+
*
|
|
349
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
350
|
+
* @param {string} message - The commit message
|
|
351
|
+
* @param {string} branch - The branch name
|
|
352
|
+
* @param {FileOperation[]} actions - Array of file operations for the commit
|
|
353
|
+
* @returns {Promise<GitLabCommit>} The created commit
|
|
354
|
+
*/
|
|
265
355
|
async function createCommit(projectId, message, branch, actions) {
|
|
266
356
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/commits`);
|
|
267
357
|
const response = await fetch(url.toString(), {
|
|
@@ -293,6 +383,15 @@ async function createCommit(projectId, message, branch, actions) {
|
|
|
293
383
|
const data = await response.json();
|
|
294
384
|
return GitLabCommitSchema.parse(data);
|
|
295
385
|
}
|
|
386
|
+
/**
|
|
387
|
+
* Search for GitLab projects
|
|
388
|
+
* 프로젝트 검색
|
|
389
|
+
*
|
|
390
|
+
* @param {string} query - The search query
|
|
391
|
+
* @param {number} [page=1] - The page number
|
|
392
|
+
* @param {number} [perPage=20] - Number of items per page
|
|
393
|
+
* @returns {Promise<GitLabSearchResponse>} The search results
|
|
394
|
+
*/
|
|
296
395
|
async function searchProjects(query, page = 1, perPage = 20) {
|
|
297
396
|
const url = new URL(`${GITLAB_API_URL}/projects`);
|
|
298
397
|
url.searchParams.append("search", query);
|
|
@@ -323,6 +422,13 @@ async function searchProjects(query, page = 1, perPage = 20) {
|
|
|
323
422
|
items: projects,
|
|
324
423
|
});
|
|
325
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* Create a new GitLab repository
|
|
427
|
+
* 새 저장소 생성
|
|
428
|
+
*
|
|
429
|
+
* @param {z.infer<typeof CreateRepositoryOptionsSchema>} options - Repository creation options
|
|
430
|
+
* @returns {Promise<GitLabRepository>} The created repository
|
|
431
|
+
*/
|
|
326
432
|
async function createRepository(options) {
|
|
327
433
|
const response = await fetch(`${GITLAB_API_URL}/projects`, {
|
|
328
434
|
method: "POST",
|
|
@@ -347,7 +453,14 @@ async function createRepository(options) {
|
|
|
347
453
|
const data = await response.json();
|
|
348
454
|
return GitLabRepositorySchema.parse(data);
|
|
349
455
|
}
|
|
350
|
-
|
|
456
|
+
/**
|
|
457
|
+
* Get merge request details
|
|
458
|
+
* MR 조회 함수 (Function to retrieve merge request)
|
|
459
|
+
*
|
|
460
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
461
|
+
* @param {number} mergeRequestIid - The internal ID of the merge request
|
|
462
|
+
* @returns {Promise<GitLabMergeRequest>} The merge request details
|
|
463
|
+
*/
|
|
351
464
|
async function getMergeRequest(projectId, mergeRequestIid) {
|
|
352
465
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}`);
|
|
353
466
|
const response = await fetch(url.toString(), {
|
|
@@ -356,7 +469,15 @@ async function getMergeRequest(projectId, mergeRequestIid) {
|
|
|
356
469
|
await handleGitLabError(response);
|
|
357
470
|
return GitLabMergeRequestSchema.parse(await response.json());
|
|
358
471
|
}
|
|
359
|
-
|
|
472
|
+
/**
|
|
473
|
+
* Get merge request changes/diffs
|
|
474
|
+
* MR 변경사항 조회 함수 (Function to retrieve merge request changes)
|
|
475
|
+
*
|
|
476
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
477
|
+
* @param {number} mergeRequestIid - The internal ID of the merge request
|
|
478
|
+
* @param {string} [view] - The view type for the diff (inline or parallel)
|
|
479
|
+
* @returns {Promise<GitLabMergeRequestDiff[]>} The merge request diffs
|
|
480
|
+
*/
|
|
360
481
|
async function getMergeRequestDiffs(projectId, mergeRequestIid, view) {
|
|
361
482
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}/changes`);
|
|
362
483
|
if (view) {
|
|
@@ -369,7 +490,15 @@ async function getMergeRequestDiffs(projectId, mergeRequestIid, view) {
|
|
|
369
490
|
const data = (await response.json());
|
|
370
491
|
return z.array(GitLabMergeRequestDiffSchema).parse(data.changes);
|
|
371
492
|
}
|
|
372
|
-
|
|
493
|
+
/**
|
|
494
|
+
* Update a merge request
|
|
495
|
+
* MR 업데이트 함수 (Function to update merge request)
|
|
496
|
+
*
|
|
497
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
498
|
+
* @param {number} mergeRequestIid - The internal ID of the merge request
|
|
499
|
+
* @param {Object} options - The update options
|
|
500
|
+
* @returns {Promise<GitLabMergeRequest>} The updated merge request
|
|
501
|
+
*/
|
|
373
502
|
async function updateMergeRequest(projectId, mergeRequestIid, options) {
|
|
374
503
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}`);
|
|
375
504
|
const response = await fetch(url.toString(), {
|
|
@@ -380,7 +509,17 @@ async function updateMergeRequest(projectId, mergeRequestIid, options) {
|
|
|
380
509
|
await handleGitLabError(response);
|
|
381
510
|
return GitLabMergeRequestSchema.parse(await response.json());
|
|
382
511
|
}
|
|
383
|
-
|
|
512
|
+
/**
|
|
513
|
+
* Create a new note (comment) on an issue or merge request
|
|
514
|
+
* 📦 새로운 함수: createNote - 이슈 또는 병합 요청에 노트(댓글)를 추가하는 함수
|
|
515
|
+
* (New function: createNote - Function to add a note (comment) to an issue or merge request)
|
|
516
|
+
*
|
|
517
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
518
|
+
* @param {"issue" | "merge_request"} noteableType - The type of the item to add a note to (issue or merge_request)
|
|
519
|
+
* @param {number} noteableIid - The internal ID of the issue or merge request
|
|
520
|
+
* @param {string} body - The content of the note
|
|
521
|
+
* @returns {Promise<any>} The created note
|
|
522
|
+
*/
|
|
384
523
|
async function createNote(projectId, noteableType, // 'issue' 또는 'merge_request' 타입 명시
|
|
385
524
|
noteableIid, body) {
|
|
386
525
|
// ⚙️ 응답 타입은 GitLab API 문서에 따라 조정 가능
|
|
@@ -597,6 +736,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
597
736
|
throw error;
|
|
598
737
|
}
|
|
599
738
|
});
|
|
739
|
+
/**
|
|
740
|
+
* Initialize and run the server
|
|
741
|
+
* 서버 초기화 및 실행
|
|
742
|
+
*/
|
|
600
743
|
async function runServer() {
|
|
601
744
|
try {
|
|
602
745
|
console.error("========================");
|