@zereight/mcp-gitlab 1.0.30 → 1.0.32
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 +224 -82
- package/build/schemas.js +36 -0
- package/package.json +5 -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,13 +3,17 @@ 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";
|
|
12
|
-
import {
|
|
15
|
+
import { URL } from 'url';
|
|
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, ListWikiPagesSchema, GetWikiPageSchema, CreateWikiPageSchema, UpdateWikiPageSchema, DeleteWikiPageSchema, GitLabWikiPageSchema,
|
|
13
17
|
// Discussion Schemas
|
|
14
18
|
GitLabDiscussionNoteSchema, // Added
|
|
15
19
|
GitLabDiscussionSchema, UpdateMergeRequestNoteSchema, // Added
|
|
@@ -40,6 +44,45 @@ 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
|
+
const USE_GITLAB_WIKI = process.env.USE_GITLAB_WIKI === "true";
|
|
48
|
+
// Add proxy configuration
|
|
49
|
+
const HTTP_PROXY = process.env.HTTP_PROXY;
|
|
50
|
+
const HTTPS_PROXY = process.env.HTTPS_PROXY;
|
|
51
|
+
// Configure proxy agents if proxies are set
|
|
52
|
+
let httpAgent = undefined;
|
|
53
|
+
let httpsAgent = undefined;
|
|
54
|
+
if (HTTP_PROXY) {
|
|
55
|
+
if (HTTP_PROXY.startsWith('socks')) {
|
|
56
|
+
httpAgent = new SocksProxyAgent(HTTP_PROXY);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
httpAgent = new HttpProxyAgent(HTTP_PROXY);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (HTTPS_PROXY) {
|
|
63
|
+
if (HTTPS_PROXY.startsWith('socks')) {
|
|
64
|
+
httpsAgent = new SocksProxyAgent(HTTPS_PROXY);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
httpsAgent = new HttpsProxyAgent(HTTPS_PROXY);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Modify DEFAULT_HEADERS to include agent configuration
|
|
71
|
+
const DEFAULT_HEADERS = {
|
|
72
|
+
Accept: "application/json",
|
|
73
|
+
"Content-Type": "application/json",
|
|
74
|
+
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
75
|
+
};
|
|
76
|
+
// Create a default fetch configuration object that includes proxy agents if set
|
|
77
|
+
const DEFAULT_FETCH_CONFIG = {
|
|
78
|
+
headers: DEFAULT_HEADERS,
|
|
79
|
+
agent: (parsedUrl) => {
|
|
80
|
+
if (parsedUrl.protocol === 'https:') {
|
|
81
|
+
return httpsAgent;
|
|
82
|
+
}
|
|
83
|
+
return httpAgent;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
43
86
|
// Define all available tools
|
|
44
87
|
const allTools = [
|
|
45
88
|
{
|
|
@@ -108,7 +151,7 @@ const allTools = [
|
|
|
108
151
|
inputSchema: zodToJsonSchema(CreateNoteSchema),
|
|
109
152
|
},
|
|
110
153
|
{
|
|
111
|
-
name: "
|
|
154
|
+
name: "mr_discussions",
|
|
112
155
|
description: "List discussion items for a merge request",
|
|
113
156
|
inputSchema: zodToJsonSchema(ListMergeRequestDiscussionsSchema),
|
|
114
157
|
},
|
|
@@ -212,6 +255,31 @@ const allTools = [
|
|
|
212
255
|
description: "List projects in a GitLab group with filtering options",
|
|
213
256
|
inputSchema: zodToJsonSchema(ListGroupProjectsSchema),
|
|
214
257
|
},
|
|
258
|
+
{
|
|
259
|
+
name: "list_wiki_pages",
|
|
260
|
+
description: "List wiki pages in a GitLab project",
|
|
261
|
+
inputSchema: zodToJsonSchema(ListWikiPagesSchema),
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: "get_wiki_page",
|
|
265
|
+
description: "Get details of a specific wiki page",
|
|
266
|
+
inputSchema: zodToJsonSchema(GetWikiPageSchema),
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
name: "create_wiki_page",
|
|
270
|
+
description: "Create a new wiki page in a GitLab project",
|
|
271
|
+
inputSchema: zodToJsonSchema(CreateWikiPageSchema),
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
name: "update_wiki_page",
|
|
275
|
+
description: "Update an existing wiki page in a GitLab project",
|
|
276
|
+
inputSchema: zodToJsonSchema(UpdateWikiPageSchema),
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
name: "delete_wiki_page",
|
|
280
|
+
description: "Delete a wiki page from a GitLab project",
|
|
281
|
+
inputSchema: zodToJsonSchema(DeleteWikiPageSchema),
|
|
282
|
+
}
|
|
215
283
|
];
|
|
216
284
|
// Define which tools are read-only
|
|
217
285
|
const readOnlyTools = [
|
|
@@ -219,7 +287,7 @@ const readOnlyTools = [
|
|
|
219
287
|
"get_file_contents",
|
|
220
288
|
"get_merge_request",
|
|
221
289
|
"get_merge_request_diffs",
|
|
222
|
-
"
|
|
290
|
+
"mr_discussions",
|
|
223
291
|
"list_issues",
|
|
224
292
|
"get_issue",
|
|
225
293
|
"list_issue_links",
|
|
@@ -233,6 +301,15 @@ const readOnlyTools = [
|
|
|
233
301
|
"get_label",
|
|
234
302
|
"list_group_projects",
|
|
235
303
|
];
|
|
304
|
+
// Define which tools are related to wiki and can be toggled by USE_GITLAB_WIKI
|
|
305
|
+
const wikiToolNames = [
|
|
306
|
+
"list_wiki_pages",
|
|
307
|
+
"get_wiki_page",
|
|
308
|
+
"create_wiki_page",
|
|
309
|
+
"update_wiki_page",
|
|
310
|
+
"delete_wiki_page",
|
|
311
|
+
"upload_wiki_attachment",
|
|
312
|
+
];
|
|
236
313
|
/**
|
|
237
314
|
* Smart URL handling for GitLab API
|
|
238
315
|
*
|
|
@@ -259,15 +336,6 @@ if (!GITLAB_PERSONAL_ACCESS_TOKEN) {
|
|
|
259
336
|
console.error("GITLAB_PERSONAL_ACCESS_TOKEN environment variable is not set");
|
|
260
337
|
process.exit(1);
|
|
261
338
|
}
|
|
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
339
|
/**
|
|
272
340
|
* Utility function for handling GitLab API errors
|
|
273
341
|
* API 에러 처리를 위한 유틸리티 함수 (Utility function for handling API errors)
|
|
@@ -299,14 +367,13 @@ async function handleGitLabError(response) {
|
|
|
299
367
|
* @returns {Promise<GitLabFork>} The created fork
|
|
300
368
|
*/
|
|
301
369
|
async function forkProject(projectId, namespace) {
|
|
302
|
-
// API 엔드포인트 URL 생성
|
|
303
370
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/fork`);
|
|
304
371
|
if (namespace) {
|
|
305
372
|
url.searchParams.append("namespace", namespace);
|
|
306
373
|
}
|
|
307
374
|
const response = await fetch(url.toString(), {
|
|
375
|
+
...DEFAULT_FETCH_CONFIG,
|
|
308
376
|
method: "POST",
|
|
309
|
-
headers: DEFAULT_HEADERS,
|
|
310
377
|
});
|
|
311
378
|
// 이미 존재하는 프로젝트인 경우 처리
|
|
312
379
|
if (response.status === 409) {
|
|
@@ -327,8 +394,8 @@ async function forkProject(projectId, namespace) {
|
|
|
327
394
|
async function createBranch(projectId, options) {
|
|
328
395
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/branches`);
|
|
329
396
|
const response = await fetch(url.toString(), {
|
|
397
|
+
...DEFAULT_FETCH_CONFIG,
|
|
330
398
|
method: "POST",
|
|
331
|
-
headers: DEFAULT_HEADERS,
|
|
332
399
|
body: JSON.stringify({
|
|
333
400
|
branch: options.name,
|
|
334
401
|
ref: options.ref,
|
|
@@ -347,7 +414,7 @@ async function createBranch(projectId, options) {
|
|
|
347
414
|
async function getDefaultBranchRef(projectId) {
|
|
348
415
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`);
|
|
349
416
|
const response = await fetch(url.toString(), {
|
|
350
|
-
|
|
417
|
+
...DEFAULT_FETCH_CONFIG,
|
|
351
418
|
});
|
|
352
419
|
await handleGitLabError(response);
|
|
353
420
|
const project = GitLabRepositorySchema.parse(await response.json());
|
|
@@ -371,7 +438,7 @@ async function getFileContents(projectId, filePath, ref) {
|
|
|
371
438
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/files/${encodedPath}`);
|
|
372
439
|
url.searchParams.append("ref", ref);
|
|
373
440
|
const response = await fetch(url.toString(), {
|
|
374
|
-
|
|
441
|
+
...DEFAULT_FETCH_CONFIG,
|
|
375
442
|
});
|
|
376
443
|
// 파일을 찾을 수 없는 경우 처리
|
|
377
444
|
if (response.status === 404) {
|
|
@@ -398,8 +465,8 @@ async function getFileContents(projectId, filePath, ref) {
|
|
|
398
465
|
async function createIssue(projectId, options) {
|
|
399
466
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`);
|
|
400
467
|
const response = await fetch(url.toString(), {
|
|
468
|
+
...DEFAULT_FETCH_CONFIG,
|
|
401
469
|
method: "POST",
|
|
402
|
-
headers: DEFAULT_HEADERS,
|
|
403
470
|
body: JSON.stringify({
|
|
404
471
|
title: options.title,
|
|
405
472
|
description: options.description,
|
|
@@ -440,7 +507,7 @@ async function listIssues(projectId, options = {}) {
|
|
|
440
507
|
}
|
|
441
508
|
});
|
|
442
509
|
const response = await fetch(url.toString(), {
|
|
443
|
-
|
|
510
|
+
...DEFAULT_FETCH_CONFIG,
|
|
444
511
|
});
|
|
445
512
|
await handleGitLabError(response);
|
|
446
513
|
const data = await response.json();
|
|
@@ -457,7 +524,7 @@ async function listIssues(projectId, options = {}) {
|
|
|
457
524
|
async function getIssue(projectId, issueIid) {
|
|
458
525
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`);
|
|
459
526
|
const response = await fetch(url.toString(), {
|
|
460
|
-
|
|
527
|
+
...DEFAULT_FETCH_CONFIG,
|
|
461
528
|
});
|
|
462
529
|
await handleGitLabError(response);
|
|
463
530
|
const data = await response.json();
|
|
@@ -480,8 +547,8 @@ async function updateIssue(projectId, issueIid, options) {
|
|
|
480
547
|
body.labels = body.labels.join(",");
|
|
481
548
|
}
|
|
482
549
|
const response = await fetch(url.toString(), {
|
|
550
|
+
...DEFAULT_FETCH_CONFIG,
|
|
483
551
|
method: "PUT",
|
|
484
|
-
headers: DEFAULT_HEADERS,
|
|
485
552
|
body: JSON.stringify(body),
|
|
486
553
|
});
|
|
487
554
|
await handleGitLabError(response);
|
|
@@ -499,8 +566,8 @@ async function updateIssue(projectId, issueIid, options) {
|
|
|
499
566
|
async function deleteIssue(projectId, issueIid) {
|
|
500
567
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`);
|
|
501
568
|
const response = await fetch(url.toString(), {
|
|
569
|
+
...DEFAULT_FETCH_CONFIG,
|
|
502
570
|
method: "DELETE",
|
|
503
|
-
headers: DEFAULT_HEADERS,
|
|
504
571
|
});
|
|
505
572
|
await handleGitLabError(response);
|
|
506
573
|
}
|
|
@@ -515,7 +582,7 @@ async function deleteIssue(projectId, issueIid) {
|
|
|
515
582
|
async function listIssueLinks(projectId, issueIid) {
|
|
516
583
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links`);
|
|
517
584
|
const response = await fetch(url.toString(), {
|
|
518
|
-
|
|
585
|
+
...DEFAULT_FETCH_CONFIG,
|
|
519
586
|
});
|
|
520
587
|
await handleGitLabError(response);
|
|
521
588
|
const data = await response.json();
|
|
@@ -533,7 +600,7 @@ async function listIssueLinks(projectId, issueIid) {
|
|
|
533
600
|
async function getIssueLink(projectId, issueIid, issueLinkId) {
|
|
534
601
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links/${issueLinkId}`);
|
|
535
602
|
const response = await fetch(url.toString(), {
|
|
536
|
-
|
|
603
|
+
...DEFAULT_FETCH_CONFIG,
|
|
537
604
|
});
|
|
538
605
|
await handleGitLabError(response);
|
|
539
606
|
const data = await response.json();
|
|
@@ -553,8 +620,8 @@ async function getIssueLink(projectId, issueIid, issueLinkId) {
|
|
|
553
620
|
async function createIssueLink(projectId, issueIid, targetProjectId, targetIssueIid, linkType = "relates_to") {
|
|
554
621
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links`);
|
|
555
622
|
const response = await fetch(url.toString(), {
|
|
623
|
+
...DEFAULT_FETCH_CONFIG,
|
|
556
624
|
method: "POST",
|
|
557
|
-
headers: DEFAULT_HEADERS,
|
|
558
625
|
body: JSON.stringify({
|
|
559
626
|
target_project_id: targetProjectId,
|
|
560
627
|
target_issue_iid: targetIssueIid,
|
|
@@ -577,8 +644,8 @@ async function createIssueLink(projectId, issueIid, targetProjectId, targetIssue
|
|
|
577
644
|
async function deleteIssueLink(projectId, issueIid, issueLinkId) {
|
|
578
645
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links/${issueLinkId}`);
|
|
579
646
|
const response = await fetch(url.toString(), {
|
|
647
|
+
...DEFAULT_FETCH_CONFIG,
|
|
580
648
|
method: "DELETE",
|
|
581
|
-
headers: DEFAULT_HEADERS,
|
|
582
649
|
});
|
|
583
650
|
await handleGitLabError(response);
|
|
584
651
|
}
|
|
@@ -593,12 +660,8 @@ async function deleteIssueLink(projectId, issueIid, issueLinkId) {
|
|
|
593
660
|
async function createMergeRequest(projectId, options) {
|
|
594
661
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests`);
|
|
595
662
|
const response = await fetch(url.toString(), {
|
|
663
|
+
...DEFAULT_FETCH_CONFIG,
|
|
596
664
|
method: "POST",
|
|
597
|
-
headers: {
|
|
598
|
-
Accept: "application/json",
|
|
599
|
-
"Content-Type": "application/json",
|
|
600
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
601
|
-
},
|
|
602
665
|
body: JSON.stringify({
|
|
603
666
|
title: options.title,
|
|
604
667
|
description: options.description,
|
|
@@ -630,7 +693,7 @@ async function createMergeRequest(projectId, options) {
|
|
|
630
693
|
async function listMergeRequestDiscussions(projectId, mergeRequestIid) {
|
|
631
694
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}/discussions`);
|
|
632
695
|
const response = await fetch(url.toString(), {
|
|
633
|
-
|
|
696
|
+
...DEFAULT_FETCH_CONFIG,
|
|
634
697
|
});
|
|
635
698
|
await handleGitLabError(response);
|
|
636
699
|
const data = await response.json();
|
|
@@ -656,8 +719,8 @@ async function updateMergeRequestNote(projectId, mergeRequestIid, discussionId,
|
|
|
656
719
|
payload.resolved = resolved;
|
|
657
720
|
}
|
|
658
721
|
const response = await fetch(url.toString(), {
|
|
722
|
+
...DEFAULT_FETCH_CONFIG,
|
|
659
723
|
method: "PUT",
|
|
660
|
-
headers: DEFAULT_HEADERS,
|
|
661
724
|
body: JSON.stringify(payload),
|
|
662
725
|
});
|
|
663
726
|
await handleGitLabError(response);
|
|
@@ -723,12 +786,8 @@ async function createOrUpdateFile(projectId, filePath, content, commitMessage, b
|
|
|
723
786
|
}
|
|
724
787
|
}
|
|
725
788
|
const response = await fetch(url.toString(), {
|
|
789
|
+
...DEFAULT_FETCH_CONFIG,
|
|
726
790
|
method,
|
|
727
|
-
headers: {
|
|
728
|
-
Accept: "application/json",
|
|
729
|
-
"Content-Type": "application/json",
|
|
730
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
731
|
-
},
|
|
732
791
|
body: JSON.stringify(body),
|
|
733
792
|
});
|
|
734
793
|
if (!response.ok) {
|
|
@@ -753,12 +812,8 @@ async function createTree(projectId, files, ref) {
|
|
|
753
812
|
url.searchParams.append("ref", ref);
|
|
754
813
|
}
|
|
755
814
|
const response = await fetch(url.toString(), {
|
|
815
|
+
...DEFAULT_FETCH_CONFIG,
|
|
756
816
|
method: "POST",
|
|
757
|
-
headers: {
|
|
758
|
-
Accept: "application/json",
|
|
759
|
-
"Content-Type": "application/json",
|
|
760
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
761
|
-
},
|
|
762
817
|
body: JSON.stringify({
|
|
763
818
|
files: files.map((file) => ({
|
|
764
819
|
file_path: file.path,
|
|
@@ -791,12 +846,8 @@ async function createTree(projectId, files, ref) {
|
|
|
791
846
|
async function createCommit(projectId, message, branch, actions) {
|
|
792
847
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/commits`);
|
|
793
848
|
const response = await fetch(url.toString(), {
|
|
849
|
+
...DEFAULT_FETCH_CONFIG,
|
|
794
850
|
method: "POST",
|
|
795
|
-
headers: {
|
|
796
|
-
Accept: "application/json",
|
|
797
|
-
"Content-Type": "application/json",
|
|
798
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
799
|
-
},
|
|
800
851
|
body: JSON.stringify({
|
|
801
852
|
branch,
|
|
802
853
|
commit_message: message,
|
|
@@ -836,11 +887,7 @@ async function searchProjects(query, page = 1, perPage = 20) {
|
|
|
836
887
|
url.searchParams.append("order_by", "id");
|
|
837
888
|
url.searchParams.append("sort", "desc");
|
|
838
889
|
const response = await fetch(url.toString(), {
|
|
839
|
-
|
|
840
|
-
Accept: "application/json",
|
|
841
|
-
"Content-Type": "application/json",
|
|
842
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
843
|
-
},
|
|
890
|
+
...DEFAULT_FETCH_CONFIG,
|
|
844
891
|
});
|
|
845
892
|
if (!response.ok) {
|
|
846
893
|
const errorBody = await response.text();
|
|
@@ -867,12 +914,8 @@ async function searchProjects(query, page = 1, perPage = 20) {
|
|
|
867
914
|
*/
|
|
868
915
|
async function createRepository(options) {
|
|
869
916
|
const response = await fetch(`${GITLAB_API_URL}/projects`, {
|
|
917
|
+
...DEFAULT_FETCH_CONFIG,
|
|
870
918
|
method: "POST",
|
|
871
|
-
headers: {
|
|
872
|
-
Accept: "application/json",
|
|
873
|
-
"Content-Type": "application/json",
|
|
874
|
-
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
|
875
|
-
},
|
|
876
919
|
body: JSON.stringify({
|
|
877
920
|
name: options.name,
|
|
878
921
|
description: options.description,
|
|
@@ -900,7 +943,7 @@ async function createRepository(options) {
|
|
|
900
943
|
async function getMergeRequest(projectId, mergeRequestIid) {
|
|
901
944
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}`);
|
|
902
945
|
const response = await fetch(url.toString(), {
|
|
903
|
-
|
|
946
|
+
...DEFAULT_FETCH_CONFIG,
|
|
904
947
|
});
|
|
905
948
|
await handleGitLabError(response);
|
|
906
949
|
return GitLabMergeRequestSchema.parse(await response.json());
|
|
@@ -920,7 +963,7 @@ async function getMergeRequestDiffs(projectId, mergeRequestIid, view) {
|
|
|
920
963
|
url.searchParams.append("view", view);
|
|
921
964
|
}
|
|
922
965
|
const response = await fetch(url.toString(), {
|
|
923
|
-
|
|
966
|
+
...DEFAULT_FETCH_CONFIG,
|
|
924
967
|
});
|
|
925
968
|
await handleGitLabError(response);
|
|
926
969
|
const data = (await response.json());
|
|
@@ -938,8 +981,8 @@ async function getMergeRequestDiffs(projectId, mergeRequestIid, view) {
|
|
|
938
981
|
async function updateMergeRequest(projectId, mergeRequestIid, options) {
|
|
939
982
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}`);
|
|
940
983
|
const response = await fetch(url.toString(), {
|
|
984
|
+
...DEFAULT_FETCH_CONFIG,
|
|
941
985
|
method: "PUT",
|
|
942
|
-
headers: DEFAULT_HEADERS,
|
|
943
986
|
body: JSON.stringify(options),
|
|
944
987
|
});
|
|
945
988
|
await handleGitLabError(response);
|
|
@@ -962,8 +1005,8 @@ noteableIid, body) {
|
|
|
962
1005
|
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
1006
|
);
|
|
964
1007
|
const response = await fetch(url.toString(), {
|
|
1008
|
+
...DEFAULT_FETCH_CONFIG,
|
|
965
1009
|
method: "POST",
|
|
966
|
-
headers: DEFAULT_HEADERS,
|
|
967
1010
|
body: JSON.stringify({ body }),
|
|
968
1011
|
});
|
|
969
1012
|
if (!response.ok) {
|
|
@@ -994,7 +1037,7 @@ async function listNamespaces(options) {
|
|
|
994
1037
|
url.searchParams.append("top_level_only", "true");
|
|
995
1038
|
}
|
|
996
1039
|
const response = await fetch(url.toString(), {
|
|
997
|
-
|
|
1040
|
+
...DEFAULT_FETCH_CONFIG,
|
|
998
1041
|
});
|
|
999
1042
|
await handleGitLabError(response);
|
|
1000
1043
|
const data = await response.json();
|
|
@@ -1010,7 +1053,7 @@ async function listNamespaces(options) {
|
|
|
1010
1053
|
async function getNamespace(id) {
|
|
1011
1054
|
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(id)}`);
|
|
1012
1055
|
const response = await fetch(url.toString(), {
|
|
1013
|
-
|
|
1056
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1014
1057
|
});
|
|
1015
1058
|
await handleGitLabError(response);
|
|
1016
1059
|
const data = await response.json();
|
|
@@ -1030,7 +1073,7 @@ async function verifyNamespaceExistence(namespacePath, parentId) {
|
|
|
1030
1073
|
url.searchParams.append("parent_id", parentId.toString());
|
|
1031
1074
|
}
|
|
1032
1075
|
const response = await fetch(url.toString(), {
|
|
1033
|
-
|
|
1076
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1034
1077
|
});
|
|
1035
1078
|
await handleGitLabError(response);
|
|
1036
1079
|
const data = await response.json();
|
|
@@ -1059,7 +1102,7 @@ async function getProject(projectId, options = {}) {
|
|
|
1059
1102
|
url.searchParams.append("with_custom_attributes", "true");
|
|
1060
1103
|
}
|
|
1061
1104
|
const response = await fetch(url.toString(), {
|
|
1062
|
-
|
|
1105
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1063
1106
|
});
|
|
1064
1107
|
await handleGitLabError(response);
|
|
1065
1108
|
const data = await response.json();
|
|
@@ -1087,8 +1130,7 @@ async function listProjects(options = {}) {
|
|
|
1087
1130
|
}
|
|
1088
1131
|
// Make the API request
|
|
1089
1132
|
const response = await fetch(`${GITLAB_API_URL}/projects?${params.toString()}`, {
|
|
1090
|
-
|
|
1091
|
-
headers: DEFAULT_HEADERS,
|
|
1133
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1092
1134
|
});
|
|
1093
1135
|
// Handle errors
|
|
1094
1136
|
await handleGitLabError(response);
|
|
@@ -1119,7 +1161,7 @@ async function listLabels(projectId, options = {}) {
|
|
|
1119
1161
|
});
|
|
1120
1162
|
// Make the API request
|
|
1121
1163
|
const response = await fetch(url.toString(), {
|
|
1122
|
-
|
|
1164
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1123
1165
|
});
|
|
1124
1166
|
// Handle errors
|
|
1125
1167
|
await handleGitLabError(response);
|
|
@@ -1143,7 +1185,7 @@ async function getLabel(projectId, labelId, includeAncestorGroups) {
|
|
|
1143
1185
|
}
|
|
1144
1186
|
// Make the API request
|
|
1145
1187
|
const response = await fetch(url.toString(), {
|
|
1146
|
-
|
|
1188
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1147
1189
|
});
|
|
1148
1190
|
// Handle errors
|
|
1149
1191
|
await handleGitLabError(response);
|
|
@@ -1161,8 +1203,8 @@ async function getLabel(projectId, labelId, includeAncestorGroups) {
|
|
|
1161
1203
|
async function createLabel(projectId, options) {
|
|
1162
1204
|
// Make the API request
|
|
1163
1205
|
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`, {
|
|
1206
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1164
1207
|
method: "POST",
|
|
1165
|
-
headers: DEFAULT_HEADERS,
|
|
1166
1208
|
body: JSON.stringify(options),
|
|
1167
1209
|
});
|
|
1168
1210
|
// Handle errors
|
|
@@ -1182,8 +1224,8 @@ async function createLabel(projectId, options) {
|
|
|
1182
1224
|
async function updateLabel(projectId, labelId, options) {
|
|
1183
1225
|
// Make the API request
|
|
1184
1226
|
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`, {
|
|
1227
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1185
1228
|
method: "PUT",
|
|
1186
|
-
headers: DEFAULT_HEADERS,
|
|
1187
1229
|
body: JSON.stringify(options),
|
|
1188
1230
|
});
|
|
1189
1231
|
// Handle errors
|
|
@@ -1201,8 +1243,8 @@ async function updateLabel(projectId, labelId, options) {
|
|
|
1201
1243
|
async function deleteLabel(projectId, labelId) {
|
|
1202
1244
|
// Make the API request
|
|
1203
1245
|
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`, {
|
|
1246
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1204
1247
|
method: "DELETE",
|
|
1205
|
-
headers: DEFAULT_HEADERS,
|
|
1206
1248
|
});
|
|
1207
1249
|
// Handle errors
|
|
1208
1250
|
await handleGitLabError(response);
|
|
@@ -1249,18 +1291,93 @@ async function listGroupProjects(options) {
|
|
|
1249
1291
|
if (options.with_security_reports !== undefined)
|
|
1250
1292
|
url.searchParams.append("with_security_reports", options.with_security_reports.toString());
|
|
1251
1293
|
const response = await fetch(url.toString(), {
|
|
1252
|
-
|
|
1253
|
-
headers: DEFAULT_HEADERS,
|
|
1294
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1254
1295
|
});
|
|
1255
1296
|
await handleGitLabError(response);
|
|
1256
1297
|
const projects = await response.json();
|
|
1257
1298
|
return GitLabProjectSchema.array().parse(projects);
|
|
1258
1299
|
}
|
|
1300
|
+
// Wiki API helper functions
|
|
1301
|
+
/**
|
|
1302
|
+
* List wiki pages in a project
|
|
1303
|
+
*/
|
|
1304
|
+
async function listWikiPages(projectId, options = {}) {
|
|
1305
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/wikis`);
|
|
1306
|
+
if (options.page)
|
|
1307
|
+
url.searchParams.append('page', options.page.toString());
|
|
1308
|
+
if (options.per_page)
|
|
1309
|
+
url.searchParams.append('per_page', options.per_page.toString());
|
|
1310
|
+
const response = await fetch(url.toString(), {
|
|
1311
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1312
|
+
});
|
|
1313
|
+
await handleGitLabError(response);
|
|
1314
|
+
const data = await response.json();
|
|
1315
|
+
return GitLabWikiPageSchema.array().parse(data);
|
|
1316
|
+
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Get a specific wiki page
|
|
1319
|
+
*/
|
|
1320
|
+
async function getWikiPage(projectId, slug) {
|
|
1321
|
+
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/wikis/${encodeURIComponent(slug)}`, { ...DEFAULT_FETCH_CONFIG });
|
|
1322
|
+
await handleGitLabError(response);
|
|
1323
|
+
const data = await response.json();
|
|
1324
|
+
return GitLabWikiPageSchema.parse(data);
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Create a new wiki page
|
|
1328
|
+
*/
|
|
1329
|
+
async function createWikiPage(projectId, title, content, format) {
|
|
1330
|
+
const body = { title, content };
|
|
1331
|
+
if (format)
|
|
1332
|
+
body.format = format;
|
|
1333
|
+
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/wikis`, {
|
|
1334
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1335
|
+
method: 'POST',
|
|
1336
|
+
body: JSON.stringify(body),
|
|
1337
|
+
});
|
|
1338
|
+
await handleGitLabError(response);
|
|
1339
|
+
const data = await response.json();
|
|
1340
|
+
return GitLabWikiPageSchema.parse(data);
|
|
1341
|
+
}
|
|
1342
|
+
/**
|
|
1343
|
+
* Update an existing wiki page
|
|
1344
|
+
*/
|
|
1345
|
+
async function updateWikiPage(projectId, slug, title, content, format) {
|
|
1346
|
+
const body = {};
|
|
1347
|
+
if (title)
|
|
1348
|
+
body.title = title;
|
|
1349
|
+
if (content)
|
|
1350
|
+
body.content = content;
|
|
1351
|
+
if (format)
|
|
1352
|
+
body.format = format;
|
|
1353
|
+
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/wikis/${encodeURIComponent(slug)}`, {
|
|
1354
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1355
|
+
method: 'PUT',
|
|
1356
|
+
body: JSON.stringify(body),
|
|
1357
|
+
});
|
|
1358
|
+
await handleGitLabError(response);
|
|
1359
|
+
const data = await response.json();
|
|
1360
|
+
return GitLabWikiPageSchema.parse(data);
|
|
1361
|
+
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Delete a wiki page
|
|
1364
|
+
*/
|
|
1365
|
+
async function deleteWikiPage(projectId, slug) {
|
|
1366
|
+
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/wikis/${encodeURIComponent(slug)}`, {
|
|
1367
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1368
|
+
method: 'DELETE',
|
|
1369
|
+
});
|
|
1370
|
+
await handleGitLabError(response);
|
|
1371
|
+
}
|
|
1259
1372
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
1260
|
-
//
|
|
1261
|
-
const
|
|
1373
|
+
// Apply read-only filter first
|
|
1374
|
+
const tools0 = GITLAB_READ_ONLY_MODE
|
|
1262
1375
|
? allTools.filter((tool) => readOnlyTools.includes(tool.name))
|
|
1263
1376
|
: allTools;
|
|
1377
|
+
// Toggle wiki tools by USE_GITLAB_WIKI flag
|
|
1378
|
+
const tools = USE_GITLAB_WIKI
|
|
1379
|
+
? tools0
|
|
1380
|
+
: tools0.filter((tool) => !wikiToolNames.includes(tool.name));
|
|
1264
1381
|
return {
|
|
1265
1382
|
tools,
|
|
1266
1383
|
};
|
|
@@ -1400,7 +1517,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1400
1517
|
],
|
|
1401
1518
|
};
|
|
1402
1519
|
}
|
|
1403
|
-
case "
|
|
1520
|
+
case "mr_discussions": {
|
|
1404
1521
|
const args = ListMergeRequestDiscussionsSchema.parse(request.params.arguments);
|
|
1405
1522
|
const discussions = await listMergeRequestDiscussions(args.project_id, args.merge_request_iid);
|
|
1406
1523
|
return {
|
|
@@ -1425,7 +1542,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1425
1542
|
url.searchParams.append("owned", args.owned.toString());
|
|
1426
1543
|
}
|
|
1427
1544
|
const response = await fetch(url.toString(), {
|
|
1428
|
-
|
|
1545
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1429
1546
|
});
|
|
1430
1547
|
await handleGitLabError(response);
|
|
1431
1548
|
const data = await response.json();
|
|
@@ -1440,7 +1557,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1440
1557
|
const args = GetNamespaceSchema.parse(request.params.arguments);
|
|
1441
1558
|
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(args.namespace_id)}`);
|
|
1442
1559
|
const response = await fetch(url.toString(), {
|
|
1443
|
-
|
|
1560
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1444
1561
|
});
|
|
1445
1562
|
await handleGitLabError(response);
|
|
1446
1563
|
const data = await response.json();
|
|
@@ -1453,7 +1570,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1453
1570
|
const args = VerifyNamespaceSchema.parse(request.params.arguments);
|
|
1454
1571
|
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(args.path)}/exists`);
|
|
1455
1572
|
const response = await fetch(url.toString(), {
|
|
1456
|
-
|
|
1573
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1457
1574
|
});
|
|
1458
1575
|
await handleGitLabError(response);
|
|
1459
1576
|
const data = await response.json();
|
|
@@ -1468,7 +1585,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1468
1585
|
const args = GetProjectSchema.parse(request.params.arguments);
|
|
1469
1586
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(args.project_id)}`);
|
|
1470
1587
|
const response = await fetch(url.toString(), {
|
|
1471
|
-
|
|
1588
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1472
1589
|
});
|
|
1473
1590
|
await handleGitLabError(response);
|
|
1474
1591
|
const data = await response.json();
|
|
@@ -1611,6 +1728,31 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1611
1728
|
content: [{ type: "text", text: JSON.stringify(projects, null, 2) }],
|
|
1612
1729
|
};
|
|
1613
1730
|
}
|
|
1731
|
+
case "list_wiki_pages": {
|
|
1732
|
+
const { project_id, page, per_page } = ListWikiPagesSchema.parse(request.params.arguments);
|
|
1733
|
+
const wikiPages = await listWikiPages(project_id, { page, per_page });
|
|
1734
|
+
return { content: [{ type: "text", text: JSON.stringify(wikiPages, null, 2) }] };
|
|
1735
|
+
}
|
|
1736
|
+
case "get_wiki_page": {
|
|
1737
|
+
const { project_id, slug } = GetWikiPageSchema.parse(request.params.arguments);
|
|
1738
|
+
const wikiPage = await getWikiPage(project_id, slug);
|
|
1739
|
+
return { content: [{ type: "text", text: JSON.stringify(wikiPage, null, 2) }] };
|
|
1740
|
+
}
|
|
1741
|
+
case "create_wiki_page": {
|
|
1742
|
+
const { project_id, title, content, format } = CreateWikiPageSchema.parse(request.params.arguments);
|
|
1743
|
+
const wikiPage = await createWikiPage(project_id, title, content, format);
|
|
1744
|
+
return { content: [{ type: "text", text: JSON.stringify(wikiPage, null, 2) }] };
|
|
1745
|
+
}
|
|
1746
|
+
case "update_wiki_page": {
|
|
1747
|
+
const { project_id, slug, title, content, format } = UpdateWikiPageSchema.parse(request.params.arguments);
|
|
1748
|
+
const wikiPage = await updateWikiPage(project_id, slug, title, content, format);
|
|
1749
|
+
return { content: [{ type: "text", text: JSON.stringify(wikiPage, null, 2) }] };
|
|
1750
|
+
}
|
|
1751
|
+
case "delete_wiki_page": {
|
|
1752
|
+
const { project_id, slug } = DeleteWikiPageSchema.parse(request.params.arguments);
|
|
1753
|
+
await deleteWikiPage(project_id, slug);
|
|
1754
|
+
return { content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Wiki page deleted successfully" }, null, 2) }] };
|
|
1755
|
+
}
|
|
1614
1756
|
default:
|
|
1615
1757
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
1616
1758
|
}
|
package/build/schemas.js
CHANGED
|
@@ -682,3 +682,39 @@ export const ListGroupProjectsSchema = z.object({
|
|
|
682
682
|
with_custom_attributes: z.boolean().optional().describe("Include custom attributes"),
|
|
683
683
|
with_security_reports: z.boolean().optional().describe("Include security reports")
|
|
684
684
|
});
|
|
685
|
+
// Add wiki operation schemas
|
|
686
|
+
export const ListWikiPagesSchema = z.object({
|
|
687
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
688
|
+
page: z.number().optional().describe("Page number for pagination"),
|
|
689
|
+
per_page: z.number().optional().describe("Number of items per page"),
|
|
690
|
+
});
|
|
691
|
+
export const GetWikiPageSchema = z.object({
|
|
692
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
693
|
+
slug: z.string().describe("URL-encoded slug of the wiki page"),
|
|
694
|
+
});
|
|
695
|
+
export const CreateWikiPageSchema = z.object({
|
|
696
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
697
|
+
title: z.string().describe("Title of the wiki page"),
|
|
698
|
+
content: z.string().describe("Content of the wiki page"),
|
|
699
|
+
format: z.string().optional().describe("Content format, e.g., markdown, rdoc"),
|
|
700
|
+
});
|
|
701
|
+
export const UpdateWikiPageSchema = z.object({
|
|
702
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
703
|
+
slug: z.string().describe("URL-encoded slug of the wiki page"),
|
|
704
|
+
title: z.string().optional().describe("New title of the wiki page"),
|
|
705
|
+
content: z.string().optional().describe("New content of the wiki page"),
|
|
706
|
+
format: z.string().optional().describe("Content format, e.g., markdown, rdoc"),
|
|
707
|
+
});
|
|
708
|
+
export const DeleteWikiPageSchema = z.object({
|
|
709
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
710
|
+
slug: z.string().describe("URL-encoded slug of the wiki page"),
|
|
711
|
+
});
|
|
712
|
+
// Define wiki response schemas
|
|
713
|
+
export const GitLabWikiPageSchema = z.object({
|
|
714
|
+
title: z.string(),
|
|
715
|
+
slug: z.string(),
|
|
716
|
+
format: z.string(),
|
|
717
|
+
content: z.string(),
|
|
718
|
+
created_at: z.string().optional(),
|
|
719
|
+
updated_at: z.string().optional(),
|
|
720
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zereight/mcp-gitlab",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.32",
|
|
4
4
|
"description": "MCP server for using the GitLab API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "zereight",
|
|
@@ -23,8 +23,12 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@modelcontextprotocol/sdk": "1.8.0",
|
|
26
|
+
"form-data": "^4.0.0",
|
|
26
27
|
"@types/node-fetch": "^2.6.12",
|
|
28
|
+
"http-proxy-agent": "^7.0.2",
|
|
29
|
+
"https-proxy-agent": "^7.0.6",
|
|
27
30
|
"node-fetch": "^3.3.2",
|
|
31
|
+
"socks-proxy-agent": "^8.0.5",
|
|
28
32
|
"zod-to-json-schema": "^3.23.5"
|
|
29
33
|
},
|
|
30
34
|
"devDependencies": {
|