@zereight/mcp-gitlab 1.0.31 → 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/build/index.js +142 -6
- package/build/schemas.js +36 -0
- package/package.json +2 -1
package/build/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import { dirname } from "path";
|
|
|
13
13
|
import fs from "fs";
|
|
14
14
|
import path from "path";
|
|
15
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,
|
|
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,
|
|
17
17
|
// Discussion Schemas
|
|
18
18
|
GitLabDiscussionNoteSchema, // Added
|
|
19
19
|
GitLabDiscussionSchema, UpdateMergeRequestNoteSchema, // Added
|
|
@@ -44,6 +44,7 @@ const server = new Server({
|
|
|
44
44
|
});
|
|
45
45
|
const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_PERSONAL_ACCESS_TOKEN;
|
|
46
46
|
const GITLAB_READ_ONLY_MODE = process.env.GITLAB_READ_ONLY_MODE === "true";
|
|
47
|
+
const USE_GITLAB_WIKI = process.env.USE_GITLAB_WIKI === "true";
|
|
47
48
|
// Add proxy configuration
|
|
48
49
|
const HTTP_PROXY = process.env.HTTP_PROXY;
|
|
49
50
|
const HTTPS_PROXY = process.env.HTTPS_PROXY;
|
|
@@ -150,7 +151,7 @@ const allTools = [
|
|
|
150
151
|
inputSchema: zodToJsonSchema(CreateNoteSchema),
|
|
151
152
|
},
|
|
152
153
|
{
|
|
153
|
-
name: "
|
|
154
|
+
name: "mr_discussions",
|
|
154
155
|
description: "List discussion items for a merge request",
|
|
155
156
|
inputSchema: zodToJsonSchema(ListMergeRequestDiscussionsSchema),
|
|
156
157
|
},
|
|
@@ -254,6 +255,31 @@ const allTools = [
|
|
|
254
255
|
description: "List projects in a GitLab group with filtering options",
|
|
255
256
|
inputSchema: zodToJsonSchema(ListGroupProjectsSchema),
|
|
256
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
|
+
}
|
|
257
283
|
];
|
|
258
284
|
// Define which tools are read-only
|
|
259
285
|
const readOnlyTools = [
|
|
@@ -261,7 +287,7 @@ const readOnlyTools = [
|
|
|
261
287
|
"get_file_contents",
|
|
262
288
|
"get_merge_request",
|
|
263
289
|
"get_merge_request_diffs",
|
|
264
|
-
"
|
|
290
|
+
"mr_discussions",
|
|
265
291
|
"list_issues",
|
|
266
292
|
"get_issue",
|
|
267
293
|
"list_issue_links",
|
|
@@ -275,6 +301,15 @@ const readOnlyTools = [
|
|
|
275
301
|
"get_label",
|
|
276
302
|
"list_group_projects",
|
|
277
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
|
+
];
|
|
278
313
|
/**
|
|
279
314
|
* Smart URL handling for GitLab API
|
|
280
315
|
*
|
|
@@ -1262,11 +1297,87 @@ async function listGroupProjects(options) {
|
|
|
1262
1297
|
const projects = await response.json();
|
|
1263
1298
|
return GitLabProjectSchema.array().parse(projects);
|
|
1264
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
|
+
}
|
|
1265
1372
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
1266
|
-
//
|
|
1267
|
-
const
|
|
1373
|
+
// Apply read-only filter first
|
|
1374
|
+
const tools0 = GITLAB_READ_ONLY_MODE
|
|
1268
1375
|
? allTools.filter((tool) => readOnlyTools.includes(tool.name))
|
|
1269
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));
|
|
1270
1381
|
return {
|
|
1271
1382
|
tools,
|
|
1272
1383
|
};
|
|
@@ -1406,7 +1517,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1406
1517
|
],
|
|
1407
1518
|
};
|
|
1408
1519
|
}
|
|
1409
|
-
case "
|
|
1520
|
+
case "mr_discussions": {
|
|
1410
1521
|
const args = ListMergeRequestDiscussionsSchema.parse(request.params.arguments);
|
|
1411
1522
|
const discussions = await listMergeRequestDiscussions(args.project_id, args.merge_request_iid);
|
|
1412
1523
|
return {
|
|
@@ -1617,6 +1728,31 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1617
1728
|
content: [{ type: "text", text: JSON.stringify(projects, null, 2) }],
|
|
1618
1729
|
};
|
|
1619
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
|
+
}
|
|
1620
1756
|
default:
|
|
1621
1757
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
1622
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,6 +23,7 @@
|
|
|
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",
|
|
27
28
|
"http-proxy-agent": "^7.0.2",
|
|
28
29
|
"https-proxy-agent": "^7.0.6",
|