@zereight/mcp-gitlab 2.1.56 → 2.1.57

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.
@@ -0,0 +1,218 @@
1
+ import { describe, test, before, after } from "node:test";
2
+ import assert from "node:assert";
3
+ import { spawn } from "child_process";
4
+ import { MockGitLabServer, findMockServerPort } from "./utils/mock-gitlab-server.js";
5
+ const MOCK_TOKEN = "glpat-mock-token-webhooks";
6
+ const TEST_PROJECT_ID = "123";
7
+ const TEST_GROUP_ID = "my-group";
8
+ const TEST_HOOK_ID = 42;
9
+ const MOCK_PROJECT_HOOK = {
10
+ id: TEST_HOOK_ID,
11
+ url: "https://example.com/hook",
12
+ name: "AI Hook",
13
+ description: "Registered by MCP",
14
+ project_id: Number(TEST_PROJECT_ID),
15
+ push_events: true,
16
+ issues_events: false,
17
+ enable_ssl_verification: true,
18
+ };
19
+ const MOCK_GROUP_HOOK = {
20
+ id: TEST_HOOK_ID,
21
+ url: "https://example.com/group-hook",
22
+ name: "Group Hook",
23
+ group_id: 3,
24
+ push_events: true,
25
+ member_events: true,
26
+ enable_ssl_verification: true,
27
+ };
28
+ function isRecord(value) {
29
+ return typeof value === "object" && value !== null && !Array.isArray(value);
30
+ }
31
+ async function callTool(toolName, args, env) {
32
+ return new Promise((resolve, reject) => {
33
+ const proc = spawn("node", ["build/index.js"], {
34
+ stdio: ["pipe", "pipe", "pipe"],
35
+ env: { ...process.env, ...env },
36
+ });
37
+ let output = "";
38
+ let errorOutput = "";
39
+ proc.stdout?.on("data", (d) => (output += d));
40
+ proc.stderr?.on("data", (d) => (errorOutput += d));
41
+ proc.on("close", code => {
42
+ if (code !== 0) {
43
+ return reject(new Error(`Process exited with code ${code}: ${errorOutput}`));
44
+ }
45
+ const line = output.split("\n").find(l => l.startsWith("{"));
46
+ if (!line)
47
+ return reject(new Error("No JSON output found"));
48
+ try {
49
+ const response = JSON.parse(line);
50
+ if (response.error) {
51
+ reject(new Error(response.error?.message ?? String(response.error)));
52
+ }
53
+ else {
54
+ const content = response.result?.content?.[0]?.text;
55
+ resolve(content ? JSON.parse(content) : response.result);
56
+ }
57
+ }
58
+ catch (e) {
59
+ reject(e);
60
+ }
61
+ });
62
+ proc.stdin?.end(JSON.stringify({
63
+ jsonrpc: "2.0",
64
+ id: 1,
65
+ method: "tools/call",
66
+ params: { name: toolName, arguments: args },
67
+ }) + "\n");
68
+ });
69
+ }
70
+ describe("When managing webhooks", () => {
71
+ let mockServer;
72
+ let baseEnv;
73
+ let lastCreateBody;
74
+ let lastUpdateBody;
75
+ let lastDeletePath;
76
+ before(async () => {
77
+ mockServer = new MockGitLabServer({
78
+ port: await findMockServerPort(),
79
+ validTokens: [MOCK_TOKEN],
80
+ });
81
+ mockServer.addMockHandler("post", `/projects/${TEST_PROJECT_ID}/hooks`, (req, res) => {
82
+ lastCreateBody = isRecord(req.body) ? req.body : undefined;
83
+ res.status(201).json({ ...MOCK_PROJECT_HOOK, ...lastCreateBody });
84
+ });
85
+ mockServer.addMockHandler("put", `/projects/${TEST_PROJECT_ID}/hooks/${TEST_HOOK_ID}`, (req, res) => {
86
+ lastUpdateBody = isRecord(req.body) ? req.body : undefined;
87
+ res.json({ ...MOCK_PROJECT_HOOK, ...lastUpdateBody, id: TEST_HOOK_ID });
88
+ });
89
+ mockServer.addMockHandler("delete", `/projects/${TEST_PROJECT_ID}/hooks/${TEST_HOOK_ID}`, (req, res) => {
90
+ lastDeletePath = req.path;
91
+ res.status(204).send();
92
+ });
93
+ mockServer.addMockHandler("post", `/groups/${TEST_GROUP_ID}/hooks`, (req, res) => {
94
+ lastCreateBody = isRecord(req.body) ? req.body : undefined;
95
+ res.status(201).json({ ...MOCK_GROUP_HOOK, ...lastCreateBody });
96
+ });
97
+ mockServer.addMockHandler("put", `/groups/${TEST_GROUP_ID}/hooks/${TEST_HOOK_ID}`, (req, res) => {
98
+ lastUpdateBody = isRecord(req.body) ? req.body : undefined;
99
+ res.json({ ...MOCK_GROUP_HOOK, ...lastUpdateBody, id: TEST_HOOK_ID });
100
+ });
101
+ mockServer.addMockHandler("delete", `/groups/${TEST_GROUP_ID}/hooks/${TEST_HOOK_ID}`, (req, res) => {
102
+ lastDeletePath = req.path;
103
+ res.status(204).send();
104
+ });
105
+ await mockServer.start();
106
+ baseEnv = {
107
+ GITLAB_API_URL: mockServer.getUrl() + "/api/v4",
108
+ GITLAB_PERSONAL_ACCESS_TOKEN: MOCK_TOKEN,
109
+ GITLAB_TOOLSETS: "webhooks",
110
+ GITLAB_READ_ONLY_MODE: "false",
111
+ };
112
+ });
113
+ after(async () => {
114
+ if (mockServer)
115
+ await mockServer.stop();
116
+ });
117
+ describe("with create_webhook on a project", () => {
118
+ test("should create a webhook and return the GitLab response", async () => {
119
+ lastCreateBody = undefined;
120
+ const result = await callTool("create_webhook", {
121
+ project_id: TEST_PROJECT_ID,
122
+ url: "https://example.com/hook",
123
+ name: "AI Hook",
124
+ push_events: true,
125
+ issues_events: true,
126
+ }, baseEnv);
127
+ assert.deepStrictEqual(lastCreateBody, {
128
+ url: "https://example.com/hook",
129
+ name: "AI Hook",
130
+ push_events: true,
131
+ issues_events: true,
132
+ });
133
+ assert.ok(isRecord(result));
134
+ assert.strictEqual(result.url, "https://example.com/hook");
135
+ assert.strictEqual(result.name, "AI Hook");
136
+ });
137
+ });
138
+ describe("with update_webhook on a project", () => {
139
+ test("should update a webhook and return the GitLab response", async () => {
140
+ lastUpdateBody = undefined;
141
+ const result = await callTool("update_webhook", {
142
+ project_id: TEST_PROJECT_ID,
143
+ hook_id: TEST_HOOK_ID,
144
+ url: "https://example.com/hook-updated",
145
+ name: "Renamed Hook",
146
+ }, baseEnv);
147
+ assert.deepStrictEqual(lastUpdateBody, {
148
+ url: "https://example.com/hook-updated",
149
+ name: "Renamed Hook",
150
+ });
151
+ assert.ok(isRecord(result));
152
+ assert.strictEqual(result.url, "https://example.com/hook-updated");
153
+ });
154
+ });
155
+ describe("with delete_webhook on a project", () => {
156
+ test("should delete a webhook and return a deleted status", async () => {
157
+ lastDeletePath = undefined;
158
+ const result = await callTool("delete_webhook", {
159
+ project_id: TEST_PROJECT_ID,
160
+ hook_id: TEST_HOOK_ID,
161
+ }, baseEnv);
162
+ assert.strictEqual(lastDeletePath, `/projects/${TEST_PROJECT_ID}/hooks/${TEST_HOOK_ID}`);
163
+ assert.deepStrictEqual(result, { status: "deleted", hook_id: TEST_HOOK_ID });
164
+ });
165
+ });
166
+ describe("with create_webhook on a group", () => {
167
+ test("should create a group webhook", async () => {
168
+ lastCreateBody = undefined;
169
+ const result = await callTool("create_webhook", {
170
+ group_id: TEST_GROUP_ID,
171
+ url: "https://example.com/group-hook",
172
+ member_events: true,
173
+ }, baseEnv);
174
+ assert.ok(lastCreateBody);
175
+ assert.strictEqual(lastCreateBody["url"], "https://example.com/group-hook");
176
+ assert.strictEqual(lastCreateBody["member_events"], true);
177
+ assert.ok(isRecord(result));
178
+ assert.strictEqual(result["url"], "https://example.com/group-hook");
179
+ });
180
+ });
181
+ describe("with update_webhook on a group", () => {
182
+ test("should update a group webhook", async () => {
183
+ lastUpdateBody = undefined;
184
+ const result = await callTool("update_webhook", {
185
+ group_id: TEST_GROUP_ID,
186
+ hook_id: TEST_HOOK_ID,
187
+ url: "https://example.com/group-hook-updated",
188
+ name: "Renamed Group Hook",
189
+ }, baseEnv);
190
+ assert.deepStrictEqual(lastUpdateBody, {
191
+ url: "https://example.com/group-hook-updated",
192
+ name: "Renamed Group Hook",
193
+ });
194
+ assert.ok(isRecord(result));
195
+ assert.strictEqual(result.url, "https://example.com/group-hook-updated");
196
+ });
197
+ });
198
+ describe("with delete_webhook on a group", () => {
199
+ test("should delete a group webhook", async () => {
200
+ lastDeletePath = undefined;
201
+ const result = await callTool("delete_webhook", {
202
+ group_id: TEST_GROUP_ID,
203
+ hook_id: TEST_HOOK_ID,
204
+ }, baseEnv);
205
+ assert.strictEqual(lastDeletePath, `/groups/${TEST_GROUP_ID}/hooks/${TEST_HOOK_ID}`);
206
+ assert.deepStrictEqual(result, { status: "deleted", hook_id: TEST_HOOK_ID });
207
+ });
208
+ });
209
+ describe("with invalid scope", () => {
210
+ test("should reject when both project_id and group_id are provided", async () => {
211
+ await assert.rejects(() => callTool("create_webhook", {
212
+ project_id: TEST_PROJECT_ID,
213
+ group_id: TEST_GROUP_ID,
214
+ url: "https://example.com/hook",
215
+ }, baseEnv), /project_id or group_id/);
216
+ });
217
+ });
218
+ });
@@ -3,7 +3,6 @@
3
3
  * with the fixed endpoint URL construction that uses plural resource names
4
4
  * (issues instead of issue, merge_requests instead of merge_request).
5
5
  */
6
- import fetch from "node-fetch";
7
6
  // GitLab API configuration (replace with actual values when testing)
8
7
  const GITLAB_API_URL = process.env.GITLAB_API_URL || "https://gitlab.com";
9
8
  const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_TOKEN || "";
@@ -3,7 +3,6 @@
3
3
  * It shows how to use the update_issue_note tool to resolve or unresolve
4
4
  * issue discussion threads.
5
5
  */
6
- import fetch from "node-fetch";
7
6
  // GitLab API configuration (replace with actual values when testing)
8
7
  const GITLAB_API_URL = process.env.GITLAB_API_URL || "https://gitlab.com";
9
8
  const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_TOKEN || "";
@@ -2,7 +2,7 @@ import { zodToJsonSchema } from "zod-to-json-schema";
2
2
  import { toJSONSchema } from "../utils/schema.js";
3
3
  import { USE_GITLAB_WIKI, USE_MILESTONE, USE_PIPELINE, SSE, STREAMABLE_HTTP, } from "../config.js";
4
4
  import { getToolDescription } from "./tool-descriptions.js";
5
- import { ApproveMergeRequestSchema, BulkPublishDraftNotesSchema, CancelPipelineJobSchema, CancelPipelineSchema, ConvertWorkItemTypeSchema, CreateBranchSchema, CreateDraftNoteSchema, CreateGroupSchema, CreateGroupWikiPageSchema, CreateIssueLinkSchema, CreateIssueNoteSchema, CreateIssueSchema, CreateIssueEmojiReactionSchema, CreateIssueNoteEmojiReactionSchema, ListIssueEmojiReactionsSchema, ListIssueNoteEmojiReactionsSchema, CreateLabelSchema, MarkAllTodosDoneSchema, ListTodosSchema, MarkTodoDoneSchema, CreateMergeRequestDiscussionNoteSchema, CreateMergeRequestEmojiReactionSchema, ListMergeRequestEmojiReactionsSchema, ListMergeRequestNoteEmojiReactionsSchema, CreateMergeRequestNoteSchema, CreateMergeRequestNoteEmojiReactionSchema, CreateMergeRequestSchema, CreateMergeRequestThreadSchema, CreateNoteSchema, CreateCommitStatusSchema, CreateOrUpdateFileSchema, CreatePipelineSchema, CreateProjectMilestoneSchema, CreateGroupMilestoneSchema, CreateReleaseEvidenceSchema, CreateReleaseSchema, CreateRepositorySchema, CreateTagSchema, CreateTimelineEventSchema, CreateWikiPageSchema, CreateWorkItemNoteSchema, CreateWorkItemEmojiReactionSchema, CreateWorkItemNoteEmojiReactionSchema, ListWorkItemEmojiReactionsSchema, ListWorkItemNoteEmojiReactionsSchema, CreateWorkItemSchema, DeleteBranchSchema, GetProtectedBranchSchema, ListProtectedBranchesSchema, ProtectBranchSchema, UnprotectBranchSchema, UpdateDefaultBranchSchema, DeleteDraftNoteSchema, DeleteGroupMilestoneSchema, DeleteGroupWikiPageSchema, DeleteIssueLinkSchema, DeleteIssueSchema, DeleteIssueEmojiReactionSchema, DeleteIssueNoteEmojiReactionSchema, DeleteLabelSchema, DeleteMergeRequestDiscussionNoteSchema, DeleteMergeRequestNoteSchema, DeleteMergeRequestEmojiReactionSchema, DeleteMergeRequestNoteEmojiReactionSchema, DeleteProjectMilestoneSchema, DeleteReleaseSchema, DeleteTagSchema, DeleteWikiPageSchema, DeleteWorkItemEmojiReactionSchema, DeleteWorkItemNoteEmojiReactionSchema, DownloadAttachmentSchema, DownloadAttachmentRemoteSchema, DownloadJobArtifactsSchema, DownloadJobArtifactsRemoteSchema, DownloadReleaseAssetSchema, EditProjectMilestoneSchema, EditGroupMilestoneSchema, ExecuteGraphQLSchema, ForkRepositorySchema, HealthCheckSchema, GetBranchSchema, GetBranchDiffsSchema, GetCommitDiffSchema, GetCommitSchema, GetFileBlameSchema, GetDeploymentSchema, GetDraftNoteSchema, GetEnvironmentSchema, GetFileContentsSchema, GetGroupWikiPageSchema, GetIssueLinkSchema, GetIssueSchema, GetJobArtifactFileSchema, GetLabelSchema, GetMergeRequestApprovalStateSchema, GetMergeRequestConflictsSchema, GetMergeRequestDiffsSchema, GetMergeRequestFileDiffSchema, GetMergeRequestNoteSchema, GetMergeRequestNotesSchema, GetMergeRequestSchema, GetMergeRequestVersionSchema, GetMilestoneBurndownEventsSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, GetGroupMilestoneSchema, GetGroupMilestoneIssuesSchema, GetGroupMilestoneMergeRequestsSchema, GetGroupMilestoneBurndownEventsSchema, GetNamespaceSchema, GetPipelineJobOutputSchema, PipelineJobControlSchema, GetPipelineSchema, GetProjectEventsSchema, GetProjectMilestoneSchema, GetProjectSchema, GetReleaseSchema, GetRepositoryTreeSchema, GetTagSchema, GetTagSignatureSchema, GetTimelineEventsSchema, GetUsersSchema, GetUserSchema, WhoAmISchema, GetWebhookEventSchema, GetWikiPageSchema, GetWorkItemSchema, ListBranchesSchema, ListCommitsSchema, ListCommitStatusesSchema, ListCustomFieldDefinitionsSchema, ListDeploymentsSchema, ListDraftNotesSchema, ListEnvironmentsSchema, ListEventsSchema, ListGroupIterationsSchema, ListGroupMilestonesSchema, ListGroupProjectsSchema, ListGroupWikiPagesSchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListJobArtifactsSchema, ListLabelsSchema, ListMergeRequestChangedFilesSchema, ListMergeRequestDiffsSchema, ListMergeRequestDiscussionsSchema, ListMergeRequestPipelinesSchema, ListMergeRequestVersionsSchema, ListMergeRequestsSchema, ListGroupMergeRequestsSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelineTriggerJobsSchema, ValidateCiLintSchema, ValidateProjectCiLintSchema, ListCiCatalogResourcesSchema, GetCiCatalogResourceSchema, ListPipelinesSchema, ListPipelineSchedulesSchema, GetPipelineScheduleSchema, ListPipelineSchedulePipelinesSchema, CreatePipelineScheduleSchema, UpdatePipelineScheduleSchema, DeletePipelineScheduleSchema, PlayPipelineScheduleSchema, TakeOwnershipPipelineScheduleSchema, GetPipelineScheduleVariableSchema, CreatePipelineScheduleVariableSchema, UpdatePipelineScheduleVariableSchema, DeletePipelineScheduleVariableSchema, ListGroupMembersSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListReleasesSchema, ListTagsSchema, ListWebhookEventsSchema, ListWebhooksSchema, ListWikiPagesSchema, ListWorkItemNotesSchema, ListWorkItemStatusesSchema, ListWorkItemsSchema, MarkdownUploadSchema, MarkdownUploadRemoteSchema, MergeMergeRequestSchema, MoveWorkItemSchema, MyIssuesSchema, PlayPipelineJobSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PushFilesSchema, ResolveMergeRequestThreadSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchCodeSchema, SearchGroupCodeSchema, SearchProjectCodeSchema, SearchRepositoriesSchema, UnapproveMergeRequestSchema, UpdateDraftNoteSchema, UpdateGroupWikiPageSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateIssueDescriptionPatchSchema, UpdateLabelSchema, UpdateProjectSchema, UpdateMergeRequestDiscussionNoteSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestSchema, UpdateReleaseSchema, UpdateWikiPageSchema, UpdateWorkItemSchema, VerifyNamespaceSchema, ListProjectVariablesSchema, GetProjectVariableSchema, CreateProjectVariableSchema, UpdateProjectVariableSchema, DeleteProjectVariableSchema, ListGroupVariablesSchema, GetGroupVariableSchema, CreateGroupVariableSchema, UpdateGroupVariableSchema, DeleteGroupVariableSchema, GetDependencyProxySettingsSchema, UpdateDependencyProxySettingsSchema, ListDependencyProxyBlobsSchema, PurgeDependencyProxyCacheSchema, ListProjectVulnerabilitiesSchema, GetVulnerabilitySchema, DismissVulnerabilitySchema, ConfirmVulnerabilitySchema, } from "../schemas.js";
5
+ import { ApproveMergeRequestSchema, BulkPublishDraftNotesSchema, CancelPipelineJobSchema, CancelPipelineSchema, ConvertWorkItemTypeSchema, CreateBranchSchema, CreateDraftNoteSchema, CreateGroupSchema, CreateGroupWikiPageSchema, CreateIssueLinkSchema, CreateIssueNoteSchema, CreateIssueSchema, CreateIssueEmojiReactionSchema, CreateIssueNoteEmojiReactionSchema, ListIssueEmojiReactionsSchema, ListIssueNoteEmojiReactionsSchema, CreateLabelSchema, MarkAllTodosDoneSchema, ListTodosSchema, MarkTodoDoneSchema, CreateMergeRequestDiscussionNoteSchema, CreateMergeRequestEmojiReactionSchema, ListMergeRequestEmojiReactionsSchema, ListMergeRequestNoteEmojiReactionsSchema, CreateMergeRequestNoteSchema, CreateMergeRequestNoteEmojiReactionSchema, CreateMergeRequestSchema, CreateMergeRequestThreadSchema, CreateNoteSchema, CreateCommitStatusSchema, CreateOrUpdateFileSchema, CreatePipelineSchema, CreateProjectMilestoneSchema, CreateGroupMilestoneSchema, CreateReleaseEvidenceSchema, CreateReleaseSchema, CreateRepositorySchema, CreateTagSchema, CreateTimelineEventSchema, CreateWebhookSchema, CreateWikiPageSchema, CreateWorkItemNoteSchema, CreateWorkItemEmojiReactionSchema, CreateWorkItemNoteEmojiReactionSchema, ListWorkItemEmojiReactionsSchema, ListWorkItemNoteEmojiReactionsSchema, CreateWorkItemSchema, DeleteBranchSchema, GetProtectedBranchSchema, ListProtectedBranchesSchema, ProtectBranchSchema, UnprotectBranchSchema, UpdateDefaultBranchSchema, DeleteDraftNoteSchema, DeleteGroupMilestoneSchema, DeleteGroupWikiPageSchema, DeleteIssueLinkSchema, DeleteIssueSchema, DeleteIssueEmojiReactionSchema, DeleteIssueNoteEmojiReactionSchema, DeleteLabelSchema, DeleteMergeRequestDiscussionNoteSchema, DeleteMergeRequestNoteSchema, DeleteMergeRequestEmojiReactionSchema, DeleteMergeRequestNoteEmojiReactionSchema, DeleteProjectMilestoneSchema, DeleteReleaseSchema, DeleteTagSchema, DeleteWebhookSchema, DeleteWikiPageSchema, DeleteWorkItemEmojiReactionSchema, DeleteWorkItemNoteEmojiReactionSchema, DownloadAttachmentSchema, DownloadAttachmentRemoteSchema, DownloadJobArtifactsSchema, DownloadJobArtifactsRemoteSchema, DownloadReleaseAssetSchema, EditProjectMilestoneSchema, EditGroupMilestoneSchema, ExecuteGraphQLSchema, ForkRepositorySchema, HealthCheckSchema, GetBranchSchema, GetBranchDiffsSchema, GetCommitDiffSchema, GetCommitSchema, GetFileBlameSchema, GetDeploymentSchema, GetDraftNoteSchema, GetEnvironmentSchema, GetFileContentsSchema, GetGroupWikiPageSchema, GetIssueLinkSchema, GetIssueSchema, GetJobArtifactFileSchema, GetLabelSchema, GetMergeRequestApprovalStateSchema, GetMergeRequestConflictsSchema, GetMergeRequestDiffsSchema, GetMergeRequestFileDiffSchema, GetMergeRequestNoteSchema, GetMergeRequestNotesSchema, GetMergeRequestSchema, GetMergeRequestVersionSchema, GetMilestoneBurndownEventsSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, GetGroupMilestoneSchema, GetGroupMilestoneIssuesSchema, GetGroupMilestoneMergeRequestsSchema, GetGroupMilestoneBurndownEventsSchema, GetNamespaceSchema, GetPipelineJobOutputSchema, PipelineJobControlSchema, GetPipelineSchema, GetProjectEventsSchema, GetProjectMilestoneSchema, GetProjectSchema, GetReleaseSchema, GetRepositoryTreeSchema, GetTagSchema, GetTagSignatureSchema, GetTimelineEventsSchema, GetUsersSchema, GetUserSchema, WhoAmISchema, GetWebhookEventSchema, GetWikiPageSchema, GetWorkItemSchema, ListBranchesSchema, ListCommitsSchema, ListCommitStatusesSchema, ListCustomFieldDefinitionsSchema, ListDeploymentsSchema, ListDraftNotesSchema, ListEnvironmentsSchema, ListEventsSchema, ListGroupIterationsSchema, ListGroupMilestonesSchema, ListGroupProjectsSchema, ListGroupWikiPagesSchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListJobArtifactsSchema, ListLabelsSchema, ListMergeRequestChangedFilesSchema, ListMergeRequestDiffsSchema, ListMergeRequestDiscussionsSchema, ListMergeRequestPipelinesSchema, ListMergeRequestVersionsSchema, ListMergeRequestsSchema, ListGroupMergeRequestsSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelineTriggerJobsSchema, ValidateCiLintSchema, ValidateProjectCiLintSchema, ListCiCatalogResourcesSchema, GetCiCatalogResourceSchema, ListPipelinesSchema, ListPipelineSchedulesSchema, GetPipelineScheduleSchema, ListPipelineSchedulePipelinesSchema, CreatePipelineScheduleSchema, UpdatePipelineScheduleSchema, DeletePipelineScheduleSchema, PlayPipelineScheduleSchema, TakeOwnershipPipelineScheduleSchema, GetPipelineScheduleVariableSchema, CreatePipelineScheduleVariableSchema, UpdatePipelineScheduleVariableSchema, DeletePipelineScheduleVariableSchema, ListGroupMembersSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListReleasesSchema, ListTagsSchema, ListWebhookEventsSchema, ListWebhooksSchema, ListWikiPagesSchema, ListWorkItemNotesSchema, ListWorkItemStatusesSchema, ListWorkItemsSchema, MarkdownUploadSchema, MarkdownUploadRemoteSchema, MergeMergeRequestSchema, MoveWorkItemSchema, MyIssuesSchema, PlayPipelineJobSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PushFilesSchema, ResolveMergeRequestThreadSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchCodeSchema, SearchGroupCodeSchema, SearchProjectCodeSchema, SearchRepositoriesSchema, UnapproveMergeRequestSchema, UpdateDraftNoteSchema, UpdateGroupWikiPageSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateIssueDescriptionPatchSchema, UpdateLabelSchema, UpdateProjectSchema, UpdateMergeRequestDiscussionNoteSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestSchema, UpdateReleaseSchema, UpdateWebhookSchema, UpdateWikiPageSchema, UpdateWorkItemSchema, VerifyNamespaceSchema, ListProjectVariablesSchema, GetProjectVariableSchema, CreateProjectVariableSchema, UpdateProjectVariableSchema, DeleteProjectVariableSchema, ListGroupVariablesSchema, GetGroupVariableSchema, CreateGroupVariableSchema, UpdateGroupVariableSchema, DeleteGroupVariableSchema, GetDependencyProxySettingsSchema, UpdateDependencyProxySettingsSchema, ListDependencyProxyBlobsSchema, PurgeDependencyProxyCacheSchema, ListProjectVulnerabilitiesSchema, GetVulnerabilitySchema, DismissVulnerabilitySchema, ConfirmVulnerabilitySchema, } from "../schemas.js";
6
6
  const IS_REMOTE = SSE || STREAMABLE_HTTP;
7
7
  // Define all available tools
8
8
  export const allTools = [
@@ -1057,6 +1057,21 @@ export const allTools = [
1057
1057
  description: "List webhooks for a project or group",
1058
1058
  inputSchema: toJSONSchema(ListWebhooksSchema),
1059
1059
  },
1060
+ {
1061
+ name: "create_webhook",
1062
+ description: "Create a webhook on a project or group",
1063
+ inputSchema: toJSONSchema(CreateWebhookSchema),
1064
+ },
1065
+ {
1066
+ name: "update_webhook",
1067
+ description: "Update an existing project or group webhook",
1068
+ inputSchema: toJSONSchema(UpdateWebhookSchema),
1069
+ },
1070
+ {
1071
+ name: "delete_webhook",
1072
+ description: "Delete a project or group webhook",
1073
+ inputSchema: toJSONSchema(DeleteWebhookSchema),
1074
+ },
1060
1075
  {
1061
1076
  name: "list_webhook_events",
1062
1077
  description: "List recent webhook events (past 7 days)",
@@ -1329,6 +1344,7 @@ export const destructiveTools = new Set([
1329
1344
  "delete_group_milestone",
1330
1345
  "delete_release",
1331
1346
  "delete_tag",
1347
+ "delete_webhook",
1332
1348
  "delete_merge_request_note",
1333
1349
  "delete_merge_request_discussion_note",
1334
1350
  "delete_draft_note",
@@ -1373,6 +1389,7 @@ export const deleteTools = new Set([
1373
1389
  "delete_project_variable",
1374
1390
  "delete_release",
1375
1391
  "delete_tag",
1392
+ "delete_webhook",
1376
1393
  "delete_wiki_page",
1377
1394
  "delete_work_item_emoji_reaction",
1378
1395
  "delete_work_item_note_emoji_reaction",
@@ -1748,6 +1765,9 @@ export const TOOLSET_DEFINITIONS = [
1748
1765
  isDefault: false,
1749
1766
  tools: new Set([
1750
1767
  "list_webhooks",
1768
+ "create_webhook",
1769
+ "update_webhook",
1770
+ "delete_webhook",
1751
1771
  "list_webhook_events",
1752
1772
  "get_webhook_event",
1753
1773
  ]),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zereight/mcp-gitlab",
3
- "version": "2.1.56",
3
+ "version": "2.1.57",
4
4
  "mcpName": "io.github.zereight/gitlab-mcp",
5
5
  "description": "GitLab MCP server for projects, merge requests, issues, pipelines, wiki, releases, and more",
6
6
  "keywords": [
@@ -40,7 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "engines": {
43
- "node": ">=18.0.0",
43
+ "node": ">=18.17.0",
44
44
  "npm": ">=9.0.0"
45
45
  },
46
46
  "scripts": {
@@ -73,15 +73,10 @@
73
73
  },
74
74
  "dependencies": {
75
75
  "@modelcontextprotocol/sdk": "^1.29.0",
76
- "@types/node-fetch": "^2.6.12",
77
76
  "diff": "^9.0.0",
78
77
  "express": "^5.1.0",
79
78
  "express-rate-limit": "^8.5.2",
80
79
  "fetch-cookie": "^3.1.0",
81
- "form-data": "^4.0.0",
82
- "http-proxy-agent": "^7.0.2",
83
- "https-proxy-agent": "^7.0.6",
84
- "node-fetch": "^3.3.2",
85
80
  "open": "^10.2.0",
86
81
  "pino": "^9.7.0",
87
82
  "pino-pretty": "^13.0.0",
@@ -89,6 +84,7 @@
89
84
  "socks-proxy-agent": "^8.0.5",
90
85
  "tldts": "^6.1.86",
91
86
  "tough-cookie": "^5.1.2",
87
+ "undici": "^6.28.0",
92
88
  "zod": "^3.24.2",
93
89
  "zod-to-json-schema": "3.24.5"
94
90
  },