@zereight/mcp-gitlab 2.0.36 → 2.1.0

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.
@@ -38,15 +38,13 @@ const DEFAULT_TOOLSETS = [
38
38
  "branches",
39
39
  "projects",
40
40
  "labels",
41
- "pipelines",
42
- "milestones",
43
- "wiki",
44
- "releases",
45
41
  "users",
46
42
  ];
47
- const NON_DEFAULT_TOOLSETS = ["search", "webhooks"];
48
- const DEFAULT_TOOL_COUNT = DEFAULT_TOOLSETS.reduce((sum, id) => sum + TOOLSET_TOOL_COUNTS[id], 0);
49
- const ALL_TOOLSET_TOOL_COUNT = Object.values(TOOLSET_TOOL_COUNTS).reduce((sum, c) => sum + c, 0);
43
+ const NON_DEFAULT_TOOLSETS = ["pipelines", "milestones", "wiki", "releases", "workitems", "webhooks", "search"];
44
+ // discover_tools meta-tool is always force-injected (Step 5.5)
45
+ const DISCOVER_TOOLS_COUNT = 1;
46
+ const DEFAULT_TOOL_COUNT = DEFAULT_TOOLSETS.reduce((sum, id) => sum + TOOLSET_TOOL_COUNTS[id], 0) + DISCOVER_TOOLS_COUNT;
47
+ const ALL_TOOLSET_TOOL_COUNT = Object.values(TOOLSET_TOOL_COUNTS).reduce((sum, c) => sum + c, 0) + DISCOVER_TOOLS_COUNT;
50
48
  // Representative tools per toolset for spot-checking
51
49
  const TOOLSET_SAMPLE_TOOLS = {
52
50
  merge_requests: ["merge_merge_request", "create_merge_request_thread", "list_draft_notes"],
@@ -136,8 +134,10 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
136
134
  assertContainsAll(tools, TOOLSET_SAMPLE_TOOLS[id], id);
137
135
  }
138
136
  });
139
- test("excludes non-default toolsets (search)", () => {
137
+ test("excludes non-default toolsets (search, pipelines, wiki)", () => {
140
138
  assertContainsNone(tools, TOOLSET_SAMPLE_TOOLS.search, "non-default search");
139
+ assertContainsNone(tools, TOOLSET_SAMPLE_TOOLS.pipelines, "non-default pipelines");
140
+ assertContainsNone(tools, TOOLSET_SAMPLE_TOOLS.wiki, "non-default wiki");
141
141
  });
142
142
  test("excludes execute_graphql (not in any toolset)", () => {
143
143
  assertContainsNone(tools, ["execute_graphql"], "unassigned");
@@ -155,8 +155,8 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
155
155
  tools = await getToolNames(`http://${HOST}:${port}/mcp`);
156
156
  });
157
157
  after(() => cleanupServers([server]));
158
- test("returns only issue tools", () => {
159
- assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues);
158
+ test("returns only issue tools + discover_tools", () => {
159
+ assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues + DISCOVER_TOOLS_COUNT);
160
160
  });
161
161
  test("includes issue sample tools", () => {
162
162
  assertContainsAll(tools, TOOLSET_SAMPLE_TOOLS.issues, "issues");
@@ -201,14 +201,14 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
201
201
  tools = await getToolNames(`http://${HOST}:${port}/mcp`);
202
202
  });
203
203
  after(() => cleanupServers([server]));
204
- test("returns default tools plus execute_graphql (list_pipelines already in default)", () => {
205
- assert.strictEqual(tools.length, DEFAULT_TOOL_COUNT + 1);
204
+ test("returns default tools plus list_pipelines and execute_graphql (both not in default toolsets)", () => {
205
+ assert.strictEqual(tools.length, DEFAULT_TOOL_COUNT + 2);
206
206
  });
207
207
  test("includes the individually added tools", () => {
208
208
  assertContainsAll(tools, ["list_pipelines", "execute_graphql"], "individual");
209
209
  });
210
- test("includes pipeline tools from default toolset", () => {
211
- assertContainsAll(tools, ["create_pipeline", "cancel_pipeline"], "default pipelines");
210
+ test("excludes other pipeline tools (not individually enabled)", () => {
211
+ assertContainsNone(tools, ["create_pipeline", "cancel_pipeline"], "non-enabled pipelines");
212
212
  });
213
213
  });
214
214
  // ---- 5. Toolset + individual tools combined ----
@@ -224,8 +224,8 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
224
224
  tools = await getToolNames(`http://${HOST}:${port}/mcp`);
225
225
  });
226
226
  after(() => cleanupServers([server]));
227
- test("returns issue tools + 2 individual pipeline tools", () => {
228
- assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues + 2);
227
+ test("returns issue tools + 2 individual pipeline tools + discover_tools", () => {
228
+ assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues + 2 + DISCOVER_TOOLS_COUNT);
229
229
  });
230
230
  test("includes issue tools and the two pipeline tools", () => {
231
231
  assertContainsAll(tools, TOOLSET_SAMPLE_TOOLS.issues, "issues");
@@ -248,8 +248,8 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
248
248
  tools = await getToolNames(`http://${HOST}:${port}/mcp`);
249
249
  });
250
250
  after(() => cleanupServers([server]));
251
- test("returns issue tools + all pipeline tools", () => {
252
- assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues + TOOLSET_TOOL_COUNTS.pipelines);
251
+ test("returns issue tools + all pipeline tools + discover_tools", () => {
252
+ assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues + TOOLSET_TOOL_COUNTS.pipelines + DISCOVER_TOOLS_COUNT);
253
253
  });
254
254
  test("includes all pipeline tools via legacy flag", () => {
255
255
  assertContainsAll(tools, TOOLSET_SAMPLE_TOOLS.pipelines, "pipelines");
@@ -267,8 +267,8 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
267
267
  tools = await getToolNames(`http://${HOST}:${port}/mcp`);
268
268
  });
269
269
  after(() => cleanupServers([server]));
270
- test("returns default tool count (wiki is already default)", () => {
271
- assert.strictEqual(tools.length, DEFAULT_TOOL_COUNT);
270
+ test("returns default tools + wiki tools (wiki is NOT default, USE_GITLAB_WIKI adds it)", () => {
271
+ assert.strictEqual(tools.length, DEFAULT_TOOL_COUNT + TOOLSET_TOOL_COUNTS.wiki);
272
272
  });
273
273
  test("includes wiki tools", () => {
274
274
  assertContainsAll(tools, TOOLSET_SAMPLE_TOOLS.wiki, "wiki");
@@ -312,8 +312,8 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
312
312
  test("excludes write issue tools", () => {
313
313
  assertContainsNone(tools, writeIssueTools, "write issues");
314
314
  });
315
- test("returns correct count", () => {
316
- assert.strictEqual(tools.length, readOnlyIssueTools.length);
315
+ test("returns correct count (read-only issues + discover_tools)", () => {
316
+ assert.strictEqual(tools.length, readOnlyIssueTools.length + DISCOVER_TOOLS_COUNT);
317
317
  });
318
318
  });
319
319
  // ---- 9. GITLAB_DENIED_TOOLS_REGEX applied after toolset filter ----
@@ -378,8 +378,8 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
378
378
  tools = await getToolNames(`http://${HOST}:${port}/mcp`);
379
379
  });
380
380
  after(() => cleanupServers([server]));
381
- test("returns exactly pipeline tool count (no duplicates)", () => {
382
- assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.pipelines);
381
+ test("returns exactly pipeline tool count + discover_tools (no duplicates)", () => {
382
+ assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.pipelines + DISCOVER_TOOLS_COUNT);
383
383
  });
384
384
  });
385
385
  // ---- 12. GITLAB_TOOLS with tool already in enabled toolset (no dupes) ----
@@ -395,8 +395,8 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
395
395
  tools = await getToolNames(`http://${HOST}:${port}/mcp`);
396
396
  });
397
397
  after(() => cleanupServers([server]));
398
- test("returns exactly issue tool count (no duplicates)", () => {
399
- assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues);
398
+ test("returns exactly issue tool count + discover_tools (no duplicates)", () => {
399
+ assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues + DISCOVER_TOOLS_COUNT);
400
400
  });
401
401
  });
402
402
  // ---- 13. Invalid toolset ID is silently ignored ----
@@ -411,8 +411,8 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
411
411
  tools = await getToolNames(`http://${HOST}:${port}/mcp`);
412
412
  });
413
413
  after(() => cleanupServers([server]));
414
- test("returns only issue tools (invalid toolset ignored)", () => {
415
- assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues);
414
+ test("returns only issue tools + discover_tools (invalid toolset ignored)", () => {
415
+ assert.strictEqual(tools.length, TOOLSET_TOOL_COUNTS.issues + DISCOVER_TOOLS_COUNT);
416
416
  });
417
417
  });
418
418
  // ---- 14. GITLAB_TOOLS case-insensitive matching ----
@@ -430,8 +430,8 @@ describe("Toolset Filtering", { concurrency: 1 }, () => {
430
430
  test("resolves mixed-case tool names to lowercase equivalents", () => {
431
431
  assertContainsAll(tools, ["list_pipelines", "execute_graphql"], "case-insensitive tools");
432
432
  });
433
- test("returns default tools plus execute_graphql (list_pipelines already in default)", () => {
434
- assert.strictEqual(tools.length, DEFAULT_TOOL_COUNT + 1);
433
+ test("returns default tools plus list_pipelines and execute_graphql", () => {
434
+ assert.strictEqual(tools.length, DEFAULT_TOOL_COUNT + 2);
435
435
  });
436
436
  });
437
437
  // ---- 15. GITLAB_TOOLS with unknown tool names ----