@zereight/mcp-gitlab 1.0.17 â 1.0.18
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 +30 -133
- package/build/index.js +321 -11
- package/build/schemas.js +129 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,139 +40,36 @@ 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 đ ī¸
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
|
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 |
|
|
72
|
+
| **`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 |
|
|
176
73
|
|
|
177
74
|
## Environment Variable Configuration
|
|
178
75
|
|
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, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, 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, CreateNoteSchema, } from "./schemas.js";
|
|
13
13
|
/**
|
|
14
14
|
* Read version from package.json
|
|
15
15
|
*/
|
|
@@ -215,6 +215,171 @@ async function createIssue(projectId, options) {
|
|
|
215
215
|
const data = await response.json();
|
|
216
216
|
return GitLabIssueSchema.parse(data);
|
|
217
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* List issues in a GitLab project
|
|
220
|
+
* íëĄė í¸ė ė´ė ëĒŠëĄ ėĄ°í
|
|
221
|
+
*
|
|
222
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
223
|
+
* @param {Object} options - Options for listing issues
|
|
224
|
+
* @returns {Promise<GitLabIssue[]>} List of issues
|
|
225
|
+
*/
|
|
226
|
+
async function listIssues(projectId, options = {}) {
|
|
227
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`);
|
|
228
|
+
// Add all query parameters
|
|
229
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
230
|
+
if (value !== undefined) {
|
|
231
|
+
if (key === 'label_name' && Array.isArray(value)) {
|
|
232
|
+
// Handle array of labels
|
|
233
|
+
url.searchParams.append(key, value.join(','));
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
url.searchParams.append(key, value.toString());
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
const response = await fetch(url.toString(), {
|
|
241
|
+
headers: DEFAULT_HEADERS,
|
|
242
|
+
});
|
|
243
|
+
await handleGitLabError(response);
|
|
244
|
+
const data = await response.json();
|
|
245
|
+
return z.array(GitLabIssueSchema).parse(data);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Get a single issue from a GitLab project
|
|
249
|
+
* ë¨ėŧ ė´ė ėĄ°í
|
|
250
|
+
*
|
|
251
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
252
|
+
* @param {number} issueIid - The internal ID of the project issue
|
|
253
|
+
* @returns {Promise<GitLabIssue>} The issue
|
|
254
|
+
*/
|
|
255
|
+
async function getIssue(projectId, issueIid) {
|
|
256
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`);
|
|
257
|
+
const response = await fetch(url.toString(), {
|
|
258
|
+
headers: DEFAULT_HEADERS,
|
|
259
|
+
});
|
|
260
|
+
await handleGitLabError(response);
|
|
261
|
+
const data = await response.json();
|
|
262
|
+
return GitLabIssueSchema.parse(data);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Update an issue in a GitLab project
|
|
266
|
+
* ė´ė ė
ë°ė´í¸
|
|
267
|
+
*
|
|
268
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
269
|
+
* @param {number} issueIid - The internal ID of the project issue
|
|
270
|
+
* @param {Object} options - Update options for the issue
|
|
271
|
+
* @returns {Promise<GitLabIssue>} The updated issue
|
|
272
|
+
*/
|
|
273
|
+
async function updateIssue(projectId, issueIid, options) {
|
|
274
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`);
|
|
275
|
+
// Convert labels array to comma-separated string if present
|
|
276
|
+
const body = { ...options };
|
|
277
|
+
if (body.labels && Array.isArray(body.labels)) {
|
|
278
|
+
body.labels = body.labels.join(',');
|
|
279
|
+
}
|
|
280
|
+
const response = await fetch(url.toString(), {
|
|
281
|
+
method: "PUT",
|
|
282
|
+
headers: DEFAULT_HEADERS,
|
|
283
|
+
body: JSON.stringify(body),
|
|
284
|
+
});
|
|
285
|
+
await handleGitLabError(response);
|
|
286
|
+
const data = await response.json();
|
|
287
|
+
return GitLabIssueSchema.parse(data);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Delete an issue from a GitLab project
|
|
291
|
+
* ė´ė ėė
|
|
292
|
+
*
|
|
293
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
294
|
+
* @param {number} issueIid - The internal ID of the project issue
|
|
295
|
+
* @returns {Promise<void>}
|
|
296
|
+
*/
|
|
297
|
+
async function deleteIssue(projectId, issueIid) {
|
|
298
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`);
|
|
299
|
+
const response = await fetch(url.toString(), {
|
|
300
|
+
method: "DELETE",
|
|
301
|
+
headers: DEFAULT_HEADERS,
|
|
302
|
+
});
|
|
303
|
+
await handleGitLabError(response);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* List all issue links for a specific issue
|
|
307
|
+
* ė´ė ę´ęŗ ëĒŠëĄ ėĄ°í
|
|
308
|
+
*
|
|
309
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
310
|
+
* @param {number} issueIid - The internal ID of the project issue
|
|
311
|
+
* @returns {Promise<GitLabIssueWithLinkDetails[]>} List of issues with link details
|
|
312
|
+
*/
|
|
313
|
+
async function listIssueLinks(projectId, issueIid) {
|
|
314
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links`);
|
|
315
|
+
const response = await fetch(url.toString(), {
|
|
316
|
+
headers: DEFAULT_HEADERS,
|
|
317
|
+
});
|
|
318
|
+
await handleGitLabError(response);
|
|
319
|
+
const data = await response.json();
|
|
320
|
+
return z.array(GitLabIssueWithLinkDetailsSchema).parse(data);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Get a specific issue link
|
|
324
|
+
* íšė ė´ė ę´ęŗ ėĄ°í
|
|
325
|
+
*
|
|
326
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
327
|
+
* @param {number} issueIid - The internal ID of the project issue
|
|
328
|
+
* @param {number} issueLinkId - The ID of the issue link
|
|
329
|
+
* @returns {Promise<GitLabIssueLink>} The issue link
|
|
330
|
+
*/
|
|
331
|
+
async function getIssueLink(projectId, issueIid, issueLinkId) {
|
|
332
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links/${issueLinkId}`);
|
|
333
|
+
const response = await fetch(url.toString(), {
|
|
334
|
+
headers: DEFAULT_HEADERS,
|
|
335
|
+
});
|
|
336
|
+
await handleGitLabError(response);
|
|
337
|
+
const data = await response.json();
|
|
338
|
+
return GitLabIssueLinkSchema.parse(data);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Create an issue link between two issues
|
|
342
|
+
* ė´ė ę´ęŗ ėėą
|
|
343
|
+
*
|
|
344
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
345
|
+
* @param {number} issueIid - The internal ID of the project issue
|
|
346
|
+
* @param {string} targetProjectId - The ID or URL-encoded path of the target project
|
|
347
|
+
* @param {number} targetIssueIid - The internal ID of the target project issue
|
|
348
|
+
* @param {string} linkType - The type of the relation (relates_to, blocks, is_blocked_by)
|
|
349
|
+
* @returns {Promise<GitLabIssueLink>} The created issue link
|
|
350
|
+
*/
|
|
351
|
+
async function createIssueLink(projectId, issueIid, targetProjectId, targetIssueIid, linkType = 'relates_to') {
|
|
352
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links`);
|
|
353
|
+
const response = await fetch(url.toString(), {
|
|
354
|
+
method: "POST",
|
|
355
|
+
headers: DEFAULT_HEADERS,
|
|
356
|
+
body: JSON.stringify({
|
|
357
|
+
target_project_id: targetProjectId,
|
|
358
|
+
target_issue_iid: targetIssueIid,
|
|
359
|
+
link_type: linkType
|
|
360
|
+
}),
|
|
361
|
+
});
|
|
362
|
+
await handleGitLabError(response);
|
|
363
|
+
const data = await response.json();
|
|
364
|
+
return GitLabIssueLinkSchema.parse(data);
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Delete an issue link
|
|
368
|
+
* ė´ė ę´ęŗ ėė
|
|
369
|
+
*
|
|
370
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
371
|
+
* @param {number} issueIid - The internal ID of the project issue
|
|
372
|
+
* @param {number} issueLinkId - The ID of the issue link
|
|
373
|
+
* @returns {Promise<void>}
|
|
374
|
+
*/
|
|
375
|
+
async function deleteIssueLink(projectId, issueIid, issueLinkId) {
|
|
376
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links/${issueLinkId}`);
|
|
377
|
+
const response = await fetch(url.toString(), {
|
|
378
|
+
method: "DELETE",
|
|
379
|
+
headers: DEFAULT_HEADERS,
|
|
380
|
+
});
|
|
381
|
+
await handleGitLabError(response);
|
|
382
|
+
}
|
|
218
383
|
/**
|
|
219
384
|
* Create a new merge request in a GitLab project
|
|
220
385
|
* ëŗíŠ ėė˛ ėėą
|
|
@@ -743,6 +908,46 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
743
908
|
description: "Create a new note (comment) to an issue or merge request",
|
|
744
909
|
inputSchema: zodToJsonSchema(CreateNoteSchema),
|
|
745
910
|
},
|
|
911
|
+
{
|
|
912
|
+
name: "list_issues",
|
|
913
|
+
description: "List issues in a GitLab project with filtering options",
|
|
914
|
+
inputSchema: zodToJsonSchema(ListIssuesSchema),
|
|
915
|
+
},
|
|
916
|
+
{
|
|
917
|
+
name: "get_issue",
|
|
918
|
+
description: "Get details of a specific issue in a GitLab project",
|
|
919
|
+
inputSchema: zodToJsonSchema(GetIssueSchema),
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
name: "update_issue",
|
|
923
|
+
description: "Update an issue in a GitLab project",
|
|
924
|
+
inputSchema: zodToJsonSchema(UpdateIssueSchema),
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
name: "delete_issue",
|
|
928
|
+
description: "Delete an issue from a GitLab project",
|
|
929
|
+
inputSchema: zodToJsonSchema(DeleteIssueSchema),
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
name: "list_issue_links",
|
|
933
|
+
description: "List all issue links for a specific issue",
|
|
934
|
+
inputSchema: zodToJsonSchema(ListIssueLinksSchema),
|
|
935
|
+
},
|
|
936
|
+
{
|
|
937
|
+
name: "get_issue_link",
|
|
938
|
+
description: "Get a specific issue link",
|
|
939
|
+
inputSchema: zodToJsonSchema(GetIssueLinkSchema),
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
name: "create_issue_link",
|
|
943
|
+
description: "Create an issue link between two issues",
|
|
944
|
+
inputSchema: zodToJsonSchema(CreateIssueLinkSchema),
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
name: "delete_issue_link",
|
|
948
|
+
description: "Delete an issue link",
|
|
949
|
+
inputSchema: zodToJsonSchema(DeleteIssueLinkSchema),
|
|
950
|
+
},
|
|
746
951
|
{
|
|
747
952
|
name: "list_namespaces",
|
|
748
953
|
description: "List all namespaces available to the current user",
|
|
@@ -750,17 +955,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
750
955
|
},
|
|
751
956
|
{
|
|
752
957
|
name: "get_namespace",
|
|
753
|
-
description: "Get details
|
|
958
|
+
description: "Get details of a namespace by ID or path",
|
|
754
959
|
inputSchema: zodToJsonSchema(GetNamespaceSchema),
|
|
755
960
|
},
|
|
756
961
|
{
|
|
757
962
|
name: "verify_namespace",
|
|
758
|
-
description: "Verify if a
|
|
963
|
+
description: "Verify if a namespace path exists",
|
|
759
964
|
inputSchema: zodToJsonSchema(VerifyNamespaceSchema),
|
|
760
965
|
},
|
|
761
966
|
{
|
|
762
967
|
name: "get_project",
|
|
763
|
-
description: "Get details
|
|
968
|
+
description: "Get details of a specific project",
|
|
764
969
|
inputSchema: zodToJsonSchema(GetProjectSchema),
|
|
765
970
|
},
|
|
766
971
|
{
|
|
@@ -893,36 +1098,83 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
893
1098
|
}
|
|
894
1099
|
case "list_namespaces": {
|
|
895
1100
|
const args = ListNamespacesSchema.parse(request.params.arguments);
|
|
896
|
-
const
|
|
1101
|
+
const url = new URL(`${GITLAB_API_URL}/namespaces`);
|
|
1102
|
+
if (args.search) {
|
|
1103
|
+
url.searchParams.append("search", args.search);
|
|
1104
|
+
}
|
|
1105
|
+
if (args.page) {
|
|
1106
|
+
url.searchParams.append("page", args.page.toString());
|
|
1107
|
+
}
|
|
1108
|
+
if (args.per_page) {
|
|
1109
|
+
url.searchParams.append("per_page", args.per_page.toString());
|
|
1110
|
+
}
|
|
1111
|
+
if (args.owned) {
|
|
1112
|
+
url.searchParams.append("owned", args.owned.toString());
|
|
1113
|
+
}
|
|
1114
|
+
const response = await fetch(url.toString(), {
|
|
1115
|
+
headers: DEFAULT_HEADERS,
|
|
1116
|
+
});
|
|
1117
|
+
await handleGitLabError(response);
|
|
1118
|
+
const data = await response.json();
|
|
1119
|
+
const namespaces = z.array(GitLabNamespaceSchema).parse(data);
|
|
897
1120
|
return {
|
|
898
1121
|
content: [{ type: "text", text: JSON.stringify(namespaces, null, 2) }],
|
|
899
1122
|
};
|
|
900
1123
|
}
|
|
901
1124
|
case "get_namespace": {
|
|
902
1125
|
const args = GetNamespaceSchema.parse(request.params.arguments);
|
|
903
|
-
const
|
|
1126
|
+
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(args.namespace_id)}`);
|
|
1127
|
+
const response = await fetch(url.toString(), {
|
|
1128
|
+
headers: DEFAULT_HEADERS,
|
|
1129
|
+
});
|
|
1130
|
+
await handleGitLabError(response);
|
|
1131
|
+
const data = await response.json();
|
|
1132
|
+
const namespace = GitLabNamespaceSchema.parse(data);
|
|
904
1133
|
return {
|
|
905
1134
|
content: [{ type: "text", text: JSON.stringify(namespace, null, 2) }],
|
|
906
1135
|
};
|
|
907
1136
|
}
|
|
908
1137
|
case "verify_namespace": {
|
|
909
1138
|
const args = VerifyNamespaceSchema.parse(request.params.arguments);
|
|
910
|
-
const
|
|
1139
|
+
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(args.path)}/exists`);
|
|
1140
|
+
const response = await fetch(url.toString(), {
|
|
1141
|
+
headers: DEFAULT_HEADERS,
|
|
1142
|
+
});
|
|
1143
|
+
await handleGitLabError(response);
|
|
1144
|
+
const data = await response.json();
|
|
1145
|
+
const namespaceExists = GitLabNamespaceExistsResponseSchema.parse(data);
|
|
911
1146
|
return {
|
|
912
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
1147
|
+
content: [{ type: "text", text: JSON.stringify(namespaceExists, null, 2) }],
|
|
913
1148
|
};
|
|
914
1149
|
}
|
|
915
1150
|
case "get_project": {
|
|
916
1151
|
const args = GetProjectSchema.parse(request.params.arguments);
|
|
917
|
-
const
|
|
918
|
-
const
|
|
1152
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(args.project_id)}`);
|
|
1153
|
+
const response = await fetch(url.toString(), {
|
|
1154
|
+
headers: DEFAULT_HEADERS,
|
|
1155
|
+
});
|
|
1156
|
+
await handleGitLabError(response);
|
|
1157
|
+
const data = await response.json();
|
|
1158
|
+
const project = GitLabProjectSchema.parse(data);
|
|
919
1159
|
return {
|
|
920
1160
|
content: [{ type: "text", text: JSON.stringify(project, null, 2) }],
|
|
921
1161
|
};
|
|
922
1162
|
}
|
|
923
1163
|
case "list_projects": {
|
|
924
1164
|
const args = ListProjectsSchema.parse(request.params.arguments);
|
|
925
|
-
const
|
|
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);
|
|
926
1178
|
return {
|
|
927
1179
|
content: [{ type: "text", text: JSON.stringify(projects, null, 2) }],
|
|
928
1180
|
};
|
|
@@ -935,6 +1187,64 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
935
1187
|
content: [{ type: "text", text: JSON.stringify(note, null, 2) }],
|
|
936
1188
|
};
|
|
937
1189
|
}
|
|
1190
|
+
case "list_issues": {
|
|
1191
|
+
const args = ListIssuesSchema.parse(request.params.arguments);
|
|
1192
|
+
const { project_id, ...options } = args;
|
|
1193
|
+
const issues = await listIssues(project_id, options);
|
|
1194
|
+
return {
|
|
1195
|
+
content: [{ type: "text", text: JSON.stringify(issues, null, 2) }],
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
case "get_issue": {
|
|
1199
|
+
const args = GetIssueSchema.parse(request.params.arguments);
|
|
1200
|
+
const issue = await getIssue(args.project_id, args.issue_iid);
|
|
1201
|
+
return {
|
|
1202
|
+
content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
case "update_issue": {
|
|
1206
|
+
const args = UpdateIssueSchema.parse(request.params.arguments);
|
|
1207
|
+
const { project_id, issue_iid, ...options } = args;
|
|
1208
|
+
const issue = await updateIssue(project_id, issue_iid, options);
|
|
1209
|
+
return {
|
|
1210
|
+
content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
case "delete_issue": {
|
|
1214
|
+
const args = DeleteIssueSchema.parse(request.params.arguments);
|
|
1215
|
+
await deleteIssue(args.project_id, args.issue_iid);
|
|
1216
|
+
return {
|
|
1217
|
+
content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Issue deleted successfully" }, null, 2) }],
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
case "list_issue_links": {
|
|
1221
|
+
const args = ListIssueLinksSchema.parse(request.params.arguments);
|
|
1222
|
+
const links = await listIssueLinks(args.project_id, args.issue_iid);
|
|
1223
|
+
return {
|
|
1224
|
+
content: [{ type: "text", text: JSON.stringify(links, null, 2) }],
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
case "get_issue_link": {
|
|
1228
|
+
const args = GetIssueLinkSchema.parse(request.params.arguments);
|
|
1229
|
+
const link = await getIssueLink(args.project_id, args.issue_iid, args.issue_link_id);
|
|
1230
|
+
return {
|
|
1231
|
+
content: [{ type: "text", text: JSON.stringify(link, null, 2) }],
|
|
1232
|
+
};
|
|
1233
|
+
}
|
|
1234
|
+
case "create_issue_link": {
|
|
1235
|
+
const args = CreateIssueLinkSchema.parse(request.params.arguments);
|
|
1236
|
+
const link = await createIssueLink(args.project_id, args.issue_iid, args.target_project_id, args.target_issue_iid, args.link_type);
|
|
1237
|
+
return {
|
|
1238
|
+
content: [{ type: "text", text: JSON.stringify(link, null, 2) }],
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1241
|
+
case "delete_issue_link": {
|
|
1242
|
+
const args = DeleteIssueLinkSchema.parse(request.params.arguments);
|
|
1243
|
+
await deleteIssueLink(args.project_id, args.issue_iid, args.issue_link_id);
|
|
1244
|
+
return {
|
|
1245
|
+
content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Issue link deleted successfully" }, null, 2) }],
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
938
1248
|
default:
|
|
939
1249
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
940
1250
|
}
|
package/build/schemas.js
CHANGED
|
@@ -96,6 +96,8 @@ export const GitLabRepositorySchema = z.object({
|
|
|
96
96
|
group_access_level: z.number(),
|
|
97
97
|
})).optional(),
|
|
98
98
|
});
|
|
99
|
+
// Project schema (extended from repository schema)
|
|
100
|
+
export const GitLabProjectSchema = GitLabRepositorySchema;
|
|
99
101
|
// File content schemas
|
|
100
102
|
export const GitLabFileContentSchema = z.object({
|
|
101
103
|
file_name: z.string(), // Changed from name to match GitLab API
|
|
@@ -200,20 +202,6 @@ export const GitLabSearchResponseSchema = z.object({
|
|
|
200
202
|
current_page: z.number().optional(),
|
|
201
203
|
items: z.array(GitLabRepositorySchema),
|
|
202
204
|
});
|
|
203
|
-
// Fork related schemas
|
|
204
|
-
export const GitLabForkParentSchema = z.object({
|
|
205
|
-
name: z.string(),
|
|
206
|
-
path_with_namespace: z.string(), // Changed from full_name to match GitLab API
|
|
207
|
-
owner: z.object({
|
|
208
|
-
username: z.string(), // Changed from login to match GitLab API
|
|
209
|
-
id: z.number(),
|
|
210
|
-
avatar_url: z.string(),
|
|
211
|
-
}).optional(), // Made optional to handle cases where GitLab API doesn't include it
|
|
212
|
-
web_url: z.string(), // Changed from html_url to match GitLab API
|
|
213
|
-
});
|
|
214
|
-
export const GitLabForkSchema = GitLabRepositorySchema.extend({
|
|
215
|
-
forked_from_project: GitLabForkParentSchema.optional(), // Made optional to handle cases where GitLab API doesn't include it
|
|
216
|
-
});
|
|
217
205
|
// Issue related schemas
|
|
218
206
|
export const GitLabLabelSchema = z.object({
|
|
219
207
|
id: z.number(),
|
|
@@ -245,12 +233,48 @@ export const GitLabIssueSchema = z.object({
|
|
|
245
233
|
state: z.string(),
|
|
246
234
|
author: GitLabUserSchema,
|
|
247
235
|
assignees: z.array(GitLabUserSchema),
|
|
248
|
-
labels: z.array(GitLabLabelSchema),
|
|
236
|
+
labels: z.array(GitLabLabelSchema).or(z.array(z.string())), // Support both label objects and strings
|
|
249
237
|
milestone: GitLabMilestoneSchema.nullable(),
|
|
250
238
|
created_at: z.string(),
|
|
251
239
|
updated_at: z.string(),
|
|
252
240
|
closed_at: z.string().nullable(),
|
|
253
241
|
web_url: z.string(), // Changed from html_url to match GitLab API
|
|
242
|
+
references: z.object({
|
|
243
|
+
short: z.string(),
|
|
244
|
+
relative: z.string(),
|
|
245
|
+
full: z.string(),
|
|
246
|
+
}).optional(),
|
|
247
|
+
time_stats: z.object({
|
|
248
|
+
time_estimate: z.number(),
|
|
249
|
+
total_time_spent: z.number(),
|
|
250
|
+
human_time_estimate: z.string().nullable(),
|
|
251
|
+
human_total_time_spent: z.string().nullable(),
|
|
252
|
+
}).optional(),
|
|
253
|
+
confidential: z.boolean().optional(),
|
|
254
|
+
due_date: z.string().nullable().optional(),
|
|
255
|
+
discussion_locked: z.boolean().nullable().optional(),
|
|
256
|
+
weight: z.number().nullable().optional(),
|
|
257
|
+
});
|
|
258
|
+
// NEW SCHEMA: For issue with link details (used in listing issue links)
|
|
259
|
+
export const GitLabIssueWithLinkDetailsSchema = GitLabIssueSchema.extend({
|
|
260
|
+
issue_link_id: z.number(),
|
|
261
|
+
link_type: z.enum(['relates_to', 'blocks', 'is_blocked_by']),
|
|
262
|
+
link_created_at: z.string(),
|
|
263
|
+
link_updated_at: z.string(),
|
|
264
|
+
});
|
|
265
|
+
// Fork related schemas
|
|
266
|
+
export const GitLabForkParentSchema = z.object({
|
|
267
|
+
name: z.string(),
|
|
268
|
+
path_with_namespace: z.string(), // Changed from full_name to match GitLab API
|
|
269
|
+
owner: z.object({
|
|
270
|
+
username: z.string(), // Changed from login to match GitLab API
|
|
271
|
+
id: z.number(),
|
|
272
|
+
avatar_url: z.string(),
|
|
273
|
+
}).optional(), // Made optional to handle cases where GitLab API doesn't include it
|
|
274
|
+
web_url: z.string(), // Changed from html_url to match GitLab API
|
|
275
|
+
});
|
|
276
|
+
export const GitLabForkSchema = GitLabRepositorySchema.extend({
|
|
277
|
+
forked_from_project: GitLabForkParentSchema.optional(), // Made optional to handle cases where GitLab API doesn't include it
|
|
254
278
|
});
|
|
255
279
|
// Merge Request related schemas (equivalent to Pull Request)
|
|
256
280
|
export const GitLabMergeRequestDiffRefSchema = z.object({
|
|
@@ -431,44 +455,106 @@ export const CreateNoteSchema = z.object({
|
|
|
431
455
|
noteable_iid: z.number().describe("IID of the issue or merge request"),
|
|
432
456
|
body: z.string().describe("Note content"),
|
|
433
457
|
});
|
|
434
|
-
//
|
|
458
|
+
// Issues API operation schemas
|
|
459
|
+
export const ListIssuesSchema = z.object({
|
|
460
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
461
|
+
assignee_id: z.number().optional().describe("Return issues assigned to the given user ID"),
|
|
462
|
+
assignee_username: z.string().optional().describe("Return issues assigned to the given username"),
|
|
463
|
+
author_id: z.number().optional().describe("Return issues created by the given user ID"),
|
|
464
|
+
author_username: z.string().optional().describe("Return issues created by the given username"),
|
|
465
|
+
confidential: z.boolean().optional().describe("Filter confidential or public issues"),
|
|
466
|
+
created_after: z.string().optional().describe("Return issues created after the given time"),
|
|
467
|
+
created_before: z.string().optional().describe("Return issues created before the given time"),
|
|
468
|
+
due_date: z.string().optional().describe("Return issues that have the due date"),
|
|
469
|
+
label_name: z.array(z.string()).optional().describe("Array of label names"),
|
|
470
|
+
milestone: z.string().optional().describe("Milestone title"),
|
|
471
|
+
scope: z.enum(['created-by-me', 'assigned-to-me', 'all']).optional().describe("Return issues from a specific scope"),
|
|
472
|
+
search: z.string().optional().describe("Search for specific terms"),
|
|
473
|
+
state: z.enum(['opened', 'closed', 'all']).optional().describe("Return issues with a specific state"),
|
|
474
|
+
updated_after: z.string().optional().describe("Return issues updated after the given time"),
|
|
475
|
+
updated_before: z.string().optional().describe("Return issues updated before the given time"),
|
|
476
|
+
with_labels_details: z.boolean().optional().describe("Return more details for each label"),
|
|
477
|
+
page: z.number().optional().describe("Page number for pagination"),
|
|
478
|
+
per_page: z.number().optional().describe("Number of items per page"),
|
|
479
|
+
});
|
|
480
|
+
export const GetIssueSchema = z.object({
|
|
481
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
482
|
+
issue_iid: z.number().describe("The internal ID of the project issue"),
|
|
483
|
+
});
|
|
484
|
+
export const UpdateIssueSchema = z.object({
|
|
485
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
486
|
+
issue_iid: z.number().describe("The internal ID of the project issue"),
|
|
487
|
+
title: z.string().optional().describe("The title of the issue"),
|
|
488
|
+
description: z.string().optional().describe("The description of the issue"),
|
|
489
|
+
assignee_ids: z.array(z.number()).optional().describe("Array of user IDs to assign issue to"),
|
|
490
|
+
confidential: z.boolean().optional().describe("Set the issue to be confidential"),
|
|
491
|
+
discussion_locked: z.boolean().optional().describe("Flag to lock discussions"),
|
|
492
|
+
due_date: z.string().optional().describe("Date the issue is due (YYYY-MM-DD)"),
|
|
493
|
+
labels: z.array(z.string()).optional().describe("Array of label names"),
|
|
494
|
+
milestone_id: z.number().optional().describe("Milestone ID to assign"),
|
|
495
|
+
state_event: z.enum(['close', 'reopen']).optional().describe("Update issue state (close/reopen)"),
|
|
496
|
+
weight: z.number().optional().describe("Weight of the issue (0-9)"),
|
|
497
|
+
});
|
|
498
|
+
export const DeleteIssueSchema = z.object({
|
|
499
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
500
|
+
issue_iid: z.number().describe("The internal ID of the project issue"),
|
|
501
|
+
});
|
|
502
|
+
// Issue links related schemas
|
|
503
|
+
export const GitLabIssueLinkSchema = z.object({
|
|
504
|
+
source_issue: GitLabIssueSchema,
|
|
505
|
+
target_issue: GitLabIssueSchema,
|
|
506
|
+
link_type: z.enum(['relates_to', 'blocks', 'is_blocked_by']),
|
|
507
|
+
});
|
|
508
|
+
export const ListIssueLinksSchema = z.object({
|
|
509
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
510
|
+
issue_iid: z.number().describe("The internal ID of a project's issue"),
|
|
511
|
+
});
|
|
512
|
+
export const GetIssueLinkSchema = z.object({
|
|
513
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
514
|
+
issue_iid: z.number().describe("The internal ID of a project's issue"),
|
|
515
|
+
issue_link_id: z.number().describe("ID of an issue relationship"),
|
|
516
|
+
});
|
|
517
|
+
export const CreateIssueLinkSchema = z.object({
|
|
518
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
519
|
+
issue_iid: z.number().describe("The internal ID of a project's issue"),
|
|
520
|
+
target_project_id: z.string().describe("The ID or URL-encoded path of a target project"),
|
|
521
|
+
target_issue_iid: z.number().describe("The internal ID of a target project's issue"),
|
|
522
|
+
link_type: z.enum(['relates_to', 'blocks', 'is_blocked_by']).optional().describe("The type of the relation, defaults to relates_to"),
|
|
523
|
+
});
|
|
524
|
+
export const DeleteIssueLinkSchema = z.object({
|
|
525
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
526
|
+
issue_iid: z.number().describe("The internal ID of a project's issue"),
|
|
527
|
+
issue_link_id: z.number().describe("The ID of an issue relationship"),
|
|
528
|
+
});
|
|
529
|
+
// Namespace API operation schemas
|
|
435
530
|
export const ListNamespacesSchema = z.object({
|
|
436
|
-
search: z.string().optional().describe("
|
|
437
|
-
|
|
438
|
-
|
|
531
|
+
search: z.string().optional().describe("Search term for namespaces"),
|
|
532
|
+
page: z.number().optional().describe("Page number for pagination"),
|
|
533
|
+
per_page: z.number().optional().describe("Number of items per page"),
|
|
534
|
+
owned: z.boolean().optional().describe("Filter for namespaces owned by current user"),
|
|
439
535
|
});
|
|
440
536
|
export const GetNamespaceSchema = z.object({
|
|
441
|
-
|
|
537
|
+
namespace_id: z.string().describe("Namespace ID or full path"),
|
|
442
538
|
});
|
|
443
539
|
export const VerifyNamespaceSchema = z.object({
|
|
444
|
-
|
|
445
|
-
parent_id: z.number().optional().describe("ID of the parent namespace. If unspecified, only returns top-level namespaces"),
|
|
540
|
+
path: z.string().describe("Namespace path to verify"),
|
|
446
541
|
});
|
|
447
542
|
// Project API operation schemas
|
|
448
543
|
export const GetProjectSchema = z.object({
|
|
449
|
-
|
|
450
|
-
license: z.boolean().optional().describe("Include project license data"),
|
|
451
|
-
statistics: z.boolean().optional().describe("Include project statistics"),
|
|
452
|
-
with_custom_attributes: z.boolean().optional().describe("Include custom attributes in response"),
|
|
544
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
453
545
|
});
|
|
454
546
|
export const ListProjectsSchema = z.object({
|
|
455
|
-
|
|
456
|
-
id_after: z.number().optional().describe("Limit results to projects with IDs greater than the specified ID"),
|
|
457
|
-
id_before: z.number().optional().describe("Limit results to projects with IDs less than the specified ID"),
|
|
458
|
-
membership: z.boolean().optional().describe("Limit by projects that the current user is a member of"),
|
|
459
|
-
min_access_level: z.number().optional().describe("Limit by minimum access level"),
|
|
460
|
-
order_by: z.enum(['id', 'name', 'path', 'created_at', 'updated_at', 'last_activity_at']).optional().describe("Return projects ordered by field"),
|
|
461
|
-
owned: z.boolean().optional().describe("Limit by projects explicitly owned by the current user"),
|
|
462
|
-
search: z.string().optional().describe("Return list of projects matching the search criteria"),
|
|
463
|
-
simple: z.boolean().optional().describe("Return only limited fields for each project"),
|
|
464
|
-
sort: z.enum(['asc', 'desc']).optional().describe("Return projects sorted in ascending or descending order"),
|
|
465
|
-
starred: z.boolean().optional().describe("Limit by projects starred by the current user"),
|
|
466
|
-
visibility: z.enum(['public', 'internal', 'private']).optional().describe("Limit by visibility"),
|
|
467
|
-
with_custom_attributes: z.boolean().optional().describe("Include custom attributes in response"),
|
|
468
|
-
with_issues_enabled: z.boolean().optional().describe("Limit by enabled issues feature"),
|
|
469
|
-
with_merge_requests_enabled: z.boolean().optional().describe("Limit by enabled merge requests feature"),
|
|
470
|
-
with_programming_language: z.string().optional().describe("Limit by projects which use the given programming language"),
|
|
471
|
-
with_shared: z.boolean().optional().describe("Include projects shared to this group"),
|
|
547
|
+
search: z.string().optional().describe("Search term for projects"),
|
|
472
548
|
page: z.number().optional().describe("Page number for pagination"),
|
|
473
549
|
per_page: z.number().optional().describe("Number of items per page"),
|
|
550
|
+
owned: z.boolean().optional().describe("Filter for projects owned by current user"),
|
|
551
|
+
membership: z.boolean().optional().describe("Filter for projects where current user is a member"),
|
|
552
|
+
simple: z.boolean().optional().describe("Return only limited fields"),
|
|
553
|
+
archived: z.boolean().optional().describe("Filter for archived projects"),
|
|
554
|
+
visibility: z.enum(["public", "internal", "private"]).optional().describe("Filter by project visibility"),
|
|
555
|
+
order_by: z.enum(["id", "name", "path", "created_at", "updated_at", "last_activity_at"]).optional().describe("Return projects ordered by field"),
|
|
556
|
+
sort: z.enum(["asc", "desc"]).optional().describe("Return projects sorted in ascending or descending order"),
|
|
557
|
+
with_issues_enabled: z.boolean().optional().describe("Filter projects with issues feature enabled"),
|
|
558
|
+
with_merge_requests_enabled: z.boolean().optional().describe("Filter projects with merge requests feature enabled"),
|
|
559
|
+
min_access_level: z.number().optional().describe("Filter by minimum access level"),
|
|
474
560
|
});
|