@zereight/mcp-gitlab 2.1.61 → 2.1.63
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/README.ko.md +1 -1
- package/README.md +120 -116
- package/README.zh-CN.md +5 -1
- package/build/config.js +7 -0
- package/build/index.js +97 -21
- package/build/masking/engine.js +404 -0
- package/build/masking/index.js +2 -0
- package/build/masking/project-scope.js +53 -0
- package/build/schemas.js +25 -18
- package/build/test/get-merge-request-discussion-schema.test.js +30 -0
- package/build/test/gitlab-pipeline-schedule-schema.test.js +32 -0
- package/build/test/group-milestone-schema.test.js +4 -4
- package/build/test/response-masking.test.js +412 -0
- package/build/test/streamable-http-concurrent-session.test.js +16 -0
- package/build/test/test-health-check.js +9 -0
- package/build/test/test-toolset-filtering.js +1 -1
- package/build/test/test-update-project.js +1 -1
- package/build/test/utils/masking.test.js +384 -0
- package/build/test/utils/merge-request-position.test.js +1 -1
- package/build/tools/registry.js +10 -4
- package/build/tools/tool-descriptions.js +1 -0
- package/build/utils/schema.js +46 -23
- package/package.json +2 -3
package/build/utils/schema.js
CHANGED
|
@@ -1,30 +1,50 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
3
2
|
/**
|
|
4
3
|
* Convert a Zod schema to JSON Schema, fixing nullable/optional fields
|
|
5
4
|
* so they are not marked as required, and extracting required fields from the Zod schema.
|
|
6
5
|
*/
|
|
7
6
|
export const toJSONSchema = (schema) => {
|
|
8
|
-
|
|
7
|
+
// Zod 4 native conversion. (zod-to-json-schema only understands Zod 3
|
|
8
|
+
// internals and silently emits an empty schema for Zod 4 schemas.)
|
|
9
|
+
// draft-7 keeps output closest to the previous converter; io:"input"
|
|
10
|
+
// describes tool arguments (preprocess/coerce evaluated input-side).
|
|
11
|
+
const jsonSchema = z.toJSONSchema(schema, { target: "draft-7", io: "input" });
|
|
12
|
+
// Public classes only (no _def access): works on both Zod 3 and Zod 4,
|
|
13
|
+
// whose internals differ (_def.typeName vs _zod.def.type).
|
|
9
14
|
const isOptionalLikeField = (zodType) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
if (zodType instanceof z.ZodOptional ||
|
|
16
|
+
zodType instanceof z.ZodNullable ||
|
|
17
|
+
zodType instanceof z.ZodDefault ||
|
|
18
|
+
zodType instanceof z.ZodCatch) {
|
|
13
19
|
return true;
|
|
14
20
|
}
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
// ZodEffects (v3 preprocess/refine/transform): unwrap the inner schema.
|
|
22
|
+
const ZodEffects = z.ZodEffects;
|
|
23
|
+
if (ZodEffects &&
|
|
24
|
+
zodType instanceof ZodEffects &&
|
|
25
|
+
typeof zodType.innerType === "function") {
|
|
26
|
+
return isOptionalLikeField(zodType.innerType());
|
|
17
27
|
}
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
// ZodBranded: unwrap to the branded schema.
|
|
29
|
+
const ZodBranded = z.ZodBranded;
|
|
30
|
+
if (ZodBranded &&
|
|
31
|
+
zodType instanceof ZodBranded &&
|
|
32
|
+
typeof zodType.unwrap === "function") {
|
|
33
|
+
return isOptionalLikeField(zodType.unwrap());
|
|
20
34
|
}
|
|
21
|
-
|
|
22
|
-
|
|
35
|
+
// Pipes (v3 ZodPipeline / v4 ZodPipe/ZodPreprocess from preprocess/transform):
|
|
36
|
+
// optional-like when either side is optional-like.
|
|
37
|
+
const maybeIn = zodType.in;
|
|
38
|
+
const maybeOut = zodType.out;
|
|
39
|
+
if (maybeIn instanceof z.ZodType && maybeOut instanceof z.ZodType) {
|
|
40
|
+
return isOptionalLikeField(maybeIn) || isOptionalLikeField(maybeOut);
|
|
23
41
|
}
|
|
24
42
|
return false;
|
|
25
43
|
};
|
|
26
|
-
// Extract required fields from Zod schema
|
|
27
|
-
|
|
44
|
+
// Extract required fields from Zod schema (authoritative for the root object:
|
|
45
|
+
// the native converter marks defaulted fields as required, we keep the
|
|
46
|
+
// previous convention that defaulted/optional-like fields are not required).
|
|
47
|
+
const { zodRequiredFields, hasAuthoritativeRequired } = (() => {
|
|
28
48
|
if (schema instanceof z.ZodObject) {
|
|
29
49
|
const shape = schema.shape;
|
|
30
50
|
const requiredFields = [];
|
|
@@ -34,9 +54,9 @@ export const toJSONSchema = (schema) => {
|
|
|
34
54
|
requiredFields.push(key);
|
|
35
55
|
}
|
|
36
56
|
});
|
|
37
|
-
return requiredFields;
|
|
57
|
+
return { zodRequiredFields: requiredFields, hasAuthoritativeRequired: true };
|
|
38
58
|
}
|
|
39
|
-
return [];
|
|
59
|
+
return { zodRequiredFields: [], hasAuthoritativeRequired: false };
|
|
40
60
|
})();
|
|
41
61
|
// Post-process to fix nullable/optional fields and strip verbose keys
|
|
42
62
|
function fixNullableOptional(obj, isRoot = false) {
|
|
@@ -47,14 +67,13 @@ export const toJSONSchema = (schema) => {
|
|
|
47
67
|
delete obj.additionalProperties;
|
|
48
68
|
// If this object has properties, process them
|
|
49
69
|
if (obj.properties) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
zodRequiredFields.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
});
|
|
70
|
+
let requiredSet;
|
|
71
|
+
if (isRoot && hasAuthoritativeRequired) {
|
|
72
|
+
// Zod shape is the source of truth at root level.
|
|
73
|
+
requiredSet = new Set(zodRequiredFields.filter(field => obj.properties[field]));
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
requiredSet = new Set(obj.required || []);
|
|
58
77
|
}
|
|
59
78
|
Object.keys(obj.properties).forEach(key => {
|
|
60
79
|
const prop = obj.properties[key];
|
|
@@ -66,6 +85,10 @@ export const toJSONSchema = (schema) => {
|
|
|
66
85
|
else if (Array.isArray(prop.type) && prop.type.includes("null")) {
|
|
67
86
|
requiredSet.delete(key);
|
|
68
87
|
}
|
|
88
|
+
// Fields with defaults are not required (previous converter semantics).
|
|
89
|
+
if (prop && typeof prop === "object" && "default" in prop) {
|
|
90
|
+
requiredSet.delete(key);
|
|
91
|
+
}
|
|
69
92
|
// Recursively process nested objects (not root)
|
|
70
93
|
obj.properties[key] = fixNullableOptional(prop, false);
|
|
71
94
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zereight/mcp-gitlab",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.63",
|
|
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": [
|
|
@@ -85,8 +85,7 @@
|
|
|
85
85
|
"tldts": "^6.1.86",
|
|
86
86
|
"tough-cookie": "^5.1.2",
|
|
87
87
|
"undici": "^6.28.0",
|
|
88
|
-
"zod": "^
|
|
89
|
-
"zod-to-json-schema": "3.24.5"
|
|
88
|
+
"zod": "^4.6.5"
|
|
90
89
|
},
|
|
91
90
|
"devDependencies": {
|
|
92
91
|
"@types/express": "^5.0.2",
|