@structured-world/gitlab-mcp 4.5.0 → 5.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.
- package/README.md +1 -0
- package/dist/config.js +23 -23
- package/dist/config.js.map +1 -1
- package/dist/entities/core/index.d.ts +5 -5
- package/dist/entities/core/index.js +1 -1
- package/dist/entities/core/registry.d.ts +1 -1
- package/dist/entities/core/registry.js +149 -149
- package/dist/entities/core/registry.js.map +1 -1
- package/dist/entities/core/schema-readonly.d.ts +1 -1
- package/dist/entities/core/schema-readonly.js +132 -132
- package/dist/entities/core/schema-readonly.js.map +1 -1
- package/dist/entities/core/schema.d.ts +1 -1
- package/dist/entities/core/schema.js +59 -59
- package/dist/entities/files/index.d.ts +5 -5
- package/dist/entities/files/index.js +1 -1
- package/dist/entities/files/registry.d.ts +1 -1
- package/dist/entities/files/registry.js +32 -32
- package/dist/entities/files/registry.js.map +1 -1
- package/dist/entities/files/schema-readonly.d.ts +1 -1
- package/dist/entities/files/schema-readonly.js +10 -10
- package/dist/entities/files/schema.d.ts +1 -1
- package/dist/entities/files/schema.js +19 -19
- package/dist/entities/index.d.ts +10 -10
- package/dist/entities/labels/index.d.ts +5 -5
- package/dist/entities/labels/index.js +1 -1
- package/dist/entities/labels/registry.d.ts +1 -1
- package/dist/entities/labels/registry.js +31 -31
- package/dist/entities/labels/registry.js.map +1 -1
- package/dist/entities/labels/schema-readonly.d.ts +1 -1
- package/dist/entities/labels/schema-readonly.js +7 -7
- package/dist/entities/labels/schema.d.ts +1 -1
- package/dist/entities/labels/schema.js +11 -11
- package/dist/entities/milestones/index.d.ts +5 -5
- package/dist/entities/milestones/index.js +1 -1
- package/dist/entities/milestones/registry.d.ts +1 -1
- package/dist/entities/milestones/registry.js +49 -49
- package/dist/entities/milestones/registry.js.map +1 -1
- package/dist/entities/milestones/schema-readonly.d.ts +2 -2
- package/dist/entities/milestones/schema-readonly.js +11 -11
- package/dist/entities/milestones/schema.d.ts +1 -1
- package/dist/entities/milestones/schema.js +18 -18
- package/dist/entities/milestones/schema.js.map +1 -1
- package/dist/entities/mrs/index.d.ts +5 -5
- package/dist/entities/mrs/index.js +1 -1
- package/dist/entities/mrs/registry.d.ts +1 -1
- package/dist/entities/mrs/registry.js +118 -118
- package/dist/entities/mrs/registry.js.map +1 -1
- package/dist/entities/mrs/schema-readonly.d.ts +1 -1
- package/dist/entities/mrs/schema-readonly.js +47 -47
- package/dist/entities/mrs/schema-readonly.js.map +1 -1
- package/dist/entities/mrs/schema.d.ts +1 -1
- package/dist/entities/mrs/schema.js +86 -86
- package/dist/entities/mrs/schema.js.map +1 -1
- package/dist/entities/pipelines/index.d.ts +5 -5
- package/dist/entities/pipelines/index.js +1 -1
- package/dist/entities/pipelines/registry.d.ts +1 -1
- package/dist/entities/pipelines/registry.js +58 -58
- package/dist/entities/pipelines/registry.js.map +1 -1
- package/dist/entities/pipelines/schema-readonly.d.ts +1 -1
- package/dist/entities/pipelines/schema-readonly.js +65 -65
- package/dist/entities/pipelines/schema.d.ts +1 -1
- package/dist/entities/pipelines/schema.js +15 -15
- package/dist/entities/shared.d.ts +1 -1
- package/dist/entities/shared.js +7 -7
- package/dist/entities/utils.d.ts +1 -1
- package/dist/entities/utils.js +5 -5
- package/dist/entities/utils.js.map +1 -1
- package/dist/entities/variables/index.d.ts +5 -5
- package/dist/entities/variables/index.js +1 -1
- package/dist/entities/variables/registry.d.ts +1 -1
- package/dist/entities/variables/registry.js +29 -29
- package/dist/entities/variables/registry.js.map +1 -1
- package/dist/entities/variables/schema-readonly.d.ts +1 -1
- package/dist/entities/variables/schema-readonly.js +4 -4
- package/dist/entities/variables/schema.d.ts +1 -1
- package/dist/entities/variables/schema.js +32 -32
- package/dist/entities/variables/schema.js.map +1 -1
- package/dist/entities/wiki/index.d.ts +5 -5
- package/dist/entities/wiki/index.js +1 -1
- package/dist/entities/wiki/registry.d.ts +1 -1
- package/dist/entities/wiki/registry.js +26 -26
- package/dist/entities/wiki/registry.js.map +1 -1
- package/dist/entities/wiki/schema-readonly.d.ts +1 -1
- package/dist/entities/wiki/schema-readonly.js +4 -4
- package/dist/entities/wiki/schema.d.ts +1 -1
- package/dist/entities/wiki/schema.js +11 -11
- package/dist/entities/workitems/index.d.ts +5 -5
- package/dist/entities/workitems/index.js +1 -1
- package/dist/entities/workitems/registry.d.ts +1 -1
- package/dist/entities/workitems/registry.js +55 -55
- package/dist/entities/workitems/registry.js.map +1 -1
- package/dist/entities/workitems/schema-readonly.d.ts +1 -1
- package/dist/entities/workitems/schema-readonly.js +25 -25
- package/dist/entities/workitems/schema-readonly.js.map +1 -1
- package/dist/entities/workitems/schema.d.ts +1 -1
- package/dist/entities/workitems/schema.js +11 -11
- package/dist/graphql/DynamicWorkItemsQuery.d.ts +2 -2
- package/dist/graphql/DynamicWorkItemsQuery.js +47 -47
- package/dist/graphql/DynamicWorkItemsQuery.js.map +1 -1
- package/dist/graphql/client.d.ts +1 -1
- package/dist/graphql/client.js +4 -4
- package/dist/graphql/client.js.map +1 -1
- package/dist/graphql/index.d.ts +2 -2
- package/dist/graphql/workItems.d.ts +33 -33
- package/dist/graphql/workItems.js +29 -29
- package/dist/handlers.d.ts +1 -1
- package/dist/handlers.js +20 -20
- package/dist/handlers.js.map +1 -1
- package/dist/http-client.js +3 -3
- package/dist/logger.js +4 -4
- package/dist/registry-manager.d.ts +1 -1
- package/dist/registry-manager.js +27 -27
- package/dist/server.d.ts +1 -1
- package/dist/server.js +46 -46
- package/dist/services/ConnectionManager.d.ts +4 -4
- package/dist/services/ConnectionManager.js +13 -13
- package/dist/services/GitLabVersionDetector.d.ts +2 -2
- package/dist/services/GitLabVersionDetector.js +41 -41
- package/dist/services/GitLabVersionDetector.js.map +1 -1
- package/dist/services/SchemaIntrospector.d.ts +1 -1
- package/dist/services/SchemaIntrospector.js +42 -42
- package/dist/services/SchemaIntrospector.js.map +1 -1
- package/dist/services/ToolAvailability.d.ts +2 -2
- package/dist/services/ToolAvailability.js +279 -279
- package/dist/services/ToolAvailability.js.map +1 -1
- package/dist/services/WidgetAvailability.d.ts +3 -3
- package/dist/services/WidgetAvailability.js +32 -32
- package/dist/structured-world-gitlab-mcp-5.1.0.tgz +0 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types.js +4 -4
- package/dist/utils/fetch.d.ts +4 -4
- package/dist/utils/fetch.js +15 -15
- package/dist/utils/fetch.js.map +1 -1
- package/dist/utils/idConversion.js +33 -33
- package/dist/utils/idConversion.js.map +1 -1
- package/dist/utils/namespace.d.ts +2 -2
- package/dist/utils/namespace.js +13 -13
- package/dist/utils/smart-user-search.d.ts +1 -1
- package/dist/utils/smart-user-search.js +10 -10
- package/package.json +1 -1
- package/dist/structured-world-gitlab-mcp-4.5.0.tgz +0 -0
|
@@ -12,9 +12,9 @@ const smart_user_search_1 = require("../../utils/smart-user-search");
|
|
|
12
12
|
const idConversion_1 = require("../../utils/idConversion");
|
|
13
13
|
exports.coreToolRegistry = new Map([
|
|
14
14
|
[
|
|
15
|
-
|
|
15
|
+
"search_repositories",
|
|
16
16
|
{
|
|
17
|
-
name:
|
|
17
|
+
name: "search_repositories",
|
|
18
18
|
description: "DISCOVER projects across ALL of GitLab using search criteria. Use when: You DON'T know the project name/path, Looking for ANY project (not just yours), Searching by language/keywords/topics. Use with_programming_language parameter for efficient language filtering. See also: Use list_projects for YOUR accessible projects only.",
|
|
19
19
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.SearchRepositoriesSchema),
|
|
20
20
|
handler: async (args) => {
|
|
@@ -22,41 +22,41 @@ exports.coreToolRegistry = new Map([
|
|
|
22
22
|
const { q, with_programming_language, ...otherOptions } = options;
|
|
23
23
|
const queryParams = new URLSearchParams();
|
|
24
24
|
let finalLanguage = with_programming_language;
|
|
25
|
-
let finalSearchTerms = q ??
|
|
25
|
+
let finalSearchTerms = q ?? "";
|
|
26
26
|
if (q && !with_programming_language) {
|
|
27
27
|
const languageMatch = q.match(/language:(\w+)/);
|
|
28
28
|
if (languageMatch) {
|
|
29
29
|
finalLanguage = languageMatch[1];
|
|
30
|
-
finalSearchTerms = q.replace(/language:\w+/g,
|
|
30
|
+
finalSearchTerms = q.replace(/language:\w+/g, "").trim();
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
if (q) {
|
|
34
34
|
const userMatch = q.match(/user:(\w+)/);
|
|
35
35
|
if (userMatch) {
|
|
36
|
-
queryParams.set(
|
|
37
|
-
finalSearchTerms = finalSearchTerms.replace(/user:\w+/g,
|
|
36
|
+
queryParams.set("owned", "true");
|
|
37
|
+
finalSearchTerms = finalSearchTerms.replace(/user:\w+/g, "").trim();
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
if (q) {
|
|
41
41
|
const topicMatches = q.match(/topic:(\w+)/g);
|
|
42
42
|
if (topicMatches) {
|
|
43
|
-
const topics = topicMatches.map(
|
|
44
|
-
queryParams.set(
|
|
45
|
-
finalSearchTerms = finalSearchTerms.replace(/topic:\w+/g,
|
|
43
|
+
const topics = topicMatches.map(match => match.replace("topic:", ""));
|
|
44
|
+
queryParams.set("topic", topics.join(","));
|
|
45
|
+
finalSearchTerms = finalSearchTerms.replace(/topic:\w+/g, "").trim();
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
if (finalLanguage) {
|
|
49
|
-
queryParams.set(
|
|
49
|
+
queryParams.set("with_programming_language", finalLanguage);
|
|
50
50
|
}
|
|
51
51
|
if (finalSearchTerms) {
|
|
52
|
-
queryParams.set(
|
|
52
|
+
queryParams.set("search", finalSearchTerms.replace(/\s+/g, "+"));
|
|
53
53
|
}
|
|
54
54
|
Object.entries(otherOptions).forEach(([key, value]) => {
|
|
55
55
|
if (value !== undefined) {
|
|
56
56
|
queryParams.set(key, String(value));
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
|
-
queryParams.set(
|
|
59
|
+
queryParams.set("active", "true");
|
|
60
60
|
const apiUrl = `${process.env.GITLAB_API_URL}/api/v4/projects?${queryParams}`;
|
|
61
61
|
const response = await (0, fetch_1.enhancedFetch)(apiUrl, {
|
|
62
62
|
headers: {
|
|
@@ -78,38 +78,38 @@ exports.coreToolRegistry = new Map([
|
|
|
78
78
|
},
|
|
79
79
|
],
|
|
80
80
|
[
|
|
81
|
-
|
|
81
|
+
"list_projects",
|
|
82
82
|
{
|
|
83
|
-
name:
|
|
84
|
-
description:
|
|
83
|
+
name: "list_projects",
|
|
84
|
+
description: "List GitLab projects with flexible scoping. DEFAULT (no group_id): Lists YOUR accessible projects across GitLab (owned/member/starred). Use for: browsing your projects, finding your work, managing personal project lists. GROUP SCOPE (with group_id): Lists all projects within a specific group/organization. Use for: exploring team structure, finding organizational projects, auditing group resources. Parameters automatically validate based on scope.",
|
|
85
85
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.ListProjectsSchema),
|
|
86
86
|
handler: async (args) => {
|
|
87
87
|
const options = schema_readonly_1.ListProjectsSchema.parse(args);
|
|
88
88
|
const { group_id, ...otherOptions } = options;
|
|
89
89
|
if (group_id) {
|
|
90
90
|
const userOnlyParams = [
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
91
|
+
"active",
|
|
92
|
+
"imported",
|
|
93
|
+
"membership",
|
|
94
|
+
"statistics",
|
|
95
|
+
"with_programming_language",
|
|
96
|
+
"wiki_checksum_failed",
|
|
97
|
+
"repository_checksum_failed",
|
|
98
|
+
"id_after",
|
|
99
|
+
"id_before",
|
|
100
|
+
"last_activity_after",
|
|
101
|
+
"last_activity_before",
|
|
102
|
+
"marked_for_deletion_on",
|
|
103
|
+
"repository_storage",
|
|
104
104
|
];
|
|
105
|
-
const invalidParams = userOnlyParams.filter(
|
|
105
|
+
const invalidParams = userOnlyParams.filter(param => otherOptions[param] !== undefined);
|
|
106
106
|
if (invalidParams.length > 0) {
|
|
107
|
-
throw new Error(`Invalid parameters for group scope: ${invalidParams.join(
|
|
107
|
+
throw new Error(`Invalid parameters for group scope: ${invalidParams.join(", ")}. These parameters are only valid without group_id (user scope).`);
|
|
108
108
|
}
|
|
109
109
|
const queryParams = new URLSearchParams();
|
|
110
110
|
const groupDefaults = {
|
|
111
|
-
order_by:
|
|
112
|
-
sort:
|
|
111
|
+
order_by: "created_at",
|
|
112
|
+
sort: "desc",
|
|
113
113
|
simple: true,
|
|
114
114
|
per_page: 20,
|
|
115
115
|
};
|
|
@@ -133,22 +133,22 @@ exports.coreToolRegistry = new Map([
|
|
|
133
133
|
}
|
|
134
134
|
else {
|
|
135
135
|
const groupOnlyParams = [
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
"include_subgroups",
|
|
137
|
+
"with_shared",
|
|
138
|
+
"with_security_reports",
|
|
139
|
+
"topic",
|
|
140
|
+
"with_issues_enabled",
|
|
141
|
+
"with_merge_requests_enabled",
|
|
142
142
|
];
|
|
143
|
-
const invalidParams = groupOnlyParams.filter(
|
|
143
|
+
const invalidParams = groupOnlyParams.filter(param => otherOptions[param] !== undefined);
|
|
144
144
|
if (invalidParams.length > 0) {
|
|
145
|
-
throw new Error(`Invalid parameters for user scope: ${invalidParams.join(
|
|
145
|
+
throw new Error(`Invalid parameters for user scope: ${invalidParams.join(", ")}. These parameters require group_id (group scope).`);
|
|
146
146
|
}
|
|
147
147
|
const queryParams = new URLSearchParams();
|
|
148
148
|
const defaults = {
|
|
149
149
|
active: true,
|
|
150
|
-
order_by:
|
|
151
|
-
sort:
|
|
150
|
+
order_by: "created_at",
|
|
151
|
+
sort: "desc",
|
|
152
152
|
simple: true,
|
|
153
153
|
per_page: 20,
|
|
154
154
|
};
|
|
@@ -174,10 +174,10 @@ exports.coreToolRegistry = new Map([
|
|
|
174
174
|
},
|
|
175
175
|
],
|
|
176
176
|
[
|
|
177
|
-
|
|
177
|
+
"list_namespaces",
|
|
178
178
|
{
|
|
179
|
-
name:
|
|
180
|
-
description:
|
|
179
|
+
name: "list_namespaces",
|
|
180
|
+
description: "BROWSE: List GitLab namespaces (groups and user namespaces) accessible to you. Use when: Discovering available groups for project creation, Browsing organizational structure, Finding where to create/fork projects. Returns both user and group namespaces. See also: get_namespace for specific namespace details.",
|
|
181
181
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.ListNamespacesSchema),
|
|
182
182
|
handler: async (args) => {
|
|
183
183
|
const options = schema_readonly_1.ListNamespacesSchema.parse(args);
|
|
@@ -202,9 +202,9 @@ exports.coreToolRegistry = new Map([
|
|
|
202
202
|
},
|
|
203
203
|
],
|
|
204
204
|
[
|
|
205
|
-
|
|
205
|
+
"get_users",
|
|
206
206
|
{
|
|
207
|
-
name:
|
|
207
|
+
name: "get_users",
|
|
208
208
|
description: 'FIND USERS: Search and retrieve GitLab users with intelligent pattern detection. RECOMMENDED: Use "search" parameter for most queries - automatically detects emails, usernames, or names with automatic transliteration and multi-phase fallback search. ADVANCED: Use "username" or "public_email" for exact matches when you need precise control. Supports filtering by active status, creation date, and user type (human/bot).',
|
|
209
209
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.GetUsersSchema),
|
|
210
210
|
handler: async (args) => {
|
|
@@ -214,10 +214,10 @@ exports.coreToolRegistry = new Map([
|
|
|
214
214
|
const hasOnlySearch = Boolean(search) && !hasUsernameOrEmail;
|
|
215
215
|
const shouldUseSmartSearch = smart_search === false ? false : smart_search === true || hasOnlySearch;
|
|
216
216
|
if (shouldUseSmartSearch && (search || username || public_email)) {
|
|
217
|
-
const query = search ?? username ?? public_email ??
|
|
217
|
+
const query = search ?? username ?? public_email ?? "";
|
|
218
218
|
const additionalParams = {};
|
|
219
219
|
Object.entries(otherParams).forEach(([key, value]) => {
|
|
220
|
-
if (value !== undefined && key !==
|
|
220
|
+
if (value !== undefined && key !== "smart_search") {
|
|
221
221
|
additionalParams[key] = value;
|
|
222
222
|
}
|
|
223
223
|
});
|
|
@@ -227,7 +227,7 @@ exports.coreToolRegistry = new Map([
|
|
|
227
227
|
else {
|
|
228
228
|
const queryParams = new URLSearchParams();
|
|
229
229
|
Object.entries(options).forEach(([key, value]) => {
|
|
230
|
-
if (value !== undefined && key !==
|
|
230
|
+
if (value !== undefined && key !== "smart_search") {
|
|
231
231
|
queryParams.set(key, String(value));
|
|
232
232
|
}
|
|
233
233
|
});
|
|
@@ -247,17 +247,17 @@ exports.coreToolRegistry = new Map([
|
|
|
247
247
|
},
|
|
248
248
|
],
|
|
249
249
|
[
|
|
250
|
-
|
|
250
|
+
"get_project",
|
|
251
251
|
{
|
|
252
|
-
name:
|
|
253
|
-
description:
|
|
252
|
+
name: "get_project",
|
|
253
|
+
description: "GET DETAILS: Retrieve comprehensive project information including settings and metadata. Use when: Need complete project details, Checking project configuration, Getting project statistics. Requires project ID or URL-encoded path (group%2Fproject). See also: list_projects to find projects first.",
|
|
254
254
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.GetProjectSchema),
|
|
255
255
|
handler: async (args) => {
|
|
256
256
|
const options = schema_readonly_1.GetProjectSchema.parse(args);
|
|
257
257
|
const { project_id } = options;
|
|
258
258
|
const queryParams = new URLSearchParams();
|
|
259
259
|
Object.entries(options).forEach(([key, value]) => {
|
|
260
|
-
if (value !== undefined && key !==
|
|
260
|
+
if (value !== undefined && key !== "project_id") {
|
|
261
261
|
queryParams.set(key, String(value));
|
|
262
262
|
}
|
|
263
263
|
});
|
|
@@ -276,10 +276,10 @@ exports.coreToolRegistry = new Map([
|
|
|
276
276
|
},
|
|
277
277
|
],
|
|
278
278
|
[
|
|
279
|
-
|
|
279
|
+
"get_namespace",
|
|
280
280
|
{
|
|
281
|
-
name:
|
|
282
|
-
description:
|
|
281
|
+
name: "get_namespace",
|
|
282
|
+
description: "GET DETAILS: Retrieve comprehensive namespace information (group or user). Use when: Need complete namespace metadata, Checking namespace settings, Getting storage statistics. Requires namespace ID or URL-encoded path. See also: list_namespaces to browse all namespaces.",
|
|
283
283
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.GetNamespaceSchema),
|
|
284
284
|
handler: async (args) => {
|
|
285
285
|
const options = schema_readonly_1.GetNamespaceSchema.parse(args);
|
|
@@ -299,10 +299,10 @@ exports.coreToolRegistry = new Map([
|
|
|
299
299
|
},
|
|
300
300
|
],
|
|
301
301
|
[
|
|
302
|
-
|
|
302
|
+
"verify_namespace",
|
|
303
303
|
{
|
|
304
|
-
name:
|
|
305
|
-
description:
|
|
304
|
+
name: "verify_namespace",
|
|
305
|
+
description: "CHECK EXISTS: Verify if a namespace path exists and is accessible. Use when: Checking namespace availability before creation, Validating namespace references, Testing access permissions. Returns exists=true/false with namespace details if found. Faster than list_namespaces for existence checks.",
|
|
306
306
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.VerifyNamespaceSchema),
|
|
307
307
|
handler: async (args) => {
|
|
308
308
|
const options = schema_readonly_1.VerifyNamespaceSchema.parse(args);
|
|
@@ -323,17 +323,17 @@ exports.coreToolRegistry = new Map([
|
|
|
323
323
|
},
|
|
324
324
|
],
|
|
325
325
|
[
|
|
326
|
-
|
|
326
|
+
"list_project_members",
|
|
327
327
|
{
|
|
328
|
-
name:
|
|
329
|
-
description:
|
|
328
|
+
name: "list_project_members",
|
|
329
|
+
description: "TEAM MEMBERS: List all members of a project with their access levels. Use when: Auditing project access, Finding collaborators, Checking user permissions. Shows access levels: 10=Guest, 20=Reporter, 30=Developer, 40=Maintainer, 50=Owner. Supports username filtering.",
|
|
330
330
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.ListProjectMembersSchema),
|
|
331
331
|
handler: async (args) => {
|
|
332
332
|
const options = schema_readonly_1.ListProjectMembersSchema.parse(args);
|
|
333
333
|
const { project_id } = options;
|
|
334
334
|
const queryParams = new URLSearchParams();
|
|
335
335
|
Object.entries(options).forEach(([key, value]) => {
|
|
336
|
-
if (value !== undefined && key !==
|
|
336
|
+
if (value !== undefined && key !== "project_id") {
|
|
337
337
|
queryParams.set(key, String(value));
|
|
338
338
|
}
|
|
339
339
|
});
|
|
@@ -352,17 +352,17 @@ exports.coreToolRegistry = new Map([
|
|
|
352
352
|
},
|
|
353
353
|
],
|
|
354
354
|
[
|
|
355
|
-
|
|
355
|
+
"list_commits",
|
|
356
356
|
{
|
|
357
|
-
name:
|
|
358
|
-
description:
|
|
357
|
+
name: "list_commits",
|
|
358
|
+
description: "HISTORY: List repository commit history with filtering. Use when: Analyzing project history, Finding commits by author/date, Tracking file changes. Supports date ranges (since/until), author filter, and specific file paths. See also: get_commit for specific commit details.",
|
|
359
359
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.ListCommitsSchema),
|
|
360
360
|
handler: async (args) => {
|
|
361
361
|
const options = schema_readonly_1.ListCommitsSchema.parse(args);
|
|
362
362
|
const { project_id } = options;
|
|
363
363
|
const queryParams = new URLSearchParams();
|
|
364
364
|
Object.entries(options).forEach(([key, value]) => {
|
|
365
|
-
if (value !== undefined && key !==
|
|
365
|
+
if (value !== undefined && key !== "project_id") {
|
|
366
366
|
queryParams.set(key, String(value));
|
|
367
367
|
}
|
|
368
368
|
});
|
|
@@ -381,17 +381,17 @@ exports.coreToolRegistry = new Map([
|
|
|
381
381
|
},
|
|
382
382
|
],
|
|
383
383
|
[
|
|
384
|
-
|
|
384
|
+
"get_commit",
|
|
385
385
|
{
|
|
386
|
-
name:
|
|
387
|
-
description:
|
|
386
|
+
name: "get_commit",
|
|
387
|
+
description: "COMMIT DETAILS: Get comprehensive information about a specific commit. Use when: Inspecting commit metadata, Reviewing change statistics, Getting commit message/author. Shows additions/deletions per file with stats=true. See also: get_commit_diff for actual code changes.",
|
|
388
388
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.GetCommitSchema),
|
|
389
389
|
handler: async (args) => {
|
|
390
390
|
const options = schema_readonly_1.GetCommitSchema.parse(args);
|
|
391
391
|
const { project_id, commit_sha } = options;
|
|
392
392
|
const queryParams = new URLSearchParams();
|
|
393
393
|
Object.entries(options).forEach(([key, value]) => {
|
|
394
|
-
if (value !== undefined && key !==
|
|
394
|
+
if (value !== undefined && key !== "project_id" && key !== "commit_sha") {
|
|
395
395
|
queryParams.set(key, String(value));
|
|
396
396
|
}
|
|
397
397
|
});
|
|
@@ -410,17 +410,17 @@ exports.coreToolRegistry = new Map([
|
|
|
410
410
|
},
|
|
411
411
|
],
|
|
412
412
|
[
|
|
413
|
-
|
|
413
|
+
"get_commit_diff",
|
|
414
414
|
{
|
|
415
|
-
name:
|
|
416
|
-
description:
|
|
415
|
+
name: "get_commit_diff",
|
|
416
|
+
description: "COMMIT DIFF: Get actual code changes from a commit. Use when: Reviewing code modifications, Generating patches, Analyzing line-by-line changes. Returns unified diff format (git diff style). See also: get_commit for metadata without diff.",
|
|
417
417
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.GetCommitDiffSchema),
|
|
418
418
|
handler: async (args) => {
|
|
419
419
|
const options = schema_readonly_1.GetCommitDiffSchema.parse(args);
|
|
420
420
|
const { project_id, commit_sha } = options;
|
|
421
421
|
const queryParams = new URLSearchParams();
|
|
422
422
|
Object.entries(options).forEach(([key, value]) => {
|
|
423
|
-
if (value !== undefined && key !==
|
|
423
|
+
if (value !== undefined && key !== "project_id" && key !== "commit_sha") {
|
|
424
424
|
queryParams.set(key, String(value));
|
|
425
425
|
}
|
|
426
426
|
});
|
|
@@ -439,17 +439,17 @@ exports.coreToolRegistry = new Map([
|
|
|
439
439
|
},
|
|
440
440
|
],
|
|
441
441
|
[
|
|
442
|
-
|
|
442
|
+
"list_group_iterations",
|
|
443
443
|
{
|
|
444
|
-
name:
|
|
445
|
-
description:
|
|
444
|
+
name: "list_group_iterations",
|
|
445
|
+
description: "SPRINTS: List iterations/sprints for agile planning (Premium feature). Use when: Viewing sprint schedules, Tracking iteration progress, Planning releases. Filter by state: current=active sprint, upcoming=future, closed=completed. Requires GitLab Premium or higher.",
|
|
446
446
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.ListGroupIterationsSchema),
|
|
447
447
|
handler: async (args) => {
|
|
448
448
|
const options = schema_readonly_1.ListGroupIterationsSchema.parse(args);
|
|
449
449
|
const { group_id } = options;
|
|
450
450
|
const queryParams = new URLSearchParams();
|
|
451
451
|
Object.entries(options).forEach(([key, value]) => {
|
|
452
|
-
if (value !== undefined && key !==
|
|
452
|
+
if (value !== undefined && key !== "group_id") {
|
|
453
453
|
queryParams.set(key, String(value));
|
|
454
454
|
}
|
|
455
455
|
});
|
|
@@ -468,10 +468,10 @@ exports.coreToolRegistry = new Map([
|
|
|
468
468
|
},
|
|
469
469
|
],
|
|
470
470
|
[
|
|
471
|
-
|
|
471
|
+
"download_attachment",
|
|
472
472
|
{
|
|
473
|
-
name:
|
|
474
|
-
description:
|
|
473
|
+
name: "download_attachment",
|
|
474
|
+
description: "DOWNLOAD: Retrieve uploaded file attachments from issues/MRs/wikis. Use when: Downloading images from issues, Getting attached documents, Retrieving uploaded files. Requires secret token and filename from the attachment URL (/uploads/[secret]/[filename]).",
|
|
475
475
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.DownloadAttachmentSchema),
|
|
476
476
|
handler: async (args) => {
|
|
477
477
|
const options = schema_readonly_1.DownloadAttachmentSchema.parse(args);
|
|
@@ -488,17 +488,17 @@ exports.coreToolRegistry = new Map([
|
|
|
488
488
|
const attachment = await response.arrayBuffer();
|
|
489
489
|
return {
|
|
490
490
|
filename,
|
|
491
|
-
content: Buffer.from(attachment).toString(
|
|
492
|
-
contentType: response.headers.get(
|
|
491
|
+
content: Buffer.from(attachment).toString("base64"),
|
|
492
|
+
contentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
493
493
|
};
|
|
494
494
|
},
|
|
495
495
|
},
|
|
496
496
|
],
|
|
497
497
|
[
|
|
498
|
-
|
|
498
|
+
"list_events",
|
|
499
499
|
{
|
|
500
|
-
name:
|
|
501
|
-
description:
|
|
500
|
+
name: "list_events",
|
|
501
|
+
description: "USER ACTIVITY: List YOUR activity events across all projects. Use when: Tracking your contributions, Auditing your actions, Reviewing your history. Date format: YYYY-MM-DD only (not timestamps). Filters: action=created/updated/pushed, target_type=issue/merge_request.",
|
|
502
502
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.ListEventsSchema),
|
|
503
503
|
handler: async (args) => {
|
|
504
504
|
const options = schema_readonly_1.ListEventsSchema.parse(args);
|
|
@@ -523,17 +523,17 @@ exports.coreToolRegistry = new Map([
|
|
|
523
523
|
},
|
|
524
524
|
],
|
|
525
525
|
[
|
|
526
|
-
|
|
526
|
+
"get_project_events",
|
|
527
527
|
{
|
|
528
|
-
name:
|
|
529
|
-
description:
|
|
528
|
+
name: "get_project_events",
|
|
529
|
+
description: "PROJECT ACTIVITY: List all events within a specific project. Use when: Monitoring project activity, Tracking team contributions, Auditing project changes. Date format: YYYY-MM-DD only (not timestamps). Shows: commits, issues, MRs, member changes.",
|
|
530
530
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_readonly_1.GetProjectEventsSchema),
|
|
531
531
|
handler: async (args) => {
|
|
532
532
|
const options = schema_readonly_1.GetProjectEventsSchema.parse(args);
|
|
533
533
|
const { project_id } = options;
|
|
534
534
|
const queryParams = new URLSearchParams();
|
|
535
535
|
Object.entries(options).forEach(([key, value]) => {
|
|
536
|
-
if (value !== undefined && key !==
|
|
536
|
+
if (value !== undefined && key !== "project_id") {
|
|
537
537
|
queryParams.set(key, String(value));
|
|
538
538
|
}
|
|
539
539
|
});
|
|
@@ -552,10 +552,10 @@ exports.coreToolRegistry = new Map([
|
|
|
552
552
|
},
|
|
553
553
|
],
|
|
554
554
|
[
|
|
555
|
-
|
|
555
|
+
"create_repository",
|
|
556
556
|
{
|
|
557
|
-
name:
|
|
558
|
-
description:
|
|
557
|
+
name: "create_repository",
|
|
558
|
+
description: "CREATE NEW: Initialize a new GitLab project/repository with automatic validation. Features: (1) Automatically checks if project already exists before creation, (2) Resolves namespace paths to IDs automatically, (3) Generates URL-safe project path from name, (4) Returns detailed validation information. Use when: Starting new projects, Setting up repository structure, Automating project creation. Creates in your namespace by default if no namespace specified.",
|
|
559
559
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_1.CreateRepositorySchema),
|
|
560
560
|
handler: async (args) => {
|
|
561
561
|
const options = schema_1.CreateRepositorySchema.parse(args);
|
|
@@ -579,7 +579,7 @@ exports.coreToolRegistry = new Map([
|
|
|
579
579
|
}
|
|
580
580
|
const targetNamespacePath = resolvedNamespace
|
|
581
581
|
? resolvedNamespace.full_path
|
|
582
|
-
:
|
|
582
|
+
: "current-user";
|
|
583
583
|
const projectPath = `${targetNamespacePath}/${name}`;
|
|
584
584
|
const checkProjectUrl = `${process.env.GITLAB_API_URL}/api/v4/projects/${encodeURIComponent(projectPath)}`;
|
|
585
585
|
const checkResponse = await (0, fetch_1.enhancedFetch)(checkProjectUrl, {
|
|
@@ -592,20 +592,20 @@ exports.coreToolRegistry = new Map([
|
|
|
592
592
|
throw new Error(`Project '${projectPath}' already exists (ID: ${existingProject.id}). Use a different name or update the existing project.`);
|
|
593
593
|
}
|
|
594
594
|
const body = new URLSearchParams();
|
|
595
|
-
body.set(
|
|
595
|
+
body.set("name", name);
|
|
596
596
|
const generatedPath = name
|
|
597
597
|
.toLowerCase()
|
|
598
|
-
.replace(/[^a-z0-9-]/g,
|
|
599
|
-
.replace(/-+/g,
|
|
600
|
-
.replace(/^-|-$/g,
|
|
601
|
-
body.set(
|
|
598
|
+
.replace(/[^a-z0-9-]/g, "-")
|
|
599
|
+
.replace(/-+/g, "-")
|
|
600
|
+
.replace(/^-|-$/g, "");
|
|
601
|
+
body.set("path", generatedPath);
|
|
602
602
|
if (namespaceId) {
|
|
603
|
-
body.set(
|
|
603
|
+
body.set("namespace_id", namespaceId);
|
|
604
604
|
}
|
|
605
605
|
Object.entries(otherOptions).forEach(([key, value]) => {
|
|
606
606
|
if (value !== undefined) {
|
|
607
607
|
if (Array.isArray(value)) {
|
|
608
|
-
body.set(key, value.join(
|
|
608
|
+
body.set(key, value.join(","));
|
|
609
609
|
}
|
|
610
610
|
else {
|
|
611
611
|
body.set(key, String(value));
|
|
@@ -614,10 +614,10 @@ exports.coreToolRegistry = new Map([
|
|
|
614
614
|
});
|
|
615
615
|
const createApiUrl = `${process.env.GITLAB_API_URL}/api/v4/projects`;
|
|
616
616
|
const createResponse = await (0, fetch_1.enhancedFetch)(createApiUrl, {
|
|
617
|
-
method:
|
|
617
|
+
method: "POST",
|
|
618
618
|
headers: {
|
|
619
619
|
Authorization: `Bearer ${process.env.GITLAB_TOKEN}`,
|
|
620
|
-
|
|
620
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
621
621
|
},
|
|
622
622
|
body: body.toString(),
|
|
623
623
|
});
|
|
@@ -630,7 +630,7 @@ exports.coreToolRegistry = new Map([
|
|
|
630
630
|
validation: {
|
|
631
631
|
namespace_resolved: namespacePath
|
|
632
632
|
? `${namespacePath} → ${namespaceId}`
|
|
633
|
-
:
|
|
633
|
+
: "current-user",
|
|
634
634
|
project_name_available: true,
|
|
635
635
|
created_in_expected_namespace: !namespacePath ||
|
|
636
636
|
project.namespace.full_path ===
|
|
@@ -642,25 +642,25 @@ exports.coreToolRegistry = new Map([
|
|
|
642
642
|
},
|
|
643
643
|
],
|
|
644
644
|
[
|
|
645
|
-
|
|
645
|
+
"fork_repository",
|
|
646
646
|
{
|
|
647
|
-
name:
|
|
648
|
-
description:
|
|
647
|
+
name: "fork_repository",
|
|
648
|
+
description: "FORK: Create your own copy of an existing project. Use when: Contributing to other projects, Creating experimental versions, Maintaining custom forks. Preserves fork relationship for MRs back to parent. Target namespace optional (defaults to your namespace).",
|
|
649
649
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_1.ForkRepositorySchema),
|
|
650
650
|
handler: async (args) => {
|
|
651
651
|
const options = schema_1.ForkRepositorySchema.parse(args);
|
|
652
652
|
const body = new URLSearchParams();
|
|
653
653
|
Object.entries(options).forEach(([key, value]) => {
|
|
654
|
-
if (value !== undefined && key !==
|
|
654
|
+
if (value !== undefined && key !== "project_id") {
|
|
655
655
|
body.set(key, String(value));
|
|
656
656
|
}
|
|
657
657
|
});
|
|
658
658
|
const apiUrl = `${process.env.GITLAB_API_URL}/api/v4/projects/${encodeURIComponent(options.project_id)}/fork`;
|
|
659
659
|
const response = await (0, fetch_1.enhancedFetch)(apiUrl, {
|
|
660
|
-
method:
|
|
660
|
+
method: "POST",
|
|
661
661
|
headers: {
|
|
662
662
|
Authorization: `Bearer ${process.env.GITLAB_TOKEN}`,
|
|
663
|
-
|
|
663
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
664
664
|
},
|
|
665
665
|
body: body.toString(),
|
|
666
666
|
});
|
|
@@ -673,22 +673,22 @@ exports.coreToolRegistry = new Map([
|
|
|
673
673
|
},
|
|
674
674
|
],
|
|
675
675
|
[
|
|
676
|
-
|
|
676
|
+
"create_branch",
|
|
677
677
|
{
|
|
678
|
-
name:
|
|
679
|
-
description:
|
|
678
|
+
name: "create_branch",
|
|
679
|
+
description: "NEW BRANCH: Create a Git branch from existing ref. Use when: Starting new features, Preparing bug fixes, Creating release branches. REQUIRED before creating MRs. Ref can be: branch name (main), tag (v1.0), or commit SHA. Branch names cannot contain spaces.",
|
|
680
680
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_1.CreateBranchSchema),
|
|
681
681
|
handler: async (args) => {
|
|
682
682
|
const options = schema_1.CreateBranchSchema.parse(args);
|
|
683
683
|
const body = new URLSearchParams();
|
|
684
|
-
body.set(
|
|
685
|
-
body.set(
|
|
684
|
+
body.set("branch", options.branch);
|
|
685
|
+
body.set("ref", options.ref);
|
|
686
686
|
const apiUrl = `${process.env.GITLAB_API_URL}/api/v4/projects/${encodeURIComponent(options.project_id)}/repository/branches`;
|
|
687
687
|
const response = await (0, fetch_1.enhancedFetch)(apiUrl, {
|
|
688
|
-
method:
|
|
688
|
+
method: "POST",
|
|
689
689
|
headers: {
|
|
690
690
|
Authorization: `Bearer ${process.env.GITLAB_TOKEN}`,
|
|
691
|
-
|
|
691
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
692
692
|
},
|
|
693
693
|
body: body.toString(),
|
|
694
694
|
});
|
|
@@ -701,36 +701,36 @@ exports.coreToolRegistry = new Map([
|
|
|
701
701
|
},
|
|
702
702
|
],
|
|
703
703
|
[
|
|
704
|
-
|
|
704
|
+
"create_group",
|
|
705
705
|
{
|
|
706
|
-
name:
|
|
707
|
-
description:
|
|
706
|
+
name: "create_group",
|
|
707
|
+
description: "CREATE GROUP: Create a new GitLab group/namespace for organizing projects and teams. Use when: Setting up team spaces, Creating organizational structure, Establishing project hierarchies. Groups can contain projects and subgroups.",
|
|
708
708
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_1.CreateGroupSchema),
|
|
709
709
|
handler: async (args) => {
|
|
710
710
|
const options = schema_1.CreateGroupSchema.parse(args);
|
|
711
711
|
const body = new URLSearchParams();
|
|
712
|
-
body.set(
|
|
713
|
-
body.set(
|
|
712
|
+
body.set("name", options.name);
|
|
713
|
+
body.set("path", options.path);
|
|
714
714
|
if (options.description)
|
|
715
|
-
body.set(
|
|
715
|
+
body.set("description", options.description);
|
|
716
716
|
if (options.visibility)
|
|
717
|
-
body.set(
|
|
717
|
+
body.set("visibility", options.visibility);
|
|
718
718
|
if (options.parent_id !== undefined)
|
|
719
|
-
body.set(
|
|
719
|
+
body.set("parent_id", String(options.parent_id));
|
|
720
720
|
if (options.lfs_enabled !== undefined)
|
|
721
|
-
body.set(
|
|
721
|
+
body.set("lfs_enabled", String(options.lfs_enabled));
|
|
722
722
|
if (options.request_access_enabled !== undefined)
|
|
723
|
-
body.set(
|
|
723
|
+
body.set("request_access_enabled", String(options.request_access_enabled));
|
|
724
724
|
if (options.default_branch_protection !== undefined)
|
|
725
|
-
body.set(
|
|
725
|
+
body.set("default_branch_protection", String(options.default_branch_protection));
|
|
726
726
|
if (options.avatar)
|
|
727
|
-
body.set(
|
|
727
|
+
body.set("avatar", options.avatar);
|
|
728
728
|
const apiUrl = `${process.env.GITLAB_API_URL}/api/v4/groups`;
|
|
729
729
|
const response = await (0, fetch_1.enhancedFetch)(apiUrl, {
|
|
730
|
-
method:
|
|
730
|
+
method: "POST",
|
|
731
731
|
headers: {
|
|
732
732
|
Authorization: `Bearer ${process.env.GITLAB_TOKEN}`,
|
|
733
|
-
|
|
733
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
734
734
|
},
|
|
735
735
|
body: body.toString(),
|
|
736
736
|
});
|
|
@@ -745,21 +745,21 @@ exports.coreToolRegistry = new Map([
|
|
|
745
745
|
]);
|
|
746
746
|
function getCoreReadOnlyToolNames() {
|
|
747
747
|
return [
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
748
|
+
"search_repositories",
|
|
749
|
+
"list_namespaces",
|
|
750
|
+
"get_namespace",
|
|
751
|
+
"verify_namespace",
|
|
752
|
+
"get_project",
|
|
753
|
+
"list_projects",
|
|
754
|
+
"list_project_members",
|
|
755
|
+
"get_users",
|
|
756
|
+
"list_commits",
|
|
757
|
+
"get_commit",
|
|
758
|
+
"get_commit_diff",
|
|
759
|
+
"list_group_iterations",
|
|
760
|
+
"download_attachment",
|
|
761
|
+
"list_events",
|
|
762
|
+
"get_project_events",
|
|
763
763
|
];
|
|
764
764
|
}
|
|
765
765
|
function getCoreToolDefinitions() {
|
|
@@ -768,7 +768,7 @@ function getCoreToolDefinitions() {
|
|
|
768
768
|
function getFilteredCoreTools(readOnlyMode = false) {
|
|
769
769
|
if (readOnlyMode) {
|
|
770
770
|
const readOnlyNames = getCoreReadOnlyToolNames();
|
|
771
|
-
return Array.from(exports.coreToolRegistry.values()).filter(
|
|
771
|
+
return Array.from(exports.coreToolRegistry.values()).filter(tool => readOnlyNames.includes(tool.name));
|
|
772
772
|
}
|
|
773
773
|
return getCoreToolDefinitions();
|
|
774
774
|
}
|