Compare commits

...

37 Commits

Author SHA1 Message Date
3af10a3844 FIX: line range start and end optional 2025-05-28 01:31:37 +09:00
f8b1444afd [main] fix: description null error handling
📝 Details:
- GitLab issues/milestones의 null description 처리
- schemas.ts에서 description을 nullable로 변경
2025-05-27 12:25:31 +09:00
06f9437329 Merge pull request #53 from zereight/fix/51-description-nullable
FIX: description null error
2025-05-27 12:20:39 +09:00
dc99f864ca FIX: description null error 2025-05-27 02:00:36 +09:00
8ba33986f3 [main] docs: update changelog for v1.0.45 pipeline tools
🚀 Breaking Changes:
- None

📝 Details:
- Added 5 new pipeline management tools
- Pipeline status monitoring and analysis support
2025-05-24 21:02:58 +09:00
64a936446e [release] feat: update version to 1.0.45
🚀 Breaking Changes:
- Version updated from 1.0.44 to 1.0.45
2025-05-24 20:57:15 +09:00
8ab0ac7145 Merge pull request #52 from vicendominguez/main
feat(release): 1.0.44  adds pipeline jobs tool
2025-05-24 20:55:55 +09:00
ea06c21f29 feat(release): 1.0.44 adds pipeline jobs tool 2025-05-24 13:31:47 +02:00
140620397b chore(release): 1.0.43 - get_repository_tree is added read_only_mode 2025-05-23 00:41:56 +09:00
3d7aa8035d docs: translate issue notes changelog from Korean to English 2025-05-22 21:28:34 +09:00
25be1947b9 chore(release): 1.0.42 - issue note 기능 추가 (#47) 2025-05-22 21:24:29 +09:00
864ee77ae6 Merge pull request #47 from svengt/feat/add-issue-notes-support
feat: add support for creating and updating issue notes
2025-05-22 21:22:04 +09:00
dc6cc59434 feat: add support for creating and updating issue notes
- Added create_issue_note to add a new note to an existing issue thread
- Added update_issue_note to modify an existing issue thread note
- Similar to existing merge request note functions but for issues
2025-05-22 13:25:31 +02:00
5924fd3ed4 Merge pull request #45 from vlucaswang/fix/docs
fix: fix README
2025-05-21 14:28:08 +09:00
f4b265bf2e fix: fix README 2025-05-21 14:35:37 +09:30
b326f4c3c3 docs: update release notes for v1.0.40 (2025-05-21) 2025-05-21 03:40:02 +09:00
1350a024b5 Merge pull request #44 from huerlisi/feat/add-issue-notes-support
feat: add issue discussions support
2025-05-21 03:36:33 +09:00
4c57c37888 feat: add issue discussions support
Added `list_issue_discussions` tool to support GitLab issue discussions
similar to merge request discussions.
2025-05-20 15:45:23 +02:00
e4a28a9a47 버전 1.0.39로 업데이트 2025-05-20 18:34:05 +09:00
9f1e7b5bca Merge pull request #42 from vlucaswang/feat/add-docker
feat: add docker image and push to dockerhub
2025-05-20 18:32:19 +09:00
f37e210ee8 Merge pull request #41 from kamibayashi/fixed_resolve_outdated_diff_discussions_nullable
fixed resolve_outdated_diff_discussions nullable
2025-05-20 18:28:08 +09:00
6f789692be feat: add docker image and push to dockerhub 2025-05-20 16:04:37 +09:30
1bb70dccb9 fixed resolve_outdated_diff_discussions nullable 2025-05-19 17:18:01 +09:00
676bbcd4dd docs: add release-notes.md 2025-05-17 15:41:14 +09:00
0bb59a3217 Bump version 2025-05-17 15:38:18 +09:00
b908f03801 Merge pull request #40 from huerlisi/fix/discussion-enum
fix: add `expanded` to `start` and `end` for GitLabDiscussionNoteSchema
2025-05-17 15:36:11 +09:00
5024a2a5af fix: add expanded to start and end for GitLabDiscussionNoteSchema 2025-05-16 21:36:21 +02:00
d2cced1b38 Bump version 2025-05-15 10:53:14 +09:00
2fec95d469 Merge pull request #38 from ncrum/feat/merge-request-note
Adds threaded comment support for merge requests
2025-05-15 10:51:48 +09:00
3565d1b397 Merge pull request #37 from ncrum/fix/resolve-notes
Support resolving merge request discussion notes
2025-05-15 10:50:39 +09:00
353e62a401 refactor: rename add_merge_request_thread_note to create_merge_request_note for consistency 2025-05-13 16:52:17 -06:00
3f2b35535e feat: Implement add_merge_request_thread_note function for adding notes to existing MR threads 2025-05-13 16:20:21 -06:00
026dd58887 feat: Add create_merge_request_thread tool for diff notes
- Implement new tool for creating MR threads with positioning support
- Create schemas to handle diff notes with file and line number positions
- Support optional created_at timestamp parameter
- Update README with the new tool information
2025-05-13 15:45:43 -06:00
bde83c0a91 feat: support resolving merge request notes 2025-05-13 14:54:05 -06:00
08ab1357a0 feat: Decode project_id for GitLab API calls
- Decode project_id using decodeURIComponent() in relevant helper functions.
- This resolves API call issues related to project ID encoding differences between models.
- Updated CHANGELOG for 1.0.36 and added thanks to Aubermean.
2025-05-13 02:20:59 +09:00
651072dfd7 [main] chore: update version to 1.0.35 🚀
📝 Details:
- Incremented package version from 1.0.34 to 1.0.35
2025-05-13 01:53:10 +09:00
bf250b0d88 [main] refactor: update label_id schema to use string type
🚀 Breaking Changes:
- label_id now requires a string type instead of a union of number and string.

📝 Details:
- Improved consistency in schema definitions for label handling.
2025-05-13 01:53:00 +09:00
8 changed files with 1040 additions and 64 deletions

46
CHANGELOG.md Normal file
View File

@ -0,0 +1,46 @@
## [1.0.46] - 2025-05-27
### Fixed
- Fixed issue where GitLab issues and milestones with null descriptions would cause JSON-RPC errors
- Changed `description` field to be nullable with default empty string in schemas
- This allows proper handling of GitLab issues/milestones without descriptions
- See: [PR #53](https://github.com/zereight/gitlab-mcp/pull/53), [Issue #51](https://github.com/zereight/gitlab-mcp/issues/51)
---
## [1.0.45] - 2025-05-24
### Added
- 🔄 **Pipeline Management Tools**: Added GitLab pipeline status monitoring and management functionality
- `list_pipelines`: List project pipelines with various filtering options
- `get_pipeline`: Get detailed information about a specific pipeline
- `list_pipeline_jobs`: List all jobs in a specific pipeline
- `get_pipeline_job`: Get detailed information about a specific pipeline job
- `get_pipeline_job_output`: Get execution logs/output from pipeline jobs
- 📊 Pipeline status summary and analysis support
- Example: "How many of the last N pipelines are successful?"
- Example: "Can you make a summary of the output in the last pipeline?"
- See: [PR #52](https://github.com/zereight/gitlab-mcp/pull/52)
---
## [1.0.42] - 2025-05-22
### Added
- Added support for creating and updating issue notes (comments) in GitLab.
- You can now add or edit comments on issues.
- See: [PR #47](https://github.com/zereight/gitlab-mcp/pull/47)
---
## [1.0.38] - 2025-05-17
### Fixed
- Added `expanded` property to `start` and `end` in `GitLabDiscussionNoteSchema`
Now you can expand or collapse more information at the start and end of discussion notes.
Example: In code review, you can choose to show or hide specific parts of the discussion.
(See: [PR #40](https://github.com/zereight/gitlab-mcp/pull/40))

24
Dockerfile Normal file
View File

@ -0,0 +1,24 @@
FROM node:22.15-alpine AS builder
COPY . /app
COPY tsconfig.json /tsconfig.json
WORKDIR /app
RUN --mount=type=cache,target=/root/.npm npm install
RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev
FROM node:22.12-alpine AS release
WORKDIR /app
COPY --from=builder /app/build /app/build
COPY --from=builder /app/package.json /app/package.json
COPY --from=builder /app/package-lock.json /app/package-lock.json
ENV NODE_ENV=production
RUN npm ci --ignore-scripts --omit-dev
ENTRYPOINT ["node", "build/index.js"]

101
README.md
View File

@ -14,6 +14,8 @@ GitLab MCP(Model Context Protocol) Server. **Includes bug fixes and improvements
When using with the Claude App, you need to set up your API key and URLs directly.
#### npx
```json
{
"mcpServers": {
@ -24,7 +26,39 @@ When using with the Claude App, you need to set up your API key and URLs directl
"GITLAB_PERSONAL_ACCESS_TOKEN": "your_gitlab_token",
"GITLAB_API_URL": "your_gitlab_api_url",
"GITLAB_READ_ONLY_MODE": "false",
"USE_GITLAB_WIKI":"true"
"USE_GITLAB_WIKI": "true"
}
}
}
}
```
#### Docker
```json
{
"mcpServers": {
"GitLab communication server": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITLAB_PERSONAL_ACCESS_TOKEN",
"-e",
"GITLAB_API_URL",
"-e",
"GITLAB_READ_ONLY_MODE",
"-e",
"USE_GITLAB_WIKI",
"nkwd/gitlab-mcp"
],
"env": {
"GITLAB_PERSONAL_ACCESS_TOKEN": "your_gitlab_token",
"GITLAB_API_URL": "https://gitlab.com/api/v4", // Optional, for self-hosted GitLab
"GITLAB_READ_ONLY_MODE": "false",
"USE_GITLAB_WIKI": "true"
}
}
}
@ -33,7 +67,6 @@ When using with the Claude App, you need to set up your API key and URLs directl
### Environment Variables
- `GITLAB_PERSONAL_ACCESS_TOKEN`: Your GitLab personal access token.
- `GITLAB_API_URL`: Your GitLab API URL. (Default: `https://gitlab.com/api/v4`)
- `GITLAB_READ_ONLY_MODE`: When set to 'true', restricts the server to only expose read-only operations. Useful for enhanced security or when write access is not needed. Also useful for using with Cursor and it's 40 tool limit.
@ -55,31 +88,41 @@ When using with the Claude App, you need to set up your API key and URLs directl
11. `get_merge_request_diffs` - Get the changes/diffs of a merge request (Either mergeRequestIid or branchName must be provided)
12. `update_merge_request` - Update a merge request (Either mergeRequestIid or branchName must be provided)
13. `create_note` - Create a new note (comment) to an issue or merge request
14. `mr_discussions` - List discussion items for a merge request
15. `update_merge_request_note` - Modify an existing merge request thread note
16. `list_issues` - List issues in a GitLab project with filtering options
17. `get_issue` - Get details of a specific issue in a GitLab project
18. `update_issue` - Update an issue in a GitLab project
19. `delete_issue` - Delete an issue from a GitLab project
20. `list_issue_links` - List all issue links for a specific issue
21. `get_issue_link` - Get a specific issue link
22. `create_issue_link` - Create an issue link between two issues
23. `delete_issue_link` - Delete an issue link
24. `list_namespaces` - List all namespaces available to the current user
25. `get_namespace` - Get details of a namespace by ID or path
26. `verify_namespace` - Verify if a namespace path exists
27. `get_project` - Get details of a specific project
28. `list_projects` - List projects accessible by the current user
29. `list_labels` - List labels for a project
30. `get_label` - Get a single label from a project
31. `create_label` - Create a new label in a project
32. `update_label` - Update an existing label in a project
33. `delete_label` - Delete a label from a project
34. `list_group_projects` - List projects in a GitLab group with filtering options
35. `list_wiki_pages` - List wiki pages in a GitLab project
36. `get_wiki_page` - Get details of a specific wiki page
37. `create_wiki_page` - Create a new wiki page in a GitLab project
38. `update_wiki_page` - Update an existing wiki page in a GitLab project
39. `delete_wiki_page` - Delete a wiki page from a GitLab project
40. `get_repository_tree` - Get the repository tree for a GitLab project (list files and directories)
14. `create_merge_request_thread` - Create a new thread on a merge request
15. `mr_discussions` - List discussion items for a merge request
16. `update_merge_request_note` - Modify an existing merge request thread note
17. `create_merge_request_note` - Add a new note to an existing merge request thread
18. `update_issue_note` - Modify an existing issue thread note
19. `create_issue_note` - Add a new note to an existing issue thread
20. `list_issues` - List issues in a GitLab project with filtering options
21. `get_issue` - Get details of a specific issue in a GitLab project
22. `update_issue` - Update an issue in a GitLab project
23. `delete_issue` - Delete an issue from a GitLab project
24. `list_issue_links` - List all issue links for a specific issue
25. `list_issue_discussions` - List discussions for an issue in a GitLab project
26. `get_issue_link` - Get a specific issue link
27. `create_issue_link` - Create an issue link between two issues
28. `delete_issue_link` - Delete an issue link
29. `list_namespaces` - List all namespaces available to the current user
30. `get_namespace` - Get details of a namespace by ID or path
31. `verify_namespace` - Verify if a namespace path exists
32. `get_project` - Get details of a specific project
33. `list_projects` - List projects accessible by the current user
34. `list_labels` - List labels for a project
35. `get_label` - Get a single label from a project
36. `create_label` - Create a new label in a project
37. `update_label` - Update an existing label in a project
38. `delete_label` - Delete a label from a project
39. `list_group_projects` - List projects in a GitLab group with filtering options
40. `list_wiki_pages` - List wiki pages in a GitLab project
41. `get_wiki_page` - Get details of a specific wiki page
42. `create_wiki_page` - Create a new wiki page in a GitLab project
43. `update_wiki_page` - Update an existing wiki page in a GitLab project
44. `delete_wiki_page` - Delete a wiki page from a GitLab project
45. `get_repository_tree` - Get the repository tree for a GitLab project (list files and directories)
46. `list_pipelines` - List pipelines in a GitLab project with filtering options
47. `get_pipeline` - Get details of a specific pipeline in a GitLab project
48. `list_pipeline_jobs` - List all jobs in a specific pipeline
49. `get_pipeline_job` - Get details of a GitLab pipeline job number
50. `get_pipeline_job_output` - Get the output/trace of a GitLab pipeline job number
<!-- TOOLS-END -->

689
index.ts

File diff suppressed because it is too large Load Diff

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "@zereight/mcp-gitlab",
"version": "1.0.33",
"version": "1.0.38",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@zereight/mcp-gitlab",
"version": "1.0.33",
"version": "1.0.38",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.8.0",

View File

@ -1,6 +1,6 @@
{
"name": "@zereight/mcp-gitlab",
"version": "1.0.34",
"version": "1.0.46",
"description": "MCP server for using the GitLab API",
"license": "MIT",
"author": "zereight",

5
release-notes.md Normal file
View File

@ -0,0 +1,5 @@
### 1.0.40 (2025-05-21)
- Added support for listing discussions (comments/notes) on GitLab issues.
- Example: You can now easily fetch all conversations (comments) attached to an issue via the API.
- Related PR: [#44](https://github.com/zereight/gitlab-mcp/pull/44)

View File

@ -7,6 +7,119 @@ export const GitLabAuthorSchema = z.object({
date: z.string(),
});
// Pipeline related schemas
export const GitLabPipelineSchema = z.object({
id: z.number(),
project_id: z.number(),
sha: z.string(),
ref: z.string(),
status: z.string(),
source: z.string().optional(),
created_at: z.string(),
updated_at: z.string(),
web_url: z.string(),
duration: z.number().nullable().optional(),
started_at: z.string().nullable().optional(),
finished_at: z.string().nullable().optional(),
coverage: z.number().nullable().optional(),
user: z.object({
id: z.number(),
name: z.string(),
username: z.string(),
avatar_url: z.string().nullable().optional(),
}).optional(),
detailed_status: z.object({
icon: z.string().optional(),
text: z.string().optional(),
label: z.string().optional(),
group: z.string().optional(),
tooltip: z.string().optional(),
has_details: z.boolean().optional(),
details_path: z.string().optional(),
illustration: z.object({
image: z.string().optional(),
size: z.string().optional(),
title: z.string().optional(),
}).optional(),
favicon: z.string().optional(),
}).optional(),
});
// Pipeline job related schemas
export const GitLabPipelineJobSchema = z.object({
id: z.number(),
status: z.string(),
stage: z.string(),
name: z.string(),
ref: z.string(),
tag: z.boolean(),
coverage: z.number().nullable().optional(),
created_at: z.string(),
started_at: z.string().nullable().optional(),
finished_at: z.string().nullable().optional(),
duration: z.number().nullable().optional(),
user: z.object({
id: z.number(),
name: z.string(),
username: z.string(),
avatar_url: z.string().nullable().optional(),
}).optional(),
commit: z.object({
id: z.string(),
short_id: z.string(),
title: z.string(),
author_name: z.string(),
author_email: z.string(),
}).optional(),
pipeline: z.object({
id: z.number(),
project_id: z.number(),
status: z.string(),
ref: z.string(),
sha: z.string(),
}).optional(),
web_url: z.string().optional(),
});
// Schema for listing pipelines
export const ListPipelinesSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
scope: z.enum(['running', 'pending', 'finished', 'branches', 'tags']).optional().describe("The scope of pipelines"),
status: z.enum(['created', 'waiting_for_resource', 'preparing', 'pending', 'running', 'success', 'failed', 'canceled', 'skipped', 'manual', 'scheduled']).optional().describe("The status of pipelines"),
ref: z.string().optional().describe("The ref of pipelines"),
sha: z.string().optional().describe("The SHA of pipelines"),
yaml_errors: z.boolean().optional().describe("Returns pipelines with invalid configurations"),
username: z.string().optional().describe("The username of the user who triggered pipelines"),
updated_after: z.string().optional().describe("Return pipelines updated after the specified date"),
updated_before: z.string().optional().describe("Return pipelines updated before the specified date"),
order_by: z.enum(['id', 'status', 'ref', 'updated_at', 'user_id']).optional().describe("Order pipelines by"),
sort: z.enum(['asc', 'desc']).optional().describe("Sort pipelines"),
page: z.number().optional().describe("Page number for pagination"),
per_page: z.number().optional().describe("Number of items per page (max 100)"),
});
// Schema for getting a specific pipeline
export const GetPipelineSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
pipeline_id: z.number().describe("The ID of the pipeline"),
});
// Schema for listing jobs in a pipeline
export const ListPipelineJobsSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
pipeline_id: z.number().describe("The ID of the pipeline"),
scope: z.enum(['created', 'pending', 'running', 'failed', 'success', 'canceled', 'skipped', 'manual']).optional().describe("The scope of jobs to show"),
include_retried: z.boolean().optional().describe("Whether to include retried jobs"),
page: z.number().optional().describe("Page number for pagination"),
per_page: z.number().optional().describe("Number of items per page (max 100)"),
});
// Schema for the input parameters for pipeline job operations
export const GetPipelineJobOutputSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
job_id: z.number().describe("The ID of the job"),
});
// Namespace related schemas
// Base schema for project-related operations
@ -107,7 +220,7 @@ export const GitLabRepositorySchema = z.object({
jobs_enabled: z.boolean().optional(),
snippets_enabled: z.boolean().optional(),
can_create_merge_request_in: z.boolean().optional(),
resolve_outdated_diff_discussions: z.boolean().optional(),
resolve_outdated_diff_discussions: z.boolean().nullable().optional(),
shared_runners_enabled: z.boolean().optional(),
shared_with_groups: z
.array(
@ -171,11 +284,25 @@ export const GitLabTreeItemSchema = z.object({
export const GetRepositoryTreeSchema = z.object({
project_id: z.string().describe("The ID or URL-encoded path of the project"),
path: z.string().optional().describe("The path inside the repository"),
ref: z.string().optional().describe("The name of a repository branch or tag. Defaults to the default branch."),
recursive: z.boolean().optional().describe("Boolean value to get a recursive tree"),
per_page: z.number().optional().describe("Number of results to show per page"),
page_token: z.string().optional().describe("The tree record ID for pagination"),
pagination: z.string().optional().describe("Pagination method (keyset)")
ref: z
.string()
.optional()
.describe(
"The name of a repository branch or tag. Defaults to the default branch."
),
recursive: z
.boolean()
.optional()
.describe("Boolean value to get a recursive tree"),
per_page: z
.number()
.optional()
.describe("Number of results to show per page"),
page_token: z
.string()
.optional()
.describe("The tree record ID for pagination"),
pagination: z.string().optional().describe("Pagination method (keyset)"),
});
export const GitLabTreeSchema = z.object({
@ -280,7 +407,7 @@ export const GitLabMilestoneSchema = z.object({
id: z.number(),
iid: z.number(), // Added to match GitLab API
title: z.string(),
description: z.string(),
description: z.string().nullable().default(""),
state: z.string(),
web_url: z.string(), // Changed from html_url to match GitLab API
});
@ -290,7 +417,7 @@ export const GitLabIssueSchema = z.object({
iid: z.number(), // Added to match GitLab API
project_id: z.number(), // Added to match GitLab API
title: z.string(),
description: z.string(), // Changed from body to match GitLab API
description: z.string().nullable().default(""), // Changed from body to match GitLab API
state: z.string(),
author: GitLabUserSchema,
assignees: z.array(GitLabUserSchema),
@ -422,13 +549,13 @@ export const GitLabDiscussionNoteSchema = z.object({
.object({
start: z.object({
line_code: z.string(),
type: z.enum(["new", "old"]),
type: z.enum(["new", "old", "expanded"]).optional(),
old_line: z.number().nullable(),
new_line: z.number().nullable(),
}),
end: z.object({
line_code: z.string(),
type: z.enum(["new", "old"]),
type: z.enum(["new", "old", "expanded"]).optional(),
old_line: z.number().nullable(),
new_line: z.number().nullable(),
}),
@ -461,8 +588,36 @@ export const UpdateMergeRequestNoteSchema = ProjectParamsSchema.extend({
merge_request_iid: z.number().describe("The IID of a merge request"),
discussion_id: z.string().describe("The ID of a thread"),
note_id: z.number().describe("The ID of a thread note"),
body: z.string().optional().describe("The content of the note or reply"),
resolved: z.boolean().optional().describe("Resolve or unresolve the note"),
}).refine(data => data.body !== undefined || data.resolved !== undefined, {
message: "At least one of 'body' or 'resolved' must be provided"
}).refine(data => !(data.body !== undefined && data.resolved !== undefined), {
message: "Only one of 'body' or 'resolved' can be provided, not both"
});
// Input schema for adding a note to an existing merge request discussion
export const CreateMergeRequestNoteSchema = ProjectParamsSchema.extend({
merge_request_iid: z.number().describe("The IID of a merge request"),
discussion_id: z.string().describe("The ID of a thread"),
body: z.string().describe("The content of the note or reply"),
resolved: z.boolean().optional().describe("Resolve or unresolve the note"), // Optional based on API docs
created_at: z.string().optional().describe("Date the note was created at (ISO 8601 format)"),
});
// Input schema for updating an issue discussion note
export const UpdateIssueNoteSchema = ProjectParamsSchema.extend({
issue_iid: z.number().describe("The IID of an issue"),
discussion_id: z.string().describe("The ID of a thread"),
note_id: z.number().describe("The ID of a thread note"),
body: z.string().describe("The content of the note or reply"),
});
// Input schema for adding a note to an existing issue discussion
export const CreateIssueNoteSchema = ProjectParamsSchema.extend({
issue_iid: z.number().describe("The IID of an issue"),
discussion_id: z.string().describe("The ID of a thread"),
body: z.string().describe("The content of the note or reply"),
created_at: z.string().optional().describe("Date the note was created at (ISO 8601 format)"),
});
// API Operation Parameter Schemas
@ -731,6 +886,15 @@ export const ListIssueLinksSchema = z.object({
issue_iid: z.number().describe("The internal ID of a project's issue"),
});
export const ListIssueDiscussionsSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
issue_iid: z.number().describe("The internal ID of the project issue"),
page: z.number().optional().describe("Page number for pagination"),
per_page: z.number().optional().describe("Number of items per page"),
sort: z.enum(["asc", "desc"]).optional().describe("Return issue discussions sorted in ascending or descending order"),
order_by: z.enum(["created_at", "updated_at"]).optional().describe("Return issue discussions ordered by created_at or updated_at fields"),
});
export const GetIssueLinkSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
issue_iid: z.number().describe("The internal ID of a project's issue"),
@ -849,9 +1013,7 @@ export const ListLabelsSchema = z.object({
export const GetLabelSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
label_id: z
.union([z.number(), z.string()])
.describe("The ID or title of a project's label"),
label_id: z.string().describe("The ID or title of a project's label"),
include_ancestor_groups: z
.boolean()
.optional()
@ -876,9 +1038,7 @@ export const CreateLabelSchema = z.object({
export const UpdateLabelSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
label_id: z
.union([z.number(), z.string()])
.describe("The ID or title of a project's label"),
label_id: z.string().describe("The ID or title of a project's label"),
new_name: z.string().optional().describe("The new name of the label"),
color: z
.string()
@ -899,9 +1059,7 @@ export const UpdateLabelSchema = z.object({
export const DeleteLabelSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
label_id: z
.union([z.number(), z.string()])
.describe("The ID or title of a project's label"),
label_id: z.string().describe("The ID or title of a project's label"),
});
// Group projects schema
@ -996,6 +1154,30 @@ export const GitLabWikiPageSchema = z.object({
updated_at: z.string().optional(),
});
// Merge Request Thread position schema - used for diff notes
export const MergeRequestThreadPositionSchema = z.object({
base_sha: z.string().describe("Base commit SHA in the source branch"),
head_sha: z.string().describe("SHA referencing HEAD of the source branch"),
start_sha: z.string().describe("SHA referencing the start commit of the source branch"),
position_type: z.enum(["text", "image", "file"]).describe("Type of position reference"),
new_path: z.string().optional().describe("File path after change"),
old_path: z.string().optional().describe("File path before change"),
new_line: z.number().nullable().optional().describe("Line number after change"),
old_line: z.number().nullable().optional().describe("Line number before change"),
width: z.number().optional().describe("Width of the image (for image diffs)"),
height: z.number().optional().describe("Height of the image (for image diffs)"),
x: z.number().optional().describe("X coordinate on the image (for image diffs)"),
y: z.number().optional().describe("Y coordinate on the image (for image diffs)"),
});
// Schema for creating a new merge request thread
export const CreateMergeRequestThreadSchema = ProjectParamsSchema.extend({
merge_request_iid: z.number().describe("The IID of a merge request"),
body: z.string().describe("The content of the thread"),
position: MergeRequestThreadPositionSchema.optional().describe("Position when creating a diff note"),
created_at: z.string().optional().describe("Date the thread was created at (ISO 8601 format)"),
});
// Export types
export type GitLabAuthor = z.infer<typeof GitLabAuthorSchema>;
export type GitLabFork = z.infer<typeof GitLabForkSchema>;
@ -1031,6 +1213,9 @@ export type GitLabMergeRequestDiff = z.infer<
>;
export type CreateNoteOptions = z.infer<typeof CreateNoteSchema>;
export type GitLabIssueLink = z.infer<typeof GitLabIssueLinkSchema>;
export type ListIssueDiscussionsOptions = z.infer<typeof ListIssueDiscussionsSchema>;
export type UpdateIssueNoteOptions = z.infer<typeof UpdateIssueNoteSchema>;
export type CreateIssueNoteOptions = z.infer<typeof CreateIssueNoteSchema>;
export type GitLabNamespace = z.infer<typeof GitLabNamespaceSchema>;
export type GitLabNamespaceExistsResponse = z.infer<
typeof GitLabNamespaceExistsResponseSchema
@ -1045,3 +1230,11 @@ export type DeleteWikiPageOptions = z.infer<typeof DeleteWikiPageSchema>;
export type GitLabWikiPage = z.infer<typeof GitLabWikiPageSchema>;
export type GitLabTreeItem = z.infer<typeof GitLabTreeItemSchema>;
export type GetRepositoryTreeOptions = z.infer<typeof GetRepositoryTreeSchema>;
export type MergeRequestThreadPosition = z.infer<typeof MergeRequestThreadPositionSchema>;
export type CreateMergeRequestThreadOptions = z.infer<typeof CreateMergeRequestThreadSchema>;
export type CreateMergeRequestNoteOptions = z.infer<typeof CreateMergeRequestNoteSchema>;
export type GitLabPipelineJob = z.infer<typeof GitLabPipelineJobSchema>;
export type GitLabPipeline = z.infer<typeof GitLabPipelineSchema>;
export type ListPipelinesOptions = z.infer<typeof ListPipelinesSchema>;
export type GetPipelineOptions = z.infer<typeof GetPipelineSchema>;
export type ListPipelineJobsOptions = z.infer<typeof ListPipelineJobsSchema>;