@zereight/mcp-gitlab 1.0.18 → 1.0.20

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 CHANGED
@@ -40,36 +40,146 @@ env GITLAB_PERSONAL_ACCESS_TOKEN=your_gitlab_token GITLAB_API_URL=your_gitlab_ap
40
40
  - `GITLAB_PERSONAL_ACCESS_TOKEN`: Your GitLab personal access token.
41
41
  - `GITLAB_API_URL`: Your GitLab API URL. (Default: `https://gitlab.com/api/v4`)
42
42
 
43
- ## Tools Reference 🛠️
44
-
45
- | Tool | Description | Parameters | Returns |
46
- |------|-------------|------------|---------|
47
- | **`create_or_update_file`** | Create or update a single file in a GitLab project 📝 | • `project_id` (string): Project ID or path<br>• `file_path` (string): Path to create/update<br>• `content` (string): File content<br>• `commit_message` (string): Commit message<br>• `branch` (string): Target branch<br>• `previous_path` (optional): Previous path when renaming | File content and commit details |
48
- | **`push_files`** | Push multiple files in a single commit 📤 (internally creates a tree and commit) | • `project_id` (string): Project ID or path<br>• `branch` (string): Target branch<br>• `files` (array): Array of files with `file_path` and `content`<br>• `commit_message` (string): Commit message | Updated branch reference |
49
- | **`search_repositories`** | Search for GitLab projects 🔍 | • `search` (string): Search query<br>• `page` (optional): Page number (default: 1)<br>• `per_page` (optional): Results per page (default: 20) | Project search results |
50
- | **`create_repository`** | Create a new GitLab project ➕ | • `name` (string): Project name<br>• `description` (optional): Project description<br>• `visibility` (optional): Visibility level<br>• `initialize_with_readme` (optional): Initialize with README | Created project details |
51
- | **`get_file_contents`** | Get the contents of a file or directory 📂 | • `project_id` (string): Project ID or path<br>• `file_path` (string): Path to file/directory<br>• `ref` (optional): Branch, tag, or commit SHA | File/directory content |
52
- | **`create_issue`** | Create a new issue 🐛 | • `project_id` (string): Project ID or path<br>• `title` (string): Issue title<br>• `description` (string): Issue description<br>• `assignee_ids` (optional): Array of assignee IDs<br>• `milestone_id` (optional): Milestone ID<br>• `labels` (optional): Array of labels | Created issue details |
53
- | **`list_issues`** | List issues in a project with comprehensive filtering options 📋 | • `project_id` (string): Project ID or path<br>• Optional filters: `assignee_id`, `assignee_username`, `author_id`, `author_username`, `confidential`, `created_after/before`, `due_date`, `label_name`, `milestone`, `scope`, `search`, `state`, `updated_after/before`<br>• Pagination: `page`, `per_page` | Array of issues |
54
- | **`get_issue`** | Get details of a specific issue | • `project_id` (string): Project ID or path<br>• `issue_iid` (number): Issue IID | Issue details |
55
- | **`update_issue`** | Update an existing issue ✏️ | • `project_id` (string): Project ID or path<br>• `issue_iid` (number): Issue IID<br>• Editable fields: `title`, `description`, `assignee_ids`, `labels`, `milestone_id`, `state_event` (close/reopen), `confidential`, `discussion_locked`, `due_date`, `weight` | Updated issue details |
56
- | **`delete_issue`** | Delete an issue | • `project_id` (string): Project ID or path<br>• `issue_iid` (number): Issue IID | Success message |
57
- | **`list_issue_links`** | List all links for a specific issue | • `project_id` (string): Project ID or path<br>• `issue_iid` (number): Issue IID | Array of linked issues |
58
- | **`get_issue_link`** | Get details of a specific issue link | • `project_id` (string): Project ID or path<br>• `issue_iid` (number): Issue IID<br>• `issue_link_id` (number): Link ID | Issue link details |
59
- | **`create_issue_link`** | Create a link between two issues | • `project_id` (string): Project ID or path<br>• `issue_iid` (number): Source issue IID<br>• `target_project_id` (string): Target project ID<br>• `target_issue_iid` (number): Target issue IID<br>• `link_type` (optional): Relationship type | Created link details |
60
- | **`delete_issue_link`** | Delete an issue link | • `project_id` (string): Project ID or path<br>• `issue_iid` (number): Issue IID<br>• `issue_link_id` (number): Link ID | Success message |
61
- | **`create_merge_request`** | Create a new merge request 🚀 | • `project_id` (string): Project ID or path<br>• `title` (string): MR title<br>• `description` (string): MR description<br>• `source_branch` (string): Branch with changes<br>• `target_branch` (string): Branch to merge into<br>• `allow_collaboration` (optional): Allow collaborators<br>• `draft` (optional): Create as draft | Created merge request details |
62
- | **`fork_repository`** | Fork a project 🍴 | • `project_id` (string): Project ID or path to fork<br>• `namespace` (optional): Namespace to fork into | Forked project details |
63
- | **`create_branch`** | Create a new branch 🌿 | • `project_id` (string): Project ID or path<br>• `branch` (string): New branch name<br>• `ref` (optional): Reference to create from | Created branch reference |
64
- | **`get_merge_request`** | Get details of a merge request ℹ️ | • `project_id` (string): Project ID or path<br>• `merge_request_iid` (number): MR IID | Merge request details |
65
- | **`get_merge_request_diffs`** | Get changes of a merge request | • `project_id` (string): Project ID or path<br>• `merge_request_iid` (number): MR IID<br>• `view` (optional): Diff view type | Array of merge request diffs |
66
- | **`update_merge_request`** | Update a merge request 🔄 | • `project_id` (string): Project ID or path<br>• `merge_request_iid` (number): MR IID<br>• Editable fields: `title`, `description`, `target_branch`, `assignee_ids`, `labels`, `state_event` (close/reopen), `remove_source_branch`, `squash`, `draft` | Updated merge request details |
67
- | **`create_note`** | Create a comment on an issue or MR 💬 | • `project_id` (string): Project ID or path<br>• `noteable_type` (string): "issue" or "merge_request"<br>• `noteable_iid` (number): IID of the issue or MR<br>• `body` (string): Comment content | Created note details |
68
- | **`list_namespaces`** | List available namespaces | • `search` (optional): Search term<br>• `page` (optional): Page number<br>• `per_page` (optional): Results per page<br>• `owned` (optional): Filter by ownership | Array of namespaces |
69
- | **`get_namespace`** | Get details of a namespace | • `namespace_id` (string): Namespace ID or path | Namespace details |
70
- | **`verify_namespace`** | Check if a namespace exists | • `path` (string): Namespace path to verify | Verification result |
71
- | **`get_project`** | Get details of a specific project | • `project_id` (string): Project ID or path | Project details |
43
+ ## Tools 🛠️
44
+
45
+ 1. `create_or_update_file`
46
+
47
+ - Create or update a single file in a GitLab project. 📝
48
+ - Inputs:
49
+ - `project_id` (string): Project ID or namespace/project_path
50
+ - `file_path` (string): Path to create/update the file
51
+ - `content` (string): File content
52
+ - `commit_message` (string): Commit message
53
+ - `branch` (string): Branch to create/update the file in
54
+ - `previous_path` (optional string): Previous file path when renaming a file
55
+ - Returns: File content and commit details
56
+
57
+ 2. `push_files`
58
+
59
+ - Push multiple files in a single commit. 📤
60
+ - Inputs:
61
+ - `project_id` (string): Project ID or namespace/project_path
62
+ - `branch` (string): Branch to push to
63
+ - `files` (array): Array of files to push, each with `file_path` and `content` properties
64
+ - `commit_message` (string): Commit message
65
+ - Returns: Updated branch reference
66
+
67
+ 3. `search_repositories`
68
+
69
+ - Search for GitLab projects. 🔍
70
+ - Inputs:
71
+ - `search` (string): Search query
72
+ - `page` (optional number): Page number (default: 1)
73
+ - `per_page` (optional number): Results per page (default: 20, max: 100)
74
+ - Returns: Project search results
75
+
76
+ 4. `create_repository`
77
+
78
+ - Create a new GitLab project. ➕
79
+ - Inputs:
80
+ - `name` (string): Project name
81
+ - `description` (optional string): Project description
82
+ - `visibility` (optional string): Project visibility level (public, private, internal)
83
+ - `initialize_with_readme` (optional boolean): Initialize with README
84
+ - Returns: Details of the created project
85
+
86
+ 5. `get_file_contents`
87
+
88
+ - Get the contents of a file or directory. 📂
89
+ - Inputs:
90
+ - `project_id` (string): Project ID or namespace/project_path
91
+ - `file_path` (string): Path to the file/directory
92
+ - `ref` (optional string): Branch, tag, or commit SHA (default: default branch)
93
+ - Returns: File/directory content
94
+
95
+ 6. `create_issue`
96
+
97
+ - Create a new issue. 🐛
98
+ - Inputs:
99
+ - `project_id` (string): Project ID or namespace/project_path
100
+ - `title` (string): Issue title
101
+ - `description` (string): Issue description
102
+ - `assignee_ids` (optional number[]): Array of assignee IDs
103
+ - `milestone_id` (optional number): Milestone ID
104
+ - `labels` (optional string[]): Array of labels
105
+ - Returns: Details of the created issue
106
+
107
+ 7. `create_merge_request`
108
+
109
+ - Create a new merge request. 🚀
110
+ - Inputs:
111
+ - `project_id` (string): Project ID or namespace/project_path
112
+ - `title` (string): Merge request title
113
+ - `description` (string): Merge request description
114
+ - `source_branch` (string): Branch with changes
115
+ - `target_branch` (string): Branch to merge into
116
+ - `allow_collaboration` (optional boolean): Allow collaborators to push commits to the source branch
117
+ - `draft` (optional boolean): Create as a draft merge request
118
+ - Returns: Details of the created merge request
119
+
120
+ 8. `fork_repository`
121
+
122
+ - Fork a project. 🍴
123
+ - Inputs:
124
+ - `project_id` (string): Project ID or namespace/project_path to fork
125
+ - `namespace` (optional string): Namespace to fork into (default: user namespace)
126
+ - Returns: Details of the forked project
127
+
128
+ 9. `create_branch`
129
+
130
+ - Create a new branch. 🌿
131
+ - Inputs:
132
+ - `project_id` (string): Project ID or namespace/project_path
133
+ - `name` (string): New branch name
134
+ - `ref` (optional string): Ref to create the branch from (branch, tag, commit SHA, default: default branch)
135
+ - Returns: Created branch reference
136
+
137
+ 10. `get_merge_request`
138
+
139
+ - Get details of a merge request. ℹ️
140
+ - Inputs:
141
+ - `project_id` (string): Project ID or namespace/project_path
142
+ - `merge_request_iid` (number): Merge request IID
143
+ - Returns: Merge request details
144
+
145
+ 11. `get_merge_request_diffs`
146
+
147
+ - Get changes (diffs) of a merge request. diff
148
+ - Inputs:
149
+ - `project_id` (string): Project ID or namespace/project_path
150
+ - `merge_request_iid` (number): Merge request IID
151
+ - `view` (optional string): Diff view type ('inline' or 'parallel')
152
+ - Returns: Array of merge request diff information
153
+
154
+ 12. `update_merge_request`
155
+
156
+ - Update a merge request. 🔄
157
+ - Inputs:
158
+ - `project_id` (string): Project ID or namespace/project_path
159
+ - `merge_request_iid` (number): Merge request IID
160
+ - `title` (optional string): New title
161
+ - `description` (string): New description
162
+ - `target_branch` (optional string): New target branch
163
+ - `state_event` (optional string): Merge request state change event ('close', 'reopen')
164
+ - `remove_source_branch` (optional boolean): Remove source branch after merge
165
+ - `allow_collaboration` (optional boolean): Allow collaborators to push commits to the source branch
166
+ - Returns: Updated merge request details
167
+
168
+ 13. `create_note`
169
+ - Create a new note (comment) to an issue or merge request. 💬
170
+ - Inputs:
171
+ - `project_id` (string): Project ID or namespace/project_path
172
+ - `noteable_type` (string): Type of noteable ("issue" or "merge_request")
173
+ - `noteable_iid` (number): IID of the issue or merge request
174
+ - `body` (string): Note content
175
+ - Returns: Details of the created note
176
+
72
177
  | **`list_projects`** | List accessible projects with rich filtering options 📊 | • Search/filtering: `search`, `owned`, `membership`, `archived`, `visibility`<br>• Features filtering: `with_issues_enabled`, `with_merge_requests_enabled`<br>• Sorting: `order_by`, `sort`<br>• Access control: `min_access_level`<br>• Pagination: `page`, `per_page`, `simple` | Array of projects |
178
+ | **`list_labels`** | List all labels for a project with filtering options 🏷️ | • `project_id` (string): Project ID or path<br>• `with_counts` (optional): Include issue and merge request counts<br>• `include_ancestor_groups` (optional): Include ancestor groups<br>• `search` (optional): Filter labels by keyword | Array of labels |
179
+ | **`get_label`** | Get a single label from a project 🏷️ | • `project_id` (string): Project ID or path<br>• `label_id` (number/string): Label ID or name<br>• `include_ancestor_groups` (optional): Include ancestor groups | Label details |
180
+ | **`create_label`** | Create a new label in a project 🏷️➕ | • `project_id` (string): Project ID or path<br>• `name` (string): Label name<br>• `color` (string): Color in hex format (e.g., "#FF0000")<br>• `description` (optional): Label description<br>• `priority` (optional): Label priority | Created label details |
181
+ | **`update_label`** | Update an existing label in a project 🏷️✏️ | • `project_id` (string): Project ID or path<br>• `label_id` (number/string): Label ID or name<br>• `new_name` (optional): New label name<br>• `color` (optional): New color in hex format<br>• `description` (optional): New description<br>• `priority` (optional): New priority | Updated label details |
182
+ | **`delete_label`** | Delete a label from a project 🏷️❌ | • `project_id` (string): Project ID or path<br>• `label_id` (number/string): Label ID or name | Success message |
73
183
 
74
184
  ## Environment Variable Configuration
75
185
 
package/build/index.js CHANGED
@@ -9,7 +9,7 @@ import { fileURLToPath } from "url";
9
9
  import { dirname } from "path";
10
10
  import fs from "fs";
11
11
  import path from "path";
12
- 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, CreateNoteSchema, } from "./schemas.js";
12
+ 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, } from "./schemas.js";
13
13
  /**
14
14
  * Read version from package.json
15
15
  */
@@ -826,19 +826,139 @@ async function getProject(projectId, options = {}) {
826
826
  * @returns {Promise<GitLabProject[]>} List of projects
827
827
  */
828
828
  async function listProjects(options = {}) {
829
- const url = new URL(`${GITLAB_API_URL}/projects`);
830
- // Add all the query parameters from options
829
+ // Construct the query parameters
830
+ const params = new URLSearchParams();
831
+ for (const [key, value] of Object.entries(options)) {
832
+ if (value !== undefined && value !== null) {
833
+ if (typeof value === "boolean") {
834
+ params.append(key, value ? "true" : "false");
835
+ }
836
+ else {
837
+ params.append(key, String(value));
838
+ }
839
+ }
840
+ }
841
+ // Make the API request
842
+ const response = await fetch(`${GITLAB_API_URL}/projects?${params.toString()}`, {
843
+ method: "GET",
844
+ headers: DEFAULT_HEADERS,
845
+ });
846
+ // Handle errors
847
+ await handleGitLabError(response);
848
+ // Parse and return the data
849
+ const data = await response.json();
850
+ return z.array(GitLabProjectSchema).parse(data);
851
+ }
852
+ /**
853
+ * List labels for a project
854
+ *
855
+ * @param projectId The ID or URL-encoded path of the project
856
+ * @param options Optional parameters for listing labels
857
+ * @returns Array of GitLab labels
858
+ */
859
+ async function listLabels(projectId, options = {}) {
860
+ // Construct the URL with project path
861
+ const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`);
862
+ // Add query parameters
831
863
  Object.entries(options).forEach(([key, value]) => {
832
864
  if (value !== undefined) {
833
- url.searchParams.append(key, value.toString());
865
+ if (typeof value === "boolean") {
866
+ url.searchParams.append(key, value ? "true" : "false");
867
+ }
868
+ else {
869
+ url.searchParams.append(key, String(value));
870
+ }
834
871
  }
835
872
  });
873
+ // Make the API request
874
+ const response = await fetch(url.toString(), {
875
+ headers: DEFAULT_HEADERS,
876
+ });
877
+ // Handle errors
878
+ await handleGitLabError(response);
879
+ // Parse and return the data
880
+ const data = await response.json();
881
+ return data;
882
+ }
883
+ /**
884
+ * Get a single label from a project
885
+ *
886
+ * @param projectId The ID or URL-encoded path of the project
887
+ * @param labelId The ID or name of the label
888
+ * @param includeAncestorGroups Whether to include ancestor groups
889
+ * @returns GitLab label
890
+ */
891
+ async function getLabel(projectId, labelId, includeAncestorGroups) {
892
+ const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`);
893
+ // Add query parameters
894
+ if (includeAncestorGroups !== undefined) {
895
+ url.searchParams.append("include_ancestor_groups", includeAncestorGroups ? "true" : "false");
896
+ }
897
+ // Make the API request
836
898
  const response = await fetch(url.toString(), {
837
899
  headers: DEFAULT_HEADERS,
838
900
  });
901
+ // Handle errors
902
+ await handleGitLabError(response);
903
+ // Parse and return the data
904
+ const data = await response.json();
905
+ return data;
906
+ }
907
+ /**
908
+ * Create a new label in a project
909
+ *
910
+ * @param projectId The ID or URL-encoded path of the project
911
+ * @param options Options for creating the label
912
+ * @returns Created GitLab label
913
+ */
914
+ async function createLabel(projectId, options) {
915
+ // Make the API request
916
+ const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`, {
917
+ method: "POST",
918
+ headers: DEFAULT_HEADERS,
919
+ body: JSON.stringify(options),
920
+ });
921
+ // Handle errors
839
922
  await handleGitLabError(response);
923
+ // Parse and return the data
840
924
  const data = await response.json();
841
- return z.array(GitLabRepositorySchema).parse(data);
925
+ return data;
926
+ }
927
+ /**
928
+ * Update an existing label in a project
929
+ *
930
+ * @param projectId The ID or URL-encoded path of the project
931
+ * @param labelId The ID or name of the label to update
932
+ * @param options Options for updating the label
933
+ * @returns Updated GitLab label
934
+ */
935
+ async function updateLabel(projectId, labelId, options) {
936
+ // Make the API request
937
+ const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`, {
938
+ method: "PUT",
939
+ headers: DEFAULT_HEADERS,
940
+ body: JSON.stringify(options),
941
+ });
942
+ // Handle errors
943
+ await handleGitLabError(response);
944
+ // Parse and return the data
945
+ const data = await response.json();
946
+ return data;
947
+ }
948
+ /**
949
+ * Delete a label from a project
950
+ *
951
+ * @param projectId The ID or URL-encoded path of the project
952
+ * @param labelId The ID or name of the label to delete
953
+ */
954
+ async function deleteLabel(projectId, labelId) {
955
+ // Make the API request
956
+ const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`, {
957
+ method: "DELETE",
958
+ headers: DEFAULT_HEADERS,
959
+ });
960
+ // Handle errors
961
+ await handleGitLabError(response);
842
962
  }
843
963
  server.setRequestHandler(ListToolsRequestSchema, async () => {
844
964
  return {
@@ -973,6 +1093,31 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
973
1093
  description: "List projects accessible by the current user",
974
1094
  inputSchema: zodToJsonSchema(ListProjectsSchema),
975
1095
  },
1096
+ {
1097
+ name: "list_labels",
1098
+ description: "List labels for a project",
1099
+ inputSchema: zodToJsonSchema(ListLabelsSchema),
1100
+ },
1101
+ {
1102
+ name: "get_label",
1103
+ description: "Get a single label from a project",
1104
+ inputSchema: zodToJsonSchema(GetLabelSchema),
1105
+ },
1106
+ {
1107
+ name: "create_label",
1108
+ description: "Create a new label in a project",
1109
+ inputSchema: zodToJsonSchema(CreateLabelSchema),
1110
+ },
1111
+ {
1112
+ name: "update_label",
1113
+ description: "Update an existing label in a project",
1114
+ inputSchema: zodToJsonSchema(UpdateLabelSchema),
1115
+ },
1116
+ {
1117
+ name: "delete_label",
1118
+ description: "Delete a label from a project",
1119
+ inputSchema: zodToJsonSchema(DeleteLabelSchema),
1120
+ },
976
1121
  ],
977
1122
  };
978
1123
  });
@@ -1162,19 +1307,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1162
1307
  }
1163
1308
  case "list_projects": {
1164
1309
  const args = ListProjectsSchema.parse(request.params.arguments);
1165
- const url = new URL(`${GITLAB_API_URL}/projects`);
1166
- // Add query parameters for filtering
1167
- Object.entries(args).forEach(([key, value]) => {
1168
- if (value !== undefined) {
1169
- url.searchParams.append(key, value.toString());
1170
- }
1171
- });
1172
- const response = await fetch(url.toString(), {
1173
- headers: DEFAULT_HEADERS,
1174
- });
1175
- await handleGitLabError(response);
1176
- const data = await response.json();
1177
- const projects = z.array(GitLabProjectSchema).parse(data);
1310
+ const projects = await listProjects(args);
1178
1311
  return {
1179
1312
  content: [{ type: "text", text: JSON.stringify(projects, null, 2) }],
1180
1313
  };
@@ -1245,6 +1378,42 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1245
1378
  content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Issue link deleted successfully" }, null, 2) }],
1246
1379
  };
1247
1380
  }
1381
+ case "list_labels": {
1382
+ const args = ListLabelsSchema.parse(request.params.arguments);
1383
+ const labels = await listLabels(args.project_id, args);
1384
+ return {
1385
+ content: [{ type: "text", text: JSON.stringify(labels, null, 2) }],
1386
+ };
1387
+ }
1388
+ case "get_label": {
1389
+ const args = GetLabelSchema.parse(request.params.arguments);
1390
+ const label = await getLabel(args.project_id, args.label_id, args.include_ancestor_groups);
1391
+ return {
1392
+ content: [{ type: "text", text: JSON.stringify(label, null, 2) }],
1393
+ };
1394
+ }
1395
+ case "create_label": {
1396
+ const args = CreateLabelSchema.parse(request.params.arguments);
1397
+ const label = await createLabel(args.project_id, args);
1398
+ return {
1399
+ content: [{ type: "text", text: JSON.stringify(label, null, 2) }],
1400
+ };
1401
+ }
1402
+ case "update_label": {
1403
+ const args = UpdateLabelSchema.parse(request.params.arguments);
1404
+ const { project_id, label_id, ...options } = args;
1405
+ const label = await updateLabel(project_id, label_id, options);
1406
+ return {
1407
+ content: [{ type: "text", text: JSON.stringify(label, null, 2) }],
1408
+ };
1409
+ }
1410
+ case "delete_label": {
1411
+ const args = DeleteLabelSchema.parse(request.params.arguments);
1412
+ await deleteLabel(args.project_id, args.label_id);
1413
+ return {
1414
+ content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Label deleted successfully" }, null, 2) }],
1415
+ };
1416
+ }
1248
1417
  default:
1249
1418
  throw new Error(`Unknown tool: ${request.params.name}`);
1250
1419
  }
package/build/schemas.js CHANGED
@@ -207,7 +207,15 @@ export const GitLabLabelSchema = z.object({
207
207
  id: z.number(),
208
208
  name: z.string(),
209
209
  color: z.string(),
210
- description: z.string().optional(),
210
+ text_color: z.string(),
211
+ description: z.string().nullable(),
212
+ description_html: z.string().nullable(),
213
+ open_issues_count: z.number().optional(),
214
+ closed_issues_count: z.number().optional(),
215
+ open_merge_requests_count: z.number().optional(),
216
+ subscribed: z.boolean().optional(),
217
+ priority: z.number().nullable().optional(),
218
+ is_project_label: z.boolean().optional(),
211
219
  });
212
220
  export const GitLabUserSchema = z.object({
213
221
  username: z.string(), // Changed from login to match GitLab API
@@ -558,3 +566,34 @@ export const ListProjectsSchema = z.object({
558
566
  with_merge_requests_enabled: z.boolean().optional().describe("Filter projects with merge requests feature enabled"),
559
567
  min_access_level: z.number().optional().describe("Filter by minimum access level"),
560
568
  });
569
+ // Label operation schemas
570
+ export const ListLabelsSchema = z.object({
571
+ project_id: z.string().describe("Project ID or URL-encoded path"),
572
+ with_counts: z.boolean().optional().describe("Whether or not to include issue and merge request counts"),
573
+ include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
574
+ search: z.string().optional().describe("Keyword to filter labels by"),
575
+ });
576
+ export const GetLabelSchema = z.object({
577
+ project_id: z.string().describe("Project ID or URL-encoded path"),
578
+ label_id: z.union([z.number(), z.string()]).describe("The ID or title of a project's label"),
579
+ include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
580
+ });
581
+ export const CreateLabelSchema = z.object({
582
+ project_id: z.string().describe("Project ID or URL-encoded path"),
583
+ name: z.string().describe("The name of the label"),
584
+ color: z.string().describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
585
+ description: z.string().optional().describe("The description of the label"),
586
+ priority: z.number().nullable().optional().describe("The priority of the label"),
587
+ });
588
+ export const UpdateLabelSchema = z.object({
589
+ project_id: z.string().describe("Project ID or URL-encoded path"),
590
+ label_id: z.union([z.number(), z.string()]).describe("The ID or title of a project's label"),
591
+ new_name: z.string().optional().describe("The new name of the label"),
592
+ color: z.string().optional().describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
593
+ description: z.string().optional().describe("The new description of the label"),
594
+ priority: z.number().nullable().optional().describe("The new priority of the label"),
595
+ });
596
+ export const DeleteLabelSchema = z.object({
597
+ project_id: z.string().describe("Project ID or URL-encoded path"),
598
+ label_id: z.union([z.number(), z.string()]).describe("The ID or title of a project's label"),
599
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zereight/mcp-gitlab",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "MCP server for using the GitLab API",
5
5
  "license": "MIT",
6
6
  "author": "zereight",